[saods9] 03/07: New upstream+dfsg version 7.3b3

Ole Streicher olebole-guest at alioth.debian.org
Thu Sep 26 12:24:33 UTC 2013


This is an automated email from the git hooks/post-receive script.

olebole-guest pushed a commit to branch debian
in repository saods9.

commit 08d287872133691e2235646c078b103847b7352f
Author: Ole Streicher <debian at liska.ath.cx>
Date:   Thu Sep 26 10:55:30 2013 +0200

    New upstream+dfsg version 7.3b3
---
 Makefile                                           |  269 +-
 Makefile.macosx                                    |  172 +
 Makefile.unix                                      |  102 +
 Makefile.windows                                   |  116 +
 blt3.0.1/configure                                 |    4 +-
 blt3.0.1/src/bltUnixBitmap.c                       |    2 +
 blt3.0.1/src/bltUnixPainter.c                      |    8 +-
 blt3.0.1/src/bltUnixWindow.c                       |   10 +-
 doc/release/r7.0.html                              |   10 +
 ds9/Makefile                                       |  404 +-
 ds9/Makefile.macosx                                |  166 +
 ds9/Makefile.unix                                  |  226 +
 ds9/Makefile.windows                               |  132 +
 ds9/{ds9.C => ds9.macosx}                          |  137 +-
 ds9/{ds9.C => ds9.unix}                            |   86 +-
 ds9/{ds9.C => ds9.windows}                         |  122 +-
 .../Contents/Info.plist                            |    2 +-
 .../Contents/MacOS/ds9                             |    0
 .../Contents/PkgInfo                               |    0
 .../Contents/Resources/App.icns                    |  Bin 0 -> 47991 bytes
 .../Resources/English.lproj/InfoPlist.strings      |  Bin 686 -> 686 bytes
 .../Resources/English.lproj/main.nib/classes.nib   |    0
 .../Resources/English.lproj/main.nib/info.nib      |    0
 .../Resources/English.lproj/main.nib/objects.xib   |    0
 .../Contents/Resources/fits.icns                   |  Bin 0 -> 48529 bytes
 ds9/macosx/SAOImage DS9.app/Contents/Info.plist    |   26 +-
 ds9/win/ds9.rc                                     |    2 +-
 macosx/Makefile                                    |   24 +-
 macosx/macosxlib.h                                 |    6 +-
 macosx/{macosxlib.C => macosxlib.mm}               |    7 -
 {unix => macosx}/rotstr.h                          |    7 +-
 macosx/rotstr.mm                                   |   52 +
 macosx/tkmacosx.h                                  |    9 +-
 macosx/{tkmacosx.C => tkmacosx.mm}                 |  108 +-
 macosx/xxlib.C                                     |  336 -
 macosx/xxlib.h                                     |   36 +-
 macosx/xxlib.mm                                    |  142 +
 make.cygwin                                        |    6 +-
 make.darwin64x86lion                               |   10 +-
 make.darwin64x86mountainlion                       |   12 +-
 make.darwin64x86snowleopard                        |   10 +-
 make.darwinx86lion                                 |   11 +-
 make.darwinx86mountainlion                         |   11 +-
 make.darwinx86snowleopard                          |   11 +-
 make.linux                                         |    9 +-
 make.linux64                                       |    8 +-
 ...darwinx86snowleopard => make.macosxmountainlion |   16 +-
 make.macosxx86mountainlion                         |   27 -
 make.pkgs                                          |   10 +-
 make.source                                        |    1 +
 notes.txt                                          |  103 +-
 saotk/colorbar/Makefile                            |   33 +-
 saotk/colorbar/colorbarpseudocolor.C               |    2 +-
 saotk/colorbar/colorbarpseudocolor8.C              |  189 -
 saotk/colorbar/colorbarrgbtruecolor.C              |    2 +-
 saotk/colorbar/colorbarrgbtruecolor16.C            |    4 +-
 saotk/colorbar/colorbarrgbtruecolor24.C            |   43 +-
 saotk/colorbar/colorbarrgbtruecolor8.C             |    4 +-
 saotk/colorbar/colorbartrue.C                      |    2 +-
 saotk/colorbar/colorbartruecolor.C                 |    2 +-
 saotk/colorbar/colorbartruecolor16.C               |    4 +-
 saotk/colorbar/colorbartruecolor24.C               |   16 +-
 saotk/colorbar/colorbartruecolor8.C                |    4 +-
 saotk/colorbar/colortag.h                          |    4 +-
 saotk/fitsy++/Makefile                             |   20 +-
 saotk/fitsy++/alloc.C                              |    1 +
 saotk/fitsy++/analysis.C                           |    4 +-
 saotk/fitsy++/channel.C                            |    2 +
 saotk/fitsy++/compress.C                           |   11 +-
 saotk/fitsy++/compress.h                           |    4 +-
 saotk/fitsy++/envi.C                               |  208 +-
 saotk/fitsy++/envi.h                               |   20 +-
 saotk/fitsy++/envilex.C                            |  670 +-
 saotk/fitsy++/envilex.L                            |    3 +
 saotk/fitsy++/enviparser.C                         |  548 +-
 saotk/fitsy++/enviparser.H                         |  108 +-
 saotk/fitsy++/enviparser.Y                         |    5 +
 saotk/fitsy++/file.C                               |   78 +-
 saotk/fitsy++/file.h                               |   22 +-
 saotk/fitsy++/hist.C                               |    9 +-
 saotk/fitsy++/hpx.C                                |   35 -
 saotk/fitsy++/hpx.h                                |    8 +-
 saotk/fitsy++/map.C                                |   14 +-
 saotk/fitsy++/mapincr.C                            |   11 +-
 saotk/fitsy++/nrrd.C                               |  183 +-
 saotk/fitsy++/nrrd.h                               |   11 +-
 saotk/fitsy++/nrrdgzip.C                           |    2 +-
 saotk/fitsy++/nrrdparser.C                         |   11 +-
 saotk/fitsy++/nrrdparser.Y                         |    1 -
 saotk/fitsy++/outchannel.C                         |    2 +
 saotk/fitsy++/outfile.C                            |    1 +
 saotk/fitsy++/outfits.h                            |    2 -
 saotk/fitsy++/parser.C                             |  251 +-
 saotk/fitsy++/parser.Y                             |    6 +-
 saotk/fitsy++/photo.C                              |   15 +-
 saotk/fitsy++/photo.h                              |    2 +
 saotk/fitsy++/savefits.C                           |   99 +-
 saotk/fitsy++/smap.C                               |   12 +-
 saotk/fitsy++/strm.C                               |   15 +-
 saotk/fitsy++/var.C                                |    2 +
 saotk/frame/Makefile                               |   34 +-
 saotk/frame/annulus.C                              |    2 +
 saotk/frame/base.C                                 |    4 +-
 saotk/frame/base.h                                 |    4 +-
 saotk/frame/basebox.C                              |   10 +-
 saotk/frame/basebox.h                              |   11 +-
 saotk/frame/basecommand.C                          |    2 +-
 saotk/frame/baseellipse.C                          |    6 +-
 saotk/frame/baseellipse.h                          |   11 +-
 saotk/frame/baseline.C                             |    2 +
 saotk/frame/basemarker.C                           |    2 +
 saotk/frame/box.C                                  |    2 +
 saotk/frame/boxannulus.C                           |    2 +
 saotk/frame/bpanda.C                               |    6 +-
 saotk/frame/circle.C                               |    2 +
 saotk/frame/colorscale.h                           |    3 -
 saotk/frame/colorscalepseudo8.C                    |  112 -
 saotk/frame/colorscalepseudo8.h                    |   91 -
 saotk/frame/colorscalergb.h                        |    3 -
 saotk/frame/colorscaletrue32.C                     |    6 +
 saotk/frame/compass.C                              |    4 +-
 saotk/frame/composite.C                            |    2 +
 saotk/frame/context.C                              |   50 +-
 saotk/frame/context.h                              |    1 -
 saotk/frame/contour.h                              |    3 +
 saotk/frame/cpanda.C                               |    2 +
 saotk/frame/ellipse.C                              |    2 +
 saotk/frame/ellipseannulus.C                       |    2 +
 saotk/frame/epanda.C                               |    2 +
 saotk/frame/fitscompress.C                         |   62 +-
 saotk/frame/fitsenvi.C                             |   34 +-
 saotk/frame/fitsimage.C                            |   50 +-
 saotk/frame/fitsimage.h                            |    8 +-
 saotk/frame/fitsmask.C                             |    4 +
 saotk/frame/fitsmask.h                             |    1 -
 saotk/frame/fitsnrrd.C                             |   20 +-
 saotk/frame/fr3dcommand.C                          |    2 -
 saotk/frame/frame3dbase.C                          |    8 +-
 saotk/frame/frame3dtrue.C                          |    4 -
 saotk/frame/frame3dtruecolor.C                     |    4 -
 saotk/frame/framebase.C                            |    4 -
 saotk/frame/framepseudo.C                          |   53 -
 saotk/frame/framepseudo.h                          |   20 -
 saotk/frame/framepseudocolor.C                     |  143 -
 saotk/frame/framepseudocolor.h                     |   26 -
 saotk/frame/framepseudocolor8.C                    |  167 -
 saotk/frame/framepseudocolor8.h                    |   21 -
 saotk/frame/framergb.C                             |   26 +-
 saotk/frame/framergbtruecolor.C                    |    2 +-
 saotk/frame/frametrue.C                            |    6 +-
 saotk/frame/frametruecolor.C                       |    4 +-
 saotk/frame/frblt.C                                |   88 +-
 saotk/frame/frcommand.C                            |    2 +-
 saotk/frame/grid.h                                 |    2 -
 saotk/frame/grid25d.h                              |    2 -
 saotk/frame/grid2d.h                               |    2 -
 saotk/frame/grid3d.h                               |    2 -
 saotk/frame/line.C                                 |    2 +
 saotk/frame/marker.C                               |   15 +-
 saotk/frame/marker.h                               |   19 +-
 saotk/frame/point.C                                |    7 +-
 saotk/frame/point.h                                |    9 +-
 saotk/frame/polygon.C                              |    5 +-
 saotk/frame/polygon.h                              |   12 +-
 saotk/frame/projection.C                           |    2 +
 saotk/frame/ruler.C                                |    4 +-
 saotk/frame/segment.C                              |    2 +
 saotk/frame/text.C                                 |   14 +-
 saotk/frame/vect.C                                 |    2 +
 saotk/list/Makefile                                |   20 +-
 saotk/magnifier/Makefile                           |   31 +-
 saotk/magnifier/magnifierpseudo.C                  |  107 -
 saotk/magnifier/magnifierpseudo.h                  |   18 -
 saotk/magnifier/magnifiertrue.C                    |    4 +-
 saotk/panner/Makefile                              |   27 +-
 saotk/panner/panner.C                              |    2 +-
 saotk/panner/pannerpseudo.C                        |  104 -
 saotk/panner/pannerpseudo.h                        |   19 -
 saotk/panner/pannertrue.C                          |    5 +-
 saotk/util/Makefile                                |   20 +-
 saotk/util/grid25dbase.h                           |    2 -
 saotk/util/grid2dbase.h                            |    2 -
 saotk/util/gridbase.C                              |    9 +-
 saotk/util/saotk.C                                 |   21 +-
 saotk/util/util.C                                  |    4 -
 saotk/util/util.h                                  |   11 +-
 saotk/vector/Makefile                              |   20 +-
 saotk/vector/vector.C                              |    8 +-
 saotk/vector/vector.h                              |    6 +-
 saotk/vector/vector3d.C                            |    7 +-
 saotk/vector/vector3d.h                            |    4 +-
 saotk/vector/vectorold.h                           |    2 +-
 saotk/widget/Makefile                              |   20 +-
 saotk/widget/truecolor16.C                         |   18 +-
 saotk/widget/truecolor24.C                         |   29 +-
 saotk/widget/truecolor8.C                          |   18 +-
 saotk/widget/widget.h                              |    1 -
 src/3d.tcl                                         |    1 -
 src/Makefile                                       |    9 +-
 src/analysis.tcl                                   |    2 +-
 src/backup.tcl                                     |   11 +-
 src/bin.tcl                                        |    1 -
 src/buttons.tcl                                    |   44 +-
 src/catcmd.tcl                                     |   13 +
 src/catdialog.tcl                                  |    2 +-
 src/catsym.tcl                                     |    2 +-
 src/centroid.tcl                                   |    1 -
 src/colorbar.tcl                                   |  146 +-
 src/command.tcl                                    |    2 +-
 src/ds9.tcl                                        |  156 +-
 src/frame.tcl                                      |  127 +-
 src/group.tcl                                      |   10 +-
 src/hvsup.tcl                                      |    3 +
 src/layout.tcl                                     |   24 +-
 src/macosx.tcl                                     |   33 +-
 src/marker.tcl                                     |    1 +
 src/mask.tcl                                       |   12 +-
 src/mcolor.tcl                                     |    7 +-
 src/menu.tcl                                       |   19 +-
 src/mframe.tcl                                     |   14 +-
 src/mhelp.tcl                                      |   42 +-
 src/print.tcl                                      |   52 +-
 src/stdfbox.tcl                                    |   83 +-
 src/util.tcl                                       |   36 +-
 tests/parse.sh                                     |    8 +-
 tlt3.0/Makefile.in                                 |  449 +
 tlt3.0/aclocal.m4                                  |   96 +
 tlt3.0/bltBase64.c                                 |  285 +
 tlt3.0/bltBase64.h                                 |   39 +
 tlt3.0/bltBgStyle.c                                | 2018 ++++
 tlt3.0/bltBgStyle.h                                |   74 +
 tlt3.0/bltBind.c                                   |  776 ++
 tlt3.0/bltBind.h                                   |  120 +
 blt3.0.1/src/bltUnixBitmap.c => tlt3.0/bltBitmap.c |  132 +-
 tlt3.0/bltBitmap.h                                 |   43 +
 tlt3.0/bltChain.c                                  |  520 +
 tlt3.0/bltChain.h                                  |   90 +
 tlt3.0/bltConfig.c                                 | 2024 ++++
 tlt3.0/bltConfig.h                                 |  326 +
 tlt3.0/bltDBuffer.c                                |  323 +
 tlt3.0/bltDBuffer.h                                |   92 +
 tlt3.0/bltFont.h                                   |  137 +
 tlt3.0/bltGrAxis.c                                 | 5564 ++++++++++
 tlt3.0/bltGrAxis.h                                 |  332 +
 tlt3.0/bltGrBar.c                                  | 2539 +++++
 tlt3.0/bltGrElem.c                                 | 2214 ++++
 tlt3.0/bltGrElem.h                                 |  251 +
 tlt3.0/bltGrHairs.c                                |  535 +
 tlt3.0/bltGrLegd.c                                 | 2838 ++++++
 tlt3.0/bltGrLegd.h                                 |   60 +
 tlt3.0/bltGrLine.c                                 | 4798 +++++++++
 tlt3.0/bltGrMarker.c                               | 4372 ++++++++
 tlt3.0/bltGrMisc.c                                 | 1005 ++
 tlt3.0/bltGrPen.c                                  |  760 ++
 tlt3.0/bltGrPs.c                                   |  709 ++
 tlt3.0/bltGraph.c                                  | 1762 ++++
 tlt3.0/bltGraph.h                                  |  698 ++
 tlt3.0/bltHash.c                                   | 1266 +++
 tlt3.0/bltHash.h                                   |  180 +
 tlt3.0/bltImage.c                                  |  156 +
 tlt3.0/bltImage.h                                  |   51 +
 tlt3.0/bltInit.c                                   |  123 +
 tlt3.0/bltInt.c                                    |   83 +
 tlt3.0/bltInt.h                                    |  331 +
 tlt3.0/bltList.c                                   |  558 +
 tlt3.0/bltList.h                                   |  116 +
 tlt3.0/bltMath.h                                   |   45 +
 tlt3.0/bltNsUtil.c                                 |  146 +
 tlt3.0/bltNsUtil.h                                 |   59 +
 tlt3.0/bltOp.h                                     |   37 +
 tlt3.0/bltParse.c                                  |  511 +
 tlt3.0/bltParse.h                                  |   47 +
 tlt3.0/bltPool.c                                   |  474 +
 tlt3.0/bltPool.h                                   |   23 +
 tlt3.0/bltPs.c                                     | 1328 +++
 tlt3.0/bltPs.h                                     |  210 +
 tlt3.0/bltPsAfm.c                                  | 1557 +++
 tlt3.0/bltPsInt.h                                  |   49 +
 tlt3.0/bltSpline.c                                 | 1287 +++
 tlt3.0/bltSpline.h                                 |   43 +
 tlt3.0/bltSwitch.c                                 |  538 +
 tlt3.0/bltSwitch.h                                 |  134 +
 tlt3.0/bltText.c                                   | 1320 +++
 tlt3.0/bltText.h                                   |  240 +
 tlt3.0/bltUnixFont.c                               | 2658 +++++
 tlt3.0/bltUnixWindow.c                             |  211 +
 tlt3.0/bltUtil.c                                   |  731 ++
 tlt3.0/bltVecCmd.c                                 | 2418 +++++
 tlt3.0/bltVecInt.h                                 |  250 +
 tlt3.0/bltVecMath.c                                | 1897 ++++
 tlt3.0/bltVector.c                                 | 2794 +++++
 tlt3.0/bltVector.h                                 |  137 +
 tlt3.0/bltWindow.c                                 |  247 +
 tlt3.0/bltWindow.h                                 |   58 +
 tlt3.0/configure                                   |10699 ++++++++++++++++++++
 tlt3.0/configure.in                                |  299 +
 tlt3.0/doc/BLT.n                                   |  153 +
 tlt3.0/doc/barchart.n                              | 2236 ++++
 tlt3.0/doc/graph.n                                 | 2397 +++++
 tlt3.0/doc/vector.n                                | 1130 +++
 tlt3.0/library/afm/AvantGarde-Book.afm             |  574 ++
 tlt3.0/library/afm/AvantGarde-BookOblique.afm      |  574 ++
 tlt3.0/library/afm/AvantGarde-Demi.afm             |  577 ++
 tlt3.0/library/afm/AvantGarde-DemiOblique.afm      |  577 ++
 tlt3.0/library/afm/Bookman-Demi.afm                |  416 +
 tlt3.0/library/afm/Bookman-DemiItalic.afm          |  418 +
 tlt3.0/library/afm/Bookman-Light.afm               |  408 +
 tlt3.0/library/afm/Bookman-LightItalic.afm         |  411 +
 tlt3.0/library/afm/Courier-Bold.afm                |  345 +
 tlt3.0/library/afm/Courier-BoldOblique.afm         |  345 +
 tlt3.0/library/afm/Courier-Oblique.afm             |  345 +
 tlt3.0/library/afm/Courier.afm                     |  345 +
 tlt3.0/library/afm/Helvetica-Bold.afm              |  571 ++
 tlt3.0/library/afm/Helvetica-BoldOblique.afm       |  571 ++
 tlt3.0/library/afm/Helvetica-Condensed-Bold.afm    |  419 +
 tlt3.0/library/afm/Helvetica-Condensed-BoldObl.afm |  419 +
 tlt3.0/library/afm/Helvetica-Condensed-Oblique.afm |  421 +
 tlt3.0/library/afm/Helvetica-Condensed.afm         |  421 +
 tlt3.0/library/afm/Helvetica-Narrow-Bold.afm       |  571 ++
 .../library/afm/Helvetica-Narrow-BoldOblique.afm   |  571 ++
 tlt3.0/library/afm/Helvetica-Narrow-Oblique.afm    |  613 ++
 tlt3.0/library/afm/Helvetica-Narrow.afm            |  613 ++
 tlt3.0/library/afm/Helvetica-Oblique.afm           |  613 ++
 tlt3.0/library/afm/Helvetica.afm                   |  613 ++
 tlt3.0/library/afm/NewCenturySchlbk-Bold.afm       |  473 +
 tlt3.0/library/afm/NewCenturySchlbk-BoldItalic.afm |  603 ++
 tlt3.0/library/afm/NewCenturySchlbk-Italic.afm     |  537 +
 tlt3.0/library/afm/NewCenturySchlbk-Roman.afm      |  525 +
 tlt3.0/library/afm/Palatino-Bold.afm               |  435 +
 tlt3.0/library/afm/Palatino-BoldItalic.afm         |  442 +
 tlt3.0/library/afm/Palatino-Italic.afm             |  440 +
 tlt3.0/library/afm/Palatino-Roman.afm              |  446 +
 tlt3.0/library/afm/Symbol.afm                      |  210 +
 tlt3.0/library/afm/Times-Bold.afm                  |  649 ++
 tlt3.0/library/afm/Times-BoldItalic.afm            |  649 ++
 tlt3.0/library/afm/Times-Italic.afm                |  649 ++
 tlt3.0/library/afm/Times-Roman.afm                 |  649 ++
 tlt3.0/library/afm/ZapfChancery-MediumItalic.afm   |  481 +
 tlt3.0/library/afm/ZapfDingbats.afm                |  223 +
 tlt3.0/library/bltGraph.pro                        |  472 +
 tlt3.0/library/graph.tcl                           |  840 ++
 tlt3.0/pkgIndex.tcl.in                             |    5 +
 tlt3.0/tclconfig/ChangeLog                         |  980 ++
 tlt3.0/tclconfig/README.txt                        |   26 +
 tlt3.0/tclconfig/install-sh                        |  528 +
 tlt3.0/tclconfig/tcl.m4                            | 4150 ++++++++
 unix/Makefile                                      |    9 -
 unix/rotstr.C                                      |    4 +-
 unix/rotstr.h                                      |    2 +-
 win/Makefile                                       |   13 +-
 350 files changed, 104501 insertions(+), 5214 deletions(-)

diff --git a/Makefile b/Makefile
index a34466a..42defcb 100644
--- a/Makefile
+++ b/Makefile
@@ -22,89 +22,12 @@ DIRS = bin lib include man share dist
 DS9APP=SAOImage\ DS9\ $(DS9VERSION)
 XPAAPP=XPA\ $(XPAVERSION)
 
-#--------------------------blt stuff
-
-BLTINCL	= blt.h bltVector.h
-
-BLTWITHOUT = \
-	--without-jpegincdir --without-jpeglibdir \
-	--without-pngincdir --without-pnglibdir \
-	--without-tiffincdir --without-tifflibdir \
-	--without-xpmincdir --without-xpmlibdir \
-	--without-xrandrincdir --without-xrandrlibdir \
-	--without-expatincdir --without-expatlibdir \
-	--without-mysqlincdir --without-mysqllibdir
-
-#--------------------------flags
-
-ifeq ($(OS),unix)
-  PORT=unix
-
-  TCLINSTALL=install
-  TCLDIRDIR= $(TCLDIR)/unix
-  TKDIRDIR= $(TKDIR)/unix
-
-  XFLAGS = --x-includes=$(X11INCLUDE) --x-libraries=$(X11LIB)
-
-  TCLFLAGS = $(XFLAGS) $(EXTTCLFLAGS) --prefix $(root) --enable-64bit --disable-shared --disable-threads
-
-  TKTABLEFLAGS = $(XFLAGS) --prefix $(root) --disable-shared
-  BLTFLAGS = $(XFLAGS) $(BLTWITHOUT)
-  TKIMGFLAGS = $(XFLAGS)
-  XPAFLAGS = $(XFLAGS)
-
-  ZLIB=
-  SIGNAL= signal
-endif
-
-ifeq ($(OS),windows)
-  PORT= win
-
-  TCLINSTALL=install
-  TCLDIRDIR= $(TCLDIR)/win
-  TKDIRDIR= $(TKDIR)/win
-
-  TCLFLAGS = --prefix $(root) --disable-shared --disable-threads
-
-  TKTABLEFLAGS = --prefix $(root) --disable-shared
-  BLTFLAGS = --without-x $(BLTWITHOUT) \
-	--without-xftincdir --without-xftlibdir
-  TKIMGFLAGS =
-  XPAFLAGS = --without-x
-  PRETKHTMLFLAGS = config_BUILD_TCLSH=tclsh86sg \
-	config_TARGET_TCL_SCRIPT_DIR=$(root)/lib/tcl8.6
-
-  ZLIB=zlib
-  SIGNAL=
-endif
-
-ifeq ($(OS),macosx)
-  PORT= macosx
-
-  TCLINSTALL=
-  TCLDIRDIR= $(TCLDIR)/macosx
-  TKDIRDIR= $(TKDIR)/macosx
-
-  TKTABLEFLAGS = --prefix $(root)
-
-  BLTFLAGS = $(BLTWITHOUT)
-  TKIMGFLAGS =
-
-# xpa configure will not accept --without-x
-  XPAFLAGS = --with-x=disabled --enable-posix_spawn
-  PRETKHTMLFLAGS = config_TARGET_LIBS="-framework CoreFoundation -framework Carbon" \
-	config_TARGET_X_INC="-I$(root)/$(TKDIR)/xlib" \
-	config_TARGET_X_LIBS=" "
-
-  FUNTOOLSFLAGS = --enable-posix_spawn
-
-  ZLIB=
-  SIGNAL= signal
-endif
+#--------------------------cvs stuff
 
 CVSFILES = admin \
 	checkdns \
 	tkmpeg \
+	tlt3.0 \
 	COPYING \
 	copyright \
 	iis \
@@ -120,10 +43,13 @@ CVSFILES = admin \
 	make.darwinsnowleopard \
 	make.linux \
 	make.linux64 \
-	make.macosxx86mountainlion \
+	make.macosxmountainlion \
 	make.source \
 	make.pkgs \
 	Makefile \
+	Makefile.unix \
+	Makefile.macosx \
+	Makefile.windows \
 	notes.txt \
 	mods \
 	README \
@@ -148,15 +74,7 @@ CVSFILES = admin \
 
 #--------------------------build
 
-all: 	dirs \
-	tcl tk \
-	tktable tkcon xmlrpc blt \
-	$(ZLIB) tclxml tkimg tkmpeg tkhtml \
-	xpa iis checkdns $(SIGNAL) funtools \
-	ast wcssubs \
-	rice hcompress plio \
-	$(PORT) \
-	saotk zvfs ds9
+include Makefile.$(OS)
 
 doc	: FORCE
 	@echo "Making Documentation..."
@@ -180,22 +98,6 @@ dirs	: FORCE
 	@echo "Installing Directories..."
 	@for d in $(DIRS); do if [ ! -d $$d ]; then mkdir $$d; fi done
 
-tcl	: FORCE
-	@echo "Installing Tcl..."
-	cd $(TCLDIRDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure $(TCLFLAGS)
-	$(MAKE) -C $(TCLDIRDIR) -j $(JOBS) $(TCLINSTALL)
-
-tk	: FORCE
-	@echo "Installing Tk..."
-	cd $(TKDIRDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure $(TCLFLAGS)
-	$(MAKE) -C $(TKDIRDIR) -j $(JOBS) $(TCLINSTALL)
-
-tktable	: FORCE
-	@echo "Installing TkTable..."
-	cd $(TKTABLEDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure $(TKTABLEFLAGS)
-	$(MAKE) -C $(TKTABLEDIR) -j $(JOBS)
-	$(MAKE) -C $(TKTABLEDIR) -j $(JOBS) install
-
 tkcon	: FORCE
 	@echo "Installing TkCon..."
 	$(RM) -r lib/$(TKCONVER)
@@ -208,50 +110,34 @@ xmlrpc	: FORCE
 	mkdir lib/$(XMLRPCVER)
 	cp $(XMLRPCDIR)/xmlrpc.tcl lib/$(XMLRPCVER)
 
-blt	: FORCE
-	@echo "Installing BLT..."
-	cd $(BLTDIR); CC='$(CC)' CFLAGS='$(OPTS) -DUSE_INTERP_RESULT' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --with-tcl=$(root)/$(TCLDIRDIR) --with-tk=$(root)/$(TKDIRDIR) $(BLTFLAGS) --disable-shared
-	cd $(BLTDIR)/src; $(MAKE) -j $(JOBS) build_static
-	cp $(BLTDIR)/src/*.a lib/.
-	cd $(BLTDIR)/src; cp $(BLTINCL) ../../include/.
-
 zlib  : FORCE
 	@echo "Installing zlib..."
-	cd $(ZLIBDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --static
+	cd $(ZLIBDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure --prefix $(root) --static
 	$(MAKE) -C $(ZLIBDIR) -j $(JOBS) install
 
-tclxml	: FORCE
-	@echo "Installing TCLXML..."
-	cd $(TCLXMLDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --disable-shared --disable-threads --with-xml-static=1 $(TCLXMLFLAGS)
-	$(MAKE) -C $(TCLXMLDIR) -j $(JOBS)
-	$(MAKE) -C $(TCLXMLDIR) -j $(JOBS) install
-
-tkimg	: libtiff
-	@echo "Installing TKIMG..."
-	cd $(TKIMGDIR); CC='$(CC)' CFLAGS='$(OPTS) -DPNG_NO_WRITE_gAMA' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --with-tcl=$(root)/$(TCLDIRDIR) --with-tk=$(root)/$(TKDIRDIR) $(TKIMGFLAGS) --disable-shared --disable-threads
-	$(MAKE) -C $(TKIMGDIR) -j $(JOBS) install
-
 libtiff	: FORCE
 	@echo "Installing LIBTIFF..."
-	cd $(TKIMGDIR)/compat/libtiff; CC='$(CC)' CFLAGS='$(OPTS)' CXX='$(CC)' CXXFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --disable-shared
+	cd $(TKIMGDIR)/compat/libtiff; CC='$(CC)' CFLAGS='$(OPTS)' CXX='$(CC)' \
+	CXXFLAGS='$(OPTS)' \
+	./configure --prefix $(root) --disable-shared
 	$(MAKE) -C $(TKIMGDIR)/compat/libtiff -j $(JOBS) install
 
 tkmpeg	: FORCE
 	@echo "Installing TKMPEG..."
 	$(MAKE) -C $(TKMPEGDIR) -j $(JOBS) install
 
-tkhtml	: $(HTMLDIR)
-	@echo "Installing TKHTML..."
-	cd $(HTMLDIR); CC='$(CC)' CFLAGS='$(OPTS) -DUSE_INTERP_RESULT' LDFLAGS='$(LIBS)' $(PRETKHTMLFLAGS) $(root)/htmlwidget/configure --prefix $(root) --with-tcl=$(root)/$(TCLDIR) --with-tk=$(root)/$(TKDIR) $(XFLAGS) --enable-shared=no
-	$(MAKE) -C $(HTMLDIR) headers libtkhtml.a
-	cp $(HTMLDIR)/libtkhtml.a lib/.
-
 $(HTMLDIR) : FORCE
 	mkdir $(HTMLDIR)
 
 xpa	: FORCE
 	@echo "Installing XPA..."
-	cd $(XPADIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --with-tcl=$(root)/$(TCLDIRDIR) $(XPAFLAGS) --disable-shared
+	cd $(XPADIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure \
+	--prefix $(root) \
+	--disable-shared \
+	--with-tcl=$(root)/$(TCLDIRDIR) \
+	$(XPAFLAGS)
 	$(MAKE) -C $(XPADIR) -j $(JOBS) install
 	cd bin; strip xpa*
 
@@ -269,19 +155,23 @@ signal: FORCE
 
 funtools: FORCE
 	@echo "Installing Funtools..."
-#	cd $(FUNTOOLSDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --with-zlib=../../lib/libz.a --with-wcslib=../lib/libwcs.a --enable-mainlib $(FUNTOOLSFLAGS)
-	cd $(FUNTOOLSDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --with-wcslib=../lib/libwcs.a --enable-mainlib $(FUNTOOLSFLAGS)
+	cd $(FUNTOOLSDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure \
+	--prefix $(root) \
+	--with-wcslib=../lib/libwcs.a \
+	--enable-mainlib $(FUNTOOLSFLAGS)
 	$(MAKE) -C $(FUNTOOLSDIR) lib
 	cp $(FUNTOOLSDIR)/libfuntools.a lib/.
 
 ast	: FORCE
 	@echo "Installing AST..."
-	cd $(ASTDIR); \
-	touch aclocal.m4; sleep 1; \
-	touch Makefile.in; sleep 1; \
-	touch configure; \
-	./configure --enable-shared=no --prefix=$(root) $(ASTFLAGS) CC='$(CC)' CFLAGS='$(OPTS) -I.'; \
-	$(MAKE) -j $(JOBS) ast.h install-libLTLIBRARIES install-nodist_includeHEADERS install-includeHEADERS
+	cd $(ASTDIR); CC='$(CC)' CFLAGS='$(OPTS) -I.' \
+	./configure \
+	--enable-shared=no \
+	--prefix=$(root) \
+	$(ASTFLAGS)
+	$(MAKE) -C $(ASTDIR) -j $(JOBS) ast.h install-libLTLIBRARIES \
+	install-nodist_includeHEADERS install-includeHEADERS
 
 wcssubs	: FORCE
 	@echo "Installing WCSSUBS..."
@@ -299,10 +189,6 @@ plio: FORCE
 	@echo "Installing PLIO..."
 	$(MAKE) -C $(PLIODIR) -j $(JOBS) install
 
-$(PORT) : FORCE
-	@echo "Installing $(PORT)..."
-	$(MAKE) -C $(PORT) -j $(JOBS) install
-
 saotk	: FORCE
 	@echo "Installing SAOTK..."
 	$(MAKE) -C $(SAOTKDIR) -j $(JOBS) install
@@ -327,16 +213,6 @@ ifeq ($(OS),windows)
 	find . -name "*stackdump*" -exec rm {} \;
 endif
 
-distclean : tclclean tkclean \
-	tktableclean bltclean \
-	$(ZLIB)clean tclxmlclean tkimgclean tkmpegclean tkhtmlclean \
-	xpaclean iisclean checkdnsclean $(SIGNAL)clean funtoolsclean \
-	astclean wcssubsclean \
-	riceclean hcompressclean plioclean \
-	$(PORT)clean \
-	saotkclean zvfsclean ds9clean srcclean \
-	filesclean dirsclean
-
 clean: FORCE
 
 filesclean: FORCE
@@ -354,8 +230,8 @@ tkclean : FORCE
 tktableclean: FORCE
 	$(MAKE) -C $(TKTABLEDIR) distclean
 
-bltclean: FORCE
-	$(MAKE) -C $(BLTDIR) distclean
+tltclean: FORCE
+	$(MAKE) -C $(TLTDIR) distclean
 
 zlibclean: FORCE
 	$(MAKE) -C $(ZLIBDIR) distclean
@@ -408,15 +284,6 @@ hcompressclean: FORCE
 plioclean: FORCE
 	$(MAKE) -C $(PLIODIR) distclean
 
-unixclean : FORCE
-	$(MAKE) -C unix distclean
-
-winclean : FORCE
-	$(MAKE) -C win distclean
-
-macosxclean : FORCE
-	$(MAKE) -C macosx distclean
-
 saotkclean : FORCE
 	$(MAKE) -C $(SAOTKDIR) distclean
 
@@ -437,53 +304,12 @@ commit : FORCE
 update : FORCE
 	cvs update $(CVSFILES)
 
-#--------------------------app
-
-ifeq ($(OS),windows)
-ds9app	: ds9
-	$(MAKE) -C $(DS9DIR) ds9app
-
-ds9winzip : FORCE
-	$(RM) -f dist/$(DS9APP)\ Install.*
-	/cygdrive/c/Program\ Files\ \(x86\)/WinZip/wzzip -p -r dist/$(DS9APP)\ Install.zip bin/ds9app
-#	/cygdrive/c/Program\ Files\ \(x86\)/WinZip\ Self-Extractor/WINZIPSE.EXE  dist/$(DS9APP)\ Install.zip -setup -i ds9/win/ds9.ico -le -runasuser -t ds9/win/message.txt -a ds9/win/about.txt -c cscript install.vbs 
-	/cygdrive/c/Program\ Files\ \(x86\)/WinZip\ Self-Extractor/WINZIPSE.EXE  dist/$(DS9APP)\ Install.zip -d C:\\ds9 -i ds9/win/ds9.ico -le -overwrite -runasuser -c cscript install.vbs
-
-xpawinzip : FORCE
-	$(RM) -f dist/$(XPAAPP)\ Install.*
-	/cygdrive/c/Program\ Files\ \(x86\)/WinZip/wzzip dist/$(XPAAPP)\ Install.zip bin/xpa* bin/cygwin1.dll
-	/cygdrive/c/Program\ Files\ \(x86\)/WinZip\ Self-Extractor/WINZIPSE.EXE  dist/$(XPAAPP)\ Install.zip -d C:\\ds9 -le -overwrite -runasuser
-endif
-
-ifeq ($(OS),macosx)
-ds9app	: ds9
-	$(MAKE) -C $(DS9DIR) ds9app
-
-ds9dmg	: FORCE
-	rm -rf dist/$(DS9APP)
-	rm -rf dist/$(DS9APP).dmg
-	mkdir dist/$(DS9APP)
-	ln -s /Applications dist/$(DS9APP)/.
-	cp -r ds9/macosx/README dist/$(DS9APP)/.
-	cp -rp bin/SAOImage\ DS9.app dist/$(DS9APP)/.
-	hdiutil create -srcfolder dist/$(DS9APP) dist/$(DS9APP) 
-
-endif
-
 #--------------------------distribution
 
 dist	: distds9 distxpa
 
 distall	: distds9 distxpa distdoc distsource
 
-ifeq ($(OS),windows)
-distapp	: distds9app distxpaapp
-endif
-
-ifeq ($(OS),macosx)
-distapp	: distds9app
-endif
-
 ifdef CVS_SERVER
 
 #--------------------------remote
@@ -494,29 +320,12 @@ distds9 : FORCE
 	scp dist/ds9.$(ARCH).$(DS9VERSION).tar.gz $(USER)@$(DEST):build/$(ARCH)/.
 	ssh $(USER)@$(DEST) 'cd build/$(ARCH); zcat ds9.$(ARCH).$(DS9VERSION).tar.gz | tar -xvf -'
 
-ifeq ($(OS),windows)
-distds9app : ds9winzip
-	scp dist/$(DS9APP)\ Install.exe $(USER)@$(DEST):build/$(ARCH)/.
-endif
-
-ifeq ($(OS),macosx)
-distds9app : ds9dmg
-	scp -r dist/$(DS9APP)/SAOImage\ DS9.app $(USER)@$(DEST):build/$(ARCH)/.
-	scp dist/$(DS9APP).dmg $(USER)@$(DEST):build/$(ARCH)/.
-endif
-
 distxpa : FORCE
 	@echo "Creating XPA Distribution"
 	cd bin; tar cvf - xpa*$(EXE) |gzip > ../dist/xpa.$(ARCH).$(XPAVERSION).tar.gz
 	scp dist/xpa.$(ARCH).$(XPAVERSION).tar.gz $(USER)@$(DEST):build/$(ARCH)/.
 	ssh $(USER)@$(DEST) 'cd build/$(ARCH); zcat xpa.$(ARCH).$(XPAVERSION).tar.gz | tar -xvf -'
 
-ifeq ($(OS),windows)
-distxpaapp : xpawinzip
-	@echo "Creating XPA Distribution"
-	scp dist/$(XPAAPP)\ Install.exe $(USER)@$(DEST):build/$(ARCH)/.
-endif
-
 distdoc	: doc
 	@echo "Creating Documentation Distribution"
 	scp -r doc $(USER)@$(DEST):build/.
@@ -541,26 +350,12 @@ distds9 : FORCE
 	cd bin; tar cvf - ds9$(EXE) $(ZIPFILE) | gzip > ../dist/ds9.$(ARCH).$(DS9VERSION).tar.gz
 	cp dist/ds9.$(ARCH).$(DS9VERSION).tar.gz $(HOME)/build/$(ARCH)/.
 	cd $(HOME)/build/$(ARCH); $(ZCAT) ds9.$(ARCH).$(DS9VERSION).tar.gz | tar -xvf -
-ifeq ($(OS),windows)
-distds9app : ds9winzip
-	cp dist/ds9.$(ARCH).$(DS9VERSION).exe $(HOME)/build/$(ARCH)/.
-endif
-
-ifeq ($(OS),macosx)
-distds9app : ds9dmg
-	cp -r dist/$(DS9APP)/SAOImage\ DS9.app $(HOME)/build/$(ARCH)/.
-	cp dist/$(DS9APP).dmg $(HOME)/build/$(ARCH)/.
-endif
 
 distxpa : FORCE
 	@echo "Creating XPA Distribution"
 	cd bin; tar cvf - xpa*$(EXE) |gzip > ../dist/xpa.$(ARCH).$(XPAVERSION).tar.gz
 	cp dist/xpa.$(ARCH).$(XPAVERSION).tar.gz $(HOME)/build/$(ARCH)/.
 	cd $(HOME)/build/$(ARCH); $(ZCAT) xpa.$(ARCH).$(XPAVERSION).tar.gz | tar -xvf -
-ifeq ($(OS),windows)
-distxpaapp : xpawinzip
-	cp dist/xpa.$(ARCH).$(XPAVERSION).exe $(HOME)/build/$(ARCH)/.
-endif
 
 distdoc	: doc
 	@echo "Creating Documentation Distribution"
diff --git a/Makefile.macosx b/Makefile.macosx
new file mode 100644
index 0000000..26565b4
--- /dev/null
+++ b/Makefile.macosx
@@ -0,0 +1,172 @@
+TCLDIRDIR= $(TCLDIR)/macosx
+TKDIRDIR= $(TKDIR)/macosx
+
+XPAFLAGS = --with-x=disabled --enable-posix_spawn
+FUNTOOLSFLAGS = --enable-posix_spawn
+
+TCLFILES = \
+	 $(TCLDIR)/generic/tcl.h \
+	 $(TCLDIR)/generic/tclDecls.h \
+	 $(TCLDIR)/generic/tclPlatDecls.h
+
+TKFILES = \
+	 $(TKDIR)/generic/tk.h \
+	 $(TKDIR)/generic/tkDecls.h \
+	 $(TKDIR)/generic/tkPlatDecls.h \
+	 $(TKDIR)/generic/tkIntXlibDecls.h \
+	 $(TKDIR)/macosx/tkMacOSX.h
+
+all: 	dirs \
+	tcl tk \
+	tktable tkcon xmlrpc tlt \
+	tclxml tkimg tkmpeg tkhtml \
+	xpa iis checkdns signal funtools \
+	ast wcssubs \
+	rice hcompress plio \
+	macosx \
+	saotk ds9
+
+tcl	: FORCE
+	@echo "Installing Tcl..."
+	cd $(TCLDIRDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure \
+	--enable-64bit \
+	--enable-symbols
+	$(MAKE) -C $(TCLDIRDIR) -j $(JOBS)
+
+	# install include, lib
+	cp -p $(TCLFILES) include/.
+	cp -p build/tcl/Tcl.framework/libtclstub8.6.a lib/.
+	cp -rp build/tcl/Tcl.framework/Versions/8.6/Resources/Scripts lib/tcl8.6
+	cp -rp build/tcl/Tcl.framework/Versions/8.6/Resources/tcl8 lib/.
+
+	# we need a working tclsh later
+	cp -p build/tcl/tclsh8.6 bin/.
+	install_name_tool -change /Library/Frameworks/Tcl.framework/Versions/8.6/Tcl @executable_path/../build/tcl/Tcl.framework/Tcl bin/tclsh8.6
+
+tk	: FORCE
+	@echo "Installing Tk..."
+	cd $(TKDIRDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure \
+	--with-tcl=$(root)/$(TCLDIRDIR) \
+	--enable-64bit \
+	--enable-symbols
+	$(MAKE) -C $(TKDIRDIR) -j $(JOBS)
+
+	# install include, lib
+	cp -rp $(TKDIR)/xlib/X11 include/.
+	cp -p $(TKFILES) include/.
+	cp -p build/tk/Tk.framework/libtkstub8.6.a lib/.
+	cp -rp build/tk/Tk.framework/Versions/8.6/Resources/Scripts lib/tk8.6
+
+tlt	: FORCE
+	@echo "Installing TLT..."
+	cd $(TLTDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure $(XFLAGS) \
+	--with-tcl=$(root)/$(TCLDIRDIR) \
+	--with-tk=$(root)/$(TKDIRDIR) \
+	--prefix $(root) \
+	--exec-prefix $(root) \
+	--disable-shared \
+	--enable-symbols
+	$(MAKE) -C $(TLTDIR) -j $(JOBS) install
+
+tktable	: FORCE
+	@echo "Installing TkTable..."
+	cd $(TKTABLEDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure \
+	--with-tcl=$(root)/$(TCLDIRDIR) \
+	--with-tk=$(root)/$(TKDIRDIR) \
+	--with-tkinclude=$(root)/$(TKDIR)/generic  \
+	--prefix $(root) \
+	--exec-prefix $(root) \
+	--disable-shared \
+	--enable-symbols
+	$(MAKE) -C $(TKTABLEDIR) -j $(JOBS)
+	$(MAKE) -C $(TKTABLEDIR) -j $(JOBS) install
+
+tclxml	: FORCE
+	@echo "Installing TCLXML..."
+	cd $(TCLXMLDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure \
+	--with-tcl=$(root)/$(TCLDIRDIR)  \
+	--prefix $(root) \
+	--exec-prefix $(root) \
+	--disable-shared \
+	--with-xml-static=1
+	$(MAKE) -C $(TCLXMLDIR) -j $(JOBS)
+	$(MAKE) -C $(TCLXMLDIR) -j $(JOBS) install
+
+tkimg	: libtiff
+	@echo "Installing TKIMG..."
+	cd $(TKIMGDIR); CC='$(CC)' CFLAGS='$(OPTS) -DPNG_NO_WRITE_gAMA' \
+	./configure \
+	--with-tcl=$(root)/$(TCLDIRDIR) \
+	--with-tk=$(root)/$(TKDIRDIR) \
+	--prefix $(root) \
+	--exec-prefix $(root) \
+	--disable-shared
+	$(MAKE) -C $(TKIMGDIR) -j $(JOBS) install
+
+
+tkhtml	: $(HTMLDIR)
+	@echo "Installing TKHTML..."
+	cd $(HTMLDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	config_TARGET_TCL_SCRIPT_DIR=$(root)/$(TCLDIRDIR) \
+	config_TARGET_TK_SCRIPT_DIR=$(root)/$(TKDIRDIR) \
+	config_TARGET_TCL_INC=$(root)/$(TCLDIR)/generic \
+	config_TARGET_TK_INC=$(root)/$(TKDIR)/generic \
+	config_TARGET_X_INC="-I$(root)/$(TKDIR)/xlib" \
+	config_TARGET_X_LIBS=" " \
+	$(root)/htmlwidget/configure \
+	--with-tcl=$(root)/$(TCLDIRDIR) \
+	--with-tk=$(root)/$(TKDIRDIR) \
+	--prefix $(root) \
+	--enable-shared=no
+	$(MAKE) -C $(HTMLDIR) headers libtkhtml.a
+	cp $(HTMLDIR)/libtkhtml.a lib/.
+
+macosx : FORCE
+	@echo "Installing macosx..."
+	$(MAKE) -C macosx -j $(JOBS) install
+
+distclean : tclclean tkclean \
+	tktableclean tltclean \
+	tclxmlclean tkimgclean tkmpegclean tkhtmlclean \
+	xpaclean iisclean checkdnsclean signalclean funtoolsclean \
+	astclean wcssubsclean \
+	riceclean hcompressclean plioclean \
+	macosxclean \
+	saotkclean zvfsclean ds9clean srcclean \
+	filesclean dirsclean
+
+macosxclean : FORCE
+	$(MAKE) -C macosx distclean
+
+ds9app	: ds9
+	$(MAKE) -C $(DS9DIR) ds9app
+
+ds9dmg	: FORCE
+	rm -rf dist/$(DS9APP)
+	rm -rf dist/$(DS9APP).dmg
+	mkdir dist/$(DS9APP)
+	ln -s /Applications dist/$(DS9APP)/.
+	cp -r ds9/macosx/README dist/$(DS9APP)/.
+	cp -rp bin/SAOImage\ DS9.app dist/$(DS9APP)/.
+	hdiutil create -srcfolder dist/$(DS9APP) dist/$(DS9APP) 
+
+distapp	: distds9app
+
+ifdef CVS_SERVER
+
+distds9app : ds9dmg
+	scp -r dist/$(DS9APP)/SAOImage\ DS9.app $(USER)@$(DEST):build/$(ARCH)/.
+	scp dist/$(DS9APP).dmg $(USER)@$(DEST):build/$(ARCH)/.
+
+else
+
+distds9app : ds9dmg
+	cp -r dist/$(DS9APP)/SAOImage\ DS9.app $(HOME)/build/$(ARCH)/.
+	cp dist/$(DS9APP).dmg $(HOME)/build/$(ARCH)/.
+
+endif
diff --git a/Makefile.unix b/Makefile.unix
new file mode 100644
index 0000000..39bbbf2
--- /dev/null
+++ b/Makefile.unix
@@ -0,0 +1,102 @@
+TCLDIRDIR= $(TCLDIR)/unix
+TKDIRDIR= $(TKDIR)/unix
+
+XFLAGS = --x-includes=$(X11INCLUDE) --x-libraries=$(X11LIB)
+XPAFLAGS = $(XFLAGS)
+FUNTOOLSFLAGS =
+
+all: 	dirs \
+	tcl tk \
+	tktable tkcon xmlrpc tlt \
+	tclxml tkimg tkmpeg tkhtml \
+	xpa iis checkdns signal funtools \
+	ast wcssubs \
+	rice hcompress plio \
+	unix \
+	saotk zvfs ds9
+
+tcl	: FORCE
+	@echo "Installing Tcl..."
+	cd $(TCLDIRDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure $(XFLAGS) $(TCLFLAGS) \
+	--prefix $(root) \
+	--disable-shared \
+	--enable-symbols
+	$(MAKE) -C $(TCLDIRDIR) -j $(JOBS) install
+
+tk	: FORCE
+	@echo "Installing Tk..."
+	cd $(TKDIRDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure $(XFLAGS) $(TCLFLAGS) \
+	--prefix $(root) \
+	--disable-shared \
+	--enable-symbols
+	$(MAKE) -C $(TKDIRDIR) -j $(JOBS) install
+
+tlt	: FORCE
+	@echo "Installing TLT..."
+	cd $(TLTDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure $(XFLAGS) \
+	--prefix $(root) \
+	--disable-shared \
+	--enable-symbols
+	$(MAKE) -C $(TLTDIR) -j $(JOBS) install
+
+tktable	: FORCE
+	@echo "Installing TkTable..."
+	cd $(TKTABLEDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure $(XFLAGS) \
+	--prefix $(root) \
+	--disable-shared \
+	--enable-symbols
+	$(MAKE) -C $(TKTABLEDIR) -j $(JOBS)
+	$(MAKE) -C $(TKTABLEDIR) -j $(JOBS) install
+
+tclxml	: FORCE
+	@echo "Installing TCLXML..."
+	cd $(TCLXMLDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure \
+	--prefix $(root) \
+	--disable-shared
+	--with-xml-static=1
+	$(MAKE) -C $(TCLXMLDIR) -j $(JOBS)
+	$(MAKE) -C $(TCLXMLDIR) -j $(JOBS) install
+
+tkimg	: libtiff
+	@echo "Installing TKIMG..."
+	cd $(TKIMGDIR); CC='$(CC)' CFLAGS='$(OPTS) -DPNG_NO_WRITE_gAMA' \
+	./configure $(XFLAGS) \
+	--with-tcl=$(root)/$(TCLDIRDIR) \
+	--with-tk=$(root)/$(TKDIRDIR) \
+	--prefix $(root) \
+	--disable-shared
+	$(MAKE) -C $(TKIMGDIR) -j $(JOBS) install
+
+tkhtml	: $(HTMLDIR)
+	@echo "Installing TKHTML..."
+	cd $(HTMLDIR); CC='$(CC)' CFLAGS='$(OPTS) -DUSE_INTERP_RESULT' \
+	$(root)/htmlwidget/configure $(XFLAGS) \
+	--with-tcl=$(root)/$(TCLDIR) \
+	--with-tk=$(root)/$(TKDIR) \
+	--prefix $(root) \
+	--enable-shared=no
+	$(MAKE) -C $(HTMLDIR) headers libtkhtml.a
+	cp $(HTMLDIR)/libtkhtml.a lib/.
+
+unix : FORCE
+	@echo "Installing unix..."
+	$(MAKE) -C unix -j $(JOBS) install
+
+distclean : tclclean tkclean \
+	tktableclean tltclean \
+	tclxmlclean tkimgclean tkmpegclean tkhtmlclean \
+	xpaclean iisclean checkdnsclean signalclean funtoolsclean \
+	astclean wcssubsclean \
+	riceclean hcompressclean plioclean \
+	unixclean \
+	saotkclean zvfsclean ds9clean srcclean \
+	filesclean dirsclean
+
+unixclean : FORCE
+	$(MAKE) -C unix distclean
+
diff --git a/Makefile.windows b/Makefile.windows
new file mode 100644
index 0000000..04321e6
--- /dev/null
+++ b/Makefile.windows
@@ -0,0 +1,116 @@
+TCLDIRDIR= $(TCLDIR)/win
+TKDIRDIR= $(TKDIR)/win
+
+XPAFLAGS = --without-x
+FUNTOOLSFLAGS =
+
+all: 	dirs \
+	tcl tk \
+	tktable tkcon xmlrpc tlt \
+	zlib tclxml tkimg tkmpeg tkhtml \
+	xpa iis checkdns funtools \
+	ast wcssubs \
+	rice hcompress plio \
+	win \
+	saotk zvfs ds9
+
+tcl	: FORCE
+	@echo "Installing Tcl..."
+	cd $(TCLDIRDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure --prefix $(root) --disable-shared --disable-threads
+	$(MAKE) -C $(TCLDIRDIR) -j $(JOBS) install
+
+tk	: FORCE
+	@echo "Installing Tk..."
+	cd $(TKDIRDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure --prefix $(root) --disable-shared --disable-threads
+	$(MAKE) -C $(TKDIRDIR) -j $(JOBS) install
+
+tktable	: FORCE
+	@echo "Installing TkTable..."
+	cd $(TKTABLEDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure --prefix $(root) --disable-shared
+	$(MAKE) -C $(TKTABLEDIR) -j $(JOBS)
+	$(MAKE) -C $(TKTABLEDIR) -j $(JOBS) install
+
+tlt	: FORCE
+	@echo "Installing TLT..."
+	cd $(TLTDIR); CC='$(CC)' CFLAGS='$(OPTS) -DUSE_INTERP_RESULT' \
+	 ./configure --prefix $(root) --with-tcl=$(root)/$(TCLDIRDIR) --with-tk=$(root)/$(TKDIRDIR) --without-x $(TLTWITHOUT) --without-xftincdir --without-xftlibdir --disable-shared
+	cd $(TLTDIR)/src; $(MAKE) -j $(JOBS) build_static
+	cp $(TLTDIR)/src/*.a lib/.
+	cd $(TLTDIR)/src; cp $(TLTINCL) ../../include/.
+
+tclxml	: FORCE
+	@echo "Installing TCLXML..."
+	cd $(TCLXMLDIR); CC='$(CC)' CFLAGS='$(OPTS)' \
+	./configure --prefix $(root) --disable-shared --disable-threads --with-xml-static=1 $(TCLXMLFLAGS)
+	$(MAKE) -C $(TCLXMLDIR) -j $(JOBS)
+	$(MAKE) -C $(TCLXMLDIR) -j $(JOBS) install
+
+tkimg	: libtiff
+	@echo "Installing TKIMG..."
+	cd $(TKIMGDIR); CC='$(CC)' CFLAGS='$(OPTS) -DPNG_NO_WRITE_gAMA' \
+	./configure --prefix $(root) --with-tcl=$(root)/$(TCLDIRDIR) --with-tk=$(root)/$(TKDIRDIR) $(XFLAGS) --disable-shared --disable-threads
+	$(MAKE) -C $(TKIMGDIR) -j $(JOBS) install
+
+tkhtml	: $(HTMLDIR)
+	@echo "Installing TKHTML..."
+	cd $(HTMLDIR); CC='$(CC)' CFLAGS='$(OPTS) -DUSE_INTERP_RESULT' \
+	config_BUILD_TCLSH=tclsh86sg config_TARGET_TCL_SCRIPT_DIR=$(root)/lib/tcl8.6 $(root)/htmlwidget/configure --prefix $(root) --with-tcl=$(root)/$(TCLDIR) --with-tk=$(root)/$(TKDIR) $(XFLAGS) --enable-shared=no
+	$(MAKE) -C $(HTMLDIR) headers libtkhtml.a
+	cp $(HTMLDIR)/libtkhtml.a lib/.
+
+win : FORCE
+	@echo "Installing win..."
+	$(MAKE) -C win -j $(JOBS) install
+
+distclean : tclclean tkclean \
+	tktableclean tltclean \
+	zlibclean tclxmlclean tkimgclean tkmpegclean tkhtmlclean \
+	xpaclean iisclean checkdnsclean funtoolsclean \
+	astclean wcssubsclean \
+	riceclean hcompressclean plioclean \
+	winclean \
+	saotkclean zvfsclean ds9clean srcclean \
+	filesclean dirsclean
+
+winclean : FORCE
+	$(MAKE) -C win distclean
+
+ds9app	: ds9
+	$(MAKE) -C $(DS9DIR) ds9app
+
+ds9winzip : FORCE
+	$(RM) -f dist/$(DS9APP)\ Install.*
+	/cygdrive/c/Program\ Files\ \(x86\)/WinZip/wzzip -p -r dist/$(DS9APP)\ Install.zip bin/ds9app
+#	/cygdrive/c/Program\ Files\ \(x86\)/WinZip\ Self-Extractor/WINZIPSE.EXE  dist/$(DS9APP)\ Install.zip -setup -i ds9/win/ds9.ico -le -runasuser -t ds9/win/message.txt -a ds9/win/about.txt -c cscript install.vbs 
+	/cygdrive/c/Program\ Files\ \(x86\)/WinZip\ Self-Extractor/WINZIPSE.EXE  dist/$(DS9APP)\ Install.zip -d C:\\ds9 -i ds9/win/ds9.ico -le -overwrite -runasuser -c cscript install.vbs
+
+xpawinzip : FORCE
+	$(RM) -f dist/$(XPAAPP)\ Install.*
+	/cygdrive/c/Program\ Files\ \(x86\)/WinZip/wzzip dist/$(XPAAPP)\ Install.zip bin/xpa* bin/cygwin1.dll
+	/cygdrive/c/Program\ Files\ \(x86\)/WinZip\ Self-Extractor/WINZIPSE.EXE  dist/$(XPAAPP)\ Install.zip -d C:\\ds9 -le -overwrite -runasuser
+
+distapp	: distds9app distxpaapp
+
+ifdef CVS_SERVER
+
+distds9app : ds9winzip
+	scp dist/$(DS9APP)\ Install.exe $(USER)@$(DEST):build/$(ARCH)/.
+
+distxpaapp : xpawinzip
+	@echo "Creating XPA Distribution"
+	scp dist/$(XPAAPP)\ Install.exe $(USER)@$(DEST):build/$(ARCH)/.
+
+else
+
+distds9app : ds9winzip
+	cp dist/ds9.$(ARCH).$(DS9VERSION).exe $(HOME)/build/$(ARCH)/.
+
+distxpaapp : xpawinzip
+	cp dist/xpa.$(ARCH).$(XPAVERSION).exe $(HOME)/build/$(ARCH)/.
+
+endif
+
+FORCE	:
diff --git a/blt3.0.1/configure b/blt3.0.1/configure
index 94d3687..d807195 100755
--- a/blt3.0.1/configure
+++ b/blt3.0.1/configure
@@ -12569,7 +12569,7 @@ else
     fi
   done
 fi
-if test "x${TCL_LIB_DIR}" = "x" ; then
+if test "x${TCL_LIB_DIR}" = "xx" ; then
   { { echo "$as_me:$LINENO: error: Can't find tcl library ${libname} in \"${blt_with_tcl_lib_dir}\"" >&5
 echo "$as_me: error: Can't find tcl library ${libname} in \"${blt_with_tcl_lib_dir}\"" >&2;}
    { (exit 1); exit 1; }; }
@@ -12606,7 +12606,7 @@ else
     fi
   done
 fi
-if test "x${TK_LIB_DIR}" = "x" ; then
+if test "x${TK_LIB_DIR}" = "xx" ; then
   { { echo "$as_me:$LINENO: error: Can't find tk library." >&5
 echo "$as_me: error: Can't find tk library." >&2;}
    { (exit 1); exit 1; }; }
diff --git a/blt3.0.1/src/bltUnixBitmap.c b/blt3.0.1/src/bltUnixBitmap.c
index 98ce0f8..9d74771 100644
--- a/blt3.0.1/src/bltUnixBitmap.c
+++ b/blt3.0.1/src/bltUnixBitmap.c
@@ -43,7 +43,9 @@
 #include "bltPicture.h"
 #endif
 #include <X11/Xutil.h>
+#if !defined(WIN32) && !defined(MAC_OSX_TCL)
 #include <X11/Xproto.h>
+#endif
 #include "bltBitmap.h"
 
 #define ROTATE_0	0
diff --git a/blt3.0.1/src/bltUnixPainter.c b/blt3.0.1/src/bltUnixPainter.c
index 73aa2fb..8012a36 100644
--- a/blt3.0.1/src/bltUnixPainter.c
+++ b/blt3.0.1/src/bltUnixPainter.c
@@ -43,7 +43,9 @@
 #include "bltUnixPainter.h"
 #include "bltPainter.h"
 #include <X11/Xutil.h>
+#if !defined(WIN32) && !defined(MAC_OSX_TCL)
 #include <X11/Xproto.h>
+#endif
 
 typedef struct _Blt_Picture Pict;
 
@@ -941,10 +943,14 @@ DrawableToXImage(
     int result;
 
     result = TCL_OK;
+#if !defined(WIN32) && !defined(MAC_OSX_TCL)
     errHandler = Tk_CreateErrorHandler(display, BadMatch, X_GetImage, -1, 
-	XGetImageErrorProc, &result);
+	  XGetImageErrorProc, &result);
+#endif
     imgPtr = XGetImage(display, drawable, x, y, w, h, AllPlanes, ZPixmap);
+#if !defined(WIN32) && !defined(MAC_OSX_TCL)
     Tk_DeleteErrorHandler(errHandler);
+#endif
     XSync(display, False);
     if (result != TCL_OK) {
 #ifdef notdef
diff --git a/blt3.0.1/src/bltUnixWindow.c b/blt3.0.1/src/bltUnixWindow.c
index bb07671..11f2d77 100644
--- a/blt3.0.1/src/bltUnixWindow.c
+++ b/blt3.0.1/src/bltUnixWindow.c
@@ -34,7 +34,7 @@
 #include "bltInt.h"
 
 #include <X11/Xlib.h>
-#ifndef WIN32
+#if !defined(WIN32) && !defined(MAC_OSX_TCL)
 #include <X11/Xproto.h>
 #endif
 #include "tkDisplay.h"
@@ -277,8 +277,10 @@ Blt_GetWindowRegion(Display *display, Window window, int *xPtr, int *yPtr,
     int x, y;
     unsigned int w, h, bw, depth;
 
+#if !defined(WIN32) && !defined(MAC_OSX_TCL)
     handler = Tk_CreateErrorHandler(display, any, X_GetGeometry, any, 
 	XGeometryErrorProc, &result);
+#endif
     result = XGetGeometry(display, window, &root, &x, &y, &w, &h, &bw, &depth);
     if (!result) {
 	goto error;
@@ -326,7 +328,9 @@ Blt_GetWindowRegion(Display *display, Window window, int *xPtr, int *yPtr,
 	    *yPtr = rootY;
 	}
     }
+#if !defined(WIN32) && !defined(MAC_OSX_TCL)
     Tk_DeleteErrorHandler(handler);
+#endif
     XSync(display, False);
     return TCL_OK;
  error:
@@ -470,10 +474,14 @@ Blt_ReparentWindow(
     int any = -1;
 
     result = TCL_OK;
+#if !defined(WIN32) && !defined(MAC_OSX_TCL)
     handler = Tk_CreateErrorHandler(display, any, X_ReparentWindow, any,
 	XReparentWindowErrorProc, &result);
+#endif
     XReparentWindow(display, window, newParent, x, y);
+#if !defined(WIN32) && !defined(MAC_OSX_TCL)
     Tk_DeleteErrorHandler(handler);
+#endif
     XSync(display, False);
     return result;
 }
diff --git a/doc/release/r7.0.html b/doc/release/r7.0.html
index 825c37a..a20d2b6 100644
--- a/doc/release/r7.0.html
+++ b/doc/release/r7.0.html
@@ -493,6 +493,16 @@
         <li><tt>06.26.2013 SEGMENT: add new segment region.</tt></li>
         <li><tt>07.02.2013 ENVI: fixed a problem with calculating wcs.</tt></li>
         <li><tt>07.02.2013 FITSY++: changes to allow 1D image.</tt></li>
+        <li><tt>07.03.2013 GROUPS: fixed a problem allowing multiple selection of region groups.</tt></li>
+        <li><tt>08.14.2013 WCS: Linear WCS now goes straight to AST.</tt></li>          <li><tt>09.10.2013 PSEUDOCOLOR: rm support for pseudocolor visuals.</tt></li>
+        <li><tt>09.17.2013 REGIONS: PLOT3D dramatic improvements in speed of deep images and large regions.</tt></li>
+        <li><tt>09.17.2013 GUI: set last file directory based on file type last loaded.</tt></li>
+        <li><tt>09.18.2013 ENVI: minor change to hdr parser.</tt></li>
+        <li><tt>09.18.2013 ENVI: fixed a major problem with swapbytes.</tt></li>
+        <li><tt>09.18.2013 CATALOG: fixed a problem with selecting the correct region when arrow keys are used.</tt></li>
+        <li><tt>09.19.2013 FITSY++: cleaned up code for dumping array,nrrd,envi in native endian.</tt></li>
+        <li><tt>09.25.2013 AST: updated to version 7.3.2 to fix problem with SCAMP.</tt></li>
+        <li><tt>09.25.2013 FITSY++: fixed a problem parsing filters in the command line.</tt></li>
         <li><tt><b>xx.xx.2013 RELEASE version 7.3</b></tt></li>
       </ol>
     </ol>
diff --git a/ds9/Makefile b/ds9/Makefile
index cb40601..0333e7d 100644
--- a/ds9/Makefile
+++ b/ds9/Makefile
@@ -1,324 +1,13 @@
 include ../make.include
 include ../make.pkgs
 
-#--------------------------defines
-
-ZDIR	= zipdir/zvfsmntpt
-FFILES	= $(ZDIR)/$(TCLVER) \
-	$(ZDIR)/tcl8 \
-	$(ZDIR)/$(TKVER) \
-	$(ZDIR)/$(BLTVER) \
-	$(ZDIR)/$(TCLLIBVER) \
-	$(ZDIR)/$(TKCONVER) \
-	$(ZDIR)/$(XMLRPCVER) \
-	$(ZDIR)/src \
-	$(ZDIR)/msgs \
-	$(ZDIR)/doc \
-	$(ZDIR)/cmaps \
-	$(ZDIR)/template
-
-ifdef FILTERCOMPILER
-FILES	= $(FFILES) \
-	$(ZDIR)/$(FILTERCOMPILER)
-else
-FILES	= $(FFILES)
-endif
-
-# for unix, macosx
-MAINDIR = ../$(TKDIR)/unix
-MAIN	= tkAppInit
-
-LIBS	= \
-	../lib/libsaotk.a \
-	../lib/libtkhtml.a \
-	../lib/libtkmpeg.a \
-	../lib/$(TCLXMLVER)/libTclxml3.2.a \
-	../lib/$(TKTABLEVER)/libTktable2.10.a \
-	../lib/$(TKIMGVER)/libtkimgpng1.4.a \
-	../lib/$(TKIMGVER)/libpngtcl1.4.3.a \
-	../lib/$(TKIMGVER)/libtkimgtiff1.4.a \
-	../lib/$(TKIMGVER)/libtifftcl3.9.4.a \
-	../lib/$(TKIMGVER)/libtkimgjpeg1.4.a \
-	../lib/$(TKIMGVER)/libjpegtcl8.2.a \
-	../lib/$(TKIMGVER)/libtkimggif1.4.a \
-	../lib/$(TKIMGVER)/libtkimgwindow1.4.a \
-	../lib/$(TKIMGVER)/libzlibtcl1.2.5.a \
-	../lib/$(TKIMGVER)/libtkimg1.4.a \
-	../lib/libtiff.a \
-	../lib/libfuntools.a \
-	../lib/librice.a \
-	../lib/libhcomp.a \
-	../lib/libplio.a \
-	../lib/libast.a \
-	../lib/libast_err.a \
-	../lib/libast_pal.a \
-	../lib/libsaotk.a \
-	../lib/libwcs.a \
-	../lib/libzvfs.a \
-	../lib/libxpa.a \
-	../lib/libiis.a \
-	../lib/libcheckdns.a \
-	../lib/libsignal_ext.a \
-	../lib/libxxlib.a \
-	../lib/libBLTX30.a \
-	../lib/libBLTCore30.a \
-	../lib/libtk8.6.a \
-	../lib/libtkstub8.6.a \
-	../lib/libtcl8.6.a \
-	../lib/libtclstub8.6.a \
-
-# if windows, redefine
-ifeq ($(OS),windows)
-  MAINDIR = ../$(TKDIR)/win
-  MAIN	= winMain
-  RES	= ds9.res.o
-
-  LIBS	= \
-	../lib/libsaotk.a \
-	../lib/libtkhtml.a \
-	../lib/libtkmpeg.a \
-	../lib/$(TCLXMLVER)/Tclxml32.a \
-	../lib/$(TKTABLEVER)/Tktable210.a \
-	../lib/$(TKIMGVER)/tkimgpng14.a \
-	../lib/$(TKIMGVER)/pngtcl143.a \
-	../lib/$(TKIMGVER)/tkimgtiff14.a \
-	../lib/$(TKIMGVER)/tifftcl394.a \
-	../lib/$(TKIMGVER)/tkimgjpeg14.a \
-	../lib/$(TKIMGVER)/jpegtcl82.a \
-	../lib/$(TKIMGVER)/tkimggif14.a \
-	../lib/$(TKIMGVER)/tkimgwindow14.a \
-	../lib/$(TKIMGVER)/zlibtcl125.a \
-	../lib/$(TKIMGVER)/tkimg14.a \
-	../lib/libtiff.a \
-	../lib/libfuntools.a \
-	../lib/librice.a \
-	../lib/libhcomp.a \
-	../lib/libplio.a \
-	../lib/libast.a \
-	../lib/libast_err.a \
-	../lib/libast_pal.a \
-	../lib/libsaotk.a \
-	../lib/libwcs.a \
-	../lib/libzvfs.a \
-	../lib/libz.a \
-	../lib/libxpa.a \
-	../lib/libiis.a \
-	../lib/libcheckdns.a \
-	../lib/libxxlib.a \
-	../lib/libBLTX30.a \
-	../lib/libBLTCore30.a \
-	../lib/libtk86sg.a \
-	../lib/libtkstub86sg.a \
-	../lib/libtcl86sg.a \
-	../lib/libtclstub86sg.a
-endif
-
-OBJS	= ds9.o $(MAIN).o $(RES)
-
-#--------------------------linux
-
-ifneq (,$(findstring linux,$(ARCH)))
-
-CFLAGS= $(CCOPT) -I. -I../include -I../$(TKDIR)/generic \
-	-I../$(TKDIR)/unix -I$(X11INCLUDE)
-CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE)
-
-all: ds9
-
-ds9	: ds9Base ds9.zip
-	$(RM) $@
-	strip ds9Base
-	cat ds9Base ds9.zip > ds9
-	zip -A ds9
-	chmod 755 ds9
-	cp ds9 ../bin/.
-
-debug	: ds9Base ds9.zip
-	$(RM) $@
-	cat ds9Base ds9.zip > ds9
-	zip -A ds9
-	chmod 755 ds9
-
-ds9Base	: $(OBJS) $(LIBS)
-	$(RM) $@
-	$(CXX) ${OPTS} \
-	-o $@ $(OBJS) $(LIBS) \
-	-L$(X11LIB) -lX11 -lXext -lXft -lXrender -lXss \
-	-lxml2 \
-	-lz -lpthread 
-
-endif
-
-#--------------------------darwin
-
-ifneq (,$(findstring darwin,$(ARCH)))
-
-CFLAGS= $(CCOPT) -I. -I../include -I../$(TKDIR)/generic \
-	-I../$(TKDIR)/unix -I$(X11INCLUDE)
-CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE) -DZIPFILE
-
-all: ds9
-
-ds9	: ds9Base ds9.zip
-	$(RM) $@
-	strip ds9Base
-	cp ds9Base ds9
-	cp ds9 ../bin/.
-	cp ds9.zip ../bin/.
-	cd ../bin; $(CODESIGN) -s "SAOImage DS9" ds9
-
-debug	: ds9Base ds9.zip
-	$(RM) $@
-	cp ds9Base ds9
-
-ds9Base	: $(OBJS) $(LIBS)
-	$(RM) $@
-	$(CXX) ${OPTS} \
-	-o $@ $(OBJS) $(LIBS) \
-	-L$(X11LIB) -lX11 -lXext -lXft -lXrender -lXss -lfontconfig -lfreetype \
-	-lxml2
-
-endif
-
-#--------------------------cygwin
-
-ifneq (,$(findstring cygwin,$(ARCH)))
-
-CFLAGS= $(CCOPT) -I. -I../include -I../$(TKDIR)/generic \
-	-I../$(TKDIR)/unix -I$(X11INCLUDE)
-CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE)
-
-all: ds9
-
-ds9	: ds9Base ds9.zip
-	$(RM) $@
-	strip ds9Base
-	cat ds9Base ds9.zip > ds9
-	zip -A ds9
-	chmod 755 ds9
-	cp ds9 ../bin/.
-
-debug	: ds9Base ds9.zip
-	$(RM) $@
-	cat ds9Base ds9.zip > ds9
-	zip -A ds9
-	chmod 755 ds9
-
-ds9Base	: $(OBJS) $(LIBS)
-	$(RM) $@
-	$(CXX) ${OPTS} \
-	-o $@ $(OBJS) $(LIBS) \
-	-L$(X11LIB) -lX11 -lXext -lXft -lXrender -lXss -lfontconfig -lfreetype \
-	-ljbig \
-	-lxml2
-
-endif
-
-#--------------------------windows
-
-ifeq ($(OS),windows)
-
-CFLAGS= $(CCOPT) -I. -I../include -I../$(TKDIR)/generic \
-	-I../$(TKDIR)/win -I$(X11INCLUDE)
-CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE) -DZIPFILE
-
-all: ds9.exe
-
-ds9.exe	: ds9Base.exe ds9.zip ../bin/tcc
-	$(RM) $@
-	strip ds9Base.exe
-	cp ds9Base.exe ds9.exe
-	cp ds9.exe ../bin/.
-	cp ds9.zip ../bin/.
-	cp /bin/cygwin1.dll ../bin/.
-	cp /bin/cygxml2-2.dll ../bin/.
-	cp /bin/cygstdc++-6.dll ../bin/.
-	cp /bin/cygiconv-2.dll ../bin/.
-	cp /bin/cygz.dll ../bin/.
-	cp /bin/cyggcc_s-1.dll ../bin/.
-	cp /bin/cygjbig-2.dll ../bin/.
-	cp /bin/cyglzma-5.dll ../bin/.
-
-debug	: ds9Base.exe ds9.zip ../bin/tcc
-	$(RM) $@
-	cp ds9Base.exe ds9.exe
-
-ds9app	: ds9.exe
-	$(RM) -r ../bin/ds9app
-	mkdir ../bin/ds9app
-	cp ds9.exe ../bin/ds9app/.
-	cp ds9.zip ../bin/ds9app/.
-	cp /bin/cygwin1.dll ../bin/ds9app/.
-	cp /bin/cygxml2-2.dll ../bin/ds9app/.
-	cp /bin/cygstdc++-6.dll ../bin/ds9app/.
-	cp /bin/cygiconv-2.dll ../bin/ds9app/.
-	cp /bin/cygz.dll ../bin/ds9app/.
-	cp /bin/cyggcc_s-1.dll ../bin/ds9app/.
-	cp /bin/cygjbig-2.dll ../bin/ds9app/.
-	cp /bin/cyglzma-5.dll ../bin/ds9app/.
-	cp -rp ../bin/tcc ../bin/ds9app/.
-	cp ../ds9/win/install.vbs ../bin/ds9app/.
-
-ds9Base.exe: $(OBJS) $(LIBS)
-	$(RM) $@
-	$(CXX) ${OPTS} \
-	-o $@ $(OBJS) $(LIBS) \
-	-lxml2 -ljbig \
-	-lws2_32 -limm32 -lcomctl32 -mwindows 
-
-$(RES)	: win/ds9.rc win/ds9.ico
-	windres -o $@ --define STATIC_BUILD --include ../$(TKDIR)/generic \
-	--include ../$(TCLDIR)/generic --include ../$(TKDIR)/win/rc \
-	--include win win/ds9.rc
-
-../bin/tcc: ../compilers/$(TCC)
-	$(RM) -r $@
-	cd ../bin; unzip ../compilers/$(TCC)
-	chmod +x ../bin/tcc/tcc.exe
-	touch $@
-endif
-
-#--------------------------macosx
-
-ifeq ($(OS),macosx)
-
-CFLAGS= $(CCOPT) -I. -I../include -I../$(TKDIR)/generic \
-	-I../$(TKDIR)/macosx -I$(X11INCLUDE)
-CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE) -DZIPFILE
-
-all: ds9
-
-ds9	: ds9Base ds9.zip
-	$(RM) $@
-	strip ds9Base
-	cp ds9Base ds9
-	cp ds9 ../bin/.
-	cp ds9.zip ../bin/.
-
-debug	: ds9Base ds9.zip
-	$(RM) $@
-	cp ds9Base ds9
-
-ds9app	: ds9
-	rm -rf ../bin/SAOImage\ DS9.app
-	cp -rp macosx/SAOImage\ DS9.app ../bin/.
-	cd ../bin/SAOImage\ DS9.app; find -d . -name CVS -exec rm -rf {} \;
-	cp -p ../bin/ds9 ../bin/SAOImage\ DS9.app/Contents/MacOS/.
-	cp -p ../bin/ds9.zip ../bin/SAOImage\ DS9.app/Contents/MacOS/.
-	cd ../bin; $(CODESIGN) -s "SAOImage DS9" SAOImage\ DS9.app
-
-ds9Base	: $(OBJS) $(LIBS)
-	$(RM) $@
-	$(CXX) ${OPTS} \
-	-o $@ $(OBJS) $(LIBS) \
-	-lxml2 \
-	-lstdc++ -liconv \
-	-sectcreate __TEXT __tk_rsrc ../$(TKDIR)/unix/tk8.6.rsrc \
-	-framework CoreFoundation -framework Carbon
-endif
+include Makefile.$(OS)
 
 #--------------------------support
 
+ds9.C	: ds9.$(OS)
+	cp ds9.$(OS) ds9.C
+
 $(MAIN).o : $(MAIN).c
 	$(CC) $(CFLAGS) -DTK_LOCAL_APPINIT=SAOAppInit \
 	-DTK_LOCAL_MAIN_HOOK=SAOLocalMainHook -c $(MAIN).c -o $@
@@ -326,94 +15,9 @@ $(MAIN).o : $(MAIN).c
 $(MAIN).c : $(MAINDIR)/$(MAIN).c
 	cp $(MAINDIR)/$(MAIN).c .
 
-ds9.zip	: $(FILES)
-	cd zipdir; zip -r ../ds9.zip *	
-
-zipdir	: 
-	mkdir zipdir
-	mkdir $(ZDIR)
-
-$(ZDIR)/$(TCLVER) : zipdir ../lib/$(TCLVER)
-	$(RM) -r $@
-	cp -r ../lib/$(TCLVER) $(ZDIR)/.
-
-$(ZDIR)/tcl8 : zipdir ../lib/tcl8
-	$(RM) -r $@
-	cp -r ../lib/tcl8 $(ZDIR)/.
-
-$(ZDIR)/$(TKVER) : zipdir ../lib/$(TKVER)
-	$(RM) -r $@
-	cp -r ../lib/$(TKVER) $(ZDIR)/.
-	rm -rf $(ZDIR)/$(TKVER)/images
-	rm -rf $(ZDIR)/$(TKVER)/demos
-
-$(ZDIR)/$(BLTVER) : zipdir
-	$(RM) -r $@
-	mkdir $(ZDIR)/$(BLTVER)
-	mkdir $(ZDIR)/$(BLTVER)/afm
-	cp ../$(BLTDIR)/library/graph.tcl $(ZDIR)/$(BLTVER)/.
-	cp ../$(BLTDIR)/library/bltGraph.pro $(ZDIR)/$(BLTVER)/.
-	cp ../$(BLTDIR)/library/tclIndex $(ZDIR)/$(BLTVER)/.
-	cp ../$(BLTDIR)/library/afm/*.afm $(ZDIR)/$(BLTVER)/afm/.
-
-$(ZDIR)/$(TCLLIBVER) : zipdir
-	$(RM) -r $@
-	mkdir $(ZDIR)/$(TCLLIBVER)
-	cp -r ../$(TCLLIBDIR)/modules/base64 $(ZDIR)/$(TCLLIBVER)/.
-	cp -r ../$(TCLLIBDIR)/modules/ftp $(ZDIR)/$(TCLLIBVER)/.
-	cp -r ../$(TCLLIBDIR)/modules/log $(ZDIR)/$(TCLLIBVER)/.
-	cp -r ../$(TCLLIBDIR)/modules/textutil $(ZDIR)/$(TCLLIBVER)/.
-	cp -r ../$(TCLLIBDIR)/modules/math $(ZDIR)/$(TCLLIBVER)/.
-
-$(ZDIR)/$(TKCONVER) : zipdir ../lib/$(TKCONVER)
-	$(RM) -r $@
-	cp -r ../lib/$(TKCONVER) $@
-
-$(ZDIR)/$(XMLRPCVER) : zipdir ../lib/$(XMLRPCVER)
-	$(RM) -r $@
-	cp -r ../lib/$(XMLRPCVER) $@
-
-$(ZDIR)/src : zipdir ../src/*.tcl
-	$(RM) -r $@
-	cp -r ../src $(ZDIR)/.
-
-$(ZDIR)/msgs : zipdir ../msgs/*
-	$(RM) -r $@
-	cp -r ../msgs $(ZDIR)/.
-
-$(ZDIR)/doc : zipdir ../doc/* ../doc/ref/* ../doc/user/* ../doc/release/*
-	$(RM) -r $@
-	cd ..; find doc -name "*.html" | cpio -pdmuv ds9/$(ZDIR)
-	cd ..; find doc -name "*.gif" | cpio -pdmuv ds9/$(ZDIR)
-	cd ..; find doc -name "*.png" | cpio -pdmuv ds9/$(ZDIR)
-
-$(ZDIR)/cmaps : zipdir ../cmaps/*
-	$(RM) -r $@
-	cp -r ../cmaps $(ZDIR)/.
-
-$(ZDIR)/template : zipdir ../template/*
-	$(RM) -r $@
-	cd ..; find template -name "*.tpl" | cpio -pdmuv ds9/$(ZDIR)
-
-ifdef FILTERCOMPILER
-$(ZDIR)/$(FILTERCOMPILER) : zipdir ../compilers/$(FILTERCOMPILER)
-	$(RM) -r $@
-	cp ../compilers/$(FILTERCOMPILER) $(ZDIR)/$(FILTERCOMPILER)
-endif
-
 #--------------------------cleanup
 
 clean	: FORCE
 	$(RM) core *~ *# 
 
-ifeq ($(OS),windows)
-distclean: FORCE
-	$(RM) core *~ *# ds9Base.exe ds9.exe *.zip *.o
-	$(RM) -r zipdir bin/tcc
-else
-distclean: FORCE
-	$(RM) core *~ *# ds9Base ds9 *.zip *.o
-	$(RM) -r zipdir
-endif
-
 FORCE	:
diff --git a/ds9/Makefile.macosx b/ds9/Makefile.macosx
new file mode 100644
index 0000000..9ff0957
--- /dev/null
+++ b/ds9/Makefile.macosx
@@ -0,0 +1,166 @@
+#--------------------------defines
+
+CFLAGS= $(CCOPT) -I. -I../include -I$(X11INCLUDE)
+CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE)
+
+MAINDIR	= ../$(TKDIR)/unix
+MAIN	= tkAppInit
+
+OBJS	= ds9.o $(MAIN).o
+
+LIBS	= \
+	../lib/libsaotk.a \
+	../lib/libtkhtml.a \
+	../lib/libtkmpeg.a \
+	../lib/$(TCLXMLVER)/libTclxml3.2.a \
+	../lib/$(TKTABLEVER)/libTktable2.10.a \
+	../lib/$(TKIMGVER)/libtkimgpng1.4.a \
+	../lib/$(TKIMGVER)/libpngtcl1.4.3.a \
+	../lib/$(TKIMGVER)/libtkimgtiff1.4.a \
+	../lib/$(TKIMGVER)/libtifftcl3.9.4.a \
+	../lib/$(TKIMGVER)/libtkimgjpeg1.4.a \
+	../lib/$(TKIMGVER)/libjpegtcl8.2.a \
+	../lib/$(TKIMGVER)/libtkimggif1.4.a \
+	../lib/$(TKIMGVER)/libtkimgwindow1.4.a \
+	../lib/$(TKIMGVER)/libzlibtcl1.2.5.a \
+	../lib/$(TKIMGVER)/libtkimg1.4.a \
+	../lib/libtiff.a \
+	../lib/libfuntools.a \
+	../lib/librice.a \
+	../lib/libhcomp.a \
+	../lib/libplio.a \
+	../lib/libast.a \
+	../lib/libast_err.a \
+	../lib/libast_pal.a \
+	../lib/libwcs.a \
+	../lib/libxpa.a \
+	../lib/libiis.a \
+	../lib/libcheckdns.a \
+	../lib/libsignal_ext.a \
+	../lib/$(TLTVER)/libtlt3.0.a \
+	../lib/libxxlib.a \
+	../lib/libtkstub8.6.a \
+	../lib/libtclstub8.6.a
+
+APPDIR	= ../bin/SAOImage\ DS9.app
+DS9FW	= ../bin/SAOImage\ DS9.app/Contents/Frameworks/ds9.framework
+DS9RES	= ../bin/SAOImage\ DS9.app/Contents/Frameworks/ds9.framework/Resources
+TCLFW	= ../bin/SAOImage\ DS9.app/Contents/Frameworks/Tcl.framework
+TCLRES	= ../bin/SAOImage\ DS9.app/Contents/Frameworks/Tcl.framework/Resources
+TKFW	= ../bin/SAOImage\ DS9.app/Contents/Frameworks/Tk.framework
+TKRES	= ../bin/SAOImage\ DS9.app/Contents/Frameworks/Tk.framework/Resources
+
+#--------------------------main
+
+all: ds9app
+
+ds9app	: ds9 app framework tcl tk tcllib tkcon xmlrpc tlt compiler
+	cp -p ds9 $(APPDIR)/Contents/MacOS/.
+	strip $(APPDIR)/Contents/MacOS/ds9
+	install_name_tool -change \
+	/Library/Frameworks/Tcl.framework/Versions/8.6/Tcl \
+	@executable_path/../Frameworks/Tcl.framework/Tcl \
+	$(APPDIR)/Contents/MacOS/ds9
+	install_name_tool -change \
+	/Library/Frameworks/Tk.framework/Versions/8.6/Tk \
+	@executable_path/../Frameworks/Tk.framework/Tk \
+	$(APPDIR)/Contents/MacOS/ds9
+	cd ../bin; $(CODESIGN) -s "SAOImage DS9" SAOImage\ DS9.app
+
+debug	: ds9 app framework tcl_debug tk_debug tcllib tkcon xmlrpc tlt compiler
+	cp -p ds9 $(APPDIR)/Contents/MacOS/.
+	install_name_tool -change \
+	/Library/Frameworks/Tcl.framework/Versions/8.6/Tcl \
+	@executable_path/../Frameworks/Tcl.framework/Tcl \
+	$(APPDIR)/Contents/MacOS/ds9
+	install_name_tool -change \
+	/Library/Frameworks/Tk.framework/Versions/8.6/Tk \
+	@executable_path/../Frameworks/Tk.framework/Tk \
+	$(APPDIR)/Contents/MacOS/ds9
+	cd ../bin; $(CODESIGN) -s "SAOImage DS9" SAOImage\ DS9.app
+
+ds9	: $(OBJS) $(LIBS)
+	$(RM) $@
+	$(CXX) ${OPTS} \
+	-o $@ $(OBJS) $(LIBS) \
+	-lxml2 \
+	-lstdc++ -liconv \
+	-F/Users/joye/saods9/build/tcl -framework Tcl \
+	-F/Users/joye/saods9/build/tk -framework Tk \
+	-framework CoreFoundation -framework Cocoa \
+	-framework Carbon -framework IOKit
+
+app	: FORCE
+	rm -rf $(APPDIR)
+	cp -rp macosx/SAOImage\ DS9.app ../bin/.
+
+framework: FORCE
+	mkdir $(DS9FW)
+	mkdir $(DS9RES)
+	cp -pr ../src $(DS9RES)/.
+	cp -pr ../msgs $(DS9RES)/.
+	cp -pr ../doc $(DS9RES)/.
+	cp -pr ../cmaps $(DS9RES)/.
+	cp -pr ../template $(DS9RES)/.
+	cp -pr ../template $(DS9RES)/.
+
+	rm $(DS9RES)/src/source.tcl
+	cd $(APPDIR); find -d . -name CVS -exec rm -rf {} \;
+	echo "pkg_mkIndex $(DS9RES)/src *.tcl; exit" | tclsh8.6
+
+tcl	: FORCE
+	cp -p ../build/tcl/Tcl.framework/Versions/8.6/Tcl $(TCLFW)/.
+	cp -pr ../build/tcl/Tcl.framework/Versions/8.6/Resources/* $(TCLRES)/.
+
+tcl_debug: FORCE
+	cp -p ../build/tcl/Tcl.framework/Versions/8.6/Tcl_debug $(TCLFW)/Tcl
+	cp -pr ../build/tcl/Tcl.framework/Versions/8.6/Resources/* $(TCLRES)/.
+
+tk	: FORCE
+	cp -p ../build/tk/Tk.framework/Versions/8.6/Tk $(TKFW)/.
+	cp -p ../build/tk/Tk.framework/Versions/8.6/Resources/Info.plist \
+	$(TKRES)/.
+	cp -p ../build/tk/Tk.framework/Versions/8.6/Resources/license.terms \
+	$(TKRES)/.
+	cp -rp ../build/tk/Tk.framework/Versions/8.6/Resources/Scripts \
+	$(TKRES)/.
+tk_debug: FORCE
+	cp -p ../build/tk/Tk.framework/Versions/8.6/Tk_debug $(TKFW)/Tk
+	cp -p ../build/tk/Tk.framework/Versions/8.6/Resources/Info.plist \
+	$(TKRES)/.
+	cp -p ../build/tk/Tk.framework/Versions/8.6/Resources/license.terms \
+	$(TKRES)/.
+	cp -rp ../build/tk/Tk.framework/Versions/8.6/Resources/Scripts \
+	$(TKRES)/.
+
+tcllib	: FORCE
+	mkdir $(DS9RES)/$(TCLLIBVER)
+	cp -pr ../$(TCLLIBDIR)/modules/base64 $(DS9RES)/$(TCLLIBVER)/.
+	cp -pr ../$(TCLLIBDIR)/modules/ftp $(DS9RES)/$(TCLLIBVER)/.
+	cp -pr ../$(TCLLIBDIR)/modules/log $(DS9RES)/$(TCLLIBVER)/.
+	cp -pr ../$(TCLLIBDIR)/modules/textutil $(DS9RES)/$(TCLLIBVER)/.
+	cp -pr ../$(TCLLIBDIR)/modules/math $(DS9RES)/$(TCLLIBVER)/.
+
+tkcon	: FORCE
+	mkdir $(DS9RES)/$(TKCONVER)
+	cp -p ../$(TKCONDIR)/*.tcl $(DS9RES)/$(TKCONVER)/.
+
+xmlrpc	: FORCE
+	mkdir $(DS9RES)/$(XMLRPCVER)
+	cp -p ../$(XMLRPCDIR)/xmlrpc.tcl $(DS9RES)/$(XMLRPCVER)/.
+	echo "pkg_mkIndex $(DS9RES)/$(XMLRPCVER) *.tcl; exit" | tclsh8.6
+
+tlt	: FORCE
+	mkdir $(DS9RES)/$(TLTVER)
+	cp -p ../$(TLTDIR)/library/graph.tcl $(DS9RES)/$(TLTVER)/.
+	echo "pkg_mkindex $(DS9RES)/tlt3.0 *.tcl; exit" | tclsh8.6
+
+compiler: FORCE
+	cp -p ../compilers/$(FILTERCOMPILER) $(DS9RES)/.
+
+#--------------------------cleanup
+
+distclean: FORCE
+	$(RM) core *~ *# ds9Base ds9 ds9.C *.o
+
+
diff --git a/ds9/Makefile.unix b/ds9/Makefile.unix
new file mode 100644
index 0000000..6f94ab8
--- /dev/null
+++ b/ds9/Makefile.unix
@@ -0,0 +1,226 @@
+#--------------------------defines
+
+CFLAGS= $(CCOPT) -I. -I../include -I$(X11INCLUDE)
+
+MAINDIR	= ../$(TKDIR)/unix
+MAIN	= tkAppInit
+
+ZDIR = zipdir/zvfsmntpt
+OBJS	= ds9.o $(MAIN).o
+
+FILES	= \
+	$(ZDIR)/$(TCLVER) \
+	$(ZDIR)/tcl8 \
+	$(ZDIR)/$(TKVER) \
+	$(ZDIR)/$(TLTVER) \
+	$(ZDIR)/$(TCLLIBVER) \
+	$(ZDIR)/$(TKCONVER) \
+	$(ZDIR)/$(XMLRPCVER) \
+	$(ZDIR)/src \
+	$(ZDIR)/msgs \
+	$(ZDIR)/doc \
+	$(ZDIR)/cmaps \
+	$(ZDIR)/template
+
+LIBS	= \
+	../lib/libsaotk.a \
+	../lib/libtkhtml.a \
+	../lib/libtkmpeg.a \
+	../lib/$(TCLXMLVER)/libTclxml3.2.a \
+	../lib/$(TKTABLEVER)/libTktable2.10.a \
+	../lib/$(TKIMGVER)/libtkimgpng1.4.a \
+	../lib/$(TKIMGVER)/libpngtcl1.4.3.a \
+	../lib/$(TKIMGVER)/libtkimgtiff1.4.a \
+	../lib/$(TKIMGVER)/libtifftcl3.9.4.a \
+	../lib/$(TKIMGVER)/libtkimgjpeg1.4.a \
+	../lib/$(TKIMGVER)/libjpegtcl8.2.a \
+	../lib/$(TKIMGVER)/libtkimggif1.4.a \
+	../lib/$(TKIMGVER)/libtkimgwindow1.4.a \
+	../lib/$(TKIMGVER)/libzlibtcl1.2.5.a \
+	../lib/$(TKIMGVER)/libtkimg1.4.a \
+	../lib/libtiff.a \
+	../lib/libfuntools.a \
+	../lib/librice.a \
+	../lib/libhcomp.a \
+	../lib/libplio.a \
+	../lib/libast.a \
+	../lib/libast_err.a \
+	../lib/libast_pal.a \
+	../lib/libsaotk.a \
+	../lib/libwcs.a \
+	../lib/libzvfs.a \
+	../lib/libxpa.a \
+	../lib/libiis.a \
+	../lib/libcheckdns.a \
+	../lib/libsignal_ext.a \
+	../lib/libxxlib.a \
+	../lib/$(TLTVER)/libtlt3.0.a \
+	../lib/libtk8.6.a \
+	../lib/libtkstub8.6.a \
+	../lib/libtcl8.6.a \
+	../lib/libtclstub8.6.a
+
+#--------------------------main
+
+all: ds9
+
+#--------------------------linux
+
+ifneq (,$(findstring linux,$(ARCH)))
+
+CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE)
+
+ds9	: ds9Base ds9.zip
+	$(RM) $@
+	strip ds9Base
+	cat ds9Base ds9.zip > ds9
+	zip -A ds9
+	chmod 755 ds9
+	cp ds9 ../bin/.
+
+debug	: ds9Base ds9.zip
+	$(RM) $@
+	cat ds9Base ds9.zip > ds9
+	zip -A ds9
+	chmod 755 ds9
+
+ds9Base	: $(OBJS) $(LIBS)
+	$(RM) $@
+	$(CXX) ${OPTS} \
+	-o $@ $(OBJS) $(LIBS) \
+	-L$(X11LIB) -lX11 -lXext -lXft -lXrender -lXss \
+	-lxml2 \
+	-lz -lpthread 
+
+endif
+
+#--------------------------darwin
+
+ifneq (,$(findstring darwin,$(ARCH)))
+
+CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE) -DZIPFILE
+
+ds9	: ds9Base ds9.zip
+	$(RM) $@
+	strip ds9Base
+	cp ds9Base ds9
+	cp ds9 ../bin/.
+	cp ds9.zip ../bin/.
+	cd ../bin; $(CODESIGN) -s "SAOImage DS9" ds9
+
+debug	: ds9Base ds9.zip
+	$(RM) $@
+	cp ds9Base ds9
+
+ds9Base	: $(OBJS) $(LIBS)
+	$(RM) $@
+	$(CXX) ${OPTS} \
+	-o $@ $(OBJS) $(LIBS) \
+	-L$(X11LIB) -lX11 -lXext -lXft -lXrender -lXss -lfontconfig -lfreetype \
+	-lxml2
+
+endif
+
+#--------------------------cygwin
+
+ifneq (,$(findstring cygwin,$(ARCH)))
+
+CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE)
+
+ds9	: ds9Base ds9.zip
+	$(RM) $@
+	strip ds9Base
+	cat ds9Base ds9.zip > ds9
+	zip -A ds9
+	chmod 755 ds9
+	cp ds9 ../bin/.
+
+debug	: ds9Base ds9.zip
+	$(RM) $@
+	cat ds9Base ds9.zip > ds9
+	zip -A ds9
+	chmod 755 ds9
+
+ds9Base	: $(OBJS) $(LIBS)
+	$(RM) $@
+	$(CXX) ${OPTS} \
+	-o $@ $(OBJS) $(LIBS) \
+	-L$(X11LIB) -lX11 -lXext -lXft -lXrender -lXss -lfontconfig -lfreetype \
+	-ljbig \
+	-lxml2
+
+endif
+
+ds9.zip	: $(FILES)
+	cd zipdir; find . -depth -name "CVS" -exec rm -r {} \;
+	cd zipdir; zip -r ../ds9.zip *	
+
+zipdir	: 
+	mkdir zipdir
+	mkdir $(ZDIR)
+
+$(ZDIR)/$(TCLVER) : zipdir ../lib/$(TCLVER)
+	$(RM) -r $@
+	cp -r ../lib/$(TCLVER) $(ZDIR)/.
+
+$(ZDIR)/tcl8 : zipdir ../lib/tcl8
+	$(RM) -r $@
+	cp -r ../lib/tcl8 $(ZDIR)/.
+
+$(ZDIR)/$(TKVER) : zipdir ../lib/$(TKVER)
+	$(RM) -r $@
+	cp -r ../lib/$(TKVER) $(ZDIR)/.
+	rm -rf $(ZDIR)/$(TKVER)/images
+	rm -rf $(ZDIR)/$(TKVER)/demos
+
+$(ZDIR)/$(TLTVER) : zipdir
+	$(RM) -r $@
+	mkdir $(ZDIR)/$(TLTVER)
+	cp ../$(TLTDIR)/library/graph.tcl $(ZDIR)/$(TLTVER)/.
+	cp ../$(TLTDIR)/library/bltGraph.pro $(ZDIR)/$(TLTVER)/.
+	cp -rp ../$(TLTDIR)/library/afm $(ZDIR)/$(TLTVER)/.
+
+$(ZDIR)/$(TCLLIBVER) : zipdir
+	$(RM) -r $@
+	mkdir $(ZDIR)/$(TCLLIBVER)
+	cp -r ../$(TCLLIBDIR)/modules/base64 $(ZDIR)/$(TCLLIBVER)/.
+	cp -r ../$(TCLLIBDIR)/modules/ftp $(ZDIR)/$(TCLLIBVER)/.
+	cp -r ../$(TCLLIBDIR)/modules/log $(ZDIR)/$(TCLLIBVER)/.
+	cp -r ../$(TCLLIBDIR)/modules/textutil $(ZDIR)/$(TCLLIBVER)/.
+	cp -r ../$(TCLLIBDIR)/modules/math $(ZDIR)/$(TCLLIBVER)/.
+
+$(ZDIR)/$(TKCONVER) : zipdir ../lib/$(TKCONVER)
+	$(RM) -r $@
+	cp -r ../lib/$(TKCONVER) $@
+
+$(ZDIR)/$(XMLRPCVER) : zipdir ../lib/$(XMLRPCVER)
+	$(RM) -r $@
+	cp -r ../lib/$(XMLRPCVER) $@
+
+$(ZDIR)/src : zipdir ../src/*.tcl
+	$(RM) -r $@
+	cp -r ../src $(ZDIR)/.
+
+$(ZDIR)/msgs : zipdir ../msgs/*
+	$(RM) -r $@
+	cp -r ../msgs $(ZDIR)/.
+
+$(ZDIR)/doc : zipdir ../doc/* ../doc/ref/* ../doc/user/* ../doc/release/*
+	$(RM) -r $@
+	cd ..; find doc -name "*.html" | cpio -pdmuv ds9/$(ZDIR)
+	cd ..; find doc -name "*.gif" | cpio -pdmuv ds9/$(ZDIR)
+	cd ..; find doc -name "*.png" | cpio -pdmuv ds9/$(ZDIR)
+
+$(ZDIR)/cmaps : zipdir ../cmaps/*
+	$(RM) -r $@
+	cp -r ../cmaps $(ZDIR)/.
+
+$(ZDIR)/template : zipdir ../template/*
+	$(RM) -r $@
+	cd ..; find template -name "*.tpl" | cpio -pdmuv ds9/$(ZDIR)
+
+#--------------------------cleanup
+
+distclean: FORCE
+	$(RM) core *~ *# ds9Base ds9 ds9.C *.zip *.o
+	$(RM) -r zipdir
diff --git a/ds9/Makefile.windows b/ds9/Makefile.windows
new file mode 100644
index 0000000..a62de04
--- /dev/null
+++ b/ds9/Makefile.windows
@@ -0,0 +1,132 @@
+#--------------------------defines
+
+CFLAGS= $(CCOPT) -I. -I../include -I$(X11INCLUDE)
+CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE)
+
+MAINDIR	= ../$(TKDIR)/win
+MAIN	= winMain
+RES	= ds9.res.o
+
+OBJS	= ds9.o $(MAIN).o $(RES)
+
+ZDIR	= zipdir/zvfsmntpt
+FFILES	= \
+	$(ZDIR)/$(TCLVER) \
+	$(ZDIR)/tcl8 \
+	$(ZDIR)/$(TKVER) \
+	$(ZDIR)/$(TLTVER) \
+	$(ZDIR)/$(TCLLIBVER) \
+	$(ZDIR)/$(TKCONVER) \
+	$(ZDIR)/$(XMLRPCVER) \
+	$(ZDIR)/src \
+	$(ZDIR)/msgs \
+	$(ZDIR)/doc \
+	$(ZDIR)/cmaps \
+	$(ZDIR)/template
+
+ifdef FILTERCOMPILER
+	FILES = $(FFILES) $(ZDIR)/$(FILTERCOMPILER)
+else
+	FILES = $(FFILES)
+endif
+
+LIBS	= \
+	../lib/libsaotk.a \
+	../lib/libtkhtml.a \
+	../lib/libtkmpeg.a \
+	../lib/$(TCLXMLVER)/Tclxml32.a \
+	../lib/$(TKTABLEVER)/Tktable210.a \
+	../lib/$(TKIMGVER)/tkimgpng14.a \
+	../lib/$(TKIMGVER)/pngtcl143.a \
+	../lib/$(TKIMGVER)/tkimgtiff14.a \
+	../lib/$(TKIMGVER)/tifftcl394.a \
+	../lib/$(TKIMGVER)/tkimgjpeg14.a \
+	../lib/$(TKIMGVER)/jpegtcl82.a \
+	../lib/$(TKIMGVER)/tkimggif14.a \
+	../lib/$(TKIMGVER)/tkimgwindow14.a \
+	../lib/$(TKIMGVER)/zlibtcl125.a \
+	../lib/$(TKIMGVER)/tkimg14.a \
+	../lib/libtiff.a \
+	../lib/libfuntools.a \
+	../lib/librice.a \
+	../lib/libhcomp.a \
+	../lib/libplio.a \
+	../lib/libast.a \
+	../lib/libast_err.a \
+	../lib/libast_pal.a \
+	../lib/libwcs.a \
+	../lib/libzvfs.a \
+	../lib/libz.a \
+	../lib/libxpa.a \
+	../lib/libiis.a \
+	../lib/libcheckdns.a \
+	../lib/libxxlib.a \
+	../lib/libBLTX30.a \
+	../lib/libBLTCore30.a \
+	../lib/libtk86sg.a \
+	../lib/libtkstub86sg.a \
+	../lib/libtcl86sg.a \
+	../lib/libtclstub86sg.a
+
+#--------------------------main
+
+all: ds9.exe
+
+ds9.exe	: ds9Base.exe ds9.zip ../bin/tcc
+	$(RM) $@
+	strip ds9Base.exe
+	cp ds9Base.exe ds9.exe
+	cp ds9.exe ../bin/.
+	cp ds9.zip ../bin/.
+	cp /bin/cygwin1.dll ../bin/.
+	cp /bin/cygxml2-2.dll ../bin/.
+	cp /bin/cygstdc++-6.dll ../bin/.
+	cp /bin/cygiconv-2.dll ../bin/.
+	cp /bin/cygz.dll ../bin/.
+	cp /bin/cyggcc_s-1.dll ../bin/.
+	cp /bin/cygjbig-2.dll ../bin/.
+	cp /bin/cyglzma-5.dll ../bin/.
+
+debug	: ds9Base.exe ds9.zip ../bin/tcc
+	$(RM) $@
+	cp ds9Base.exe ds9.exe
+
+ds9app	: ds9.exe
+	$(RM) -r ../bin/ds9app
+	mkdir ../bin/ds9app
+	cp ds9.exe ../bin/ds9app/.
+	cp ds9.zip ../bin/ds9app/.
+	cp /bin/cygwin1.dll ../bin/ds9app/.
+	cp /bin/cygxml2-2.dll ../bin/ds9app/.
+	cp /bin/cygstdc++-6.dll ../bin/ds9app/.
+	cp /bin/cygiconv-2.dll ../bin/ds9app/.
+	cp /bin/cygz.dll ../bin/ds9app/.
+	cp /bin/cyggcc_s-1.dll ../bin/ds9app/.
+	cp /bin/cygjbig-2.dll ../bin/ds9app/.
+	cp /bin/cyglzma-5.dll ../bin/ds9app/.
+	cp -rp ../bin/tcc ../bin/ds9app/.
+	cp ../ds9/win/install.vbs ../bin/ds9app/.
+
+ds9Base.exe: $(OBJS) $(LIBS)
+	$(RM) $@
+	$(CXX) ${OPTS} \
+	-o $@ $(OBJS) $(LIBS) \
+	-lxml2 -ljbig \
+	-lws2_32 -limm32 -lcomctl32 -mwindows 
+
+$(RES)	: win/ds9.rc win/ds9.ico
+	windres -o $@ --define STATIC_BUILD --include ../$(TKDIR)/generic \
+	--include ../$(TCLDIR)/generic --include ../$(TKDIR)/win/rc \
+	--include win win/ds9.rc
+
+../bin/tcc: ../compilers/$(TCC)
+	$(RM) -r $@
+	cd ../bin; unzip ../compilers/$(TCC)
+	chmod +x ../bin/tcc/tcc.exe
+	touch $@
+
+#--------------------------cleanup
+
+distclean: FORCE
+	$(RM) core *~ *# ds9Base.exe ds9.exe *.zip *.o
+	$(RM) -r zipdir bin/tcc
diff --git a/ds9/ds9.C b/ds9/ds9.macosx
similarity index 63%
copy from ds9/ds9.C
copy to ds9/ds9.macosx
index 9005192..19809db 100644
--- a/ds9/ds9.C
+++ b/ds9/ds9.macosx
@@ -11,6 +11,8 @@ using namespace std;
 #include <tcl.h>
 #include <tk.h>
 
+#define DEBUGS(x) {FILE* fp=fopen("/Users/joye/debug.txt","a+");fprintf(fp,"%s\n",x);fclose(fp);}
+
 extern "C" {
   int SAOAppInit(Tcl_Interp *interp);
   int SAOLocalMainHook(int* argc, char*** argv);
@@ -20,8 +22,7 @@ extern "C" {
   int Zvfs_Init(Tcl_Interp*);
   int Zvfs_Mount(Tcl_Interp*, char*, char *);
 
-  int Blt_core_Init(Tcl_Interp*);
-  int Blt_x_Init(Tcl_Interp*);
+  int Tlt_Init(Tcl_Interp*);
   int Tktable_Init(Tcl_Interp*);
   int Checkdns_Init(Tcl_Interp*);
   int Saotk_Init(Tcl_Interp*);
@@ -45,25 +46,11 @@ extern "C" {
   int Tclxml_Init(Tcl_Interp*);
   int Tclxml_libxml2_Init(Tcl_Interp*);
 
-#ifndef _GWIN32
   int Signal_ext_Init(Tcl_Interp*);
-#endif
 
-#ifdef _MACOSX
   int Tkmacosx_Init(Tcl_Interp*);
-#endif
-#ifdef _GWIN32
-  int Tkwin32_Init(Tcl_Interp*);
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-
-#endif
 }
 
-static char* appname = NULL;
-char* dupstr(const char* str);
 Tcl_Interp *global_interp;
 
 void internalError(const char* msg)
@@ -72,108 +59,55 @@ void internalError(const char* msg)
   Tcl_SetVar2(global_interp, "ds9", "msg,level", "error", TCL_GLOBAL_ONLY);
 }
 
-// currently use relative path
-// using full path with spaces causes problems 
-// with htmwidget and tcl/tk
+extern char* dupstr(const char* str);
 
 int SAOLocalMainHook(int* argcPtr, char*** argvPtr)
 {
   // sync C++ io calls with C io calls
   ios::sync_with_stdio();
 
-  // save real application name
-  int argc = *argcPtr;
+  // do this first
+  Tcl_FindExecutable((*argvPtr)[0]);
+
+  // startup script
+  // use exec path, but remove name
+  int argc=*argcPtr;
   char** argv = *argvPtr;
-  appname = dupstr(argv[0]);
-
-  // so that tcl and tk know where to find their libs
-  // we do it here before InitLibraryPath is called
-  putenv((char*)"TCL_LIBRARY=./zvfsmntpt/tcl8.6");
-  putenv((char*)"TK_LIBRARY=./zvfsmntpt/tk8.6");
-  //  putenv((char*)"TCL_LIBRARY=/tmp/zvfsmntpt/tcl8.6");
-  //  putenv((char*)"TK_LIBRARY=/tmp/zvfsmntpt/tk8.6");
-
-  // invoke startup script
-  Tcl_Obj *path = Tcl_NewStringObj("./zvfsmntpt/src/ds9.tcl",-1);
-  //  Tcl_Obj *path = Tcl_NewStringObj("/tmp/zvfsmntpt/src/ds9.tcl",-1);
+  char* dir = dupstr(argv[0]);
+  char* ptr = dir+strlen(dir);
+  while (*ptr != '/' && ptr != dir)
+    ptr--;
+  *ptr = '\0';
+
+  ostringstream str;
+  str << dir
+      << "/../Frameworks/ds9.framework/Resources/src/ds9.tcl" 
+      <<  ends;
+  char* ss = (char*)str.str().c_str();
+  delete [] dir;
+
+  Tcl_Obj *path = Tcl_NewStringObj(ss,-1);
   Tcl_SetStartupScript(path, NULL);
 }
 
 int SAOAppInit(Tcl_Interp *interp)
 {
-  // reset argv0
-  if (appname) {
-    Tcl_SetVar(interp, "argv0", appname, TCL_GLOBAL_ONLY);
-    delete [] appname;
-  }
-
   // save interp for cputs function
   global_interp = interp;
 
-  // We have to initialize the virtual filesystem before calling
-  // Tcl_Init().  Otherwise, Tcl_Init() will not be able to find
-  // its startup script files.
-  if (Zvfs_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  Tcl_StaticPackage (interp, "zvfs", Zvfs_Init, (Tcl_PackageInitProc*)NULL);
-
-  // find current working directory, and set as mount point
-  {
-    Tcl_DString pwd;
-    Tcl_DStringInit(&pwd);
-    Tcl_GetCwd(interp, &pwd);
-#ifdef ZIPFILE
-    ostringstream str;
-#ifndef _GWIN32
-    str << (char *)Tcl_GetNameOfExecutable() 
-	<< ".zip" 
-	<<  ends;
-#else
-    str << (char *)Tcl_GetNameOfExecutable() 
-	<< "/../ds9.zip" 
-	<<  ends;
-#endif
-    if( Zvfs_Mount(interp, (char*)str.str().c_str(), Tcl_DStringValue(&pwd)) != TCL_OK ){
-      char str[] = "ERROR: Unable to open the auxiliary ds9 file 'ds9.zip'. If you moved the ds9 program from its original location, please also move the zip file to the same place.";
-
-#ifndef _GWIN32
-      cerr << str << endl;
-#else
-      MessageBox(NULL, str, "SAOImage DS9", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
-#endif
-      exit(1);
-    }
-#else
-    Zvfs_Mount(interp, (char *)Tcl_GetNameOfExecutable(), 
-	       Tcl_DStringValue(&pwd));
-#endif
-    Tcl_DStringFree(&pwd);
-  }
-
   // Initialize Tcl and Tk
-  if (Tcl_Init(interp))
+  if (Tcl_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
 
   // Tk
-  if (Tk_Init(interp))
+  if (Tk_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
   Tcl_StaticPackage(interp,"Tk", Tk_Init, Tk_SafeInit);
 
-  {
-    Tcl_DString pwd;
-    Tcl_DStringInit(&pwd);
-    Tcl_GetCwd(interp, &pwd);
-    Tcl_DStringFree(&pwd);
-  }
-
-  // Blt
-  if (Blt_core_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  Tcl_StaticPackage(interp, "blt_core", Blt_core_Init, 
-		    (Tcl_PackageInitProc*)NULL);
-  if (Blt_x_Init(interp) == TCL_ERROR)
+  // tlt
+  if (Tlt_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
-  Tcl_StaticPackage(interp, "blt_extra", Blt_x_Init,
+  Tcl_StaticPackage(interp, "tlt", Tlt_Init, 
 		    (Tcl_PackageInitProc*)NULL);
 
   // Tktable
@@ -283,27 +217,16 @@ int SAOAppInit(Tcl_Interp *interp)
 		     (Tcl_PackageInitProc*)NULL);
 
   // Signal_Ext
-#ifndef _GWIN32
   if (Signal_ext_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
   Tcl_StaticPackage (interp, "signal", Signal_ext_Init, 
 		     (Tcl_PackageInitProc*)NULL);
-#endif
 
-#ifdef _MACOSX
+  // Macosx
   if (Tkmacosx_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
   Tcl_StaticPackage (interp, "macosx", Tkmacosx_Init,
 		     (Tcl_PackageInitProc*)NULL);
-#endif
-
-#ifdef _GWIN32
-  if (Tkwin32_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  Tcl_StaticPackage (interp, "win32", Tkwin32_Init,
-		     (Tcl_PackageInitProc*)NULL);
-#endif
 
   return TCL_OK;
 }
-
diff --git a/ds9/ds9.C b/ds9/ds9.unix
similarity index 77%
copy from ds9/ds9.C
copy to ds9/ds9.unix
index 9005192..96d38f1 100644
--- a/ds9/ds9.C
+++ b/ds9/ds9.unix
@@ -3,6 +3,7 @@
 // For conditions of distribution and use, see copyright notice in "copyright"
 
 #include <stdlib.h>
+#include <string.h>
 
 #include <iostream>
 #include <sstream>
@@ -20,8 +21,7 @@ extern "C" {
   int Zvfs_Init(Tcl_Interp*);
   int Zvfs_Mount(Tcl_Interp*, char*, char *);
 
-  int Blt_core_Init(Tcl_Interp*);
-  int Blt_x_Init(Tcl_Interp*);
+  int Tlt_Init(Tcl_Interp*);
   int Tktable_Init(Tcl_Interp*);
   int Checkdns_Init(Tcl_Interp*);
   int Saotk_Init(Tcl_Interp*);
@@ -45,25 +45,9 @@ extern "C" {
   int Tclxml_Init(Tcl_Interp*);
   int Tclxml_libxml2_Init(Tcl_Interp*);
 
-#ifndef _GWIN32
   int Signal_ext_Init(Tcl_Interp*);
-#endif
-
-#ifdef _MACOSX
-  int Tkmacosx_Init(Tcl_Interp*);
-#endif
-#ifdef _GWIN32
-  int Tkwin32_Init(Tcl_Interp*);
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-
-#endif
 }
 
-static char* appname = NULL;
-char* dupstr(const char* str);
 Tcl_Interp *global_interp;
 
 void internalError(const char* msg)
@@ -81,32 +65,21 @@ int SAOLocalMainHook(int* argcPtr, char*** argvPtr)
   // sync C++ io calls with C io calls
   ios::sync_with_stdio();
 
-  // save real application name
-  int argc = *argcPtr;
-  char** argv = *argvPtr;
-  appname = dupstr(argv[0]);
+  // do this first
+  Tcl_FindExecutable((*argvPtr)[0]);
 
   // so that tcl and tk know where to find their libs
   // we do it here before InitLibraryPath is called
   putenv((char*)"TCL_LIBRARY=./zvfsmntpt/tcl8.6");
   putenv((char*)"TK_LIBRARY=./zvfsmntpt/tk8.6");
-  //  putenv((char*)"TCL_LIBRARY=/tmp/zvfsmntpt/tcl8.6");
-  //  putenv((char*)"TK_LIBRARY=/tmp/zvfsmntpt/tk8.6");
 
-  // invoke startup script
+  // startup script
   Tcl_Obj *path = Tcl_NewStringObj("./zvfsmntpt/src/ds9.tcl",-1);
-  //  Tcl_Obj *path = Tcl_NewStringObj("/tmp/zvfsmntpt/src/ds9.tcl",-1);
   Tcl_SetStartupScript(path, NULL);
 }
 
 int SAOAppInit(Tcl_Interp *interp)
 {
-  // reset argv0
-  if (appname) {
-    Tcl_SetVar(interp, "argv0", appname, TCL_GLOBAL_ONLY);
-    delete [] appname;
-  }
-
   // save interp for cputs function
   global_interp = interp;
 
@@ -122,25 +95,16 @@ int SAOAppInit(Tcl_Interp *interp)
     Tcl_DString pwd;
     Tcl_DStringInit(&pwd);
     Tcl_GetCwd(interp, &pwd);
+
 #ifdef ZIPFILE
     ostringstream str;
-#ifndef _GWIN32
     str << (char *)Tcl_GetNameOfExecutable() 
 	<< ".zip" 
 	<<  ends;
-#else
-    str << (char *)Tcl_GetNameOfExecutable() 
-	<< "/../ds9.zip" 
-	<<  ends;
-#endif
     if( Zvfs_Mount(interp, (char*)str.str().c_str(), Tcl_DStringValue(&pwd)) != TCL_OK ){
       char str[] = "ERROR: Unable to open the auxiliary ds9 file 'ds9.zip'. If you moved the ds9 program from its original location, please also move the zip file to the same place.";
 
-#ifndef _GWIN32
       cerr << str << endl;
-#else
-      MessageBox(NULL, str, "SAOImage DS9", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
-#endif
       exit(1);
     }
 #else
@@ -151,29 +115,18 @@ int SAOAppInit(Tcl_Interp *interp)
   }
 
   // Initialize Tcl and Tk
-  if (Tcl_Init(interp))
+  if (Tcl_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
 
   // Tk
-  if (Tk_Init(interp))
+  if (Tk_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
   Tcl_StaticPackage(interp,"Tk", Tk_Init, Tk_SafeInit);
 
-  {
-    Tcl_DString pwd;
-    Tcl_DStringInit(&pwd);
-    Tcl_GetCwd(interp, &pwd);
-    Tcl_DStringFree(&pwd);
-  }
-
-  // Blt
-  if (Blt_core_Init(interp) == TCL_ERROR)
+  // tlt
+  if (Tlt_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
-  Tcl_StaticPackage(interp, "blt_core", Blt_core_Init, 
-		    (Tcl_PackageInitProc*)NULL);
-  if (Blt_x_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  Tcl_StaticPackage(interp, "blt_extra", Blt_x_Init,
+  Tcl_StaticPackage(interp, "tlt", Tlt_Init, 
 		    (Tcl_PackageInitProc*)NULL);
 
   // Tktable
@@ -283,27 +236,10 @@ int SAOAppInit(Tcl_Interp *interp)
 		     (Tcl_PackageInitProc*)NULL);
 
   // Signal_Ext
-#ifndef _GWIN32
   if (Signal_ext_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
   Tcl_StaticPackage (interp, "signal", Signal_ext_Init, 
 		     (Tcl_PackageInitProc*)NULL);
-#endif
-
-#ifdef _MACOSX
-  if (Tkmacosx_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  Tcl_StaticPackage (interp, "macosx", Tkmacosx_Init,
-		     (Tcl_PackageInitProc*)NULL);
-#endif
-
-#ifdef _GWIN32
-  if (Tkwin32_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  Tcl_StaticPackage (interp, "win32", Tkwin32_Init,
-		     (Tcl_PackageInitProc*)NULL);
-#endif
 
   return TCL_OK;
 }
-
diff --git a/ds9/ds9.C b/ds9/ds9.windows
similarity index 62%
rename from ds9/ds9.C
rename to ds9/ds9.windows
index 9005192..3b6fcbd 100644
--- a/ds9/ds9.C
+++ b/ds9/ds9.windows
@@ -11,6 +11,8 @@ using namespace std;
 #include <tcl.h>
 #include <tk.h>
 
+#define DEBUGS(x) {FILE* fp=fopen("/Users/joye/debug.txt","a+");fprintf(fp,"%s\n",x);fclose(fp);}
+
 extern "C" {
   int SAOAppInit(Tcl_Interp *interp);
   int SAOLocalMainHook(int* argc, char*** argv);
@@ -20,8 +22,7 @@ extern "C" {
   int Zvfs_Init(Tcl_Interp*);
   int Zvfs_Mount(Tcl_Interp*, char*, char *);
 
-  int Blt_core_Init(Tcl_Interp*);
-  int Blt_x_Init(Tcl_Interp*);
+  int Tlt_Init(Tcl_Interp*);
   int Tktable_Init(Tcl_Interp*);
   int Checkdns_Init(Tcl_Interp*);
   int Saotk_Init(Tcl_Interp*);
@@ -45,25 +46,13 @@ extern "C" {
   int Tclxml_Init(Tcl_Interp*);
   int Tclxml_libxml2_Init(Tcl_Interp*);
 
-#ifndef _GWIN32
-  int Signal_ext_Init(Tcl_Interp*);
-#endif
-
-#ifdef _MACOSX
-  int Tkmacosx_Init(Tcl_Interp*);
-#endif
-#ifdef _GWIN32
   int Tkwin32_Init(Tcl_Interp*);
 
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #undef WIN32_LEAN_AND_MEAN
-
-#endif
 }
 
-static char* appname = NULL;
-char* dupstr(const char* str);
 Tcl_Interp *global_interp;
 
 void internalError(const char* msg)
@@ -72,108 +61,37 @@ void internalError(const char* msg)
   Tcl_SetVar2(global_interp, "ds9", "msg,level", "error", TCL_GLOBAL_ONLY);
 }
 
-// currently use relative path
-// using full path with spaces causes problems 
-// with htmwidget and tcl/tk
-
 int SAOLocalMainHook(int* argcPtr, char*** argvPtr)
 {
   // sync C++ io calls with C io calls
   ios::sync_with_stdio();
 
-  // save real application name
-  int argc = *argcPtr;
-  char** argv = *argvPtr;
-  appname = dupstr(argv[0]);
-
-  // so that tcl and tk know where to find their libs
-  // we do it here before InitLibraryPath is called
-  putenv((char*)"TCL_LIBRARY=./zvfsmntpt/tcl8.6");
-  putenv((char*)"TK_LIBRARY=./zvfsmntpt/tk8.6");
-  //  putenv((char*)"TCL_LIBRARY=/tmp/zvfsmntpt/tcl8.6");
-  //  putenv((char*)"TK_LIBRARY=/tmp/zvfsmntpt/tk8.6");
+  // do this first
+  Tcl_FindExecutable((*argvPtr)[0]);
 
-  // invoke startup script
+  // startup script
   Tcl_Obj *path = Tcl_NewStringObj("./zvfsmntpt/src/ds9.tcl",-1);
-  //  Tcl_Obj *path = Tcl_NewStringObj("/tmp/zvfsmntpt/src/ds9.tcl",-1);
   Tcl_SetStartupScript(path, NULL);
 }
 
 int SAOAppInit(Tcl_Interp *interp)
 {
-  // reset argv0
-  if (appname) {
-    Tcl_SetVar(interp, "argv0", appname, TCL_GLOBAL_ONLY);
-    delete [] appname;
-  }
-
   // save interp for cputs function
   global_interp = interp;
 
-  // We have to initialize the virtual filesystem before calling
-  // Tcl_Init().  Otherwise, Tcl_Init() will not be able to find
-  // its startup script files.
-  if (Zvfs_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  Tcl_StaticPackage (interp, "zvfs", Zvfs_Init, (Tcl_PackageInitProc*)NULL);
-
-  // find current working directory, and set as mount point
-  {
-    Tcl_DString pwd;
-    Tcl_DStringInit(&pwd);
-    Tcl_GetCwd(interp, &pwd);
-#ifdef ZIPFILE
-    ostringstream str;
-#ifndef _GWIN32
-    str << (char *)Tcl_GetNameOfExecutable() 
-	<< ".zip" 
-	<<  ends;
-#else
-    str << (char *)Tcl_GetNameOfExecutable() 
-	<< "/../ds9.zip" 
-	<<  ends;
-#endif
-    if( Zvfs_Mount(interp, (char*)str.str().c_str(), Tcl_DStringValue(&pwd)) != TCL_OK ){
-      char str[] = "ERROR: Unable to open the auxiliary ds9 file 'ds9.zip'. If you moved the ds9 program from its original location, please also move the zip file to the same place.";
-
-#ifndef _GWIN32
-      cerr << str << endl;
-#else
-      MessageBox(NULL, str, "SAOImage DS9", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
-#endif
-      exit(1);
-    }
-#else
-    Zvfs_Mount(interp, (char *)Tcl_GetNameOfExecutable(), 
-	       Tcl_DStringValue(&pwd));
-#endif
-    Tcl_DStringFree(&pwd);
-  }
-
   // Initialize Tcl and Tk
-  if (Tcl_Init(interp))
+  if (Tcl_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
 
   // Tk
-  if (Tk_Init(interp))
+  if (Tk_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
   Tcl_StaticPackage(interp,"Tk", Tk_Init, Tk_SafeInit);
 
-  {
-    Tcl_DString pwd;
-    Tcl_DStringInit(&pwd);
-    Tcl_GetCwd(interp, &pwd);
-    Tcl_DStringFree(&pwd);
-  }
-
-  // Blt
-  if (Blt_core_Init(interp) == TCL_ERROR)
+  // tlt
+  if (Tlt_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
-  Tcl_StaticPackage(interp, "blt_core", Blt_core_Init, 
-		    (Tcl_PackageInitProc*)NULL);
-  if (Blt_x_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  Tcl_StaticPackage(interp, "blt_extra", Blt_x_Init,
+  Tcl_StaticPackage(interp, "tlt", Tlt_Init, 
 		    (Tcl_PackageInitProc*)NULL);
 
   // Tktable
@@ -282,28 +200,10 @@ int SAOAppInit(Tcl_Interp *interp)
   Tcl_StaticPackage (interp, "window", Tkimgwindow_Init,
 		     (Tcl_PackageInitProc*)NULL);
 
-  // Signal_Ext
-#ifndef _GWIN32
-  if (Signal_ext_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  Tcl_StaticPackage (interp, "signal", Signal_ext_Init, 
-		     (Tcl_PackageInitProc*)NULL);
-#endif
-
-#ifdef _MACOSX
-  if (Tkmacosx_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  Tcl_StaticPackage (interp, "macosx", Tkmacosx_Init,
-		     (Tcl_PackageInitProc*)NULL);
-#endif
-
-#ifdef _GWIN32
   if (Tkwin32_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
   Tcl_StaticPackage (interp, "win32", Tkwin32_Init,
 		     (Tcl_PackageInitProc*)NULL);
-#endif
 
   return TCL_OK;
 }
-
diff --git a/ds9/macosx/SAOImage DS9.app/Contents/Info.plist b/ds9/macosx/SAOImage DS9.app.old/Contents/Info.plist
similarity index 98%
copy from ds9/macosx/SAOImage DS9.app/Contents/Info.plist
copy to ds9/macosx/SAOImage DS9.app.old/Contents/Info.plist
index 9bc2e76..a93e9ad 100644
--- a/ds9/macosx/SAOImage DS9.app/Contents/Info.plist	
+++ b/ds9/macosx/SAOImage DS9.app.old/Contents/Info.plist	
@@ -53,7 +53,7 @@
 	<key>CFBundleSignature</key>
 	<string>DS9 </string>
 	<key>CFBundleVersion</key>
-	<string>7.3b2</string>
+	<string>7.3b3</string>
 	<key>CSResourcesFileMapped</key>
 	<true/>
 	<key>LSMinimumSystemVersion</key>
diff --git a/ds9/macosx/SAOImage DS9.app/Contents/MacOS/ds9 b/ds9/macosx/SAOImage DS9.app.old/Contents/MacOS/ds9
similarity index 100%
rename from ds9/macosx/SAOImage DS9.app/Contents/MacOS/ds9
rename to ds9/macosx/SAOImage DS9.app.old/Contents/MacOS/ds9
diff --git a/ds9/macosx/SAOImage DS9.app/Contents/PkgInfo b/ds9/macosx/SAOImage DS9.app.old/Contents/PkgInfo
similarity index 100%
rename from ds9/macosx/SAOImage DS9.app/Contents/PkgInfo
rename to ds9/macosx/SAOImage DS9.app.old/Contents/PkgInfo
diff --git a/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/App.icns b/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/App.icns
new file mode 100644
index 0000000..bf30e38
Binary files /dev/null and b/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/App.icns differ
diff --git a/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/InfoPlist.strings b/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/English.lproj/InfoPlist.strings
similarity index 93%
rename from ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/InfoPlist.strings
rename to ds9/macosx/SAOImage DS9.app.old/Contents/Resources/English.lproj/InfoPlist.strings
index 0891356..ae42b9e 100644
Binary files a/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/InfoPlist.strings and b/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/English.lproj/InfoPlist.strings differ
diff --git a/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/main.nib/classes.nib b/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/English.lproj/main.nib/classes.nib
similarity index 100%
rename from ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/main.nib/classes.nib
rename to ds9/macosx/SAOImage DS9.app.old/Contents/Resources/English.lproj/main.nib/classes.nib
diff --git a/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/main.nib/info.nib b/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/English.lproj/main.nib/info.nib
similarity index 100%
rename from ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/main.nib/info.nib
rename to ds9/macosx/SAOImage DS9.app.old/Contents/Resources/English.lproj/main.nib/info.nib
diff --git a/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/main.nib/objects.xib b/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/English.lproj/main.nib/objects.xib
similarity index 100%
rename from ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/main.nib/objects.xib
rename to ds9/macosx/SAOImage DS9.app.old/Contents/Resources/English.lproj/main.nib/objects.xib
diff --git a/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/fits.icns b/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/fits.icns
new file mode 100644
index 0000000..0afa214
Binary files /dev/null and b/ds9/macosx/SAOImage DS9.app.old/Contents/Resources/fits.icns differ
diff --git a/ds9/macosx/SAOImage DS9.app/Contents/Info.plist b/ds9/macosx/SAOImage DS9.app/Contents/Info.plist
index 9bc2e76..b942b78 100644
--- a/ds9/macosx/SAOImage DS9.app/Contents/Info.plist	
+++ b/ds9/macosx/SAOImage DS9.app/Contents/Info.plist	
@@ -30,34 +30,34 @@
 			</array>
 			<key>CFBundleTypeRole</key>
 			<string>Viewer</string>
-			<key>LSTypeIsPackage</key>
-			<false/>
-			<key>NSDocumentClass</key>
-			<string>FITSData</string>
-			<key>NSPersistentStoreTypeKey</key>
-			<string>Binary</string>
 		</dict>
 	</array>
 	<key>CFBundleExecutable</key>
 	<string>ds9</string>
+	<key>CFBundleGetInfoString</key>
+	<string>"SAOImage DS9 7.3
+Copyright 1999-2013
+Smithsonian Astrophysical Observatory"</string>
 	<key>CFBundleIconFile</key>
-	<string>App</string>
+	<string>App.icns</string>
 	<key>CFBundleIdentifier</key>
 	<string>com.sao.SAOImageDS9</string>
 	<key>CFBundleInfoDictionaryVersion</key>
-	<string>7.1</string>
+	<string>6.0</string>
 	<key>CFBundleName</key>
 	<string>SAOImage DS9</string>
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>7.3</string>
 	<key>CFBundleSignature</key>
-	<string>DS9 </string>
+	<string>DS9</string>
 	<key>CFBundleVersion</key>
-	<string>7.3b2</string>
-	<key>CSResourcesFileMapped</key>
-	<true/>
+	<string>7.3</string>
 	<key>LSMinimumSystemVersion</key>
-	<string>10.4.0</string>
+	<string>10.5.0</string>
+	<key>LSRequiresCarbon</key>
+	<true/>
 	<key>LSEnvironment</key>
 	<dict>
 	        <key>PATH</key>
diff --git a/ds9/win/ds9.rc b/ds9/win/ds9.rc
index 3678485..ae4c940 100644
--- a/ds9/win/ds9.rc
+++ b/ds9/win/ds9.rc
@@ -1,6 +1,6 @@
 #include <windows.h>
 
-#define VV "7.3b2"
+#define VV "7.3b3"
 
 VS_VERSION_INFO VERSIONINFO
  FILEVERSION    7,3,0,0
diff --git a/macosx/Makefile b/macosx/Makefile
index 9ece3c4..3a6be7b 100644
--- a/macosx/Makefile
+++ b/macosx/Makefile
@@ -5,18 +5,20 @@ include ../make.pkgs
 CXXFLAGS = $(CXXOPT) \
 	-I../include \
 	-I../saotk/vector \
+	-I../saotk/widget \
 	-I../$(TKDIR)/generic \
 	-I../$(TKDIR)/macosx \
 	-I$(X11INCLUDE)
 
-SRC	= tkmacosx.C \
-	macosxlib.C \
-	xxlib.C \
+SRC	= \
+	macosxlib.mm \
+	rotstr.mm \
+	tkmacosx.mm \
+	xxlib.mm
 
-OBJS	= $(SRC:%.C=%.o)
+OBJS	= $(SRC:%.mm=%.o)
 
-INCLS	= macosxlib.h \
-	xxlib.h
+INCLS	= macosxlib.h xxlib.h rotstr.h
 
 LIB	= libxxlib.a
 
@@ -37,11 +39,5 @@ distclean : clean
 
 FORCE	:
 
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SRC:.C=.d)
-endif
+%.o: %.mm
+	$(COMPILE.C) $(OUTPUT_OPTION) $<
diff --git a/macosx/macosxlib.h b/macosx/macosxlib.h
index e9e16bb..51586ce 100644
--- a/macosx/macosxlib.h
+++ b/macosx/macosxlib.h
@@ -5,6 +5,9 @@
 #ifndef __macosxlib_h__
 #define __macosxlib_h__
 
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
 #include "vector.h"
 
 void macosxBegin();
@@ -27,7 +30,4 @@ void macosxFillPolygon(Vector*, int);
 
 void macosxBitmapCreate(void*, int, int, const Vector&, const Vector&);
 
-void macosxGetMasks(unsigned long* red, unsigned long* green, 
-		    unsigned long* blue);
-
 #endif
diff --git a/macosx/macosxlib.C b/macosx/macosxlib.mm
similarity index 94%
rename from macosx/macosxlib.C
rename to macosx/macosxlib.mm
index 53a0095..563177f 100644
--- a/macosx/macosxlib.C
+++ b/macosx/macosxlib.mm
@@ -156,10 +156,3 @@ void macosxBitmapCreate(void* img, int width, int height,
     tkmacosx->bitmapCreate(img, width, height, vv1[0], vv1[1], ss[0], ss[1]);
   }
 }
-
-void macosxGetMasks(unsigned long* red, unsigned long* green, 
-		    unsigned long* blue, unsigned long* alpha)
-{
-  if (tkmacosx)
-    tkmacosx->getMasks(red,green,blue,alpha);
-}
diff --git a/unix/rotstr.h b/macosx/rotstr.h
similarity index 59%
copy from unix/rotstr.h
copy to macosx/rotstr.h
index 5623831..5a4db57 100644
--- a/unix/rotstr.h
+++ b/macosx/rotstr.h
@@ -7,9 +7,8 @@
 
 #include <tk.h>
 
-class Widget;
 class Vector;
-extern void XDrawRotString(Display* display, Drawable drawable, GC gc,
-			   Vector&, double angle, const char* text, 
-			   Tk_Font font, Widget* parent);
+void XDrawRotString(Display* display, Drawable drawable, GC gc,
+		    Vector& v, double angle, const char* text,
+		    Tk_Font font);
 #endif
diff --git a/macosx/rotstr.mm b/macosx/rotstr.mm
new file mode 100644
index 0000000..bac7510
--- /dev/null
+++ b/macosx/rotstr.mm
@@ -0,0 +1,52 @@
+// Copyright (C) 1999-2013
+// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+// For conditions of distribution and use, see copyright notice in "copyright"
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+using namespace std;
+
+#include <tkMacOSXPrivate.h>
+#include <tkMacOSXFont.h>
+
+#include "vector.h"
+
+void XDrawRotString(Display* display, Drawable drawable, GC gc, 
+		   Vector& v, double angle, const char* text, 
+		   Tk_Font font)
+{
+  MacDrawable* macWin = (MacDrawable*)drawable;
+
+  TkMacOSXDrawingContext dc;
+  TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc);
+
+  // undo the xform in TkMacOSXSetupDrawingContext
+  CGContextConcatCTM(dc.context, CGAffineTransformMake(1.0, 0.0, 0.0,
+		 -1.0, 0.0, dc.portBounds.size.height));
+
+  CGAffineTransform mm = CGAffineTransformMakeRotation(angle);
+  CGContextSetTextMatrix(dc.context, mm);
+
+  // map to window space
+  Vector center = 
+	Vector(dc.portBounds.size.width/2., dc.portBounds.size.height/2.);
+  Vector vv = v *
+    Translate(-center) *
+    Translate(macWin->xOff, macWin->yOff) *
+    FlipY() *
+    Translate(center);
+
+  // draw it
+  TkFont* fontPtr = (TkFont*)font;
+  Tcl_DString ds;
+  Tcl_DStringInit(&ds);
+  int size = Tk_PostscriptFontName(font, &ds);
+  CGContextSelectFont(dc.context, Tcl_DStringValue(&ds), 
+		      size, kCGEncodingMacRoman);
+  Tcl_DStringFree(&ds);
+  CGContextShowTextAtPoint (dc.context, vv[0], vv[1], text, strlen(text));
+
+  // done
+  TkMacOSXRestoreDrawingContext(&dc);
+}
diff --git a/macosx/tkmacosx.h b/macosx/tkmacosx.h
index 0d6daf5..d891c44 100644
--- a/macosx/tkmacosx.h
+++ b/macosx/tkmacosx.h
@@ -5,8 +5,8 @@
 #ifndef __tkmacosx_h__
 #define __tkmacosx_h__
 
-#include <tk.h>
-#include <Carbon/Carbon.h>
+#include <tcl.h>
+#include <tkMacOSXPrivate.h>
 
 #include "vector.h"
 
@@ -17,10 +17,10 @@ class TkMacosx {
   int showDialog;
 
   OSStatus status;
+  CGContextRef context;
   PMPageFormat pageFormat;
   PMPrintSettings printSettings;
   PMPrintSession printSession;
-  CGContextRef context;
 
   Matrix canvasToPage;
 
@@ -58,9 +58,6 @@ class TkMacosx {
   void fillPolygon(float*, float*, int);
   
   void bitmapCreate(void*, int, int, float, float, float, float);
-
-  void getMasks(unsigned long* red,  unsigned long* green, 
-		unsigned long* blue, unsigned long* alpha);
 };
 
 extern TkMacosx* tkmacosx;
diff --git a/macosx/tkmacosx.C b/macosx/tkmacosx.mm
similarity index 89%
rename from macosx/tkmacosx.C
rename to macosx/tkmacosx.mm
index 90bfc6a..6be209b 100644
--- a/macosx/tkmacosx.C
+++ b/macosx/tkmacosx.mm
@@ -8,11 +8,9 @@ using namespace std;
 
 #include <string.h>
 
-#include "tkmacosx.h"
-
-#include <tkMacOSX.h>
-#include <tkMacOSXInt.h>
+#include <tkMacOSXPrivate.h>
 
+#include "tkmacosx.h"
 
 extern "C" {
   int Tkmacosx_Init(Tcl_Interp* interp);
@@ -178,6 +176,7 @@ int TkMacosx::pmPrintBegin(int argc, const char* argv[])
 
   Vector canvas(width,height);
 
+  /*
   // print session
   status = PMCreateSession(&printSession);
   if (status != noErr)
@@ -347,10 +346,12 @@ int TkMacosx::pmPrintBegin(int argc, const char* argv[])
  error:
   cerr << "PM Error Code: " << status << endl;
   return TCL_ERROR;
+  */
 }
 
 int TkMacosx::pmPrintEnd()
 {
+  /*
   status = PMSessionEndPage(printSession);
   if (status != noErr)
     goto error;
@@ -372,6 +373,7 @@ int TkMacosx::pmPrintEnd()
   PMRelease(printSession);
   printSession = NULL;
   return TCL_ERROR;
+  */
 }
 
 int TkMacosx::pmPrintText(int argc, const char* argv[])
@@ -407,6 +409,7 @@ int TkMacosx::pmPrintText(int argc, const char* argv[])
     return TCL_ERROR;
   }
 
+  /*
   if (!argv[4])
     goto error;
 
@@ -639,10 +642,12 @@ int TkMacosx::pmPrintText(int argc, const char* argv[])
     delete sstr;
 
   return TCL_ERROR;
+  */
 }
 
 int TkMacosx::pmPageSetup()
 {
+  /*
   // print session
   status = PMCreateSession(&printSession);
   if (status != noErr)
@@ -682,6 +687,7 @@ int TkMacosx::pmPageSetup()
   PMRelease(printSession);
   printSession = NULL;
   return TCL_ERROR;
+  */
 }
 
 // drawing routines
@@ -709,7 +715,7 @@ void TkMacosx::width(float ww)
 
 void TkMacosx::dash(float* dd, int nn)
 {
-  CGContextSetLineDash(context,0,dd,nn);
+  CGContextSetLineDash(context,0,(CGFloat*)dd,nn);
 }
 
 void TkMacosx::font(const char* font, float size)
@@ -797,95 +803,3 @@ void TkMacosx::bitmapCreate(void* data, int width, int height,
   if (cs)
     CGColorSpaceRelease(cs);
 }
-
-void TkMacosx::getMasks(unsigned long* red, unsigned long* green, 
-			unsigned long* blue, unsigned long* alpha)
-{
-  // init
-  *red   = 0;
-  *blue  = 0;
-  *green = 0;
-  *alpha = 0;
-
-  Tk_Window tkwin = Tk_MainWindow(interp);
-  if (!tkwin)
-    return;
-
-  TkWindowPrivate* ptr = ((TkWindow *) (tkwin))->privatePtr;
-  if (!ptr)
-    return;
-
-  GWorldPtr gw = ptr->grafPtr;
-  if (!gw)
-    return;
-
-  PixMapHandle ph = GetGWorldPixMap(gw);
-  if (!ph)
-    return;
-
-  PixMap* pm = *ph;
-  switch (pm->pixelFormat) {
-  case k16BE555PixelFormat: // 0x10
-    *red   = 0x00007C00;
-    *green = 0x000003E0;
-    *blue  = 0x0000001F;
-    *alpha = 0x00000000;
-    return;
-  case k16LE555PixelFormat: // 'L555'
-    *red   = 0x00007C00;
-    *green = 0x000003E0;
-    *blue  = 0x0000001F;
-    *alpha = 0x00000000;
-    return;
-  case k16BE565PixelFormat: // 'B565'
-    *red   = 0x0000F800;
-    *green = 0x000007E0;
-    *blue  = 0x0000001F;
-    *alpha = 0x00000000;
-    return;
-  case k16LE565PixelFormat: // 'L565'
-    *red   = 0x0000F800;
-    *green = 0x000007E0;
-    *blue  = 0x0000001F;
-    *alpha = 0x00000000;
-    return;
-
-  case k24RGBPixelFormat: // 0x18
-    *red   = 0x00FF0000;
-    *green = 0x0000FF00;
-    *blue  = 0x000000FF;
-    *alpha = 0x00000000;
-    return;
-  case k24BGRPixelFormat: // '24BG'
-    *red   = 0x00FF0000;
-    *green = 0x0000FF00;
-    *blue  = 0x000000FF;
-    *alpha = 0x00000000;
-    return;
-
-  case k32ARGBPixelFormat: // 0x20
-    *alpha = 0xFF000000;
-    *red   = 0x00FF0000;
-    *green = 0x0000FF00;
-    *blue  = 0x000000FF;
-    return;
-  case k32BGRAPixelFormat: // 'BGRA'
-    *alpha = 0xFF000000;
-    *red   = 0x00FF0000;
-    *green = 0x0000FF00;
-    *blue  = 0x000000FF;
-    return;
-  case k32ABGRPixelFormat: // 'ABGR'
-    *red   = 0x000000FF;
-    *green = 0x0000FF00;
-    *blue  = 0x00FF0000;
-    *alpha = 0xFF000000;
-    return;
-  case k32RGBAPixelFormat: // 'RGBA'
-    *red   = 0x000000FF;
-    *green = 0x0000FF00;
-    *blue  = 0x00FF0000;
-    *alpha = 0xFF000000;
-    return;
-  }
-}
diff --git a/macosx/xxlib.C b/macosx/xxlib.C
deleted file mode 100644
index 96e2f83..0000000
--- a/macosx/xxlib.C
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-using namespace std;
-
-#include <tcl.h>
-#include <tk.h>
-#include <Xlib.h>
-
-#include <tkMacOSX.h>
-#include <tkMacOSXInt.h>
-#include <tkMacOSXFont.h>
-#include <tkMacOSXPrivate.h>
-
-#include "vector.h"
-
-#define RGBFLOATRED(c)   ((c).red   / 65535.0)
-#define RGBFLOATGREEN(c) ((c).green / 65535.0)
-#define RGBFLOATBLUE(c)  ((c).blue  / 65535.0)
-
-char* XImageData(XImage* ximage)
-{
-  GWorldPtr gw = TkMacOSXGetDrawablePort((Pixmap)(ximage->obdata));
-  PixMapHandle ph = GetGWorldPixMap(gw);
-  PixMap* pm = *ph;
-  return GetPixBaseAddr(ph);
-}
-
-void DrawRotString(Display* display, Drawable drawable, GC gc, Tk_Font font, 
-		   double angle, const Vector& v, const char* text,
-		   Widget* parent)
-{
-  MacDrawable* macWin = (MacDrawable*)drawable;
-
-  TkMacOSXDrawingContext dc;
-  TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc);
-
-  // undo the xform in TkMacOSXSetupDrawingContext
-  CGContextConcatCTM(dc.context, CGAffineTransformMake(1.0, 0.0, 0.0,
-		 -1.0, 0.0, dc.portBounds.bottom - dc.portBounds.top));
-
-  CGAffineTransform mm = CGAffineTransformMakeRotation(angle);
-  CGContextSetTextMatrix(dc.context, mm);
-
-  // map to window space
-  Vector center = 
-    Vector((dc.portBounds.right-dc.portBounds.left)/2.,
-	   (dc.portBounds.bottom-dc.portBounds.top)/2.);
-  Vector vv = v *
-    Translate(-center) *
-    Translate(macWin->xOff, macWin->yOff) *
-    FlipY() *
-    Translate(center);
-
-  // draw it
-  TkFont* fontPtr = (TkFont*)font;
-  Tcl_DString ds;
-  Tcl_DStringInit(&ds);
-  int size = Tk_PostscriptFontName(font, &ds);
-  CGContextSelectFont(dc.context, Tcl_DStringValue(&ds), 
-		      size, kCGEncodingMacRoman);
-  Tcl_DStringFree(&ds);
-  CGContextShowTextAtPoint (dc.context, vv[0], vv[1], text, strlen(text));
-
-  // done
-  TkMacOSXRestoreDrawingContext(&dc);
-}
-
-extern "C" {
-  void XDrawString(Display* display, Drawable drawable, GC gc, 
-			  int x, int y, _Xconst char* str, int length)
-  {
-    DrawRotString(display, drawable, gc, (Tk_Font)gc->font, 0, 
-		  Vector(x,y), str);
-    //Tk_DrawChars(display, drawable, gc, (Tk_Font)gc->font, str, length, x, y);
-  }
-
-  // Pixmap Suite
-  Pixmap XCreatePixmap(Display* display, Drawable drawable, 
-			      unsigned int width, unsigned int height,
-			      unsigned int depth)
-  {
-    Tk_GetPixmap(display, drawable, width, height, depth);
-  }
-
-  // XImage Suite
-  XImage* XXCreateImage(Display* display, Visual* visual,
-			unsigned int depth, int format, int offset,
-			char* data, unsigned int width, unsigned int height,
-			int bitmap_pad, int bytes_per_line)
-  {
-    XImage* ximage = XCreateImage(display, visual, depth, format, offset,
-				  data, width, height, 
-				  bitmap_pad, bytes_per_line);
-
-    GWorldPtr gw = (GWorldPtr)data;
-    PixMapHandle ph = GetGWorldPixMap(gw);
-    PixMap* pm = *ph;
-
-    // now correct it
-    ximage->bytes_per_line = (pm->rowBytes & 0x3fff);
-
-    switch (depth) {
-    case 1:
-      ximage->bits_per_pixel = 1;
-      ximage->bitmap_unit = 8;
-      ximage->bitmap_pad = 1;
-      break;
-    case 8:
-      ximage->bits_per_pixel = 8;
-      ximage->bitmap_unit = 8;
-      ximage->bitmap_pad = 8;
-      break;
-    case 15:
-      ximage->bits_per_pixel = 16;
-      ximage->bitmap_unit = 32;
-      ximage->bitmap_pad = 32;
-      break;
-    case 16:
-      ximage->bits_per_pixel = 16;
-      ximage->bitmap_unit = 32;
-      ximage->bitmap_pad = 32;
-      break;
-    case 24:
-      ximage->bits_per_pixel = 24;
-      ximage->bitmap_unit = 32;
-      ximage->bitmap_pad = 32;
-      break;
-    case 32:
-      ximage->bits_per_pixel = 32;
-      ximage->bitmap_unit = 32;
-      ximage->bitmap_pad = 32;
-      break;
-    }
-
-    switch (pm->pixelFormat) {
-    case k16BE555PixelFormat: // 0x10
-      ximage->bitmap_bit_order = MSBFirst;
-      ximage->byte_order = MSBFirst;
-      break;
-    case k16LE555PixelFormat: // 'L555'
-      ximage->bitmap_bit_order = LSBFirst;
-      ximage->byte_order = LSBFirst;
-      break;
-    case k16BE565PixelFormat: // 'B565'
-      ximage->bitmap_bit_order = MSBFirst;
-      ximage->byte_order = MSBFirst;
-      break;
-    case k16LE565PixelFormat: // 'L565'
-      ximage->bitmap_bit_order = LSBFirst;
-      ximage->byte_order = LSBFirst;
-      break;
-
-    case k24RGBPixelFormat: // 0x18
-      ximage->bitmap_bit_order = MSBFirst;
-      ximage->byte_order = MSBFirst;
-      break;
-    case k24BGRPixelFormat: // '24BG'
-      ximage->bitmap_bit_order = LSBFirst;
-      ximage->byte_order = LSBFirst;
-      break;
-
-    case k32ARGBPixelFormat: // 0x20
-      ximage->bitmap_bit_order = MSBFirst;
-      ximage->byte_order = MSBFirst;
-      break;
-    case k32BGRAPixelFormat: // 'BGRA'
-      ximage->bitmap_bit_order = LSBFirst;
-      ximage->byte_order = LSBFirst;
-      break;
-    case k32ABGRPixelFormat: // 'ABGR'
-      ximage->bitmap_bit_order = MSBFirst;
-      ximage->byte_order = MSBFirst;
-      break;
-    case k32RGBAPixelFormat: // 'RGBA'
-      ximage->bitmap_bit_order = LSBFirst;
-      ximage->byte_order = LSBFirst;
-      break;
-
-    default:
-      cerr << "MacOSX Internal Error: XXCreateImage: pixelFormat " << hex << pm->pixelFormat 
-	   << " not implemented" << endl;
-      break;
-    }
-
-    return ximage;
-  }
-
-  XImage *XXGetImage(Display *display, Drawable drawable, 
-		     int x, int y,
-		     unsigned int width, unsigned int height,
-		     unsigned long plane_mask, int format)
-  { 
-    if (width ==0 || height ==0) {
-      cerr << "MacOSX Internal Error: XXGetImage: width/height is zero" << endl;
-      return NULL;
-    }
-
-    if (format != ZPixmap) {
-      cerr << "MacOSX Internal Error: XXGetImage: illegal format" << endl;
-      return NULL;
-    }
-
-    if (!TkMacOSXGetDrawablePort(drawable)) {
-      cerr << "MacOSX Internal Error: XXGetImage: bad drawable" << endl;
-      return NULL;
-    }
-
-    // get pixmap
-    Pixmap pixmap = Tk_GetPixmap(display, drawable, width, height, 32);
-    if (!pixmap) {
-      cerr << "MacOSX Internal Error: XXGetImage: bad pixmap" << endl;
-      return NULL;
-    }
- 
-    // get gc
-    GC gc;
-    Tk_Window win = (Tk_Window)((MacDrawable *) drawable)->winPtr;
-    if (win) {
-      XGCValues values;
-      gc = Tk_GetGC(win, 0, &values);
-    } 
-    else
-      gc = XCreateGC(display, pixmap, 0, NULL);
- 
-    // populate pixmap
-    XCopyArea(display, drawable, pixmap, gc, x, y, width, height, 0, 0);
-
-    if (win)
-      Tk_FreeGC(display, gc);
-    else
-      XFreeGC(display, gc);
-
-    GWorldPtr gw = TkMacOSXGetDrawablePort(pixmap);
-    PixMapHandle ph = GetGWorldPixMap(gw);
-    PixMap* pm = *ph;
-
-    int depth = pm->pixelSize;
-    int bitmap_pad = depth; // will be reset
-    int bytes_per_line = width; // will be reset
-    XImage* image = XXCreateImage(display, NULL, depth, format, 0,
-				     (char*)TkMacOSXGetDrawablePort(pixmap),
-				     width, height, 
-				     bitmap_pad, bytes_per_line);
-    // needed by tk
-    image->obdata = (XPointer)pixmap;
-
-    return image;
-  }
-
-  void XSetClipRectangles(Display* display, GC gc, int clip_x_origin,
-			  int  clip_y_origin, XRectangle* r,
-			  int  n, int ordering)
-  {
-    // clear it
-    TkpClipMask *clip_mask = (TkpClipMask*)gc->clip_mask;
-    if (clip_mask && clip_mask->type == TKP_CLIP_REGION)
-      TkpReleaseRegion(clip_mask->value.region);
-
-    // new region
-    TkRegion clipRgn = TkCreateRegion();
-
-    // clip origin not used, but set anyways
-    gc->clip_x_origin = clip_x_origin;
-    gc->clip_y_origin = clip_y_origin;
-
-    for (int ii =0; ii<n; ii++)
-      TkUnionRectWithRegion(&r[ii], clipRgn, clipRgn);
-
-    // and set it
-    TkSetRegion(display, gc, clipRgn);
-  }
-
-  Bool XXQueryPointer(Display* display, Window w, 
-		      Window* root_return, Window* child_return, 
-		      int* root_x_return, int* root_y_return, 
-		      int* win_x_return, int* win_y_return, 
-		      unsigned int* mask_return)
-  {
-    XQueryPointer(display, w, root_return, child_return, 
-		  root_x_return, root_y_return, 
-		  win_x_return, win_y_return, mask_return);
-
-    // flag root for XXWarpPointer
-    *root_return = 1;
-    *child_return = NULL;
-  }
-
-  void XXWarpPointer(Display* display, Window src_w, Window dest_w,
-		     int src_x, int src_y,
-		     unsigned int src_width, unsigned int src_height,
-		     int dest_x, int dest_y)
-  {
-    // we have a special mode, root=1, from XXQueryPointer
-    CGPoint pt;
-
-    if (dest_w == None) {
-      Point ppt;
-      GetGlobalMouse(&ppt);
-      pt.x = dest_x+ppt.h;
-      pt.y = dest_y+ppt.v;
-    }
-    else if (dest_w == 1) {
-      pt.x = dest_x;
-      pt.y = dest_y;
-    }
-    else {
-      Point ppt;
-      MacDrawable* macPtr = (MacDrawable*)dest_w;
-      ppt.h = dest_x+macPtr->xOff;
-      ppt.v = dest_y+macPtr->yOff;
-
-      CGrafPtr port = TkMacOSXGetDrawablePort(dest_w);
-      QDLocalToGlobalPoint(port, &ppt);
-      pt.x = ppt.h;
-      pt.y = ppt.v;
-    }
-
-    // we can't use the following, we want a mouse event generated.
-    //      CGWarpMouseCursorPosition(pt);
-    // and we can't use the following, its buggy as all get out
-    //      CGPostMouseEvent(pt, true, 1, false);
-
-    CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
-    CGEventRef ev = CGEventCreateMouseEvent(src,kCGEventMouseMoved,pt,kCGMouseButtonLeft);
-    // bug in tiger, reset event type
-    CGEventSetType(ev,kCGEventMouseMoved);
-    CGEventPost(kCGSessionEventTap,ev);
-    CFRelease(ev);
-    CFRelease(src);
-  }
-}
diff --git a/macosx/xxlib.h b/macosx/xxlib.h
index cb81817..6f33e60 100644
--- a/macosx/xxlib.h
+++ b/macosx/xxlib.h
@@ -5,22 +5,15 @@
 #ifndef __xxlib_h__
 #define __xxlib_h__
 
-#include <tcl.h>
 #include <tk.h>
 
-// direct X11 to Tk
-
-char* XImageData(XImage* ximage);
-
 extern "C" {
 
-  // available in blt/src/bltMacOSX.c
+  // New Routines
   void XPutImage(Display* display, Drawable d, GC gc, XImage* image,
 		 int src_x, int src_y, int dest_x, int dest_y,
 		 unsigned int width, unsigned int height);
-  void XFreePixmap(Display*, Pixmap);
 
-  // New Routines
   void XDrawString(Display* display, Drawable drawable, GC gc, 
 		   int x, int y, _Xconst char* str, int length);
 
@@ -28,21 +21,32 @@ extern "C" {
 		       unsigned int width, unsigned int height,
 		       unsigned int depth);
 
-  void XSetClipRectangles(Display* display, GC gc, int clip_x_origin,
-			  int  clip_y_origin, XRectangle* r,
-			  int  n, int  ordering);
+  // blt only
+  void XDrawArcs(Display *display, Drawable d, GC gc, XArc *arcArr, int nArcs);
 
-  // Redefined Routines
-  XImage *XXGetImage(Display *display, Drawable drawable, int x, int y,
-		     unsigned int width, unsigned int height,
-		     unsigned long plane_mask, int format);
+  void XDrawRectangles(Display *display, Drawable drawable, GC gc,
+		       XRectangle *rectArr, int nRects);
 
+  void XFillArcs(Display *display, Drawable d, GC gc, XArc *arcArr, int nArcs);
+
+  int XFree(void *data);
+  long XExtendedMaxRequestSize(Display *display);
+  int XFreeFontNames(char *list[]);
+  char **XListFonts(Display *display, char *pattern, int maxnames, 
+		    int *actual_count_return);
+  long XMaxRequestSize(Display *display);
+
+  // defined in tk/macosx
+  int XSetClipRectangles(Display *d, GC gc, int clip_x_origin,
+			 int clip_y_origin, XRectangle* rectangles, 
+			 int n, int ordering);
+
+  // Redefined Routines
   Bool XXQueryPointer(Display* display, Window w, 
 		      Window* root_return, Window* child_return, 
 		      int* root_x_return, int* root_y_return, 
 		      int* win_x_return, int* win_y_return, 
 		      unsigned int* mask_return);
-
   void XXWarpPointer(Display* display, Window src_w, Window dest_w,
 		     int src_x, int src_y,
 		     unsigned int src_width, unsigned int src_height,
diff --git a/macosx/xxlib.mm b/macosx/xxlib.mm
new file mode 100644
index 0000000..a99cd18
--- /dev/null
+++ b/macosx/xxlib.mm
@@ -0,0 +1,142 @@
+// Copyright (C) 1999-2012
+// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+// For conditions of distribution and use, see copyright notice in "copyright"
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+using namespace std;
+
+#include <tkMacOSXPrivate.h>
+// we need real versions of these
+#undef XFree
+#undef XFlush
+
+#include <tk.h>
+#include <tkInt.h>
+#include <X11/Xlib.h>
+
+#include "widget.h"
+#include "vector.h"
+#include "rotstr.h"
+
+#define RGBFLOATRED(c)   ((c).red   / 65535.0)
+#define RGBFLOATGREEN(c) ((c).green / 65535.0)
+#define RGBFLOATBLUE(c)  ((c).blue  / 65535.0)
+
+extern "C" {
+  void XPutImage(Display* display, Drawable d, GC gc, XImage* image,
+		 int src_x, int src_y, int dest_x, int dest_y,
+		 unsigned int width, unsigned int height)
+  {
+    TkPutImage(NULL, 0, display, d, gc, image, src_x, src_y,
+	       dest_x, dest_y, width, height);
+  }
+
+  void XDrawString(Display* display, Drawable drawable, GC gc, 
+		   int x, int y, _Xconst char* str, int length)
+  {
+    Vector vv(x,y);
+    XDrawRotString(display, drawable, gc, vv, 0, str, (Tk_Font)gc->font);
+  }
+
+  Pixmap XCreatePixmap(Display* display, Drawable drawable, 
+		       unsigned int width, unsigned int height,
+		       unsigned int depth)
+  {
+    Tk_GetPixmap(display, drawable, width, height, depth);
+  }
+
+  /*
+  void XSetClipRectangles(Display* display, GC gc, int clip_x_origin,
+			  int  clip_y_origin, XRectangle* r,
+			  int  n, int ordering)
+  {
+    // clear it
+    TkpClipMask *clip_mask = (TkpClipMask*)gc->clip_mask;
+    if (clip_mask && clip_mask->type == TKP_CLIP_REGION)
+      TkpReleaseRegion(clip_mask->value.region);
+
+    // new region
+    TkRegion clipRgn = TkCreateRegion();
+
+    // clip origin not used, but set anyways
+    gc->clip_x_origin = clip_x_origin;
+    gc->clip_y_origin = clip_y_origin;
+
+    for (int ii =0; ii<n; ii++)
+      TkUnionRectWithRegion(&r[ii], clipRgn, clipRgn);
+
+    // and set it
+    TkSetRegion(display, gc, clipRgn);
+  }
+  */
+
+  // blt only
+  int XFree(void* data)
+  {
+    if (data != NULL)
+      ckfree(data);
+    return 0;
+  }
+
+  // blt only (not implemented)
+  char **XListFonts(Display *display, char *pattern, int maxnames, int *cnt)
+  {
+    *cnt =0;
+    return NULL;
+  }
+
+  int XFreeFontNames(char *list[])
+  {
+    return 0;
+  }
+
+  // blt only (no ops)
+  int XFlush(Display *display) {return 0;}
+  long XExtendedMaxRequestSize(Display *display) {return 0;}
+
+  // Redefined Routines
+  Bool XXQueryPointer(Display* display, Window w, 
+		      Window* root_return, Window* child_return, 
+		      int* root_x_return, int* root_y_return, 
+		      int* win_x_return, int* win_y_return, 
+		      unsigned int* mask_return)
+  {
+    XQueryPointer(display, w, root_return, child_return, 
+		  root_x_return, root_y_return, 
+		  win_x_return, win_y_return, mask_return);
+
+    // flag root for XXWarpPointer
+    *root_return = 1;
+    *child_return = NULL;
+  }
+
+  void XXWarpPointer(Display* display, Window src_w, Window dest_w,
+		     int src_x, int src_y,
+		     unsigned int src_width, unsigned int src_height,
+		     int dest_x, int dest_y)
+  {
+    // we have a special mode, root=1, from XXQueryPointer
+    CGPoint pt;
+
+    if (dest_w == 1) {
+      pt.x = dest_x;
+      pt.y = dest_y;
+    }
+    else {
+      int xx, yy;
+      XQueryPointer(display, dest_w, NULL, NULL, &xx, &yy, NULL, NULL, NULL);
+      pt.x = xx+dest_x;
+      pt.y = yy+dest_y;
+    }
+
+    CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
+    CGEventRef ev = CGEventCreateMouseEvent(src,kCGEventMouseMoved,pt,kCGMouseButtonLeft);
+    CGEventPost(kCGSessionEventTap,ev);
+    CFRelease(ev);
+    CFRelease(src);
+  }
+}
+
+
diff --git a/make.cygwin b/make.cygwin
index ef76371..f59ba78 100644
--- a/make.cygwin
+++ b/make.cygwin
@@ -4,14 +4,14 @@ ARCH	= cygwin
 X11INCLUDE=/usr/X11/include
 X11LIB	= /usr/X11
 
-XX	= -O2 
+XX	= 
 YY	= -g
 ZZ	=
 
 AA	= -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H
 
-#OPTS	= ${XX} ${ZZ}
-OPTS	= ${YY} ${ZZ}
+OPTS	= ${XX} ${ZZ}
+#OPTS	= ${YY} ${ZZ}
 NOPTS	= ${YY} ${ZZ}
 
 CXX	= g++
diff --git a/make.darwin64x86lion b/make.darwin64x86lion
index 1efcd1d..7d87a70 100644
--- a/make.darwin64x86lion
+++ b/make.darwin64x86lion
@@ -5,16 +5,15 @@ ARCH	= darwin64x86lion
 
 X11INCLUDE=/usr/X11/include
 X11LIB	= /usr/X11/lib
-EXTTCLFLAGS=--disable-corefoundation
 
-XX	= -O2 
+XX	= 
 YY	= -gstabs+ -fno-inline 
-ZZ	= -m64 -arch x86_64 -mmacosx-version-min=10.7
+ZZ	= -m64
 
 AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D__M64
 
-#OPTS	= ${XX} ${ZZ}
-OPTS	= ${YY} ${ZZ}
+OPTS	= ${XX} ${ZZ}
+#OPTS	= ${YY} ${ZZ}
 NOPTS	= ${YY} ${ZZ}
 
 CXX	= g++
@@ -31,6 +30,7 @@ CODESIGN = codesign
 ZIPFILE = ds9.zip
 FILTERCOMPILER = pcc-i386-snowleopard.tar.gz
 
+TCLFLAGS= --disable-corefoundation --enable-64bit
 ASTFLAGS = star_cv_cnf_trail_type=long
 JOBS = 4
 
diff --git a/make.darwin64x86mountainlion b/make.darwin64x86mountainlion
index 5e5c8f4..940161f 100644
--- a/make.darwin64x86mountainlion
+++ b/make.darwin64x86mountainlion
@@ -5,16 +5,17 @@ ARCH	= darwin64x86mountainlion
 
 X11INCLUDE=/usr/X11/include
 X11LIB	= /usr/X11/lib
-EXTTCLFLAGS=--disable-corefoundation
 
-XX	= -O2 
+# mpeg segv's with -O
+#XX	= -O2
+XX	= 
 YY	= -gstabs+ -fno-inline 
-ZZ	= -m64 -arch x86_64 -mmacosx-version-min=10.8
+ZZ	= -m64
 
 AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D__M64
 
-#OPTS	= ${XX} ${ZZ}
-OPTS	= ${YY} ${ZZ}
+OPTS	= ${XX} ${ZZ}
+#OPTS	= ${YY} ${ZZ}
 NOPTS	= ${YY} ${ZZ}
 
 CXX	= g++
@@ -31,6 +32,7 @@ CODESIGN = codesign
 ZIPFILE = ds9.zip
 FILTERCOMPILER = pcc-i386-snowleopard.tar.gz
 
+TCLFLAGS= --disable-corefoundation --enable-64bit
 ASTFLAGS = star_cv_cnf_trail_type=long
 JOBS = 4
 
diff --git a/make.darwin64x86snowleopard b/make.darwin64x86snowleopard
index bb35bec..e19085d 100644
--- a/make.darwin64x86snowleopard
+++ b/make.darwin64x86snowleopard
@@ -3,16 +3,15 @@ ARCH	= darwin64x86snowleopard
 
 X11INCLUDE=/usr/X11/include
 X11LIB	= /usr/X11/lib
-EXTTCLFLAGS=--disable-corefoundation
 
-XX	= -O2 
+XX	= 
 YY	= -gstabs+ -fno-inline 
-ZZ	= -m64 -arch x86_64
+ZZ	= -m64
 
 AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D__M64
 
-#OPTS	= ${XX} ${ZZ}
-OPTS	= ${YY} ${ZZ}
+OPTS	= ${XX} ${ZZ}
+#OPTS	= ${YY} ${ZZ}
 NOPTS	= ${YY} ${ZZ}
 
 CXX	= g++
@@ -29,5 +28,6 @@ CODESIGN = codesign
 ZIPFILE = ds9.zip
 FILTERCOMPILER = pcc-i386-snowleopard.tar.gz
 
+TCLFLAGS= --disable-corefoundation --enable-64bit
 ASTFLAGS = star_cv_cnf_trail_type=long
 JOBS = 4
diff --git a/make.darwinx86lion b/make.darwinx86lion
index 50e378c..9a9da18 100644
--- a/make.darwinx86lion
+++ b/make.darwinx86lion
@@ -5,16 +5,15 @@ ARCH	= darwinx86lion
 
 X11INCLUDE=/usr/X11/include
 X11LIB	= /usr/X11/lib
-EXTTCLFLAGS=--disable-corefoundation
 
-XX	= -O2 
+XX	= 
 YY	= -gstabs+ -fno-inline
-ZZ	= -arch i386 -mmacosx-version-min=10.7
+ZZ	= -m32
 
 AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
 
-#OPTS	= ${XX} ${ZZ}
-OPTS	= ${YY} ${ZZ}
+OPTS	= ${XX} ${ZZ}
+#OPTS	= ${YY} ${ZZ}
 NOPTS	= ${YY} ${ZZ}
 
 CXX	= g++
@@ -30,4 +29,6 @@ ZCAT	= gzcat
 CODESIGN = codesign
 ZIPFILE = ds9.zip
 FILTERCOMPILER = pcc-i386-snowleopard.tar.gz
+
+TCLFLAGS= --disable-corefoundation
 JOBS = 4
diff --git a/make.darwinx86mountainlion b/make.darwinx86mountainlion
index b5927b2..a930417 100644
--- a/make.darwinx86mountainlion
+++ b/make.darwinx86mountainlion
@@ -5,16 +5,15 @@ ARCH	= darwinx86mountainlion
 
 X11INCLUDE=/usr/X11/include
 X11LIB	= /usr/X11/lib
-EXTTCLFLAGS=--disable-corefoundation
 
-XX	= -O2 
+XX	= 
 YY	= -gstabs+ -fno-inline
-ZZ	= -arch i386 -mmacosx-version-min=10.8
+ZZ	= -m32
 
 AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
 
-#OPTS	= ${XX} ${ZZ}
-OPTS	= ${YY} ${ZZ}
+OPTS	= ${XX} ${ZZ}
+#OPTS	= ${YY} ${ZZ}
 NOPTS	= ${YY} ${ZZ}
 
 CXX	= g++
@@ -30,4 +29,6 @@ ZCAT	= gzcat
 CODESIGN = codesign
 ZIPFILE = ds9.zip
 FILTERCOMPILER = pcc-i386-snowleopard.tar.gz
+
+TCLFLAGS= --disable-corefoundation
 JOBS = 4
diff --git a/make.darwinx86snowleopard b/make.darwinx86snowleopard
index 9c6b85e..e2a6fff 100644
--- a/make.darwinx86snowleopard
+++ b/make.darwinx86snowleopard
@@ -3,16 +3,15 @@ ARCH	= darwinx86snowleopard
 
 X11INCLUDE=/usr/X11/include
 X11LIB	= /usr/X11/lib
-EXTTCLFLAGS=--disable-corefoundation
 
-XX	= -O2 
+XX	= 
 YY	= -gstabs+ -fno-inline
-ZZ	= -arch i386
+ZZ	= -m32
 
 AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
 
-#OPTS	= ${XX} ${ZZ}
-OPTS	= ${YY} ${ZZ}
+OPTS	= ${XX} ${ZZ}
+#OPTS	= ${YY} ${ZZ}
 NOPTS	= ${YY} ${ZZ}
 
 CXX	= g++
@@ -28,4 +27,6 @@ ZCAT	= gzcat
 CODESIGN = codesign
 ZIPFILE = ds9.zip
 FILTERCOMPILER = pcc-i386-snowleopard.tar.gz
+
+TCLFLAGS= --disable-corefoundation
 JOBS = 4
diff --git a/make.linux b/make.linux
index 00ba4e7..5ebb47a 100644
--- a/make.linux
+++ b/make.linux
@@ -4,14 +4,15 @@ ARCH	= linux
 X11INCLUDE=/usr/X11R6/include
 X11LIB	= /usr/X11R6/lib
 
-XX	= -O2 
+XX	= 
 YY	= -gstabs+ -fno-inline 
-ZZ	=
+# we need this to find M_PI and isfinite() in math.h
+ZZ	= -m32 -D_GNU_SOURCE
 
 AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
 
-#OPTS	= ${XX} ${ZZ}
-OPTS	= ${YY} ${ZZ}
+OPTS	= ${XX} ${ZZ}
+#OPTS	= ${YY} ${ZZ}
 NOPTS	= ${YY} ${ZZ}
 
 #CXX	= g++
diff --git a/make.linux64 b/make.linux64
index 7438e11..bd2fb02 100644
--- a/make.linux64
+++ b/make.linux64
@@ -4,14 +4,14 @@ ARCH	= linux64
 X11INCLUDE=/usr/include/X11
 X11LIB	= /usr/lib64
 
-XX	= -O2 
+XX	= 
 YY	= -g -fno-inline
 ZZ	= -m64 -Wl,--hash-style=both
 
 AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D__M64
 
-#OPTS	= ${XX} ${ZZ}
-OPTS	= ${YY} ${ZZ}
+OPTS	= ${XX} ${ZZ}
+#OPTS	= ${YY} ${ZZ}
 NOPTS	= ${YY} ${ZZ}
 
 CXX	= g++
@@ -23,5 +23,7 @@ CCOPT	= ${OPTS} ${AA}
 CCNOPT	= ${NOPTS} ${AA}
 
 ZCAT	= zcat
+
+TCLFLAGS= --enable-64bit
 JOBS = 4
 
diff --git a/make.darwinx86snowleopard b/make.macosxmountainlion
similarity index 68%
copy from make.darwinx86snowleopard
copy to make.macosxmountainlion
index 9c6b85e..989be00 100644
--- a/make.darwinx86snowleopard
+++ b/make.macosxmountainlion
@@ -1,15 +1,13 @@
-OS	= unix
-ARCH	= darwinx86snowleopard
+OS	= macosx
+ARCH	= macosx64x86mountainlion
 
-X11INCLUDE=/usr/X11/include
-X11LIB	= /usr/X11/lib
-EXTTCLFLAGS=--disable-corefoundation
+X11INCLUDE=.
 
-XX	= -O2 
+XX	= 
 YY	= -gstabs+ -fno-inline
-ZZ	= -arch i386
+ZZ	= -m64
 
-AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -DMAC_OSX_TK=1 -D_MACOSX -D__M64
 
 #OPTS	= ${XX} ${ZZ}
 OPTS	= ${YY} ${ZZ}
@@ -28,4 +26,6 @@ ZCAT	= gzcat
 CODESIGN = codesign
 ZIPFILE = ds9.zip
 FILTERCOMPILER = pcc-i386-snowleopard.tar.gz
+
+ASTFLAGS = star_cv_cnf_trail_type=long
 JOBS = 4
diff --git a/make.macosxx86mountainlion b/make.macosxx86mountainlion
deleted file mode 100644
index 0241979..0000000
--- a/make.macosxx86mountainlion
+++ /dev/null
@@ -1,27 +0,0 @@
-OS	= macosx
-ARCH	= macosxx86mountainlion
-
-XX	= -O2 
-YY	= -gstabs+ -fno-inline
-ZZ	= -arch i386 
-
-AA	= -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H
-
-#OPTS	= ${XX} ${ZZ}
-OPTS	= ${YY} ${ZZ}
-NOPTS	= ${YY} ${ZZ}
-
-CXX	= g++
-CXXOPT	= ${OPTS} ${AA}
-CXXNOPT	= ${NOPTS} ${AA}
-
-CC	= gcc
-CCOPT	= ${OPTS} ${AA}
-CCNOPT	= ${NOPTS} ${AA}
-
-ZCAT	= gzcat
-
-CODESIGN = codesign
-ZIPFILE = ds9.zip
-FILTERCOMPILER = pcc-i386-snowleopard.tar.gz
-JOBS = 1
diff --git a/make.pkgs b/make.pkgs
index bda965c..15f8014 100644
--- a/make.pkgs
+++ b/make.pkgs
@@ -1,11 +1,10 @@
 #--------------------------basic
 
-DS9VERSION= 7.3b2
+DS9VERSION= 7.3b3
 XPAVERSION= 2.1.14
 
 #--------------------------version
 
-BLTVER	= blt3.0
 TCLVER = tcl8.6
 TCLLIBVER = tcllib1.15
 TCLXMLVER = Tclxml3.2
@@ -13,12 +12,13 @@ TKVER = tk8.6
 TKCONVER = tkcon2.5
 TKIMGVER= Img1.4
 TKTABLEVER= Tktable2.10
+TLTVER	= tlt3.0
+BLTVER	= blt3.0
 XMLRPCVER = xmlrpc0.3
 
 #--------------------------dir
 
-ASTDIR= ast-7.3.1
-BLTDIR= blt3.0.1
+ASTDIR= ast-7.3.2
 CHECKDNSDIR= checkdns
 FUNTOOLSDIR= funtools-1.4.5
 HCOMPRESSDIR = hcompress
@@ -37,6 +37,8 @@ TKDIR= tk8.6.0
 TKIMGDIR= tkimg1.4
 TKMPEGDIR= tkmpeg
 TKTABLEDIR= tktable2.10
+TLTDIR= tlt3.0
+BLTDIR= blt3.0.1
 WCSSUBSDIR= wcssubs-3.8.4
 XMLRPCDIR= xmlrpc-0.3
 XPADIR= xpa-2.1.14
diff --git a/make.source b/make.source
index e69de29..4fe6f1a 100644
--- a/make.source
+++ b/make.source
@@ -0,0 +1 @@
+OS	= unix
diff --git a/notes.txt b/notes.txt
index 65ace36..d06074f 100644
--- a/notes.txt
+++ b/notes.txt
@@ -1,3 +1,12 @@
+1. unload context.C 144
+2. loadFinish context.C 1336
+3. loadDone frload.C 723
+4. getClip context.C 417
+5. getClip context.C 420
+6. getClip context.C 417
+7. getClip context.C 420
+
+
 Ports:
 	porter			MacOSX 10.4, MacOSX 10.5, MacOSX 10.6
 	duet			MacOSX 10.7
@@ -50,7 +59,6 @@ Build:
 HTML Comment: <!-- something -->
 	
 Future:
-	MacOSX Aqua
 	XPAInfo
 	Astrometry.net
 	Tutorials
@@ -73,29 +81,46 @@ Future:
 	2D surface plot
 
 List
-        -7.3
-	vfs mount point /tmp?
-
-	fitsy++
-	  one time
-	    nrrd
-	    nrrdcompress
-	    hpx
-	    envi
-	    compress
-	  byteswap
-	    envi
-	    nrrd
-	    nrrdcompress
-	    compress
-	    hpx
-	cubes
-	  share wcs
-	tests
-	  large 64
-
-	tcl/tk 8.6	
+	-7.3 tlt
+	  rm
+	    bltBgStyle?
+	    bltHash?
+	      bltPool?
+	    Blt_Obj?
+	    bltDBuffer?
+	      bltBase64?
+	  TEA autoconf
+	    pkgindex
+	  FONT issues
+	  BLT_CONFIG_NULL flags issues
+	  rm WORDS_BIGENDIAN
+
+	  check free(); ptr =NULL;	  
 	  cygwin
+	    tests/plot.sh
+	  macosx
+	    Fonts
+	    regions?
+	    zoom stack segv
+	    tests/plot.sh
+
+        -7.3 macosx
+	prefs file
+	buttonbar causes window resize
+	3d
+        prefs dialog box resize
+	space hv base
+	printing
+	bin filter
+	clip regions
+	iis
+          warppointer/querypointer
+	saveimage
+	os
+	  print file(s)
+
+	-7.3 cygwin
+	    segv at startup without window adjust (in panner parser)
 	    64bit- not yet
 	    imexam
 	    iconify
@@ -103,9 +128,8 @@ List
 	    display size 715x450
 	    mods- windows global issue? tclWinFile.c,xmfbox.tcl
 
-	  mingw32
+	-7.3 windows-mingw32
 	    tclxml
-	    blt
 	    tkhtml
 	    tkimg
 	    xpa
@@ -114,7 +138,13 @@ List
 	    funtools
 	    wcssubs
 
-          macosx
+	vfs mount point /tmp?
+	cubes
+	  share wcs
+	  windows slow delete?
+
+	tests
+	  large 64
 
 	***
 
@@ -161,6 +191,7 @@ List
 	  mosaicwfpc2
 
 	fix
+	  compress.sh decam--24--15-g-4_01.fits.fz
 	  cleanup frame.C vs frame3d.C
 	  crop- recal LTM/V, DATASEC keywords
 
@@ -246,11 +277,7 @@ List
             HISTORY AIPS CLEAN BMAJ=  1.2500E-02 BMIN=  1.2500E-02 BPA=   0.00  
 	    take average of 3rd axis/area=JY/BEAM
 
-	  update blt?
 	  upgrade tkhtml?
-	  blt x11 only
-	    windows
-	    macosx
 
 	  update install page
 
@@ -346,17 +373,10 @@ List
 	  -64 bit FITS Fitsy++ fits keywords (test64bit.fits)
 
 	  clean up configure mods (use autoreconf)
-	    blt
 	    html
 	    tclxml
 	    tcllib
 
-	  macosx
-	    tk
-	      generic/tkEvent
-	      macosx/tkMacOSXDraw.c blt w==0
-	      xlib/X11/Xlib.h
-
 	-Bugs
 
 	[ds9|?]parser.Y allow 1e-01" and 1e-01' for vvalue
@@ -419,6 +439,7 @@ List
 
 	-Backup
 
+	enable regions with plot3d set
 	masks (per context: filename,color,mark)
         problem alloc/channel/socket/var loads
 	  mosaicimage iraf/wfpc2
@@ -476,8 +497,7 @@ List
 	clip overlay contours to image boundries
 
 	-Crop
-	
-	crop in WCS
+	crop in WCS (extract/resample)
 
 	-Examine
 	only works for files
@@ -926,6 +946,11 @@ Notes:
 
 MACOSX
 
+install_name_tool -change /Library/Frameworks/Tk.framework/Versions/8.6/Tk @executable_path/../Frameworks//Tk.framework/Versions/8.6/Tk aa/Wish.app/Contents/MacOS/Wish
+install_name_tool -change /Library/Frameworks/Tcl.framework/Versions/8.6/Tcl @executable_path/../Frameworks//Tcl.framework/Versions/8.6/Tcl aa/Wish.app/Contents/MacOS/Wish
+
+gcc -Os -pipe -fvisibility=hidden      -prebind -headerpad_max_install_names -Wl,-search_paths_first  tkAppInit.o -F/Users/joye/aa/build/tk/Deployment -framework Tk -F/Users/joye/aa/build/tcl/Deployment -framework Tcl  -lpthread -framework CoreFoundation -framework Cocoa -framework Carbon -framework IOKit    -lz  -lpthread -framework CoreFoundation  -sectcreate __TEXT __info_plist Wish-Info.plist -o wish
+
 enum {
   k1MonochromePixelFormat       = 0x00000001, /* 1 bit indexed*/
   k2IndexedPixelFormat          = 0x00000002, /* 2 bit indexed*/
diff --git a/saotk/colorbar/Makefile b/saotk/colorbar/Makefile
index 576f765..a2dfe7b 100644
--- a/saotk/colorbar/Makefile
+++ b/saotk/colorbar/Makefile
@@ -4,7 +4,7 @@ CXXFLAGS = $(CXXOPT) \
 	-I. -I.. -I../widget -I../vector -I../list -I../util \
 	-I../../include -I$(X11INCLUDE)
 
-SS	= \
+SRC	= \
 	cbgrid.C \
 	colorbarbase.C \
 	colorbar.C \
@@ -22,16 +22,7 @@ SS	= \
 	colormap.C \
 	lut.C \
 	sao.C \
-	default.C
-
-ifeq ($(OS),unix)
-SSP =	\
-	colorbarpseudo.C \
-	colorbarpseudocolor.C \
-	colorbarpseudocolor8.C
-endif
-
-SRC	= $(SS) $(SSP) \
+	default.C \
 	parser.C \
 	lex.C \
 	lutparser.C \
@@ -42,20 +33,13 @@ SRC	= $(SS) $(SSP) \
 INCLS	= $(wildcard *.h)
 OBJS	= $(SRC:%.C=%.o)
 
-all	: $(OBJS) TAGS
+all	: $(OBJS)
 
 clean	: FORCE
 	rm -f core *~ *#
 
 distclean : clean
-	rm -f TAGS *.o parser.output lutparser.output saoparser.output
-
-ifdef DEPENDS
-TAGS	: $(SS) $(INCLS)
-	etags $+
-else
-TAGS	: FORCE
-endif
+	rm -f *.o parser.output lutparser.output saoparser.output
 
 parsers	: parser lutparser saoparser
 
@@ -72,12 +56,3 @@ saoparser: FORCE
 	flex -Pli -osaolex.C saolex.L
 
 FORCE	:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SRC:.C=.d)
-endif
diff --git a/saotk/colorbar/colorbarpseudocolor.C b/saotk/colorbar/colorbarpseudocolor.C
index 36bbeb4..bb31333 100644
--- a/saotk/colorbar/colorbarpseudocolor.C
+++ b/saotk/colorbar/colorbarpseudocolor.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tcl.h>
 
 #include "colorbarpseudocolor.h"
 #include "util.h"
diff --git a/saotk/colorbar/colorbarpseudocolor8.C b/saotk/colorbar/colorbarpseudocolor8.C
deleted file mode 100644
index d6eab02..0000000
--- a/saotk/colorbar/colorbarpseudocolor8.C
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#include "tcl.h"
-
-#include "colorbarpseudocolor8.h"
-#include "util.h"
-
-// Tk Canvas Widget Function Declarations
-
-int ColorbarPseudoColor8CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int,
-				   Tcl_Obj *const []);
-
-// Colorbar Specs
-
-static Tk_CustomOption tagsOption = {
-  Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
-};
-
-static Tk_ConfigSpec colorbarPseudoColor8Specs[] = {
-
-  {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "colorbar",
-   Tk_Offset(ColorbarBaseOptions, cmdName), 
-   TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1",
-   Tk_Offset(ColorbarBaseOptions, x), TK_CONFIG_OPTION_SPECIFIED, 
-   NULL},
-  {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1",
-   Tk_Offset(ColorbarBaseOptions, y), TK_CONFIG_OPTION_SPECIFIED, 
-   NULL},
-  {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512",
-   Tk_Offset(ColorbarBaseOptions, width), TK_CONFIG_OPTION_SPECIFIED, 
-   NULL},
-  {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "22",
-   Tk_Offset(ColorbarBaseOptions, height), TK_CONFIG_OPTION_SPECIFIED,
-   NULL},
-  {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw",
-   Tk_Offset(ColorbarBaseOptions, anchor), 0, NULL},
-  {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL,
-   0, TK_CONFIG_NULL_OK, &tagsOption},
-
-  {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica",
-   Tk_Offset(ColorbarBaseOptions, helvetica), 0, NULL},
-  {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier",
-   Tk_Offset(ColorbarBaseOptions, courier), 0, NULL},
-  {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times",
-   Tk_Offset(ColorbarBaseOptions, times), 0, NULL},
-
-  {TK_CONFIG_BOOLEAN, (char*)"-orientation", NULL, NULL, "0",
-   Tk_Offset(ColorbarBaseOptions, orientation), 0, NULL},
-  {TK_CONFIG_INT, (char*)"-size", NULL, NULL, "20",
-   Tk_Offset(ColorbarBaseOptions, size), 0, NULL},
-
-  {TK_CONFIG_STRING, (char*)"-font", NULL, NULL, "helvetica",
-   Tk_Offset(ColorbarBaseOptions, font), 0, NULL},
-  {TK_CONFIG_INT, (char*)"-fontsize", NULL, NULL, "10",
-   Tk_Offset(ColorbarBaseOptions, fontSize), 0, NULL},
-  {TK_CONFIG_STRING, (char*)"-fontweight", "fontweight", NULL, "normal",
-   Tk_Offset(ColorbarBaseOptions, fontWeight), 0, NULL},
-  {TK_CONFIG_SYNONYM, (char*)"-fontstyle", "fontweight", NULL, NULL, 0, 0},
-  {TK_CONFIG_STRING, (char*)"-fontslant", NULL, NULL, "roman",
-   Tk_Offset(ColorbarBaseOptions, fontSlant), 0, NULL},
-
-  {TK_CONFIG_BOOLEAN, (char*)"-numerics", NULL, NULL, "1",
-   Tk_Offset(ColorbarBaseOptions, numerics), 0, NULL},
-  {TK_CONFIG_BOOLEAN, (char*)"-space", NULL, NULL, "1",
-   Tk_Offset(ColorbarBaseOptions, space), 0, NULL},
-  {TK_CONFIG_INT, (char*)"-ticks", NULL, NULL, "11",
-   Tk_Offset(ColorbarBaseOptions, ticks), 0, NULL},
-
-  {TK_CONFIG_INT, (char*)"-min", NULL, NULL, "80",
-   Tk_Offset(ColorbarBaseOptions, minColors), 0, NULL},
-  {TK_CONFIG_INT, (char*)"-max", NULL, NULL, "200",
-   Tk_Offset(ColorbarBaseOptions, maxColors), 0, NULL},
-  {TK_CONFIG_BOOLEAN, (char*)"-private", NULL, NULL, "false",
-   Tk_Offset(ColorbarBaseOptions, privateCmap), 0, NULL},
-  {TK_CONFIG_INT, (char*)"-privatecolors", NULL, NULL, "128",
-   Tk_Offset(ColorbarBaseOptions, privateColors), 0, NULL},
-
-  {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL},
-};
-
-// Tk Static Structure
-
-static Tk_ItemType colorbarPseudoColor8Type = {
-  (char*)"colorbarpseudocolor8",       // name
-  sizeof(ColorbarBaseOptions), // size
-  ColorbarPseudoColor8CreateProc,  // configProc
-  colorbarPseudoColor8Specs,       // configSpecs
-  WidgetConfigProc,             // configProc
-  WidgetCoordProc,              // coordProc
-  WidgetDeleteProc,             // deleteProc
-  WidgetDisplayProc,            // displayProc
-  0,                            // alwaysRedraw
-  WidgetPointProc,              // pointProc
-  WidgetAreaProc,               // areaProc
-  WidgetPostscriptProc,         // postscriptProc
-  WidgetScaleProc,              // scaleProc
-  WidgetTranslateProc,          // translateProc
-  (Tk_ItemIndexProc*)NULL,      // indexProc
-  (Tk_ItemCursorProc*)NULL,     // icursorProc
-  (Tk_ItemSelectionProc*)NULL,  // selectionProc
-  (Tk_ItemInsertProc*)NULL,     // insertProc
-  (Tk_ItemDCharsProc*)NULL,     // dCharsProc
-  (Tk_ItemType*)NULL            // nextPtr
-};
-
-// Non-Member Functions
-
-int ColorbarPseudoColor8_Init(Tcl_Interp* interp)
-{
-  Tk_CreateItemType(&colorbarPseudoColor8Type);
-  return TCL_OK;
-}
-
-int ColorbarPseudoColor8CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, 
-				   Tk_Item* item, int argc, 
-				   Tcl_Obj *const argv[])
-{
-  ColorbarPseudoColor8* colorbar = 
-    new ColorbarPseudoColor8(interp, canvas, item);
-
-  // and set default configuration
-  if (colorbar->configure(argc, (const char**)argv, 0) != TCL_OK) {
-    delete colorbar;
-    Tcl_AppendResult(interp, " error occured while creating colorbar.", NULL);
-    return TCL_ERROR;
-  }
-
-  return TCL_OK;
-}
-
-// ColorbarPseudoColor8
-
-ColorbarPseudoColor8::ColorbarPseudoColor8(Tcl_Interp* i, Tk_Canvas c, 
-					   Tk_Item* item) 
-  : ColorbarBase(i,c,item), ColorbarPseudoColor(i,c,item)
-{
-  configSpecs = colorbarPseudoColor8Specs;  // colorbar configure options
-
-  loadDefaultCMaps();
-}
-
-// UpdatePixmap. This function is responsable for creating a valid 
-// pixmap the size of the current Colorbar
-
-void ColorbarPseudoColor8::ximageToPixmap()
-{
-  if (!((ColorbarBaseOptions*)options)->orientation) {
-    ximageToPixmapHorz();
-    XPutImage(display, pixmap, gc, xmap, 0, 0, 1, 1, 
-	      options->width-2, ((ColorbarBaseOptions*)options)->size-2);
-  }
-  else {
-    ximageToPixmapVert();
-    XPutImage(display, pixmap, gc, xmap, 0, 0, 1, 1, 
-	      ((ColorbarBaseOptions*)options)->size-2, options->height-2);
-  }
-}
-
-void ColorbarPseudoColor8::ximageToPixmapHorz()
-{
-  int width = options->width-2;
-  int height = ((ColorbarBaseOptions*)options)->size-2;
-  char* data = XImageData(xmap);
-
-  // Fill in colorbar data
-  // --Calculate first row
-  for (int ii=0; ii<width; ii++)
-    data[ii] = (char)colorIndex[ii*colorCount/width];
-
-  // --and duplicate for remaining rows
-  for (int jj=1; jj<height; jj++)
-    memcpy(data+(jj*xmap->bytes_per_line), data, xmap->bytes_per_line);
-}
-
-void ColorbarPseudoColor8::ximageToPixmapVert()
-{
-  int width = ((ColorbarBaseOptions*)options)->size-2;
-  int height = options->height-2;
-  char* data = XImageData(xmap);
-
-  for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) {
-    char a = (char)colorIndex[jj*colorCount/height];
-    for (int ii=0; ii<width; ii++)
-      data[ii] = a;
-  }
-}
diff --git a/saotk/colorbar/colorbarrgbtruecolor.C b/saotk/colorbar/colorbarrgbtruecolor.C
index 26cce50..f77de70 100644
--- a/saotk/colorbar/colorbarrgbtruecolor.C
+++ b/saotk/colorbar/colorbarrgbtruecolor.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tcl.h>
 
 #include "colorbarrgbtruecolor.h"
 #include "util.h"
diff --git a/saotk/colorbar/colorbarrgbtruecolor16.C b/saotk/colorbar/colorbarrgbtruecolor16.C
index e34527f..426f415 100644
--- a/saotk/colorbar/colorbarrgbtruecolor16.C
+++ b/saotk/colorbar/colorbarrgbtruecolor16.C
@@ -137,7 +137,7 @@ void ColorbarRGBTrueColor16::updateColorsHorz()
 {
   int width = options->width-2;
   int height = ((ColorbarBaseOptions*)options)->size-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
     
   // if we have cross platforms, we need to byte swap
   unsigned char row[xmap->bytes_per_line];
@@ -216,7 +216,7 @@ void ColorbarRGBTrueColor16::updateColorsVert()
 {
   int width = ((ColorbarBaseOptions*)options)->size-2;
   int height = options->height-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
     
   // if we have cross platforms, we need to byte swap
   if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) {
diff --git a/saotk/colorbar/colorbarrgbtruecolor24.C b/saotk/colorbar/colorbarrgbtruecolor24.C
index 8d75756..0cf05b5 100644
--- a/saotk/colorbar/colorbarrgbtruecolor24.C
+++ b/saotk/colorbar/colorbarrgbtruecolor24.C
@@ -135,7 +135,7 @@ void ColorbarRGBTrueColor24::updateColorsHorz()
 {
   int width = options->width-2;
   int height = ((ColorbarBaseOptions*)options)->size-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
 
   switch (xmap->bits_per_pixel) {
   case 32:
@@ -154,7 +154,7 @@ void ColorbarRGBTrueColor24::updateColorsVert()
 {
   int width = ((ColorbarBaseOptions*)options)->size-2;
   int height = options->height-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
     
   switch (xmap->bits_per_pixel) {
   case 32:
@@ -334,10 +334,14 @@ void ColorbarRGBTrueColor24::updateColors32Horz(int width, int height,
   // if we have cross platforms, we need to byte swap
   unsigned char row[xmap->bytes_per_line];
   if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) {
-    //red
+
+    // red
     for (int ii=0; ii<width; ii++) {
       unsigned int r = colorCells[(int)(double(ii)/width*colorCount)*3];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= r << rs_;
       memcpy(row+ii*4, &a, 4);
     }
@@ -348,6 +352,9 @@ void ColorbarRGBTrueColor24::updateColors32Horz(int width, int height,
     for (int ii=0; ii<width; ii++) {
       unsigned int g = colorCells[(int)(double(ii)/width*colorCount)*3+1];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= g << gs_;
       memcpy(row+ii*4, &a, 4);
     }
@@ -358,6 +365,9 @@ void ColorbarRGBTrueColor24::updateColors32Horz(int width, int height,
     for (int ii=0; ii<width; ii++) {
       unsigned int b = colorCells[(int)(double(ii)/width*colorCount)*3+2];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= b << bs_;
       memcpy(row+ii*4, &a, 4);
     }
@@ -370,6 +380,9 @@ void ColorbarRGBTrueColor24::updateColors32Horz(int width, int height,
     for (int i=0; i<width; i++) {
       unsigned int r = colorCells[(int)(double(i)/width*colorCount)*3];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= r << rs_;
       unsigned char* rr = (unsigned char*)(&a);
       *(row+i*4) = *(rr+3);
@@ -384,6 +397,9 @@ void ColorbarRGBTrueColor24::updateColors32Horz(int width, int height,
     for (int i=0; i<width; i++) {
       unsigned int g = colorCells[(int)(double(i)/width*colorCount)*3+1];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= g << gs_;
       unsigned char* rr = (unsigned char*)(&a);
       *(row+i*4) = *(rr+3);
@@ -398,6 +414,9 @@ void ColorbarRGBTrueColor24::updateColors32Horz(int width, int height,
     for (int i=0; i<width; i++) {
       unsigned int b = colorCells[(int)(double(i)/width*colorCount)*3+2];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= b << bs_;
       unsigned char* rr = (unsigned char*)(&a);
       *(row+i*4) = *(rr+3);
@@ -421,6 +440,9 @@ void ColorbarRGBTrueColor24::updateColors32Vert(int width, int height,
       {
 	unsigned int r = colorCells[(int)(double(jj)/height*colorCount)*3];
 	unsigned int a = 0;
+#ifdef _MACOSX
+	a |= 0xff << 24;
+#endif
 	a |= r << rs_;
 	for (int ii=0; ii<(int)(width/3.); ii++)
 	  memcpy(data+ii*4, &a, 4);
@@ -430,6 +452,9 @@ void ColorbarRGBTrueColor24::updateColors32Vert(int width, int height,
       {
 	unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1];
 	unsigned int a = 0;
+#ifdef _MACOSX
+	a |= 0xff << 24;
+#endif
 	a |= g << gs_;
 	for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++)
 	  memcpy(data+ii*4, &a, 4);
@@ -439,6 +464,9 @@ void ColorbarRGBTrueColor24::updateColors32Vert(int width, int height,
       {
 	unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3+2];
 	unsigned int a = 0;
+#ifdef _MACOSX
+	a |= 0xff << 24;
+#endif
 	a |= b << bs_;
 	for (int ii=(int)(width*2/3.); ii<width; ii++)
 	  memcpy(data+ii*4, &a, 4);
@@ -452,6 +480,9 @@ void ColorbarRGBTrueColor24::updateColors32Vert(int width, int height,
       {
 	unsigned int r = colorCells[(int)(double(jj)/height*colorCount)*3];
 	unsigned int a = 0;
+#ifdef _MACOSX
+	a |= 0xff << 24;
+#endif
 	a |= r << rs_;
 	unsigned char* rr = (unsigned char*)(&a);
 	for (int ii=0; ii<(int)(width/3.); ii++) {
@@ -466,6 +497,9 @@ void ColorbarRGBTrueColor24::updateColors32Vert(int width, int height,
       {
 	unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1];
 	unsigned int a = 0;
+#ifdef _MACOSX
+	a |= 0xff << 24;
+#endif
 	a |= g << gs_;
 	unsigned char* rr = (unsigned char*)(&a);
 	for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) {
@@ -480,6 +514,9 @@ void ColorbarRGBTrueColor24::updateColors32Vert(int width, int height,
       {
 	unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3+2];
 	unsigned int a = 0;
+#ifdef _MACOSX
+	a |= 0xff << 24;
+#endif
 	a |= b << bs_;
 	unsigned char* rr = (unsigned char*)(&a);
 	for (int ii=(int)(width*2/3.); ii<width; ii++) {
diff --git a/saotk/colorbar/colorbarrgbtruecolor8.C b/saotk/colorbar/colorbarrgbtruecolor8.C
index 70a97db..92b780e 100644
--- a/saotk/colorbar/colorbarrgbtruecolor8.C
+++ b/saotk/colorbar/colorbarrgbtruecolor8.C
@@ -135,7 +135,7 @@ void ColorbarRGBTrueColor8::updateColorsHorz()
 {
   int width = options->width-2;
   int height = ((ColorbarBaseOptions*)options)->size-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
     
   unsigned char row[xmap->bytes_per_line];
 
@@ -168,7 +168,7 @@ void ColorbarRGBTrueColor8::updateColorsVert()
 {
   int width = ((ColorbarBaseOptions*)options)->size-2;
   int height = options->height-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
     
   for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) {
 
diff --git a/saotk/colorbar/colorbartrue.C b/saotk/colorbar/colorbartrue.C
index cda4271..5eb56a5 100644
--- a/saotk/colorbar/colorbartrue.C
+++ b/saotk/colorbar/colorbartrue.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tcl.h>
 
 #include "colorbartrue.h"
 #include "util.h"
diff --git a/saotk/colorbar/colorbartruecolor.C b/saotk/colorbar/colorbartruecolor.C
index 8424598..50c38ed 100644
--- a/saotk/colorbar/colorbartruecolor.C
+++ b/saotk/colorbar/colorbartruecolor.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tcl.h>
 
 #include "colorbartruecolor.h"
 #include "util.h"
diff --git a/saotk/colorbar/colorbartruecolor16.C b/saotk/colorbar/colorbartruecolor16.C
index fd086d2..2cf02ec 100644
--- a/saotk/colorbar/colorbartruecolor16.C
+++ b/saotk/colorbar/colorbartruecolor16.C
@@ -136,7 +136,7 @@ void ColorbarTrueColor16::updateColorsHorz()
 {
   int width = options->width-2;
   int height = ((ColorbarBaseOptions*)options)->size-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
     
   // if we have cross platforms, we need to byte swap
   if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) {
@@ -177,7 +177,7 @@ void ColorbarTrueColor16::updateColorsVert()
 {
   int width = ((ColorbarBaseOptions*)options)->size-2;
   int height = options->height-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
     
   // if we have cross platforms, we need to byte swap
   if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) {
diff --git a/saotk/colorbar/colorbartruecolor24.C b/saotk/colorbar/colorbartruecolor24.C
index e8be2dd..b11d504 100644
--- a/saotk/colorbar/colorbartruecolor24.C
+++ b/saotk/colorbar/colorbartruecolor24.C
@@ -135,7 +135,7 @@ void ColorbarTrueColor24::updateColorsHorz()
 {
   int width = options->width-2;
   int height = ((ColorbarBaseOptions*)options)->size-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
 
   switch (xmap->bits_per_pixel) {
   case 32:
@@ -154,7 +154,7 @@ void ColorbarTrueColor24::updateColorsVert()
 {
   int width = ((ColorbarBaseOptions*)options)->size-2;
   int height = options->height-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
     
   switch (xmap->bits_per_pixel) {
   case 32:
@@ -253,6 +253,9 @@ void ColorbarTrueColor24::updateColors32Horz(int width, int height, char* data)
       unsigned int g = colorCells[(int)(double(ii)/width*colorCount)*3+1];
       unsigned int b = colorCells[(int)(double(ii)/width*colorCount)*3];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= r << rs_;
       a |= g << gs_;
       a |= b << bs_;
@@ -266,6 +269,9 @@ void ColorbarTrueColor24::updateColors32Horz(int width, int height, char* data)
       unsigned int g = colorCells[(int)(double(ii)/width*colorCount)*3+1];
       unsigned int b = colorCells[(int)(double(ii)/width*colorCount)*3];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= r << rs_;
       a |= g << gs_;
       a |= b << bs_;
@@ -292,6 +298,9 @@ void ColorbarTrueColor24::updateColors32Vert(int width, int height, char* data)
       unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1];
       unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= r << rs_;
       a |= g << gs_;
       a |= b << bs_;
@@ -306,6 +315,9 @@ void ColorbarTrueColor24::updateColors32Vert(int width, int height, char* data)
       unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1];
       unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= r << rs_;
       a |= g << gs_;
       a |= b << bs_;
diff --git a/saotk/colorbar/colorbartruecolor8.C b/saotk/colorbar/colorbartruecolor8.C
index 6f39eef..ef42f97 100644
--- a/saotk/colorbar/colorbartruecolor8.C
+++ b/saotk/colorbar/colorbartruecolor8.C
@@ -137,7 +137,7 @@ void ColorbarTrueColor8::updateColorsHorz()
 {
   int width = options->width-2;
   int height = ((ColorbarBaseOptions*)options)->size-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
     
   for (int ii=0; ii<width; ii++)
     data[ii] = 
@@ -154,7 +154,7 @@ void ColorbarTrueColor8::updateColorsVert()
 {
   int width = ((ColorbarBaseOptions*)options)->size-2;
   int height = options->height-2;
-  char* data = XImageData(xmap);
+  char* data = xmap->data;
     
   for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) {
     char a =
diff --git a/saotk/colorbar/colortag.h b/saotk/colorbar/colortag.h
index 99d3d8b..24c6b72 100644
--- a/saotk/colorbar/colortag.h
+++ b/saotk/colorbar/colortag.h
@@ -15,8 +15,8 @@
 #include <iomanip>
 using namespace std;
 
-#include <tcl.h>
-#include <tk.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
 
 class Colorbar;
 
diff --git a/saotk/fitsy++/Makefile b/saotk/fitsy++/Makefile
index 5e37b21..94767d8 100644
--- a/saotk/fitsy++/Makefile
+++ b/saotk/fitsy++/Makefile
@@ -57,20 +57,13 @@ SRC	= $(SS) \
 INCLS	= $(wildcard *.h)
 OBJS	= $(SRC:%.C=%.o)
 
-all	: $(OBJS) TAGS
+all	: $(OBJS)
 
 clean	: FORCE
 	rm -f core *~ *#
 
 distclean : clean
-	rm -f TAGS *.o parser.output nrrdparser.output enviparser.output
-
-ifdef DEPENDS
-TAGS	: $(SS) $(INCLS)
-	etags $+
-else
-TAGS	: FORCE
-endif
+	rm -f *.o parser.output nrrdparser.output enviparser.output
 
 parsers	: parser nrrdparser enviparser
 
@@ -92,12 +85,3 @@ shmload	: shmload.C
 	cp $@ ../../bin/.
 
 FORCE	:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SS:.C=.d)
-endif
diff --git a/saotk/fitsy++/alloc.C b/saotk/fitsy++/alloc.C
index 3b124b6..82ff2cd 100644
--- a/saotk/fitsy++/alloc.C
+++ b/saotk/fitsy++/alloc.C
@@ -2,6 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <stdio.h>
 #include "alloc.h"
 
 FitsAlloc::FitsAlloc(const char* fn)
diff --git a/saotk/fitsy++/analysis.C b/saotk/fitsy++/analysis.C
index 5754d9f..ffd2b5f 100644
--- a/saotk/fitsy++/analysis.C
+++ b/saotk/fitsy++/analysis.C
@@ -14,7 +14,6 @@ FitsAnalysis::FitsAnalysis(FitsFile* src)
 
   ext_ = src->ext();
   inherit_ = src->inherit();
-  byteswap_ = 0;
 
   // change bitpix to double
   head_->setInteger("BITPIX", -64, "");
@@ -44,7 +43,8 @@ FitsAnalysis::FitsAnalysis(FitsFile* src)
   memset(data_, 0, size*sizeof(double));
 
   // made it this far, must be valid
-  orgFits_ = 0;
+  byteswap_ = 0;
+  endian_ = lsb() ? LITTLE : BIG;
   valid_ = 1;
 }
 
diff --git a/saotk/fitsy++/channel.C b/saotk/fitsy++/channel.C
index 44f1eb7..8b528be 100644
--- a/saotk/fitsy++/channel.C
+++ b/saotk/fitsy++/channel.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tcl.h>
+
 #include "channel.h"
 
 FitsChannel::FitsChannel(Tcl_Interp* interp, const char* ch, const char* ext) 
diff --git a/saotk/fitsy++/compress.C b/saotk/fitsy++/compress.C
index e70266a..85c6283 100644
--- a/saotk/fitsy++/compress.C
+++ b/saotk/fitsy++/compress.C
@@ -729,7 +729,7 @@ template class FitsCompressm<long long>;
 template class FitsCompressm<float>;
 template class FitsCompressm<double>;
 
-FitsCompressNext::FitsCompressNext(FitsFile* p)
+FitsPostNext::FitsPostNext(FitsFile* p)
 {
   FitsCompress* prev = (FitsCompress*)p;
 
@@ -747,15 +747,8 @@ FitsCompressNext::FitsCompressNext(FitsFile* p)
   ext_ = prev->ext();
   inherit_ = head_->inherit();
   byteswap_ = prev->byteswap();
-  orgFits_ = prev->orgFits();
+  endian_ = prev->endian();
   valid_ = 1;
 
-  pWidth_ = prev->pWidth();
-  pHeight_ = prev->pHeight();
-  pDepth_ = prev->pDepth();
-  pBitpix_ = prev->pBitpix();
-  pSkip_ = prev->pSkip();
-  pArch_ = prev->pArch();
-
   return;
 }
diff --git a/saotk/fitsy++/compress.h b/saotk/fitsy++/compress.h
index d05430d..11464c0 100644
--- a/saotk/fitsy++/compress.h
+++ b/saotk/fitsy++/compress.h
@@ -81,9 +81,9 @@ class FitsCompressm : public FitsCompress {
   FitsCompressm(FitsFile*);
 };
 
-class FitsCompressNext : public FitsFile {
+class FitsPostNext : public FitsFile {
 public:
-  FitsCompressNext(FitsFile* prev);
+  FitsPostNext(FitsFile* prev);
 };
 
 #endif
diff --git a/saotk/fitsy++/envi.C b/saotk/fitsy++/envi.C
index a17cf85..c733afc 100644
--- a/saotk/fitsy++/envi.C
+++ b/saotk/fitsy++/envi.C
@@ -5,17 +5,23 @@
 #include "envi.h"
 #include "head.h"
 
-FitsENVI::FitsENVI(FitsFile* fits) : FitsFile(fits)
+FitsENVI::FitsENVI(FitsFile* fits)
 {
-  pSize_ = (size_t)pWidth_*pHeight_*pDepth_;
-  pSkip_ = 0;
-  pArch_ = fits->pArch();
+  byteswap_ = fits->byteswap();
+  endian_ = fits->endian();
+
+  pBitpix_ = fits->pBitpix();
+  pWidth_ = fits->pWidth();
+  pHeight_ = fits->pHeight();
+  pDepth_ = fits->pDepth();
 
   pEncoding_ = FitsFile::BSQ;
 
   pCRPIX3_ = fits->pCRPIX3();
   pCRVAL3_ = fits->pCRVAL3();
   pCDELT3_ = fits->pCDELT3();
+
+  size_ = (size_t)pWidth_*pHeight_*pDepth_;
 }
 
 FitsENVI::~FitsENVI()
@@ -62,198 +68,18 @@ int FitsENVI::initHeader(FitsFile* fits)
   return 1;
 }
 
-template<class T> FitsENVIm<T>::FitsENVIm(FitsFile* fits) 
-  : FitsENVI(fits)
-{
-  //  cerr << "FitsENVIm<T>(FitsFile* fits)" << endl;
-}
-
-template<class T> void FitsENVIm<T>::swapBytes(FitsFile::ArchType arch) 
-{
-  switch (arch) {
-  case FitsFile::NATIVE:
-    break;
-  case FitsFile::BIG:
-    if (!byteswap_) {
-      T* dest = (T*)data_;
-      for (int i=0; i<pSize_; i++)
-	dest[i] = swap(dest+i);
-    }
-    break;
-  case FitsFile::LITTLE:
-    if (byteswap_) {
-      T* dest = (T*)data_;
-      for (int i=0; i<pSize_; i++)
-	dest[i] = swap(dest+i);
-    }
-    break;
-  }
-}
-
-template <> unsigned char FitsENVIm<unsigned char>::swap(unsigned char* ptr)
-{
-  return *ptr;
-}
-
-template <> short FitsENVIm<short>::swap(short* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[2];
-    short s;
-  } u;
-
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.s;
-}
-
-template <> unsigned short FitsENVIm<unsigned short>::swap(unsigned short* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[2];
-    unsigned short s;
-  } u;
-
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.s;
-}
-
-template <> int FitsENVIm<int>::swap(int* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[4];
-    int i;
-  } u;
-
-  u.c[3] = *p++;
-  u.c[2] = *p++;
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.i;
-}
-
-template <> long long FitsENVIm<long long>::swap(long long* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[8];
-    long long i;
-  } u;
-
-  u.c[7] = *p++;
-  u.c[6] = *p++;
-  u.c[5] = *p++;
-  u.c[4] = *p++;
-  u.c[3] = *p++;
-  u.c[2] = *p++;
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.i;
-}
-
-template <> float FitsENVIm<float>::swap(float* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[4];
-    float f;
-  } u;
-
-  u.c[3] = *p++;
-  u.c[2] = *p++;
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.f;
-}
-
-template <> double FitsENVIm<double>::swap(double* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[8];
-    double d;
-  } u;
-
-  u.c[7] = *p++;
-  u.c[6] = *p++;
-  u.c[5] = *p++;
-  u.c[4] = *p++;
-  u.c[3] = *p++;
-  u.c[2] = *p++;
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.d;
-}
-
-template class FitsENVIm<unsigned char>;
-template class FitsENVIm<short>;
-template class FitsENVIm<unsigned short>;
-template class FitsENVIm<int>;
-template class FitsENVIm<long long>;
-template class FitsENVIm<float>;
-template class FitsENVIm<double>;
-
-FitsENVINext::FitsENVINext(FitsFile* p)
-{
-  FitsENVI* prev = (FitsENVI*)p;
-
-  primary_ = prev->primary();
-  managePrimary_ = 0;
-
-  head_ = prev->head();
-  manageHead_ = 0;
-
-  FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu();
-  data_ = (char*)prev->data() + hdu->imgbytes();
-  dataSize_ = 0;
-  dataSkip_ = 0;
-
-  ext_ = prev->ext();
-  inherit_ = prev->inherit();
-  byteswap_ = prev->byteswap();
-  orgFits_ = prev->orgFits();
-  valid_ = 1;
-
-  pBitpix_ = prev->pBitpix();
-  pWidth_ = prev->pWidth();
-  pHeight_ = prev->pHeight();
-  pDepth_ = prev->pDepth();
-  pSkip_ = prev->pSkip();
-  pArch_ = prev->pArch();
-
-  pEncoding_ = prev->pEncoding();
-
-  pCRPIX3_ = prev->pCRPIX3();
-  pCRVAL3_ = prev->pCRVAL3();
-  pCDELT3_ = prev->pCDELT3();
-
-  return;
-}
-
 template <class T> FitsENVIBIPm<T>::FitsENVIBIPm(FitsFile* fits)
   : FitsENVI(fits)
 {
-  //  cerr << "FitsENVIBIPm(FitsFile* fits)" << endl;
-
   if (!initHeader(fits))
     return;
 
-  T* dest = new T[pSize_];
+  T* dest = new T[size_];
   if (!dest) {
     internalError("Fitsy++ envi unable to allocate memory");
     return;
   }
-  memset(dest, 0, pSize_*sizeof(T));
+  memset(dest, 0, size_*sizeof(T));
 
   T* ptr = (T*)fits->data();
   for (int jj=0; jj<pHeight_; jj++)
@@ -263,7 +89,7 @@ template <class T> FitsENVIBIPm<T>::FitsENVIBIPm(FitsFile* fits)
 
   data_ = dest;
 
-  dataSize_ = pSize_;
+  dataSize_ = size_;
   dataSkip_ = 0;
 
   // all done
@@ -281,17 +107,15 @@ template class FitsENVIBIPm<double>;
 template <class T> FitsENVIBILm<T>::FitsENVIBILm(FitsFile* fits)
   : FitsENVI(fits)
 {
-  //  cerr << "FitsENVIBILm(FitsFile* fits)" << endl;
-
   if (!initHeader(fits))
     return;
 
-  T* dest = new T[pSize_];
+  T* dest = new T[size_];
   if (!dest) {
     internalError("Fitsy++ envi unable to allocate memory");
     return;
   }
-  memset(dest, 0, pSize_*sizeof(T));
+  memset(dest, 0, size_*sizeof(T));
 
   T* ptr = (T*)fits->data();
   for (int jj=0; jj<pHeight_; jj++)
@@ -301,7 +125,7 @@ template <class T> FitsENVIBILm<T>::FitsENVIBILm(FitsFile* fits)
 
   data_ = dest;
 
-  dataSize_ = pSize_;
+  dataSize_ = size_;
   dataSkip_ = 0;
 
   // all done
diff --git a/saotk/fitsy++/envi.h b/saotk/fitsy++/envi.h
index 87d13b8..2739296 100644
--- a/saotk/fitsy++/envi.h
+++ b/saotk/fitsy++/envi.h
@@ -9,6 +9,9 @@
 
 class FitsENVI : public FitsFile {
  protected:
+  size_t size_;
+
+ protected:
   int initHeader(FitsFile*);
 
  public:
@@ -17,23 +20,6 @@ class FitsENVI : public FitsFile {
 };
 
 template<class T>
-class FitsENVIm : public FitsENVI {
- private:
-  void swapBytes(FitsFile::ArchType);
-
- protected:
-  T swap(T* ptr);
-
- public:
-  FitsENVIm(FitsFile*);
-};
-
-class FitsENVINext : public FitsFile {
-public:
-  FitsENVINext(FitsFile* prev);
-};
-
-template<class T>
 class FitsENVIBILm : public FitsENVI {
  public:
   FitsENVIBILm(FitsFile*);
diff --git a/saotk/fitsy++/envilex.C b/saotk/fitsy++/envilex.C
index 1d858e4..d97f5ef 100644
--- a/saotk/fitsy++/envilex.C
+++ b/saotk/fitsy++/envilex.C
@@ -324,8 +324,8 @@ int yyFlexLexer::yywrap() { return 1; }
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
 
-#define YY_NUM_RULES 69
-#define YY_END_OF_BUFFER 70
+#define YY_NUM_RULES 72
+#define YY_END_OF_BUFFER 73
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -333,38 +333,39 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[273] =
+static yyconst flex_int16_t yy_accept[282] =
     {   0,
-        0,    0,    2,    2,    0,    0,   70,   68,   65,   67,
-       68,   68,   68,   61,   64,   64,   64,   64,   64,   64,
-       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
-       64,   64,   64,   64,    3,    2,    1,   60,   58,   59,
-       60,   57,   56,   60,   53,   56,    4,   65,   66,    0,
-       61,   63,   62,   61,   64,   64,   64,   64,   64,   64,
-       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
-       64,   64,   64,   64,   64,   64,   64,   64,    6,   64,
-       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
-       64,   64,   64,   64,   64,    2,   58,    0,   53,   56,
-
-       53,   55,   54,   56,    0,    0,    0,   62,   64,   64,
-       11,   12,   13,   14,   64,   64,   64,   64,   64,   64,
-       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
-       64,   31,   64,   64,    7,   64,   64,   64,   64,   64,
-       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
-       64,    0,    0,    0,   56,   54,   62,    0,   63,   64,
-        9,   15,   17,   64,   64,   64,   16,   64,   22,   64,
-       23,   24,   64,   64,   26,   64,   64,   64,   64,   64,
-       64,   64,   64,   38,   64,   64,   64,   64,   64,   64,
-       45,   64,   64,   48,   64,   64,   64,   54,    0,   55,
-
-       64,   10,    5,   64,   64,   64,   21,   64,   64,   64,
-       29,   30,   32,   33,   64,   36,   37,   64,   40,   64,
-       64,   43,   64,   64,   64,   49,   50,   64,   64,   64,
-       64,   20,   25,   27,   64,   34,   64,   64,   64,   44,
-       64,   47,   51,   64,    8,   18,   64,   64,   35,   64,
-       64,   42,   46,   64,   64,   64,   64,   64,   64,   64,
-       64,   64,   64,   64,   64,   28,   39,   64,   52,   19,
-       41,    0
+        0,    0,    2,    2,    0,    0,   73,   71,   68,   70,
+       71,   71,   71,   64,   67,   67,   67,   67,   67,   67,
+       67,   67,   67,   67,   67,   67,   67,   67,   67,   67,
+       67,   67,   67,   67,    3,    2,    1,   63,   61,   62,
+       63,   60,   59,   63,   56,   59,    4,   68,   69,    0,
+       64,   66,   65,   64,   67,   67,   67,   67,   67,   67,
+       67,   67,   67,   67,   67,   67,   67,   67,   67,   67,
+       67,   67,   67,   67,   67,   67,   67,   67,    6,   67,
+       67,   67,   67,   67,   67,   67,   67,   67,   67,   67,
+       67,   67,   67,   67,   67,    2,   61,    0,   56,   59,
+
+       56,   58,   57,   59,    0,    0,    0,   65,   67,   67,
+       11,   12,   13,   14,   67,   67,   67,   67,   67,   67,
+       67,   67,   67,   67,   67,   67,   67,   67,   67,   67,
+       67,   67,   32,   67,   67,    7,   67,   67,   67,   67,
+       67,   67,   67,   67,   67,   67,   67,   67,   67,   67,
+       67,   67,    0,    0,    0,   59,   57,   65,    0,   66,
+       67,    9,   15,   17,   67,   67,   67,   16,   67,   22,
+       67,   23,   24,   67,   67,   26,   67,   67,   67,   67,
+       67,   67,   67,   67,   67,   40,   67,   67,   67,   67,
+       67,   67,   67,   48,   67,   67,   51,   67,   67,   67,
+
+       57,    0,   58,   67,   10,    5,   67,   67,   67,   21,
+       67,   67,   67,   67,   30,   31,   33,   34,   67,   37,
+       38,   67,   42,   67,   67,   45,   67,   67,   67,   67,
+       52,   53,   67,   67,   67,   67,   20,   25,   27,   67,
+       29,   35,   39,   67,   67,   67,   67,   47,   67,   50,
+       54,   67,    8,   18,   67,   67,   36,   67,   67,   44,
+       46,   49,   67,   67,   67,   67,   67,   67,   67,   67,
+       67,   67,   67,   67,   28,   41,   67,   55,   19,   43,
+        0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -410,75 +411,77 @@ static yyconst flex_int32_t yy_meta[63] =
         1,    1
     } ;
 
-static yyconst flex_int16_t yy_base[278] =
+static yyconst flex_int16_t yy_base[287] =
     {   0,
-        0,    0,  779,  778,   62,  124,  780,  783,  777,  783,
-      771,   64,  753,   66,   78,  179,  753,   68,   69,  127,
+        0,    0,  806,  805,   62,  124,  807,  810,  800,  810,
+      788,   64,  781,   66,   78,  179,  781,   68,   69,  127,
        71,   75,  128,   76,   77,   80,  150,  148,  132,  231,
-      144,   91,   83,  102,  783,    0,  783,  783,  758,  783,
-       88,  783,   92,  749,  141,  749,  783,  753,  783,  745,
-      187,  134,  190,  197,  745,  212,  153,  202,  201,  227,
+      144,   91,   83,  102,  810,    0,  810,  810,  786,  810,
+       88,  810,   92,  778,  141,  778,  810,  783,  810,  775,
+      187,  134,  190,  197,  775,  212,  153,  202,  201,  227,
       200,  204,  226,  246,  228,  145,  210,  232,  236,  254,
-      255,  258,  274,  270,  282,  286,  278,  280,  744,  284,
-      296,  288,  300,  294,  305,  297,  323,  303,  306,   95,
-      314,  322,  327,  331,  330,    0,  749,  739,  348,  738,
-
-      355,  339,  341,  375,  369,  380,  735,  220,  365,  352,
-      734,  732,  730,  728,  382,  389,  385,  390,  393,  386,
-      394,  395,  398,  399,  404,  400,  408,  410,  428,  429,
-      425,  726,  430,  433,  436,  442,  447,  443,  457,  450,
-      454,  403,  459,  455,  463,  470,  473,  477,  478,  482,
-      485,  504,  509,  723,  487,  512,  706,  704,  699,  514,
-      498,  678,  668,  507,  522,  519,  667,  480,  626,  520,
-      624,  610,  525,  527,  602,  528,  530,  532,  534,  535,
-      533,  537,  523,  548,  554,  558,  562,  566,  567,  577,
-      545,  549,  582,  493,  583,  585,  574,  489,  461,  451,
-
-      589,  421,  416,  592,  596,  540,  411,  600,  601,  598,
-      406,  402,  367,  362,  608,  359,  350,  609,  332,  616,
-      615,  328,  622,  627,  625,  308,  635,  637,  642,  638,
-      634,  302,  268,  262,  650,  640,  652,  658,  661,  256,
-      653,  238,  216,  649,  206,  174,  665,  675,  172,  683,
-      690,  156,  152,  663,  691,  672,  694,  699,  687,  696,
-      709,  702,  721,  713,  716,  133,  110,  723,  103,   97,
-       94,  783,  764,  768,   94,  772,  774
+      255,  258,  274,  270,  282,  286,  278,  280,  772,  297,
+      289,  288,  296,  300,  311,  294,  303,  306,  316,   95,
+      327,  325,  322,  323,  330,    0,  776,  768,  349,  767,
+
+      351,  353,  359,  375,  365,  383,  765,  220,  369,  387,
+      765,  764,  763,  761,  371,  393,  379,  394,  386,  389,
+      398,  400,  397,  409,  402,  407,  404,  408,  427,  405,
+      428,  414,  760,  431,  429,  437,  446,  456,  443,  439,
+      458,  467,  451,  470,  453,  463,  465,  474,  475,  479,
+      477,  484,  505,  512,  757,  334,  514,  756,  751,  750,
+      494,  501,  750,  746,  518,  517,  519,  739,  520,  725,
+      523,  687,  684,  527,  528,  636,  530,  532,  531,  535,
+      537,  540,  562,  548,  544,  629,  565,  569,  577,  573,
+      584,  580,  550,  570,  587,  593,  558,  598,  596,  600,
+
+      544,  542,  541,  606,  541,  534,  604,  605,  588,  503,
+      603,  621,  610,  619,  491,  486,  454,  440,  624,  410,
+      626,  630,  370,  631,  644,  363,  649,  654,  652,  657,
+      356,  658,  659,  662,  651,  663,  347,  345,  341,  669,
+      338,  666,  268,  667,  674,  679,  685,  262,  683,  256,
+      238,  693,  216,  206,  689,  712,  174,  690,  715,  172,
+      156,  152,  719,  696,  589,  707,  716,  709,  721,  722,
+      734,  738,  736,  744,  133,  110,  741,  103,   97,   94,
+      810,  792,  796,   94,  800,  802
     } ;
 
-static yyconst flex_int16_t yy_def[278] =
+static yyconst flex_int16_t yy_def[287] =
     {   0,
-      272,    1,  273,  273,  274,  274,  272,  272,  272,  272,
-      272,  272,  272,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  272,  276,  272,  272,  272,  272,
-      272,  272,  277,  272,  277,  277,  272,  272,  272,  272,
-      272,  272,  272,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  276,  272,  272,  272,  277,
-
-      277,  272,  272,  277,  272,  272,  272,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  272,  272,  272,  277,  277,  272,  272,  272,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  272,  272,  272,
-
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
-      275,    0,  272,  272,  272,  272,  272
+      281,    1,  282,  282,  283,  283,  281,  281,  281,  281,
+      281,  281,  281,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  281,  285,  281,  281,  281,  281,
+      281,  281,  286,  281,  286,  286,  281,  281,  281,  281,
+      281,  281,  281,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  285,  281,  281,  281,  286,
+
+      286,  281,  281,  286,  281,  281,  281,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  281,  281,  281,  286,  286,  281,  281,  281,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+
+      281,  281,  281,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+        0,  281,  281,  281,  281,  281
     } ;
 
-static yyconst flex_int16_t yy_nxt[846] =
+static yyconst flex_int16_t yy_nxt[873] =
     {   0,
         8,    9,   10,   11,   12,    8,   12,   13,   14,   15,
        16,   17,   18,   19,   20,   21,   22,   23,   17,   17,
@@ -487,95 +490,98 @@ static yyconst flex_int16_t yy_nxt[846] =
        20,   21,   22,   23,   17,   24,   25,   26,   27,   28,
        17,   29,   30,   31,   32,   33,   34,   17,   17,   17,
        35,    8,   38,   39,   40,   38,   41,   42,   43,   44,
-       45,   50,   51,   53,   54,  272,  272,   63,  272,   56,
-       70,   64,  272,  272,  272,  272,   75,  272,   71,   77,
-      272,   65,   94,   74,   76,   98,   99,   55,  272,   98,
-
-      101,  272,  272,   63,  272,   56,   70,   64,   57,  272,
-      272,   95,   75,   93,   71,   77,   65,  272,   94,   74,
-       76,  146,   38,   47,   38,   39,   40,   38,   41,   42,
-       43,   44,   45,   57,  272,  272,   66,   95,   93,  272,
-      272,   84,   52,   72,   67,   85,  146,  106,  103,  101,
-       73,  272,  272,   68,  104,  272,  121,  272,   69,  272,
-      272,   91,   66,  272,   78,   81,  109,   84,   82,   72,
-       67,   85,   79,  106,   83,   73,   80,   92,   68,  272,
-      104,  272,  121,   69,   38,   47,  272,   91,   58,   59,
+       45,   50,   51,   53,   54,  281,  281,   63,  281,   56,
+       70,   64,  281,  281,  281,  281,   75,  281,   71,   77,
+      281,   65,   94,   74,   76,   98,   99,   55,  281,   98,
+
+      101,  281,  281,   63,  281,   56,   70,   64,   57,  281,
+      281,   95,   75,   93,   71,   77,   65,  281,   94,   74,
+       76,  147,   38,   47,   38,   39,   40,   38,   41,   42,
+       43,   44,   45,   57,  281,  281,   66,   95,   93,  281,
+      281,   84,   52,   72,   67,   85,  147,  106,  103,  101,
+       73,  281,  281,   68,  104,  281,  121,  281,   69,  281,
+      281,   91,   66,  281,   78,   81,  109,   84,   82,   72,
+       67,   85,   79,  106,   83,   73,   80,   92,   68,  281,
+      104,  281,  121,   69,   38,   47,  281,   91,   58,   59,
        78,   81,  109,   82,   53,   51,   60,   79,   52,   83,
 
-      105,   80,   92,  105,   53,   54,   61,  272,  272,  272,
-       56,  272,   62,  272,   58,   59,  107,  272,  107,  272,
-      108,  111,   60,  272,  110,  114,  105,  272,  108,  105,
-      122,   61,  115,  272,  272,  272,   56,   62,  272,  272,
-       86,  123,   87,  272,   88,  272,  111,  112,   89,  110,
-      114,  113,  124,  272,  116,  122,  117,  115,  120,   90,
-      118,  272,  272,  272,  126,  272,   86,  123,   87,  272,
-       88,  125,  112,  119,   89,  272,  113,  272,  124,  116,
-      127,  272,  117,  120,   90,  272,  118,  272,  128,  272,
-      126,  272,  130,  272,  135,  272,  136,  125,  119,  134,
-
-      131,  272,  129,  272,  272,  127,  132,  272,  133,  272,
-      272,  138,  272,  272,  128,  272,  140,  130,  142,  141,
-      135,  272,  136,  139,  134,  144,  131,  129,  137,  272,
-      272,  132,  143,  133,  272,  272,  138,  272,  272,  272,
-      145,  140,  147,  142,  149,  141,  148,  102,  139,  102,
-      144,  150,  153,  137,  152,  103,   99,  272,  143,  272,
-      151,  152,  103,  101,  161,  145,  272,  147,  104,  272,
-      149,  148,  272,  107,  272,  107,  150,  157,  153,  154,
-      152,  155,  272,  156,  158,  151,  158,  152,  159,  272,
-      161,  160,  272,  272,  104,  162,  272,  272,  163,  165,
-
-      272,  272,  272,  167,  166,  272,  272,  272,  169,  272,
-      272,  272,  173,  272,  164,  272,  160,  272,  272,  170,
-      171,  162,  168,  272,  163,  165,  172,  188,  272,  167,
-      166,  174,  272,  175,  169,  272,  272,  272,  173,  164,
-      272,  176,  177,  272,  170,  171,  180,  168,  178,  272,
-      272,  172,  188,  179,  272,  182,  174,  272,  175,  200,
-      183,  272,  272,  181,  272,  186,  272,  176,  177,  200,
-      272,  184,  180,  178,  187,  185,  191,  272,  179,  189,
-      272,  182,  190,  192,  272,  272,  183,  272,  181,  272,
-      194,  186,  272,  193,  272,  156,  184,  198,  197,  187,
-
-      272,  185,  191,  206,  189,  272,  195,  190,  154,  192,
-      154,  196,  198,  199,  272,  199,  194,  200,  193,  272,
-      156,  272,  203,  201,  197,  202,  272,  272,  206,  272,
-      272,  195,  272,  207,  272,  272,  196,  272,  208,  272,
-      272,  272,  272,  217,  272,  205,  215,  272,  203,  201,
-      202,  204,  272,  209,  210,  272,  272,  211,  212,  207,
-      213,  272,  214,  216,  208,  272,  232,  218,  217,  272,
-      205,  219,  215,  272,  272,  220,  204,  224,  209,  210,
-      222,  272,  211,  212,  272,  213,  221,  214,  216,  272,
-      272,  232,  272,  218,  228,  225,  272,  219,  227,  272,
-
-      223,  220,  224,  272,  229,  272,  222,  272,  272,  272,
-      226,  221,  230,  231,  234,  272,  272,  272,  235,  228,
-      237,  225,  272,  272,  227,  223,  233,  238,  239,  272,
-      229,  272,  272,  272,  272,  226,  236,  230,  241,  231,
-      234,  272,  272,  235,  272,  272,  237,  272,  240,  272,
-      244,  233,  242,  238,  239,  245,  272,  272,  247,  272,
-      272,  236,  243,  248,  241,  272,  246,  249,  272,  253,
-      272,  254,  272,  240,  272,  272,  244,  242,  259,  272,
-      250,  245,  272,  247,  256,  272,  251,  243,  252,  248,
-      272,  246,  249,  255,  272,  253,  254,  272,  272,  258,
-
-      257,  272,  261,  272,  259,  250,  272,  159,  260,  272,
-      256,  251,  159,  252,  157,  264,  272,  262,  255,  265,
-      272,  263,  266,  272,  267,  258,  257,  261,  272,  269,
-      272,  198,  268,  272,  260,  272,  271,  272,  270,  272,
-      264,  272,  262,  157,  265,  272,  263,  102,  266,  267,
-       97,  272,  272,   52,   48,  269,  272,  102,  268,   97,
-      272,   52,  271,  270,   36,   36,   36,   36,   46,   46,
-       46,   46,   96,   49,   96,   96,  100,  100,   48,  272,
-       37,   37,    7,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272
+      105,   80,   92,  105,   53,   54,   61,  281,  281,  281,
+       56,  281,   62,  281,   58,   59,  107,  281,  107,  281,
+      108,  111,   60,  281,  110,  114,  105,  281,  108,  105,
+      122,   61,  115,  281,  281,  281,   56,   62,  281,  281,
+       86,  123,   87,  281,   88,  281,  111,  112,   89,  110,
+      114,  113,  124,  281,  116,  122,  117,  115,  120,   90,
+      118,  281,  281,  281,  126,  281,   86,  123,   87,  281,
+       88,  125,  112,  119,   89,  281,  113,  281,  124,  116,
+      127,  281,  117,  120,   90,  281,  118,  281,  128,  281,
+      126,  130,  131,  281,  136,  281,  281,  125,  119,  135,
+
+      132,  281,  129,  281,  281,  127,  133,  281,  134,  137,
+      281,  139,  144,  281,  128,  143,  130,  131,  281,  140,
+      136,  138,  141,  281,  135,  142,  132,  129,  145,  281,
+      281,  133,  281,  134,  281,  137,  139,  281,  144,  150,
+      143,  281,  157,  151,  140,  281,  138,  141,  281,  149,
+      146,  142,  281,  145,  281,  148,  103,   99,  103,  101,
+      152,  102,  153,  281,  104,  150,  154,  102,  151,  107,
+      281,  107,  153,  158,  149,  146,  281,  281,  281,  155,
+      148,  156,  281,  157,  163,  152,  281,  159,  153,  159,
+      104,  160,  154,  281,  281,  161,  281,  167,  153,  162,
+
+      281,  281,  164,  166,  281,  281,  168,  281,  165,  281,
+      163,  281,  281,  170,  281,  281,  281,  281,  171,  174,
+      161,  281,  178,  167,  173,  162,  169,  175,  164,  166,
+      172,  176,  168,  165,  281,  281,  281,  180,  281,  170,
+      177,  179,  182,  171,  281,  174,  281,  281,  178,  173,
+      281,  169,  175,  281,  181,  172,  176,  187,  281,  184,
+      281,  281,  180,  281,  183,  281,  177,  179,  182,  185,
+      281,  186,  281,  188,  281,  190,  194,  281,  195,  181,
+      193,  281,  281,  187,  281,  184,  281,  189,  197,  183,
+      191,  281,  192,  281,  196,  185,  186,  200,  281,  188,
+
+      190,  281,  194,  204,  195,  193,  199,  198,  281,  155,
+      281,  155,  189,  201,  197,  191,  202,  192,  202,  196,
+      203,  281,  157,  200,  281,  281,  281,  281,  205,  204,
+      281,  199,  198,  206,  281,  281,  210,  281,  281,  281,
+      211,  281,  281,  209,  281,  208,  207,  281,  281,  203,
+      203,  281,  201,  205,  212,  281,  213,  281,  215,  206,
+      214,  216,  210,  217,  221,  281,  211,  218,  209,  281,
+      208,  207,  281,  228,  220,  219,  281,  281,  222,  212,
+      281,  213,  223,  215,  281,  214,  216,  281,  217,  221,
+      224,  281,  218,  225,  281,  281,  281,  226,  228,  220,
+
+      281,  219,  227,  281,  222,  281,  230,  281,  223,  232,
+      281,  281,  281,  281,  237,  229,  224,  281,  225,  270,
+      233,  234,  236,  226,  235,  231,  281,  227,  281,  238,
+      240,  281,  230,  281,  239,  232,  281,  281,  281,  237,
+      229,  244,  245,  281,  270,  233,  241,  234,  236,  235,
+      231,  281,  242,  243,  238,  240,  281,  246,  281,  281,
+      239,  281,  247,  249,  281,  281,  281,  244,  245,  281,
+      281,  241,  252,  281,  281,  253,  281,  242,  243,  254,
+      248,  281,  256,  246,  250,  251,  281,  255,  247,  249,
+      281,  281,  281,  257,  281,  258,  281,  281,  252,  262,
+
+      281,  253,  259,  281,  254,  248,  260,  266,  256,  250,
+      251,  261,  255,  269,  281,  263,  281,  264,  257,  281,
+      258,  265,  281,  281,  267,  262,  281,  259,  281,  281,
+      271,  260,  281,  266,  268,  275,  261,  273,  272,  269,
+      263,  281,  264,  281,  274,  281,  281,  265,  281,  277,
+      267,  281,  278,  281,  280,  271,  276,  281,  160,  160,
+      268,  275,  273,  272,  158,  201,  279,  281,  281,  274,
+      281,  281,  281,  158,  281,  277,  102,   97,  278,  281,
+      280,  276,  281,   52,   48,  281,  102,   97,  281,   52,
+       49,  279,   36,   36,   36,   36,   46,   46,   46,   46,
+
+       96,   48,   96,   96,  100,  100,  281,   37,   37,    7,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281
     } ;
 
-static yyconst flex_int16_t yy_chk[846] =
+static yyconst flex_int16_t yy_chk[873] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -586,90 +592,93 @@ static yyconst flex_int16_t yy_chk[846] =
         1,    1,    5,    5,    5,    5,    5,    5,    5,    5,
         5,   12,   12,   14,   14,   18,   19,   18,   21,   14,
        21,   18,   22,   24,   25,   15,   25,   26,   22,   26,
-       33,   19,   33,   24,   25,   41,   41,  275,   32,   43,
+       33,   19,   33,   24,   25,   41,   41,  284,   32,   43,
 
-       43,  271,   90,   18,  270,   14,   21,   18,   15,   34,
-      269,   34,   25,   32,   22,   26,   19,  267,   33,   24,
+       43,  280,   90,   18,  279,   14,   21,   18,   15,   34,
+      278,   34,   25,   32,   22,   26,   19,  276,   33,   24,
        25,   90,    5,    5,    6,    6,    6,    6,    6,    6,
         6,    6,    6,   15,   20,   23,   20,   34,   32,   29,
-      266,   29,   52,   23,   20,   29,   90,   52,   45,   45,
-       23,   31,   66,   20,   45,   28,   66,   27,   20,  253,
-       57,   31,   20,  252,   27,   28,   57,   29,   28,   23,
-       20,   29,   27,   52,   28,   23,   27,   31,   20,  249,
-       45,  246,   66,   20,    6,    6,   16,   31,   16,   16,
+      275,   29,   52,   23,   20,   29,   90,   52,   45,   45,
+       23,   31,   66,   20,   45,   28,   66,   27,   20,  262,
+       57,   31,   20,  261,   27,   28,   57,   29,   28,   23,
+       20,   29,   27,   52,   28,   23,   27,   31,   20,  260,
+       45,  257,   66,   20,    6,    6,   16,   31,   16,   16,
        27,   28,   57,   28,   51,   51,   16,   27,   53,   28,
 
        51,   27,   31,   53,   54,   54,   16,   61,   59,   58,
-       54,   62,   16,  245,   16,   16,   56,   67,   56,   56,
-       56,   59,   16,  243,   58,   61,   51,  108,  108,   53,
+       54,   62,   16,  254,   16,   16,   56,   67,   56,   56,
+       56,   59,   16,  253,   58,   61,   51,  108,  108,   53,
        67,   16,   62,   63,   60,   65,   54,   16,   30,   68,
-       30,   68,   30,   69,   30,  242,   59,   60,   30,   58,
+       30,   68,   30,   69,   30,  251,   59,   60,   30,   58,
        61,   60,   69,   64,   63,   67,   64,   62,   65,   30,
-       64,   70,   71,  240,   71,   72,   30,   68,   30,  234,
-       30,   70,   60,   64,   30,  233,   60,   74,   69,   63,
+       64,   70,   71,  250,   71,   72,   30,   68,   30,  248,
+       30,   70,   60,   64,   30,  243,   60,   74,   69,   63,
        72,   73,   64,   65,   30,   77,   64,   78,   73,   75,
-       71,   80,   74,   76,   78,   82,   80,   70,   64,   77,
-
-       75,   84,   73,   81,   86,   72,   75,   83,   76,  232,
-       88,   82,   85,   89,   73,  226,   84,   74,   86,   85,
-       78,   91,   80,   83,   77,   88,   75,   73,   81,   92,
-       87,   75,   87,   76,   93,  222,   82,   95,   94,  219,
-       89,   84,   91,   86,   93,   85,   92,  102,   83,  103,
-       88,   94,  102,   81,  103,   99,   99,  217,   87,  110,
-       95,   99,  101,  101,  110,   89,  216,   91,  101,  214,
-       93,   92,  109,  105,  213,  105,   94,  105,  102,  104,
-      103,  104,  104,  104,  106,   95,  106,   99,  106,  115,
-      110,  109,  117,  120,  101,  115,  116,  118,  116,  118,
-
-      119,  121,  122,  120,  119,  123,  124,  126,  122,  212,
-      142,  125,  126,  211,  117,  127,  109,  128,  207,  123,
-      124,  115,  121,  203,  116,  118,  125,  142,  202,  120,
-      119,  127,  131,  128,  122,  129,  130,  133,  126,  117,
-      134,  129,  130,  135,  123,  124,  134,  121,  131,  136,
-      138,  125,  142,  133,  137,  136,  127,  140,  128,  200,
-      137,  141,  144,  135,  139,  140,  143,  129,  130,  199,
-      145,  138,  134,  131,  141,  139,  145,  146,  133,  143,
-      147,  136,  144,  146,  148,  149,  137,  168,  135,  150,
-      148,  140,  151,  147,  155,  155,  138,  198,  151,  141,
-
-      194,  139,  145,  168,  143,  161,  149,  144,  152,  146,
-      152,  150,  152,  153,  164,  153,  148,  153,  147,  156,
-      156,  160,  164,  160,  151,  161,  166,  170,  168,  165,
-      183,  149,  173,  170,  174,  176,  150,  177,  173,  178,
-      181,  179,  180,  183,  182,  166,  181,  206,  164,  160,
-      161,  165,  191,  174,  176,  184,  192,  177,  178,  170,
-      179,  185,  180,  182,  173,  186,  206,  185,  183,  187,
-      166,  186,  181,  188,  189,  187,  165,  192,  174,  176,
-      189,  197,  177,  178,  190,  179,  188,  180,  182,  193,
-      195,  206,  196,  185,  197,  193,  201,  186,  196,  204,
-
-      190,  187,  192,  205,  201,  210,  189,  208,  209,  175,
-      195,  188,  204,  205,  209,  215,  218,  172,  210,  197,
-      218,  193,  221,  220,  196,  190,  208,  220,  221,  223,
-      201,  171,  225,  169,  224,  195,  215,  204,  224,  205,
-      209,  231,  227,  210,  228,  230,  218,  236,  223,  229,
-      228,  208,  225,  220,  221,  229,  244,  235,  231,  237,
-      241,  215,  227,  235,  224,  238,  230,  236,  239,  241,
-      254,  244,  247,  223,  167,  163,  228,  225,  254,  256,
-      237,  229,  248,  231,  248,  162,  238,  227,  239,  235,
-      250,  230,  236,  247,  259,  241,  244,  251,  255,  251,
-
-      250,  257,  256,  260,  254,  237,  258,  159,  255,  262,
-      248,  238,  158,  239,  157,  259,  261,  257,  247,  260,
-      264,  258,  261,  265,  262,  251,  250,  256,  263,  264,
-      268,  154,  263,  132,  255,  114,  268,  113,  265,  112,
-      259,  111,  257,  107,  260,  100,  258,   98,  261,  262,
-       97,   79,   55,   50,   48,  264,   46,   44,  263,   39,
-       17,   13,  268,  265,  273,  273,  273,  273,  274,  274,
-      274,  274,  276,   11,  276,  276,  277,  277,    9,    7,
-        4,    3,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272
+       71,   74,   74,   76,   78,   82,   81,   70,   64,   77,
+
+       75,   86,   73,   83,   80,   72,   75,   84,   76,   80,
+       87,   82,   87,   88,   73,   86,   74,   74,   85,   83,
+       78,   81,   84,   89,   77,   85,   75,   73,   88,   93,
+       94,   75,   92,   76,   91,   80,   82,   95,   87,   93,
+       86,  156,  156,   94,   83,  241,   81,   84,  239,   92,
+       89,   85,  238,   88,  237,   91,   99,   99,  101,  101,
+       95,  102,   99,  231,  101,   93,  102,  103,   94,  105,
+      226,  105,  103,  105,   92,   89,  109,  223,  115,  104,
+       91,  104,  104,  104,  115,   95,  117,  106,   99,  106,
+      101,  106,  102,  119,  110,  109,  120,  119,  103,  110,
+
+      116,  118,  116,  118,  123,  121,  120,  122,  117,  125,
+      115,  127,  130,  122,  126,  128,  124,  220,  123,  126,
+      109,  132,  130,  119,  125,  110,  121,  127,  116,  118,
+      124,  128,  120,  117,  129,  131,  135,  132,  134,  122,
+      129,  131,  135,  123,  136,  126,  140,  218,  130,  125,
+      139,  121,  127,  137,  134,  124,  128,  140,  143,  137,
+      145,  217,  132,  138,  136,  141,  129,  131,  135,  138,
+      146,  139,  147,  141,  142,  143,  146,  144,  147,  134,
+      145,  148,  149,  140,  151,  137,  150,  142,  149,  136,
+      144,  152,  144,  216,  148,  138,  139,  152,  215,  141,
+
+      143,  161,  146,  161,  147,  145,  151,  150,  162,  153,
+      210,  153,  142,  153,  149,  144,  154,  144,  154,  148,
+      154,  157,  157,  152,  166,  165,  167,  169,  162,  161,
+      171,  151,  150,  165,  174,  175,  171,  177,  179,  178,
+      174,  206,  180,  169,  181,  167,  166,  182,  205,  203,
+      202,  185,  201,  162,  175,  184,  177,  193,  179,  165,
+      178,  180,  171,  181,  185,  197,  174,  182,  169,  183,
+      167,  166,  187,  193,  184,  183,  188,  194,  187,  175,
+      190,  177,  188,  179,  189,  178,  180,  192,  181,  185,
+      189,  191,  182,  190,  195,  209,  265,  191,  193,  184,
+
+      196,  183,  192,  199,  187,  198,  196,  200,  188,  199,
+      211,  207,  208,  204,  209,  195,  189,  213,  190,  265,
+      200,  204,  208,  191,  207,  198,  214,  192,  212,  211,
+      213,  219,  196,  221,  212,  199,  186,  222,  224,  209,
+      195,  222,  224,  176,  265,  200,  214,  204,  208,  207,
+      198,  225,  219,  221,  211,  213,  227,  225,  235,  229,
+      212,  228,  227,  229,  230,  232,  233,  222,  224,  234,
+      236,  214,  233,  242,  244,  234,  240,  219,  221,  235,
+      228,  245,  240,  225,  230,  232,  246,  236,  227,  229,
+      249,  173,  247,  242,  172,  244,  255,  258,  233,  249,
+
+      252,  234,  245,  264,  235,  228,  246,  258,  240,  230,
+      232,  247,  236,  264,  266,  252,  268,  255,  242,  256,
+      244,  256,  259,  267,  259,  249,  263,  245,  269,  270,
+      266,  246,  170,  258,  263,  270,  247,  268,  267,  264,
+      252,  271,  255,  273,  269,  272,  168,  256,  277,  272,
+      259,  274,  273,  164,  277,  266,  271,  163,  160,  159,
+      263,  270,  268,  267,  158,  155,  274,  133,  114,  269,
+      113,  112,  111,  107,  100,  272,   98,   97,  273,   79,
+      277,  271,   55,   50,   48,   46,   44,   39,   17,   13,
+       11,  274,  282,  282,  282,  282,  283,  283,  283,  283,
+
+      285,    9,  285,  285,  286,  286,    7,    4,    3,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281,  281,  281,  281,  281,  281,  281,  281,  281,
+      281,  281
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -697,7 +706,7 @@ static yyconst flex_int16_t yy_chk[846] =
 
 
 /* rules */
-#line 701 "envilex.C"
+#line 710 "envilex.C"
 
 #define INITIAL 0
 #define DISCARD 1
@@ -802,7 +811,7 @@ YY_DECL
 #line 30 "envilex.L"
 
 
-#line 806 "envilex.C"
+#line 815 "envilex.C"
 
 	if ( !(yy_init) )
 		{
@@ -855,13 +864,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 273 )
+				if ( yy_current_state >= 282 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 272 );
+		while ( yy_current_state != 281 );
 		yy_cp = (yy_last_accepting_cpos);
 		yy_current_state = (yy_last_accepting_state);
 
@@ -1042,144 +1051,159 @@ YY_RULE_SETUP
 case 29:
 YY_RULE_SETUP
 #line 82 "envilex.L"
-{return LINES_;}
+{return LIMITS_;}
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
 #line 83 "envilex.L"
-{return MAJOR_;}
+{return LINES_;}
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
 #line 84 "envilex.L"
-{return MAP_;}
+{return MAJOR_;}
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
 #line 85 "envilex.L"
-{return MINOR_;}
+{return MAP_;}
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
 #line 86 "envilex.L"
-{return NAMES_;}
+{return MINOR_;}
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
 #line 87 "envilex.L"
-{return OFFSET_;}
+{return NAMES_;}
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
 #line 88 "envilex.L"
-{return OFFSETS_;}
+{return OFFSET_;}
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
 #line 89 "envilex.L"
-{return ORDER_;}
+{return OFFSETS_;}
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
 #line 90 "envilex.L"
-{return PIXEL_;}
+{return ORDER_;}
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
 #line 91 "envilex.L"
-{return PLOT_;}
+{return PIXEL_;}
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
 #line 92 "envilex.L"
-{return PROJECTION_;}
+{return PIXELS_;}
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
 #line 93 "envilex.L"
-{return RANGE_;}
+{return PLOT_;}
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
 #line 94 "envilex.L"
-{return REFLECTANCE_;}
+{return PROJECTION_;}
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
 #line 95 "envilex.L"
-{return SAMPLES_;}
+{return RANGE_;}
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
 #line 96 "envilex.L"
-{return SCALE_;}
+{return REFLECTANCE_;}
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
 #line 97 "envilex.L"
-{return SENSOR_;}
+{return SAMPLES_;}
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
 #line 98 "envilex.L"
-{return SIZE_;}
+{return SCALE_;}
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
 #line 99 "envilex.L"
-{return STRETCH_;}
+{return SCANNER_;}
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
 #line 100 "envilex.L"
-{return TITLES_;}
+{return SENSOR_;}
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
 #line 101 "envilex.L"
-{return TYPE_;}
+{return SIZE_;}
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
 #line 102 "envilex.L"
-{return UNITS_;}
+{return STRETCH_;}
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
 #line 103 "envilex.L"
-{return VALUE_;}
+{return TITLES_;}
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
 #line 104 "envilex.L"
-{return VALUES_;}
+{return TYPE_;}
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
 #line 105 "envilex.L"
-{return WAVELENGTH_;}
+{return UNITS_;}
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
+#line 106 "envilex.L"
+{return VALUE_;}
+	YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 107 "envilex.L"
+{return VALUES_;}
+	YY_BREAK
+case 55:
+YY_RULE_SETUP
 #line 108 "envilex.L"
+{return WAVELENGTH_;}
+	YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 111 "envilex.L"
 { // Integer
 		  envilval->integer = atoi(yytext);
 		  return INT;
 		}
 	YY_BREAK
-case 54:
-#line 114 "envilex.L"
-case 55:
+case 57:
+#line 117 "envilex.L"
+case 58:
 YY_RULE_SETUP
-#line 114 "envilex.L"
+#line 117 "envilex.L"
 { // Real Number
 		  envilval->real = atof(yytext);
 		  return REAL;
 		}
 	YY_BREAK
-case 56:
+case 59:
 YY_RULE_SETUP
-#line 120 "envilex.L"
+#line 123 "envilex.L"
 { // General String
 		  int ll = yyleng <(ENVIPARSERSIZE-1) ? yyleng:(ENVIPARSERSIZE-1);
 		  strncpy(envilval->str,yytext,ll);
@@ -1187,53 +1211,53 @@ YY_RULE_SETUP
 		  return STRING;
 		}
 	YY_BREAK
-case 57:
+case 60:
 YY_RULE_SETUP
-#line 127 "envilex.L"
+#line 130 "envilex.L"
 {
                   return ',';
                 }
 	YY_BREAK
-case 58:
+case 61:
 YY_RULE_SETUP
-#line 131 "envilex.L"
+#line 134 "envilex.L"
 { // White Spaces
 		} 
 	YY_BREAK
-case 59:
-/* rule 59 can match eol */
+case 62:
+/* rule 62 can match eol */
 YY_RULE_SETUP
-#line 134 "envilex.L"
+#line 137 "envilex.L"
 { // linefeed
 		}
 	YY_BREAK
-case 60:
+case 63:
 YY_RULE_SETUP
-#line 137 "envilex.L"
+#line 140 "envilex.L"
 { // other chars, eat it
                 }
 	YY_BREAK
-case 61:
+case 64:
 YY_RULE_SETUP
-#line 140 "envilex.L"
+#line 143 "envilex.L"
 { // Integer
 		  envilval->integer = atoi(yytext);
 		  return INT;
 		}
 	YY_BREAK
-case 62:
-#line 146 "envilex.L"
-case 63:
+case 65:
+#line 149 "envilex.L"
+case 66:
 YY_RULE_SETUP
-#line 146 "envilex.L"
+#line 149 "envilex.L"
 { // Real Number
 		  envilval->real = atof(yytext);
 		  return REAL;
 		}
 	YY_BREAK
-case 64:
+case 67:
 YY_RULE_SETUP
-#line 152 "envilex.L"
+#line 155 "envilex.L"
 { // General String
 		  int ll = yyleng <(ENVIPARSERSIZE-1) ? yyleng:(ENVIPARSERSIZE-1);
 		  strncpy(envilval->str,yytext,ll);
@@ -1241,24 +1265,24 @@ YY_RULE_SETUP
 		  return STRING;
 		}
 	YY_BREAK
-case 65:
+case 68:
 YY_RULE_SETUP
-#line 159 "envilex.L"
+#line 162 "envilex.L"
 { // White Spaces
 		} 
 	YY_BREAK
-case 66:
-/* rule 66 can match eol */
+case 69:
+/* rule 69 can match eol */
 YY_RULE_SETUP
-#line 162 "envilex.L"
+#line 165 "envilex.L"
 { // windows line feed
 		  return '\n';
 		}
 	YY_BREAK
-case 67:
-/* rule 67 can match eol */
+case 70:
+/* rule 70 can match eol */
 YY_RULE_SETUP
-#line 166 "envilex.L"
+#line 169 "envilex.L"
 { // linefeed
 		  return '\n';
 		}
@@ -1266,24 +1290,24 @@ YY_RULE_SETUP
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(DISCARD):
 case YY_STATE_EOF(BRACKET):
-#line 170 "envilex.L"
+#line 173 "envilex.L"
 { // eof
 		  return EOF_;
 		}
 	YY_BREAK
-case 68:
+case 71:
 YY_RULE_SETUP
-#line 174 "envilex.L"
+#line 177 "envilex.L"
 { // Else, return the char
 		  return yytext[0];
 		}
 	YY_BREAK
-case 69:
+case 72:
 YY_RULE_SETUP
-#line 178 "envilex.L"
+#line 181 "envilex.L"
 ECHO;
 	YY_BREAK
-#line 1287 "envilex.C"
+#line 1311 "envilex.C"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1663,7 +1687,7 @@ int yyFlexLexer::yy_get_next_buffer()
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 273 )
+			if ( yy_current_state >= 282 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1691,11 +1715,11 @@ int yyFlexLexer::yy_get_next_buffer()
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 273 )
+		if ( yy_current_state >= 282 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 272);
+	yy_is_jam = (yy_current_state == 281);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
@@ -2180,7 +2204,7 @@ void envifree (void * ptr )
 
 #define YYTABLES_NAME "yytables"
 
-#line 178 "envilex.L"
+#line 181 "envilex.L"
 
 
 
diff --git a/saotk/fitsy++/envilex.L b/saotk/fitsy++/envilex.L
index 440f8aa..dc4e655 100644
--- a/saotk/fitsy++/envilex.L
+++ b/saotk/fitsy++/envilex.L
@@ -79,6 +79,7 @@ header          {return HEADER_;}
 info            {return INFO_;}
 ignore          {return IGNORE_;}
 interleave      {return INTERLEAVE_;}
+limits          {return LIMITS_;}
 lines           {return LINES_;}
 major           {return MAJOR_;}
 map             {return MAP_;}
@@ -88,12 +89,14 @@ offset          {return OFFSET_;}
 offsets         {return OFFSETS_;}
 order           {return ORDER_;}
 pixel           {return PIXEL_;}
+pixels          {return PIXELS_;}
 plot            {return PLOT_;}
 projection      {return PROJECTION_;}
 range           {return RANGE_;}
 reflectance     {return REFLECTANCE_;}
 samples         {return SAMPLES_;}
 scale           {return SCALE_;}
+scanner         {return SCANNER_;}
 sensor          {return SENSOR_;}
 size            {return SIZE_;}
 stretch         {return STRETCH_;}
diff --git a/saotk/fitsy++/enviparser.C b/saotk/fitsy++/enviparser.C
index b5fbb12..ab8c8ad 100644
--- a/saotk/fitsy++/enviparser.C
+++ b/saotk/fitsy++/enviparser.C
@@ -102,31 +102,34 @@
      INFO_ = 283,
      IGNORE_ = 284,
      INTERLEAVE_ = 285,
-     LINES_ = 286,
-     MAJOR_ = 287,
-     MAP_ = 288,
-     MINOR_ = 289,
-     NAMES_ = 290,
-     OFFSET_ = 291,
-     OFFSETS_ = 292,
-     ORDER_ = 293,
-     PIXEL_ = 294,
-     PLOT_ = 295,
-     PROJECTION_ = 296,
-     RANGE_ = 297,
-     REFLECTANCE_ = 298,
-     SAMPLES_ = 299,
-     SCALE_ = 300,
-     SENSOR_ = 301,
-     SIZE_ = 302,
-     START_ = 303,
-     STRETCH_ = 304,
-     TITLES_ = 305,
-     TYPE_ = 306,
-     UNITS_ = 307,
-     VALUE_ = 308,
-     VALUES_ = 309,
-     WAVELENGTH_ = 310
+     LIMITS_ = 286,
+     LINES_ = 287,
+     MAJOR_ = 288,
+     MAP_ = 289,
+     MINOR_ = 290,
+     NAMES_ = 291,
+     OFFSET_ = 292,
+     OFFSETS_ = 293,
+     ORDER_ = 294,
+     PIXEL_ = 295,
+     PIXELS_ = 296,
+     PLOT_ = 297,
+     PROJECTION_ = 298,
+     RANGE_ = 299,
+     REFLECTANCE_ = 300,
+     SAMPLES_ = 301,
+     SCALE_ = 302,
+     SCANNER_ = 303,
+     SENSOR_ = 304,
+     SIZE_ = 305,
+     START_ = 306,
+     STRETCH_ = 307,
+     TITLES_ = 308,
+     TYPE_ = 309,
+     UNITS_ = 310,
+     VALUE_ = 311,
+     VALUES_ = 312,
+     WAVELENGTH_ = 313
    };
 #endif
 /* Tokens.  */
@@ -158,31 +161,34 @@
 #define INFO_ 283
 #define IGNORE_ 284
 #define INTERLEAVE_ 285
-#define LINES_ 286
-#define MAJOR_ 287
-#define MAP_ 288
-#define MINOR_ 289
-#define NAMES_ 290
-#define OFFSET_ 291
-#define OFFSETS_ 292
-#define ORDER_ 293
-#define PIXEL_ 294
-#define PLOT_ 295
-#define PROJECTION_ 296
-#define RANGE_ 297
-#define REFLECTANCE_ 298
-#define SAMPLES_ 299
-#define SCALE_ 300
-#define SENSOR_ 301
-#define SIZE_ 302
-#define START_ 303
-#define STRETCH_ 304
-#define TITLES_ 305
-#define TYPE_ 306
-#define UNITS_ 307
-#define VALUE_ 308
-#define VALUES_ 309
-#define WAVELENGTH_ 310
+#define LIMITS_ 286
+#define LINES_ 287
+#define MAJOR_ 288
+#define MAP_ 289
+#define MINOR_ 290
+#define NAMES_ 291
+#define OFFSET_ 292
+#define OFFSETS_ 293
+#define ORDER_ 294
+#define PIXEL_ 295
+#define PIXELS_ 296
+#define PLOT_ 297
+#define PROJECTION_ 298
+#define RANGE_ 299
+#define REFLECTANCE_ 300
+#define SAMPLES_ 301
+#define SCALE_ 302
+#define SCANNER_ 303
+#define SENSOR_ 304
+#define SIZE_ 305
+#define START_ 306
+#define STRETCH_ 307
+#define TITLES_ 308
+#define TYPE_ 309
+#define UNITS_ 310
+#define VALUE_ 311
+#define VALUES_ 312
+#define WAVELENGTH_ 313
 
 
 
@@ -237,7 +243,7 @@ typedef union YYSTYPE
   char str[ENVIPARSERSIZE];
 }
 /* Line 193 of yacc.c.  */
-#line 241 "enviparser.C"
+#line 247 "enviparser.C"
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -250,7 +256,7 @@ typedef union YYSTYPE
 
 
 /* Line 216 of yacc.c.  */
-#line 254 "enviparser.C"
+#line 260 "enviparser.C"
 
 #ifdef short
 # undef short
@@ -463,22 +469,22 @@ union yyalloc
 #endif
 
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  63
+#define YYFINAL  65
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   192
+#define YYLAST   201
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  65
+#define YYNTOKENS  70
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  26
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  73
+#define YYNRULES  75
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  190
+#define YYNSTATES  198
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   310
+#define YYMAXUTOK   313
 
 #define YYTRANSLATE(YYX)						\
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -487,18 +493,18 @@ union yyalloc
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      61,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      66,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,    64,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,    60,
-       2,    56,     2,     2,     2,     2,     2,     2,     2,     2,
+      63,    64,     2,     2,    69,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,    65,
+       2,    59,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    57,    58,
-      59,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    60,    61,
+      62,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    62,     2,    63,     2,     2,     2,     2,
+       2,     2,     2,    67,     2,    68,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -517,7 +523,7 @@ static const yytype_uint8 yytranslate[] =
       25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
       35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
       45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
-      55
+      55,    56,    57,    58
 };
 
 #if YYDEBUG
@@ -529,56 +535,58 @@ static const yytype_uint16 yyprhs[] =
       26,    30,    34,    39,    45,    51,    52,    58,    63,    67,
       68,    74,    79,    84,    89,    94,    99,   104,   109,   115,
      121,   127,   133,   134,   141,   146,   151,   152,   157,   161,
-     165,   171,   177,   178,   182,   184,   186,   188,   190,   192,
-     194,   196,   198,   200,   202,   204,   207,   211,   214,   216,
-     220,   224,   226,   230,   234,   236,   255,   256,   261,   264,
-     267,   271,   275,   277
+     165,   171,   177,   186,   187,   191,   193,   195,   197,   199,
+     201,   203,   205,   207,   209,   211,   213,   216,   220,   223,
+     225,   229,   233,   235,   239,   243,   245,   264,   265,   270,
+     273,   276,   280,   284,   287,   289
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
-      66,     0,    -1,    66,    67,    74,    -1,    67,    74,    -1,
-      -1,     7,    76,    -1,    72,    -1,    21,    -1,    20,    56,
-      80,    -1,    44,    56,     4,    -1,    31,    56,     4,    -1,
-      12,    56,     4,    -1,    27,    36,    56,     4,    -1,    32,
-      23,    37,    56,    84,    -1,    34,    23,    37,    56,    84,
-      -1,    -1,    24,    51,    56,    68,     6,    -1,    18,    51,
-      56,    77,    -1,    30,    56,    78,    -1,    -1,    46,    51,
-      56,    69,     6,    -1,    17,    38,    56,    79,    -1,    57,
-      48,    56,    84,    -1,    58,    48,    56,    84,    -1,    33,
-      28,    56,    86,    -1,    41,    28,    56,    80,    -1,    19,
-      12,    56,    84,    -1,    55,    52,    56,     6,    -1,    43,
-      45,    22,    56,    75,    -1,    59,    40,    42,    56,    82,
-      -1,    59,    40,    10,    56,    82,    -1,    59,    40,    50,
-      56,    80,    -1,    -1,    18,    29,    54,    56,    70,     6,
-      -1,    39,    47,    56,    82,    -1,    11,    35,    56,    80,
-      -1,    -1,    55,    56,    71,    88,    -1,    25,    56,    80,
-      -1,    13,    56,    80,    -1,    18,    26,    54,    56,    82,
-      -1,    18,    36,    54,    56,    82,    -1,    -1,    60,    73,
-       6,    -1,    61,    -1,     3,    -1,     5,    -1,     4,    -1,
-       8,    -1,     9,    -1,     4,    -1,    16,    -1,    15,    -1,
-      14,    -1,     4,    -1,    62,    63,    -1,    62,    81,    63,
-      -1,    81,     6,    -1,     6,    -1,    62,    83,    63,    -1,
-      83,    64,    75,    -1,    75,    -1,    62,    85,    63,    -1,
-      85,    64,     4,    -1,     4,    -1,    62,     6,    64,     4,
-      64,     4,    64,    75,    64,    75,    64,    75,    64,    75,
-      64,     4,    87,    63,    -1,    -1,    64,     6,    64,     6,
-      -1,    64,     6,    -1,    62,    63,    -1,    62,    89,    63,
-      -1,    89,    64,    90,    -1,    90,    -1,    75,    -1
+      71,     0,    -1,    71,    72,    79,    -1,    72,    79,    -1,
+      -1,     7,    81,    -1,    77,    -1,    21,    -1,    20,    59,
+      85,    -1,    46,    59,     4,    -1,    32,    59,     4,    -1,
+      12,    59,     4,    -1,    27,    37,    59,     4,    -1,    33,
+      23,    38,    59,    89,    -1,    35,    23,    38,    59,    89,
+      -1,    -1,    24,    54,    59,    73,     6,    -1,    18,    54,
+      59,    82,    -1,    30,    59,    83,    -1,    -1,    49,    54,
+      59,    74,     6,    -1,    17,    39,    59,    84,    -1,    60,
+      51,    59,    89,    -1,    61,    51,    59,    89,    -1,    34,
+      28,    59,    91,    -1,    43,    28,    59,    85,    -1,    19,
+      12,    59,    89,    -1,    58,    55,    59,     6,    -1,    45,
+      47,    22,    59,    80,    -1,    62,    42,    44,    59,    87,
+      -1,    62,    42,    10,    59,    87,    -1,    62,    42,    53,
+      59,    85,    -1,    -1,    18,    29,    57,    59,    75,     6,
+      -1,    40,    50,    59,    87,    -1,    11,    36,    59,    85,
+      -1,    -1,    58,    59,    76,    93,    -1,    25,    59,    85,
+      -1,    13,    59,    85,    -1,    18,    26,    57,    59,    87,
+      -1,    18,    37,    57,    59,    87,    -1,    48,    31,    63,
+      41,    64,    59,     4,     4,    -1,    -1,    65,    78,     6,
+      -1,    66,    -1,     3,    -1,     5,    -1,     4,    -1,     8,
+      -1,     9,    -1,     4,    -1,    16,    -1,    15,    -1,    14,
+      -1,     4,    -1,    67,    68,    -1,    67,    86,    68,    -1,
+      86,     6,    -1,     6,    -1,    67,    88,    68,    -1,    88,
+      69,    80,    -1,    80,    -1,    67,    90,    68,    -1,    90,
+      69,     4,    -1,     4,    -1,    67,     6,    69,     4,    69,
+       4,    69,    80,    69,    80,    69,    80,    69,    80,    69,
+       4,    92,    68,    -1,    -1,    69,     6,    69,     6,    -1,
+      69,     6,    -1,    67,    68,    -1,    67,    94,    68,    -1,
+      94,    69,    95,    -1,    94,    69,    -1,    95,    -1,    80,
+      -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   101,   101,   102,   105,   106,   107,   108,   109,   110,
-     111,   112,   113,   114,   115,   116,   116,   117,   118,   119,
-     119,   120,   121,   122,   123,   124,   125,   126,   127,   128,
-     129,   130,   131,   131,   132,   133,   134,   134,   135,   136,
-     137,   138,   141,   141,   144,   145,   148,   149,   152,   153,
-     156,   186,   187,   188,   191,   204,   205,   208,   209,   212,
-     215,   216,   219,   222,   223,   226,   229,   230,   231,   234,
-     240,   255,   256,   259
+       0,   104,   104,   105,   108,   109,   110,   111,   112,   113,
+     114,   115,   116,   117,   118,   119,   119,   120,   121,   122,
+     122,   123,   124,   125,   126,   127,   128,   129,   130,   131,
+     132,   133,   134,   134,   135,   136,   137,   137,   138,   139,
+     140,   141,   142,   145,   145,   148,   149,   152,   153,   156,
+     157,   160,   190,   191,   192,   195,   208,   209,   212,   213,
+     216,   219,   220,   223,   226,   227,   230,   233,   234,   235,
+     238,   244,   259,   260,   261,   264
 };
 #endif
 
@@ -591,15 +599,16 @@ static const char *const yytname[] =
   "DEBUG_", "ON_", "OFF_", "AVERAGE_", "BAND_", "BANDS_", "BBL_", "BIL_",
   "BIP_", "BSQ_", "BYTE_", "DATA_", "DEFAULT_", "DESCRIPTION_", "ENVI_",
   "FACTOR_", "FRAME_", "FILE_", "FWHM_", "GAIN_", "HEADER_", "INFO_",
-  "IGNORE_", "INTERLEAVE_", "LINES_", "MAJOR_", "MAP_", "MINOR_", "NAMES_",
-  "OFFSET_", "OFFSETS_", "ORDER_", "PIXEL_", "PLOT_", "PROJECTION_",
-  "RANGE_", "REFLECTANCE_", "SAMPLES_", "SCALE_", "SENSOR_", "SIZE_",
-  "START_", "STRETCH_", "TITLES_", "TYPE_", "UNITS_", "VALUE_", "VALUES_",
-  "WAVELENGTH_", "'='", "'X'", "'Y'", "'Z'", "';'", "'\\n'", "'{'", "'}'",
-  "','", "$accept", "commands", "command", "@1", "@2", "@3", "@4",
-  "comment", "@5", "terminator", "numeric", "debug", "bitpix", "encoding",
-  "endian", "liststr", "strings", "listnum", "numerics", "listint", "ints",
-  "listmap", "listmapopt", "listwave", "aWaves", "aWave", 0
+  "IGNORE_", "INTERLEAVE_", "LIMITS_", "LINES_", "MAJOR_", "MAP_",
+  "MINOR_", "NAMES_", "OFFSET_", "OFFSETS_", "ORDER_", "PIXEL_", "PIXELS_",
+  "PLOT_", "PROJECTION_", "RANGE_", "REFLECTANCE_", "SAMPLES_", "SCALE_",
+  "SCANNER_", "SENSOR_", "SIZE_", "START_", "STRETCH_", "TITLES_", "TYPE_",
+  "UNITS_", "VALUE_", "VALUES_", "WAVELENGTH_", "'='", "'X'", "'Y'", "'Z'",
+  "'('", "')'", "';'", "'\\n'", "'{'", "'}'", "','", "$accept", "commands",
+  "command", "@1", "@2", "@3", "@4", "comment", "@5", "terminator",
+  "numeric", "debug", "bitpix", "encoding", "endian", "liststr", "strings",
+  "listnum", "numerics", "listint", "ints", "listmap", "listmapopt",
+  "listwave", "aWaves", "aWave", 0
 };
 #endif
 
@@ -613,22 +622,22 @@ static const yytype_uint16 yytoknum[] =
      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
      285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
      295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
-     305,   306,   307,   308,   309,   310,    61,    88,    89,    90,
-      59,    10,   123,   125,    44
+     305,   306,   307,   308,   309,   310,   311,   312,   313,    61,
+      88,    89,    90,    40,    41,    59,    10,   123,   125,    44
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    65,    66,    66,    67,    67,    67,    67,    67,    67,
-      67,    67,    67,    67,    67,    68,    67,    67,    67,    69,
-      67,    67,    67,    67,    67,    67,    67,    67,    67,    67,
-      67,    67,    70,    67,    67,    67,    71,    67,    67,    67,
-      67,    67,    73,    72,    74,    74,    75,    75,    76,    76,
-      77,    78,    78,    78,    79,    80,    80,    81,    81,    82,
-      83,    83,    84,    85,    85,    86,    87,    87,    87,    88,
-      88,    89,    89,    90
+       0,    70,    71,    71,    72,    72,    72,    72,    72,    72,
+      72,    72,    72,    72,    72,    73,    72,    72,    72,    74,
+      72,    72,    72,    72,    72,    72,    72,    72,    72,    72,
+      72,    72,    75,    72,    72,    72,    76,    72,    72,    72,
+      72,    72,    72,    78,    77,    79,    79,    80,    80,    81,
+      81,    82,    83,    83,    83,    84,    85,    85,    86,    86,
+      87,    88,    88,    89,    90,    90,    91,    92,    92,    92,
+      93,    93,    94,    94,    94,    95
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -638,10 +647,10 @@ static const yytype_uint8 yyr2[] =
        3,     3,     4,     5,     5,     0,     5,     4,     3,     0,
        5,     4,     4,     4,     4,     4,     4,     4,     5,     5,
        5,     5,     0,     6,     4,     4,     0,     4,     3,     3,
-       5,     5,     0,     3,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     2,     3,     2,     1,     3,
-       3,     1,     3,     3,     1,    18,     0,     4,     2,     2,
-       3,     3,     1,     1
+       5,     5,     8,     0,     3,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     2,     3,     2,     1,
+       3,     3,     1,     3,     3,     1,    18,     0,     4,     2,
+       2,     3,     3,     2,     1,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -651,65 +660,67 @@ static const yytype_uint8 yydefact[] =
 {
        4,     0,     0,     0,     0,     0,     0,     0,     0,     7,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,    42,     4,     0,
-       6,    48,    49,     5,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    43,     4,
+       0,     6,    49,    50,     5,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    36,     0,
-       0,     0,     0,     1,     0,    45,    44,     3,     0,    11,
-       0,    39,     0,     0,     0,     0,     0,     0,     8,    15,
-      38,     0,    53,    52,    51,    18,    10,     0,     0,     0,
-       0,     0,     0,     9,    19,     0,     0,     0,     0,     0,
-       0,     0,    43,     2,    35,    58,    55,     0,    54,    21,
-       0,    32,     0,    50,    17,     0,    26,     0,    12,     0,
-       0,    24,     0,     0,    34,    25,     0,     0,    27,     0,
-      37,    22,    23,     0,     0,     0,    57,    56,    40,     0,
-      41,    64,     0,    16,    13,     0,    14,    47,    46,    61,
-       0,    28,    20,    69,    73,     0,    72,    30,    29,    31,
-      33,    62,     0,     0,    59,     0,    70,     0,    63,     0,
-      60,    71,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    66,     0,     0,    68,    65,     0,    67
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      36,     0,     0,     0,     0,     1,     0,    46,    45,     3,
+       0,    11,     0,    39,     0,     0,     0,     0,     0,     0,
+       8,    15,    38,     0,    54,    53,    52,    18,    10,     0,
+       0,     0,     0,     0,     0,     9,     0,    19,     0,     0,
+       0,     0,     0,     0,     0,    44,     2,    35,    59,    56,
+       0,    55,    21,     0,    32,     0,    51,    17,     0,    26,
+       0,    12,     0,     0,    24,     0,     0,    34,    25,     0,
+       0,     0,    27,     0,    37,    22,    23,     0,     0,     0,
+      58,    57,    40,     0,    41,    65,     0,    16,    13,     0,
+      14,    48,    47,    62,     0,    28,     0,    20,    70,    75,
+       0,    74,    30,    29,    31,    33,    63,     0,     0,    60,
+       0,     0,    71,    73,    64,     0,    61,     0,    72,     0,
+      42,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    67,     0,     0,    69,    66,     0,    68
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,    28,    29,   117,   127,   139,    96,    30,    62,    67,
-     154,    33,   114,    85,   109,    71,   107,   124,   150,   116,
-     142,   121,   185,   130,   155,   156
+      -1,    29,    30,   120,   131,   143,    99,    31,    64,    69,
+     159,    34,   117,    87,   112,    73,   110,   127,   154,   119,
+     146,   124,   193,   134,   160,   161
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -98
+#define YYPACT_NINF -91
 static const yytype_int16 yypact[] =
 {
-      77,    23,   -31,   -47,   -39,   -25,    88,    27,   -15,   -98,
-      -6,    -5,    30,    11,    24,    59,    63,    64,    46,    71,
-      55,    47,    54,   -45,    58,    65,    72,   -98,     3,    -2,
-     -98,   -98,   -98,   -98,    66,   111,    57,    69,    73,    74,
-      75,    70,    82,    57,    84,    57,    85,    39,   126,    94,
-      86,    96,    87,    89,   122,   142,    91,    92,   -98,    93,
-      95,    28,   144,   -98,    -2,   -98,   -98,   -98,    57,   -98,
-       2,   -98,   148,    97,    98,    99,   152,   100,   -98,   -98,
-     -98,   153,   -98,   -98,   -98,   -98,   -98,   102,   101,   103,
-     104,    57,   105,   -98,   -98,   154,   106,   100,   100,   108,
-     109,   113,   -98,   -98,   -98,   -98,   -98,     6,   -98,   -98,
-     104,   -98,   104,   -98,   -98,   163,   -98,   164,   -98,   100,
-     165,   -98,   100,    52,   -98,   -98,    52,   166,   -98,     1,
-     -98,   -98,   -98,   104,   104,    57,   -98,   -98,   -98,   167,
-     -98,   -98,     8,   -98,   -98,   110,   -98,   -98,   -98,   -98,
-      12,   -98,   -98,   -98,   -98,    22,   -98,   -98,   -98,   -98,
-     -98,   -98,   171,   172,   -98,    52,   -98,    52,   -98,   114,
-     -98,   -98,   173,   115,    52,   116,    52,   117,    52,   118,
-      52,   119,   180,   121,   181,   123,   124,   -98,   183,   -98
+      90,    11,   -30,   -47,   -41,   -24,   -21,    26,   -27,   -91,
+     -13,    -8,    37,    19,    22,    56,    55,    61,    39,    62,
+      44,    34,    68,    46,   -46,    53,    54,    64,   -91,    10,
+      -2,   -91,   -91,   -91,   -91,    57,   108,    51,    60,    69,
+      70,    71,    73,    75,    51,    78,    51,    81,    72,   109,
+      83,    82,    91,    84,    85,   120,   127,    86,    87,    88,
+     -91,    94,    95,     4,   139,   -91,    -2,   -91,   -91,   -91,
+      51,   -91,     1,   -91,   152,    98,    99,   100,   156,    96,
+     -91,   -91,   -91,   157,   -91,   -91,   -91,   -91,   -91,   103,
+      97,   106,   101,    51,   107,   -91,   126,   -91,   163,   104,
+      96,    96,   111,   113,   114,   -91,   -91,   -91,   -91,   -91,
+       5,   -91,   -91,   101,   -91,   101,   -91,   -91,   170,   -91,
+     169,   -91,    96,   171,   -91,    96,    20,   -91,   -91,    20,
+     112,   172,   -91,    -1,   -91,   -91,   -91,   101,   101,    51,
+     -91,   -91,   -91,   173,   -91,   -91,   -22,   -91,   -91,   115,
+     -91,   -91,   -91,   -91,    -6,   -91,   121,   -91,   -91,   -91,
+      -3,   -91,   -91,   -91,   -91,   -91,   -91,   177,   178,   -91,
+      20,   179,   -91,    20,   -91,   116,   -91,   182,   -91,   183,
+     -91,   119,    20,   122,    20,   123,    20,   124,    20,   125,
+     185,   128,   184,   130,   131,   -91,   189,   -91
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-     -98,   -98,   162,   -98,   -98,   -98,   -98,   -98,   -98,   127,
-     -97,   -98,   -98,   -98,   -98,   -43,   -98,   -60,   -98,   -79,
-     -98,   -98,   -98,   -98,   -98,    25
+     -91,   -91,   167,   -91,   -91,   -91,   -91,   -91,   -91,   133,
+     -90,   -91,   -91,   -91,   -91,   -44,   -91,   -61,   -91,   -40,
+     -91,   -91,   -91,   -91,   -91,    28
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
@@ -719,50 +730,52 @@ static const yytype_int16 yypgoto[] =
 #define YYTABLE_NINF -1
 static const yytype_uint8 yytable[] =
 {
-      78,    65,    80,    63,    34,   147,   148,    57,   105,    35,
-       1,    58,   136,    37,     2,     3,     4,    36,   131,   132,
-       5,     6,     7,     8,     9,   104,   149,    10,    11,   151,
-      12,    31,    32,    13,    14,    15,    16,    17,    99,    42,
-     144,    43,    18,   146,    19,    44,    20,    21,   125,    22,
-     138,    45,   140,    82,    83,    84,   147,   148,    23,    66,
-      24,    25,    26,    27,   153,   106,    46,    47,   170,   137,
-     100,   161,   162,   157,   158,   164,   165,   175,   101,   177,
-      48,   179,    49,   181,     1,   166,   167,    51,     2,     3,
-       4,    50,   159,    52,     5,     6,     7,     8,     9,    53,
-      54,    10,    11,    55,    12,    56,    59,    13,    14,    15,
-      16,    17,    61,    60,    38,    69,    18,    39,    19,    70,
-      20,    21,    68,    22,    40,    72,    76,    73,    74,    75,
-      86,    87,    23,    89,    24,    25,    26,    27,    77,    41,
-      79,    81,    88,    90,    92,    91,    93,    94,    95,    97,
-     102,    98,   108,   110,   111,   112,   113,   118,   119,   122,
-     128,   126,   115,   120,   133,   134,   123,   141,   129,   135,
-     143,   145,   152,   160,   163,   168,   169,   173,   172,   174,
-     176,   178,   180,   182,   183,   184,   187,   186,   188,   189,
-      64,   103,   171
+      80,    67,    82,   151,   152,    39,    35,   108,    40,    59,
+      65,   140,    36,    60,   102,    38,    41,     1,    37,    32,
+      33,     2,     3,     4,   151,   152,   107,     5,     6,     7,
+       8,     9,    44,    42,    10,    11,   153,    12,    43,   155,
+      13,    45,    14,    15,    16,    17,   166,   167,   103,   128,
+      18,    46,   142,    19,   144,    20,    21,   104,    22,    23,
+     135,   136,   169,   170,    68,   172,   173,   158,    24,   109,
+      25,    26,    27,   141,    47,    28,   162,   163,    48,    50,
+     176,    49,   148,    51,    52,   150,    84,    85,    86,    53,
+      54,    55,   183,    56,   185,   164,   187,     1,   189,    57,
+      58,     2,     3,     4,    61,    62,    63,     5,     6,     7,
+       8,     9,    71,    88,    10,    11,    70,    12,    72,    74,
+      13,    89,    14,    15,    16,    17,    75,    76,    77,    91,
+      18,    95,    78,    19,    79,    20,    21,    81,    22,    23,
+      83,    90,    94,    92,    93,   105,    97,    98,    24,    96,
+      25,    26,    27,   100,   101,    28,   111,   113,   114,   115,
+     116,   121,   122,   118,   123,   125,   129,   130,   126,   132,
+     137,   133,   138,   139,   145,   147,   156,   149,   157,   165,
+     171,   174,   175,   177,   168,   179,   180,   181,   182,   191,
+     194,   184,   186,   188,   190,   197,    66,   192,   195,   106,
+     196,   178
 };
 
 static const yytype_uint8 yycheck[] =
 {
-      43,     3,    45,     0,    35,     4,     5,    52,     6,    56,
-       7,    56,     6,    38,    11,    12,    13,    56,    97,    98,
-      17,    18,    19,    20,    21,    68,   123,    24,    25,   126,
-      27,     8,     9,    30,    31,    32,    33,    34,    10,    12,
-     119,    56,    39,   122,    41,    51,    43,    44,    91,    46,
-     110,    56,   112,    14,    15,    16,     4,     5,    55,    61,
-      57,    58,    59,    60,    63,    63,    36,    56,   165,    63,
-      42,    63,    64,   133,   134,    63,    64,   174,    50,   176,
-      56,   178,    23,   180,     7,    63,    64,    23,    11,    12,
-      13,    28,   135,    47,    17,    18,    19,    20,    21,    28,
-      45,    24,    25,    56,    27,    51,    48,    30,    31,    32,
-      33,    34,    40,    48,    26,     4,    39,    29,    41,    62,
-      43,    44,    56,    46,    36,    56,    56,    54,    54,    54,
-       4,    37,    55,    37,    57,    58,    59,    60,    56,    51,
-      56,    56,    56,    56,    22,    56,     4,    56,    56,    56,
-       6,    56,     4,    56,    56,    56,     4,     4,    56,    56,
-       6,    56,    62,    62,    56,    56,    62,     4,    62,    56,
-       6,     6,     6,     6,    64,     4,     4,     4,    64,    64,
-      64,    64,    64,    64,     4,    64,    63,     6,    64,     6,
-      28,    64,   167
+      44,     3,    46,     4,     5,    26,    36,     6,    29,    55,
+       0,     6,    59,    59,    10,    39,    37,     7,    59,     8,
+       9,    11,    12,    13,     4,     5,    70,    17,    18,    19,
+      20,    21,    59,    54,    24,    25,   126,    27,    12,   129,
+      30,    54,    32,    33,    34,    35,    68,    69,    44,    93,
+      40,    59,   113,    43,   115,    45,    46,    53,    48,    49,
+     100,   101,    68,    69,    66,    68,    69,    68,    58,    68,
+      60,    61,    62,    68,    37,    65,   137,   138,    59,    23,
+     170,    59,   122,    28,    23,   125,    14,    15,    16,    50,
+      28,    47,   182,    59,   184,   139,   186,     7,   188,    31,
+      54,    11,    12,    13,    51,    51,    42,    17,    18,    19,
+      20,    21,     4,     4,    24,    25,    59,    27,    67,    59,
+      30,    38,    32,    33,    34,    35,    57,    57,    57,    38,
+      40,     4,    59,    43,    59,    45,    46,    59,    48,    49,
+      59,    59,    22,    59,    59,     6,    59,    59,    58,    63,
+      60,    61,    62,    59,    59,    65,     4,    59,    59,    59,
+       4,     4,    59,    67,    67,    59,    59,    41,    67,     6,
+      59,    67,    59,    59,     4,     6,    64,     6,     6,     6,
+      59,     4,     4,     4,    69,    69,     4,     4,    69,     4,
+       6,    69,    69,    69,    69,     6,    29,    69,    68,    66,
+      69,   173
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -770,24 +783,25 @@ static const yytype_uint8 yycheck[] =
 static const yytype_uint8 yystos[] =
 {
        0,     7,    11,    12,    13,    17,    18,    19,    20,    21,
-      24,    25,    27,    30,    31,    32,    33,    34,    39,    41,
-      43,    44,    46,    55,    57,    58,    59,    60,    66,    67,
-      72,     8,     9,    76,    35,    56,    56,    38,    26,    29,
-      36,    51,    12,    56,    51,    56,    36,    56,    56,    23,
-      28,    23,    47,    28,    45,    56,    51,    52,    56,    48,
-      48,    40,    73,     0,    67,     3,    61,    74,    56,     4,
-      62,    80,    56,    54,    54,    54,    56,    56,    80,    56,
-      80,    56,    14,    15,    16,    78,     4,    37,    56,    37,
-      56,    56,    22,     4,    56,    56,    71,    56,    56,    10,
-      42,    50,     6,    74,    80,     6,    63,    81,     4,    79,
-      56,    56,    56,     4,    77,    62,    84,    68,     4,    56,
-      62,    86,    56,    62,    82,    80,    56,    69,     6,    62,
-      88,    84,    84,    56,    56,    56,     6,    63,    82,    70,
-      82,     4,    85,     6,    84,     6,    84,     4,     5,    75,
-      83,    75,     6,    63,    75,    89,    90,    82,    82,    80,
-       6,    63,    64,    64,    63,    64,    63,    64,     4,     4,
-      75,    90,    64,     4,    64,    75,    64,    75,    64,    75,
-      64,    75,    64,     4,    64,    87,     6,    63,    64,     6
+      24,    25,    27,    30,    32,    33,    34,    35,    40,    43,
+      45,    46,    48,    49,    58,    60,    61,    62,    65,    71,
+      72,    77,     8,     9,    81,    36,    59,    59,    39,    26,
+      29,    37,    54,    12,    59,    54,    59,    37,    59,    59,
+      23,    28,    23,    50,    28,    47,    59,    31,    54,    55,
+      59,    51,    51,    42,    78,     0,    72,     3,    66,    79,
+      59,     4,    67,    85,    59,    57,    57,    57,    59,    59,
+      85,    59,    85,    59,    14,    15,    16,    83,     4,    38,
+      59,    38,    59,    59,    22,     4,    63,    59,    59,    76,
+      59,    59,    10,    44,    53,     6,    79,    85,     6,    68,
+      86,     4,    84,    59,    59,    59,     4,    82,    67,    89,
+      73,     4,    59,    67,    91,    59,    67,    87,    85,    59,
+      41,    74,     6,    67,    93,    89,    89,    59,    59,    59,
+       6,    68,    87,    75,    87,     4,    90,     6,    89,     6,
+      89,     4,     5,    80,    88,    80,    64,     6,    68,    80,
+      94,    95,    87,    87,    85,     6,    68,    69,    69,    68,
+      69,    59,    68,    69,     4,     4,    80,     4,    95,    69,
+       4,     4,    69,    80,    69,    80,    69,    80,    69,    80,
+      69,     4,    69,    92,     6,    68,    69,     6
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -1615,77 +1629,77 @@ yyreduce:
   switch (yyn)
     {
         case 9:
-#line 110 "enviparser.Y"
+#line 113 "enviparser.Y"
     {envi->setpWidth((yyvsp[(3) - (3)].integer));;}
     break;
 
   case 10:
-#line 111 "enviparser.Y"
+#line 114 "enviparser.Y"
     {envi->setpHeight((yyvsp[(3) - (3)].integer));;}
     break;
 
   case 11:
-#line 112 "enviparser.Y"
+#line 115 "enviparser.Y"
     {envi->setpDepth((yyvsp[(3) - (3)].integer));;}
     break;
 
   case 12:
-#line 113 "enviparser.Y"
+#line 116 "enviparser.Y"
     {envi->setpSkip((yyvsp[(4) - (4)].integer));;}
     break;
 
   case 15:
-#line 116 "enviparser.Y"
+#line 119 "enviparser.Y"
     {DISCARD_(1);}
     break;
 
   case 19:
-#line 119 "enviparser.Y"
+#line 122 "enviparser.Y"
     {DISCARD_(1);}
     break;
 
   case 32:
-#line 131 "enviparser.Y"
+#line 134 "enviparser.Y"
     {DISCARD_(1);}
     break;
 
   case 36:
-#line 134 "enviparser.Y"
+#line 137 "enviparser.Y"
     {numWave=0;;}
     break;
 
-  case 42:
-#line 141 "enviparser.Y"
+  case 43:
+#line 145 "enviparser.Y"
     {DISCARD_(1);}
     break;
 
-  case 45:
-#line 145 "enviparser.Y"
+  case 46:
+#line 149 "enviparser.Y"
     {YYACCEPT;;}
     break;
 
-  case 46:
-#line 148 "enviparser.Y"
+  case 47:
+#line 152 "enviparser.Y"
     {(yyval.real)=(yyvsp[(1) - (1)].real);;}
     break;
 
-  case 47:
-#line 149 "enviparser.Y"
+  case 48:
+#line 153 "enviparser.Y"
     {(yyval.real)=(yyvsp[(1) - (1)].integer);;}
     break;
 
-  case 48:
-#line 152 "enviparser.Y"
+  case 49:
+#line 156 "enviparser.Y"
     {yydebug=1;;}
     break;
 
-  case 49:
-#line 153 "enviparser.Y"
+  case 50:
+#line 157 "enviparser.Y"
     {yydebug=0;;}
     break;
 
-  case 50:
-#line 157 "enviparser.Y"
+  case 51:
+#line 161 "enviparser.Y"
     {
 	  switch((yyvsp[(1) - (1)].integer)) {
 	  case 1:
@@ -1715,23 +1729,23 @@ yyreduce:
 	;}
     break;
 
-  case 51:
-#line 186 "enviparser.Y"
+  case 52:
+#line 190 "enviparser.Y"
     {envi->setpEncoding(FitsFile::BSQ);;}
     break;
 
-  case 52:
-#line 187 "enviparser.Y"
+  case 53:
+#line 191 "enviparser.Y"
     {envi->setpEncoding(FitsFile::BIP);;}
     break;
 
-  case 53:
-#line 188 "enviparser.Y"
+  case 54:
+#line 192 "enviparser.Y"
     {envi->setpEncoding(FitsFile::BIL);;}
     break;
 
-  case 54:
-#line 192 "enviparser.Y"
+  case 55:
+#line 196 "enviparser.Y"
     {
 	  switch((yyvsp[(1) - (1)].integer)) {
 	  case 0:
@@ -1744,8 +1758,8 @@ yyreduce:
 	;}
     break;
 
-  case 69:
-#line 235 "enviparser.Y"
+  case 70:
+#line 239 "enviparser.Y"
     {
 	  envi->setpCRPIX3(1);
 	  envi->setpCRVAL3(1);
@@ -1753,8 +1767,8 @@ yyreduce:
 	;}
     break;
 
-  case 70:
-#line 241 "enviparser.Y"
+  case 71:
+#line 245 "enviparser.Y"
     {
 	  if (numWave>=2) {
 	    envi->setpCRPIX3(1);
@@ -1769,8 +1783,8 @@ yyreduce:
 	;}
     break;
 
-  case 73:
-#line 260 "enviparser.Y"
+  case 75:
+#line 265 "enviparser.Y"
     {
 	  if (numWave < MAXWAVES)
 	    wave[numWave++] = (yyvsp[(1) - (1)].real);
@@ -1779,7 +1793,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 1783 "enviparser.C"
+#line 1797 "enviparser.C"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1993,6 +2007,6 @@ yyreturn:
 }
 
 
-#line 266 "enviparser.Y"
+#line 271 "enviparser.Y"
 
 
diff --git a/saotk/fitsy++/enviparser.H b/saotk/fitsy++/enviparser.H
index a2b3e31..087fd44 100644
--- a/saotk/fitsy++/enviparser.H
+++ b/saotk/fitsy++/enviparser.H
@@ -67,31 +67,34 @@
      INFO_ = 283,
      IGNORE_ = 284,
      INTERLEAVE_ = 285,
-     LINES_ = 286,
-     MAJOR_ = 287,
-     MAP_ = 288,
-     MINOR_ = 289,
-     NAMES_ = 290,
-     OFFSET_ = 291,
-     OFFSETS_ = 292,
-     ORDER_ = 293,
-     PIXEL_ = 294,
-     PLOT_ = 295,
-     PROJECTION_ = 296,
-     RANGE_ = 297,
-     REFLECTANCE_ = 298,
-     SAMPLES_ = 299,
-     SCALE_ = 300,
-     SENSOR_ = 301,
-     SIZE_ = 302,
-     START_ = 303,
-     STRETCH_ = 304,
-     TITLES_ = 305,
-     TYPE_ = 306,
-     UNITS_ = 307,
-     VALUE_ = 308,
-     VALUES_ = 309,
-     WAVELENGTH_ = 310
+     LIMITS_ = 286,
+     LINES_ = 287,
+     MAJOR_ = 288,
+     MAP_ = 289,
+     MINOR_ = 290,
+     NAMES_ = 291,
+     OFFSET_ = 292,
+     OFFSETS_ = 293,
+     ORDER_ = 294,
+     PIXEL_ = 295,
+     PIXELS_ = 296,
+     PLOT_ = 297,
+     PROJECTION_ = 298,
+     RANGE_ = 299,
+     REFLECTANCE_ = 300,
+     SAMPLES_ = 301,
+     SCALE_ = 302,
+     SCANNER_ = 303,
+     SENSOR_ = 304,
+     SIZE_ = 305,
+     START_ = 306,
+     STRETCH_ = 307,
+     TITLES_ = 308,
+     TYPE_ = 309,
+     UNITS_ = 310,
+     VALUE_ = 311,
+     VALUES_ = 312,
+     WAVELENGTH_ = 313
    };
 #endif
 /* Tokens.  */
@@ -123,31 +126,34 @@
 #define INFO_ 283
 #define IGNORE_ 284
 #define INTERLEAVE_ 285
-#define LINES_ 286
-#define MAJOR_ 287
-#define MAP_ 288
-#define MINOR_ 289
-#define NAMES_ 290
-#define OFFSET_ 291
-#define OFFSETS_ 292
-#define ORDER_ 293
-#define PIXEL_ 294
-#define PLOT_ 295
-#define PROJECTION_ 296
-#define RANGE_ 297
-#define REFLECTANCE_ 298
-#define SAMPLES_ 299
-#define SCALE_ 300
-#define SENSOR_ 301
-#define SIZE_ 302
-#define START_ 303
-#define STRETCH_ 304
-#define TITLES_ 305
-#define TYPE_ 306
-#define UNITS_ 307
-#define VALUE_ 308
-#define VALUES_ 309
-#define WAVELENGTH_ 310
+#define LIMITS_ 286
+#define LINES_ 287
+#define MAJOR_ 288
+#define MAP_ 289
+#define MINOR_ 290
+#define NAMES_ 291
+#define OFFSET_ 292
+#define OFFSETS_ 293
+#define ORDER_ 294
+#define PIXEL_ 295
+#define PIXELS_ 296
+#define PLOT_ 297
+#define PROJECTION_ 298
+#define RANGE_ 299
+#define REFLECTANCE_ 300
+#define SAMPLES_ 301
+#define SCALE_ 302
+#define SCANNER_ 303
+#define SENSOR_ 304
+#define SIZE_ 305
+#define START_ 306
+#define STRETCH_ 307
+#define TITLES_ 308
+#define TYPE_ 309
+#define UNITS_ 310
+#define VALUE_ 311
+#define VALUES_ 312
+#define WAVELENGTH_ 313
 
 
 
@@ -162,7 +168,7 @@ typedef union YYSTYPE
   char str[ENVIPARSERSIZE];
 }
 /* Line 1529 of yacc.c.  */
-#line 166 "enviparser.H"
+#line 172 "enviparser.H"
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
diff --git a/saotk/fitsy++/enviparser.Y b/saotk/fitsy++/enviparser.Y
index 13da876..341b7af 100644
--- a/saotk/fitsy++/enviparser.Y
+++ b/saotk/fitsy++/enviparser.Y
@@ -67,6 +67,7 @@ static float wave[MAXWAVES];
 %token INFO_
 %token IGNORE_
 %token INTERLEAVE_
+%token LIMITS_
 %token LINES_
 %token MAJOR_
 %token MAP_
@@ -76,12 +77,14 @@ static float wave[MAXWAVES];
 %token OFFSETS_
 %token ORDER_
 %token PIXEL_
+%token PIXELS_
 %token PLOT_
 %token PROJECTION_
 %token RANGE_
 %token REFLECTANCE_
 %token SAMPLES_
 %token SCALE_
+%token SCANNER_
 %token SENSOR_
 %token SIZE_
 %token START_
@@ -136,6 +139,7 @@ command : /* empty */
 	| BBL_ '=' liststr
 	| DATA_ GAIN_ VALUES_ '=' listnum
 	| DATA_ OFFSET_ VALUES_ '=' listnum
+	| SCANNER_ LIMITS_ '(' PIXELS_ ')' '=' INT INT
 	;
 
 comment : ';' {DISCARD_(1)} STRING
@@ -253,6 +257,7 @@ listwave: '{' '}'
         ;
 
 aWaves  : aWaves ',' aWave
+        | aWaves ','
         | aWave
         ;
 
diff --git a/saotk/fitsy++/file.C b/saotk/fitsy++/file.C
index ea7f73c..9188738 100644
--- a/saotk/fitsy++/file.C
+++ b/saotk/fitsy++/file.C
@@ -83,8 +83,6 @@ void envierror(FitsFile* envi, enviFlexLexer* ll, const char* m)
 
 FitsFile::FitsFile()
 {
-  //  cerr << "FitsFile()" << endl;
-
   primary_ = NULL;
   managePrimary_ = 0;
 
@@ -98,7 +96,7 @@ FitsFile::FitsFile()
   ext_ = 0;
   inherit_ = 0;
   byteswap_ = lsb();
-  orgFits_ = 1;
+  endian_ = BIG;
   valid_ = 0;
 
   pName_ = NULL;
@@ -114,78 +112,11 @@ FitsFile::FitsFile()
   pWidth_ =0;
   pHeight_ =0;
   pDepth_ =1;
-  pSize_ =0;
   pSkip_ =0;
-  pArch_ =NATIVE;
+  pArch_ =BIG;
 
   pEncoding_ =RAW;
 
-  pNRRDDimension_ = 0;
-  
-  pHPXOrder_ =-1;
-  pHPXSystem_ =-1;
-  pHPXLayout_ =-1;
-  pHPXColumn_ =-1;
-  pHPXQuad_ =-1;
-
-  pCRPIX3_ =1;
-  pCRVAL3_ =1;
-  pCDELT3_ =1;
-
-  coord_ =0;
-  xvalid_ =0;
-  xmin_ =0;
-  xmax_ =0;
-  yvalid_ =0;
-  ymin_ =0;
-  ymax_ =0;
-  zvalid_ =0;
-  zmin_ =0;
-  zmax_ =0;
-}
-
-FitsFile::FitsFile(FitsFile* fits)
-{
-  //  cerr << "FitsFile(FitsFile* fits)" << endl;
-
-  primary_ = NULL;
-  managePrimary_ = 0;
-
-  head_ = NULL;
-  manageHead_ = 1;
-
-  data_ = NULL;
-
-  dataSize_ = 0;
-  dataSkip_ = 0;
-
-  ext_ = 0;
-  inherit_ = 0;
-  byteswap_ = lsb();
-  orgFits_ = 1;
-  valid_ = 0;
-
-  pName_ = NULL;
-  pExt_ = NULL;
-  pIndex_ = -1;
-
-  pFilter_ = NULL;
-  pBinX_ = NULL;
-  pBinY_ = NULL;
-  pBinZ_ = NULL;
-
-  pBitpix_ = fits->pBitpix();
-  pWidth_ = fits->pWidth();
-  pHeight_ = fits->pHeight();
-  pDepth_ = fits->pDepth();
-  pSize_ = fits->pSize();
-  pSkip_ =0;
-  pArch_ =NATIVE;
-
-  pEncoding_ =RAW;
-
-  pNRRDDimension_ = 0;
-  
   pHPXOrder_ =-1;
   pHPXSystem_ =-1;
   pHPXLayout_ =-1;
@@ -432,10 +363,7 @@ int FitsFile::validParams()
 
 void FitsFile::setByteSwap()
 {
-  switch (pArch_) {
-  case NATIVE:
-    byteswap_ = 0;
-    break;
+  switch (endian_) {
   case BIG:
     byteswap_ = lsb();
     break;
diff --git a/saotk/fitsy++/file.h b/saotk/fitsy++/file.h
index 4444a0d..403bb0e 100644
--- a/saotk/fitsy++/file.h
+++ b/saotk/fitsy++/file.h
@@ -5,8 +5,6 @@
 #ifndef __fitsfile_h__
 #define __fitsfile_h__
 
-#include <tcl.h>
-
 #include "head.h"
 
 #define B4KB 4096
@@ -39,7 +37,7 @@ protected:
   int ext_;                  // extension number
   int inherit_;              // do we have inheritence?
   int byteswap_;             // flag, true if byteswap is needed
-  int orgFits_;              // flag to indicate origin
+  ArchType endian_;          // endian of data
   int valid_;                // flag, true if file is valid
 
   char* pName_;              // parsed file name
@@ -55,21 +53,17 @@ protected:
   int pWidth_;               // parsed width
   int pHeight_;              // parsed height
   int pDepth_;               // parsed depth
-  size_t pSize_;             // parsed size
   size_t pSkip_;             // parsed skip size
   ArchType pArch_;           // parsed arch type
+  EncodingType pEncoding_;   // parsed encoding
 
-  EncodingType pEncoding_;
-
-  int pNRRDDimension_;
-
-  int pHPXOrder_;             // parsed HPX params
+  int pHPXOrder_;            // parsed HPX params
   int pHPXSystem_;
   int pHPXLayout_;
   int pHPXColumn_;
   int pHPXQuad_;
 
-  double pCRPIX3_;
+  double pCRPIX3_;           // WCS_3 axis params
   double pCRVAL3_;
   double pCDELT3_;
 
@@ -94,7 +88,6 @@ protected:
 
 public:
   FitsFile();
-  FitsFile(FitsFile*);
   virtual ~FitsFile();
 
   virtual void done() {}
@@ -109,13 +102,14 @@ public:
   int ext() {return ext_;}
   const char* extname() {return head_ ? head_->extname() : NULL;}
   int inherit() {return inherit_;}
+  int setValid(int vv) {valid_=vv;}
   int isValid() {return valid_;}
   int isImage() {return head_ ? head_->isImage() : 0;}
   int isTable() {return head_ ? head_->isTable() : 0;}
   int isAsciiTable() {return head_ ? head_->isAsciiTable() : 0;}
   int isBinTable() {return head_ ? head_->isBinTable() : 0;}
   int byteswap() {return byteswap_;}
-  int orgFits() {return orgFits_;}
+  ArchType endian() {return endian_;}
 
   void setpName(const char*);
   void setpExt(const char*);
@@ -142,7 +136,6 @@ public:
   int pWidth() {return pWidth_;}
   int pHeight() {return pHeight_;}
   int pDepth() {return pDepth_;}
-  size_t pSize() {return pSize_;}
   size_t pSkip() {return pSkip_;}
   ArchType pArch() {return pArch_;}
 
@@ -156,9 +149,6 @@ public:
   EncodingType pEncoding() {return pEncoding_;}
   void setpEncoding(EncodingType e) {pEncoding_ = e;}
 
-  int pNRRDDimension() {return pNRRDDimension_;}
-  void setpNRRDDimension(int d) {pNRRDDimension_ = d;}
-
   int pHPXOrder() {return pHPXOrder_;}
   int pHPXSystem() {return pHPXSystem_;}
   int pHPXLayout() {return pHPXLayout_;}
diff --git a/saotk/fitsy++/hist.C b/saotk/fitsy++/hist.C
index 9faf7b5..1c4115d 100644
--- a/saotk/fitsy++/hist.C
+++ b/saotk/fitsy++/hist.C
@@ -521,15 +521,8 @@ FitsHistNext::FitsHistNext(FitsFile* prev)
   ext_ = prev->ext();
   inherit_ = prev->inherit();
   byteswap_ = prev->byteswap();
-  orgFits_ = prev->orgFits();
+  endian_ = prev->endian();
   valid_ = 1;
 
-  pWidth_ = prev->pWidth();
-  pHeight_ = prev->pHeight();
-  pDepth_ = prev->pDepth();
-  pBitpix_ = prev->pBitpix();
-  pSkip_ = prev->pSkip();
-  pArch_ = prev->pArch();
-
   return;
 }
diff --git a/saotk/fitsy++/hpx.C b/saotk/fitsy++/hpx.C
index 33b867d..f8c1792 100644
--- a/saotk/fitsy++/hpx.C
+++ b/saotk/fitsy++/hpx.C
@@ -564,38 +564,3 @@ void FitsHPX::swap()
     dest[i] = u.f;
   }
 }
-
-FitsHPXNext::FitsHPXNext(FitsFile* prev)
-{
-  primary_ = prev->primary();
-  managePrimary_ = 0;
-
-  head_ = prev->head();
-  manageHead_ = 0;
-
-  FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu();
-  data_ = (char*)prev->data() + hdu->imgbytes();
-  dataSize_ = 0;
-  dataSkip_ = 0;
-
-  ext_ = prev->ext();
-  inherit_ = prev->inherit();
-  byteswap_ = prev->byteswap();
-  orgFits_ = prev->orgFits();
-  valid_ = 1;
-
-  pWidth_ = prev->pWidth();
-  pHeight_ = prev->pHeight();
-  pDepth_ = prev->pDepth();
-  pBitpix_ = prev->pBitpix();
-  pSkip_ = prev->pSkip();
-  pArch_ = prev->pArch();
-
-  pHPXOrder_ = prev->pHPXColumn();
-  pHPXSystem_ = prev->pHPXColumn();
-  pHPXLayout_ = prev->pHPXColumn();
-  pHPXColumn_ = prev->pHPXColumn();
-  pHPXQuad_ = prev->pHPXQuad();
-
-  return;
-}
diff --git a/saotk/fitsy++/hpx.h b/saotk/fitsy++/hpx.h
index 563d786..b53af4e 100644
--- a/saotk/fitsy++/hpx.h
+++ b/saotk/fitsy++/hpx.h
@@ -31,14 +31,12 @@ class FitsHPX : public FitsFile {
   void NESTidx(int facet, int rotn, int jmap, long *healidx);
   void RINGidx(int facet, int rotn, int jmap, long *healidx);
 
+ protected:
+  size_t pSize_;
+
  public:
   FitsHPX(FitsFile*, Order, CoordSys, Layout, int, int);
   ~FitsHPX();
 };
 
-class FitsHPXNext : public FitsFile {
- public:
-  FitsHPXNext(FitsFile* prev);
-};
-
 #endif
diff --git a/saotk/fitsy++/map.C b/saotk/fitsy++/map.C
index 63f8cd1..0da9170 100644
--- a/saotk/fitsy++/map.C
+++ b/saotk/fitsy++/map.C
@@ -255,16 +255,9 @@ FitsFitsNextMap::FitsFitsNextMap(FitsFile* p)
   ext_ = prev->ext();
   inherit_ = prev->inherit();
   byteswap_ = prev->byteswap();
-  orgFits_ = prev->orgFits();
+  endian_ = prev->endian();
   valid_ = 1;
 
-  pWidth_ = prev->pWidth();
-  pHeight_ = prev->pHeight();
-  pDepth_ = prev->pDepth();
-  pBitpix_ = prev->pBitpix();
-  pSkip_ = prev->pSkip();
-  pArch_ = prev->pArch();
-
   coord_ = prev->coord();
   xvalid_ = prev->xvalid();
   xmin_ = prev->xmin();
@@ -310,11 +303,11 @@ FitsArrMap::FitsArrMap()
     return;
 
   // do we byteswap?
+  endian_ = pArch_;
   setByteSwap();
 
   // made it this far, must be valid
   valid_ = 1;
-  orgFits_ = 0;
 }
 
 FitsNRRDMap::FitsNRRDMap()
@@ -367,10 +360,9 @@ FitsNRRDMap::FitsNRRDMap()
     return;
 
   // do we byteswap?
+  endian_ = pArch_;
   setByteSwap();
 
-  orgFits_ = 0;
-
   // so far, so good
   valid_ = 1;
 }
diff --git a/saotk/fitsy++/mapincr.C b/saotk/fitsy++/mapincr.C
index 53dad6d..a133eb7 100644
--- a/saotk/fitsy++/mapincr.C
+++ b/saotk/fitsy++/mapincr.C
@@ -452,16 +452,9 @@ FitsFitsNextMapIncr::FitsFitsNextMapIncr(FitsFile* p)
   ext_ = prev->ext();
   inherit_ = prev->inherit();
   byteswap_ = prev->byteswap();
-  orgFits_ = prev->orgFits();
+  endian_ = prev->endian();
   valid_ = 1;
 
-  pWidth_ = prev->pWidth();
-  pHeight_ = prev->pHeight();
-  pDepth_ = prev->pDepth();
-  pBitpix_ = prev->pBitpix();
-  pSkip_ = prev->pSkip();
-  pArch_ = prev->pArch();
-
   coord_ = prev->coord();
   xvalid_ = prev->xvalid();
   xmin_ = prev->xmin();
@@ -519,10 +512,10 @@ FitsArrMapIncr::FitsArrMapIncr()
   dataSkip_ = pSkip_;
 
   // do we byteswap?
+  endian_ = pArch_;
   setByteSwap();
 
   // made it this far, must be valid
-  orgFits_ = 0;
   valid_ = 1;
 }
 
diff --git a/saotk/fitsy++/nrrd.C b/saotk/fitsy++/nrrd.C
index 8d372f5..cf1d021 100644
--- a/saotk/fitsy++/nrrd.C
+++ b/saotk/fitsy++/nrrd.C
@@ -5,11 +5,17 @@
 #include "nrrd.h"
 #include "head.h"
 
-FitsNRRD::FitsNRRD(FitsFile* fits) : FitsFile(fits)
+FitsNRRD::FitsNRRD(FitsFile* fits)
 {
-  pSize_ = (size_t)pWidth_*pHeight_*pDepth_;
-  pSkip_ = 0;
-  pArch_ = fits->pArch();
+  byteswap_ = fits->byteswap();
+  endian_ = fits->endian();
+
+  pBitpix_ = fits->pBitpix();
+  pWidth_ = fits->pWidth();
+  pHeight_ = fits->pHeight();
+  pDepth_ = fits->pDepth();
+
+  size_ = (size_t)pWidth_*pHeight_*pDepth_;
 }
 
 FitsNRRD::~FitsNRRD()
@@ -48,152 +54,23 @@ template <class T> void FitsNRRDm<T>::uncompress(FitsFile* fits)
   if (!initHeader(fits))
     return;
 
-  T* dest = new T[pSize_];
+  T* dest = new T[size_];
   if (!dest) {
     internalError("Fitsy++ nrrd unable to allocate memory");
     return;
   }
-  memset(dest, 0, pSize_*sizeof(T));
+  memset(dest, 0, size_*sizeof(T));
   compressed(dest, (char*)fits->data(), fits->dataSize()-fits->dataSkip());
 
   data_ = dest;
 
-  dataSize_ = pSize_;
+  dataSize_ = size_;
   dataSkip_ = 0;
 
-  swapBytes(fits->pArch());
-
   // all done
   valid_ = 1;
 }
 
-template<class T> void FitsNRRDm<T>::swapBytes(FitsFile::ArchType arch) 
-{
-  switch (arch) {
-  case FitsFile::NATIVE:
-    break;
-  case FitsFile::BIG:
-    if (!byteswap_) {
-      T* dest = (T*)data_;
-      for (int i=0; i<pSize_; i++)
-	dest[i] = swap(dest+i);
-    }
-    break;
-  case FitsFile::LITTLE:
-    if (byteswap_) {
-      T* dest = (T*)data_;
-      for (int i=0; i<pSize_; i++)
-	dest[i] = swap(dest+i);
-    }
-    break;
-  }
-}
-
-template <> unsigned char FitsNRRDm<unsigned char>::swap(unsigned char* ptr)
-{
-  return *ptr;
-}
-
-template <> short FitsNRRDm<short>::swap(short* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[2];
-    short s;
-  } u;
-
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.s;
-}
-
-template <> unsigned short FitsNRRDm<unsigned short>::swap(unsigned short* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[2];
-    unsigned short s;
-  } u;
-
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.s;
-}
-
-template <> int FitsNRRDm<int>::swap(int* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[4];
-    int i;
-  } u;
-
-  u.c[3] = *p++;
-  u.c[2] = *p++;
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.i;
-}
-
-template <> long long FitsNRRDm<long long>::swap(long long* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[8];
-    long long i;
-  } u;
-
-  u.c[7] = *p++;
-  u.c[6] = *p++;
-  u.c[5] = *p++;
-  u.c[4] = *p++;
-  u.c[3] = *p++;
-  u.c[2] = *p++;
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.i;
-}
-
-template <> float FitsNRRDm<float>::swap(float* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[4];
-    float f;
-  } u;
-
-  u.c[3] = *p++;
-  u.c[2] = *p++;
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.f;
-}
-
-template <> double FitsNRRDm<double>::swap(double* ptr)
-{
-  const char* p = (const char*)ptr;
-  union {
-    char c[8];
-    double d;
-  } u;
-
-  u.c[7] = *p++;
-  u.c[6] = *p++;
-  u.c[5] = *p++;
-  u.c[4] = *p++;
-  u.c[3] = *p++;
-  u.c[2] = *p++;
-  u.c[1] = *p++;
-  u.c[0] = *p;
-
-  return u.d;
-}
-
 template class FitsNRRDm<unsigned char>;
 template class FitsNRRDm<short>;
 template class FitsNRRDm<unsigned short>;
@@ -201,37 +78,3 @@ template class FitsNRRDm<int>;
 template class FitsNRRDm<long long>;
 template class FitsNRRDm<float>;
 template class FitsNRRDm<double>;
-
-FitsNRRDNext::FitsNRRDNext(FitsFile* p)
-{
-  FitsNRRD* prev = (FitsNRRD*)p;
-
-  primary_ = prev->primary();
-  managePrimary_ = 0;
-
-  head_ = prev->head();
-  manageHead_ = 0;
-
-  FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu();
-  data_ = (char*)prev->data() + hdu->imgbytes();
-  dataSize_ = 0;
-  dataSkip_ = 0;
-
-  ext_ = prev->ext();
-  inherit_ = prev->inherit();
-  byteswap_ = prev->byteswap();
-  orgFits_ = prev->orgFits();
-  valid_ = 1;
-
-  pWidth_ = prev->pWidth();
-  pHeight_ = prev->pHeight();
-  pDepth_ = prev->pDepth();
-  pBitpix_ = prev->pBitpix();
-  pSkip_ = prev->pSkip();
-  pArch_ = prev->pArch();
-
-  pEncoding_ = prev->pEncoding();
-  pNRRDDimension_ = prev->pNRRDDimension();
-
-  return;
-}
diff --git a/saotk/fitsy++/nrrd.h b/saotk/fitsy++/nrrd.h
index 6dc20ad..ee62525 100644
--- a/saotk/fitsy++/nrrd.h
+++ b/saotk/fitsy++/nrrd.h
@@ -9,6 +9,9 @@
 
 class FitsNRRD : public FitsFile {
  protected:
+  size_t size_;
+
+ protected:
   int initHeader(FitsFile*);
 
  public:
@@ -22,9 +25,6 @@ class FitsNRRDm : public FitsNRRD {
   void swapBytes(FitsFile::ArchType);
 
  protected:
-  T swap(T* ptr);
-
- protected:
   void uncompress(FitsFile* fits);
   virtual int compressed(T*, char*, size_t) =0;
   
@@ -32,10 +32,5 @@ class FitsNRRDm : public FitsNRRD {
   FitsNRRDm(FitsFile*);
 };
 
-class FitsNRRDNext : public FitsFile {
-public:
-  FitsNRRDNext(FitsFile* prev);
-};
-
 #endif
 
diff --git a/saotk/fitsy++/nrrdgzip.C b/saotk/fitsy++/nrrdgzip.C
index 68a83e1..7e99466 100644
--- a/saotk/fitsy++/nrrdgzip.C
+++ b/saotk/fitsy++/nrrdgzip.C
@@ -27,7 +27,7 @@ template <class T> int FitsNRRDGzipm<T>::compressed(T* dest, char* src,
   zstrm.opaque = NULL;
   zstrm.avail_in = sz;
   zstrm.next_in = (Bytef*)src;
-  zstrm.avail_out = this->pSize_*sizeof(T);
+  zstrm.avail_out = this->size_*sizeof(T);
   zstrm.next_out = (Bytef*)dest;
 
   // look for both zlib and gzip headers
diff --git a/saotk/fitsy++/nrrdparser.C b/saotk/fitsy++/nrrdparser.C
index 6828661..4bd31a3 100644
--- a/saotk/fitsy++/nrrdparser.C
+++ b/saotk/fitsy++/nrrdparser.C
@@ -696,9 +696,9 @@ static const yytype_uint16 yyrline[] =
      291,   292,   293,   294,   295,   298,   299,   300,   301,   302,
      305,   306,   309,   310,   311,   312,   313,   314,   315,   316,
      317,   320,   321,   324,   325,   328,   329,   332,   333,   336,
-     337,   340,   341,   344,   362,   363,   366,   367,   370,   371,
-     374,   375,   378,   379,   382,   383,   384,   387,   388,   391,
-     392,   395,   396
+     337,   340,   341,   344,   361,   362,   365,   366,   369,   370,
+     373,   374,   377,   378,   381,   382,   383,   386,   387,   390,
+     391,   394,   395
 };
 #endif
 
@@ -1972,13 +1972,12 @@ yyreduce:
 	    break;
 	  }
 	  dim++;
-	  nrrd->setpNRRDDimension(dim);
 	;}
     break;
 
 
 /* Line 1267 of yacc.c.  */
-#line 1982 "nrrdparser.C"
+#line 1981 "nrrdparser.C"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -2192,6 +2191,6 @@ yyreturn:
 }
 
 
-#line 399 "nrrdparser.Y"
+#line 398 "nrrdparser.Y"
 
 
diff --git a/saotk/fitsy++/nrrdparser.Y b/saotk/fitsy++/nrrdparser.Y
index 9678990..a8672b3 100644
--- a/saotk/fitsy++/nrrdparser.Y
+++ b/saotk/fitsy++/nrrdparser.Y
@@ -355,7 +355,6 @@ size    : INT
 	    break;
 	  }
 	  dim++;
-	  nrrd->setpNRRDDimension(dim);
 	}
         ;
 
diff --git a/saotk/fitsy++/outchannel.C b/saotk/fitsy++/outchannel.C
index f5b248b..8351acd 100644
--- a/saotk/fitsy++/outchannel.C
+++ b/saotk/fitsy++/outchannel.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tcl.h>
+
 #include "outchannel.h"
 
 OutFitsChannel::OutFitsChannel(Tcl_Interp* interp, const char* ch)
diff --git a/saotk/fitsy++/outfile.C b/saotk/fitsy++/outfile.C
index 49f2f9d..b90e7a7 100644
--- a/saotk/fitsy++/outfile.C
+++ b/saotk/fitsy++/outfile.C
@@ -2,6 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <stdio.h>
 #include "outfile.h"
 
 OutFitsFile::OutFitsFile(const char* fn)
diff --git a/saotk/fitsy++/outfits.h b/saotk/fitsy++/outfits.h
index 1ead96d..d861050 100644
--- a/saotk/fitsy++/outfits.h
+++ b/saotk/fitsy++/outfits.h
@@ -5,8 +5,6 @@
 #ifndef __outfits_h__
 #define __outfits_h__
 
-#include <tcl.h>
-
 #include "util.h"
 
 #define B1KB 1024
diff --git a/saotk/fitsy++/parser.C b/saotk/fitsy++/parser.C
index 7fdd9f2..2b9bdef 100644
--- a/saotk/fitsy++/parser.C
+++ b/saotk/fitsy++/parser.C
@@ -436,7 +436,7 @@ union yyalloc
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  29
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  111
+#define YYNRULES  110
 /* YYNRULES -- Number of states.  */
 #define YYNSTATES  188
 
@@ -494,11 +494,11 @@ static const yytype_uint16 yyprhs[] =
      167,   171,   175,   179,   181,   185,   189,   193,   197,   199,
      203,   207,   210,   212,   214,   216,   218,   224,   228,   236,
      242,   246,   248,   252,   254,   258,   262,   266,   270,   274,
-     278,   282,   286,   290,   292,   293,   295,   297,   299,   301,
-     306,   308,   310,   312,   314,   316,   318,   320,   322,   324,
-     328,   334,   335,   338,   339,   341,   343,   347,   349,   353,
-     357,   361,   365,   369,   371,   373,   375,   377,   379,   381,
-     383,   385
+     278,   282,   286,   290,   292,   294,   296,   298,   300,   305,
+     307,   309,   311,   313,   315,   317,   319,   321,   323,   327,
+     333,   334,   337,   338,   340,   342,   346,   348,   352,   356,
+     360,   364,   368,   370,   372,   374,   376,   378,   380,   382,
+     384
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
@@ -533,16 +533,16 @@ static const yytype_int8 yyrhs[] =
        3,    -1,    36,    45,     3,    -1,    15,    45,     3,    -1,
       16,    45,     3,    -1,    13,    45,     3,    -1,    30,    45,
        3,    -1,     6,    45,    73,    -1,    18,    45,    73,    -1,
-      73,    -1,    -1,     8,    -1,     9,    -1,    23,    -1,    24,
-      -1,    75,    76,    77,    78,    -1,    46,    -1,    47,    -1,
-      48,    -1,    49,    -1,    50,    -1,    51,    -1,    52,    -1,
-      53,    -1,     3,    -1,     3,    54,     3,    -1,     3,    54,
-       3,    54,     3,    -1,    -1,    43,     3,    -1,    -1,    50,
-      -1,    46,    -1,    79,    41,    80,    -1,    80,    -1,    32,
-      45,    81,    -1,    27,    45,    82,    -1,    22,    45,    83,
-      -1,    14,    45,     3,    -1,    28,    45,     3,    -1,    19,
-      -1,    20,    -1,    17,    -1,    33,    -1,    29,    -1,    25,
-      -1,    19,    -1,    26,    -1,    31,    -1
+      73,    -1,     8,    -1,     9,    -1,    23,    -1,    24,    -1,
+      75,    76,    77,    78,    -1,    46,    -1,    47,    -1,    48,
+      -1,    49,    -1,    50,    -1,    51,    -1,    52,    -1,    53,
+      -1,     3,    -1,     3,    54,     3,    -1,     3,    54,     3,
+      54,     3,    -1,    -1,    43,     3,    -1,    -1,    50,    -1,
+      46,    -1,    79,    41,    80,    -1,    80,    -1,    32,    45,
+      81,    -1,    27,    45,    82,    -1,    22,    45,    83,    -1,
+      14,    45,     3,    -1,    28,    45,     3,    -1,    19,    -1,
+      20,    -1,    17,    -1,    33,    -1,    29,    -1,    25,    -1,
+      19,    -1,    26,    -1,    31,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
@@ -550,16 +550,16 @@ static const yytype_uint16 yyrline[] =
 {
        0,    82,    82,    83,    84,    85,    86,    87,    88,    89,
       90,    91,    92,    93,    94,    94,    95,    96,    97,    98,
-      98,   101,   102,   111,   112,   115,   116,   119,   121,   122,
-     123,   128,   134,   140,   149,   151,   156,   158,   163,   166,
-     168,   173,   175,   180,   183,   185,   190,   192,   197,   200,
-     202,   203,   206,   207,   208,   209,   212,   213,   214,   215,
-     216,   217,   220,   221,   224,   225,   226,   227,   228,   229,
-     230,   231,   232,   233,   236,   237,   238,   239,   240,   243,
-     246,   247,   248,   249,   250,   251,   252,   253,   256,   257,
-     258,   262,   263,   266,   267,   268,   271,   272,   275,   276,
-     277,   278,   279,   282,   283,   284,   285,   288,   289,   292,
-     293,   294
+      98,   102,   103,   112,   113,   116,   117,   120,   122,   123,
+     124,   129,   135,   141,   150,   152,   157,   159,   164,   167,
+     169,   174,   176,   181,   184,   186,   191,   193,   198,   201,
+     203,   204,   207,   208,   209,   210,   213,   214,   215,   216,
+     217,   218,   221,   222,   225,   226,   227,   228,   229,   230,
+     231,   232,   233,   234,   237,   238,   239,   240,   243,   246,
+     247,   248,   249,   250,   251,   252,   253,   256,   257,   258,
+     262,   263,   266,   267,   268,   271,   272,   275,   276,   277,
+     278,   279,   282,   283,   284,   285,   288,   289,   292,   293,
+     294
 };
 #endif
 
@@ -606,11 +606,11 @@ static const yytype_uint8 yyr1[] =
       65,    65,    65,    65,    66,    66,    66,    66,    66,    67,
       68,    68,    69,    69,    69,    69,    70,    70,    70,    70,
       70,    70,    71,    71,    72,    72,    72,    72,    72,    72,
-      72,    72,    72,    72,    73,    73,    73,    73,    73,    74,
-      75,    75,    75,    75,    75,    75,    75,    75,    76,    76,
-      76,    77,    77,    78,    78,    78,    79,    79,    80,    80,
-      80,    80,    80,    81,    81,    81,    81,    82,    82,    83,
-      83,    83
+      72,    72,    72,    72,    73,    73,    73,    73,    74,    75,
+      75,    75,    75,    75,    75,    75,    75,    76,    76,    76,
+      77,    77,    78,    78,    78,    79,    79,    80,    80,    80,
+      80,    80,    81,    81,    81,    81,    82,    82,    83,    83,
+      83
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -623,11 +623,11 @@ static const yytype_uint8 yyr2[] =
        3,     3,     3,     1,     3,     3,     3,     3,     1,     3,
        3,     2,     1,     1,     1,     1,     5,     3,     7,     5,
        3,     1,     3,     1,     3,     3,     3,     3,     3,     3,
-       3,     3,     3,     1,     0,     1,     1,     1,     1,     4,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     3,
-       5,     0,     2,     0,     1,     1,     3,     1,     3,     3,
-       3,     3,     3,     1,     1,     1,     1,     1,     1,     1,
-       1,     1
+       3,     3,     3,     1,     1,     1,     1,     1,     4,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     3,     5,
+       0,     2,     0,     1,     1,     3,     1,     3,     3,     3,
+       3,     3,     1,     1,     1,     1,     1,     1,     1,     1,
+       1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -635,25 +635,25 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       0,    19,    22,     0,     2,     0,     1,    74,     3,     9,
-       7,    20,     0,     0,     0,    14,    75,    76,    52,    53,
-      54,     0,     0,     0,     0,     0,    55,     0,    77,    78,
+       0,    19,    22,     0,     2,     0,     1,     0,     3,     9,
+       7,    20,     0,     0,     0,    14,    74,    75,    52,    53,
+      54,     0,     0,     0,     0,     0,    55,     0,    76,    77,
        0,     0,     0,     0,     0,     0,     0,    38,     0,     0,
-       0,     0,     0,     0,    63,    73,     0,    97,     0,     4,
-       5,     0,     8,    24,    26,     0,     0,    23,    25,    74,
-       0,     0,     0,     0,     0,    74,     0,     0,     0,     0,
+       0,     0,     0,     0,    63,    73,     0,    96,     0,     4,
+       5,     0,     8,    24,    26,     0,     0,    23,    25,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,    27,     0,
-      49,    61,     0,     0,    51,    12,    74,    16,     0,     0,
-       6,    36,    37,    34,    35,    71,     0,    69,   101,    67,
-      68,    72,   109,   110,   111,   100,   108,   107,    99,   102,
-      70,   105,   103,   104,   106,    98,    64,    65,    66,    10,
+      49,    61,     0,     0,    51,    12,     0,    16,     0,     0,
+       6,    36,    37,    34,    35,    71,     0,    69,   100,    67,
+      68,    72,   108,   109,   110,    99,   107,   106,    98,   101,
+      70,   104,   102,   103,   105,    97,    64,    65,    66,    10,
       11,    18,     0,    43,    28,     0,     0,    50,    13,    62,
-      17,    96,     0,    80,    81,    82,    83,    84,    85,    86,
-      87,     0,     0,     0,     0,     0,    57,    60,     0,    30,
-      32,     0,    88,    91,    41,    42,    39,    40,     0,    48,
-      29,     0,     0,     0,    15,     0,     0,    93,     0,     0,
-      59,    56,     0,    31,    33,    89,    92,    95,    94,    79,
-      46,    47,    44,    45,     0,     0,    58,    90
+      17,    95,     0,    79,    80,    81,    82,    83,    84,    85,
+      86,     0,     0,     0,     0,     0,    57,    60,     0,    30,
+      32,     0,    87,    90,    41,    42,    39,    40,     0,    48,
+      29,     0,     0,     0,    15,     0,     0,    92,     0,     0,
+      59,    56,     0,    31,    33,    88,    91,    94,    93,    78,
+      46,    47,    44,    45,     0,     0,    58,    89
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
@@ -1615,37 +1615,37 @@ yyreduce:
     break;
 
   case 20:
-#line 98 "parser.Y"
-    {ff->setpFilter(ff_filter);;}
+#line 99 "parser.Y"
+    {ff->setValid(1); ff->setpFilter(ff_filter);;}
     break;
 
   case 22:
-#line 102 "parser.Y"
+#line 103 "parser.Y"
     {ff->setpName((yyvsp[(1) - (1)].str));;}
     break;
 
   case 23:
-#line 111 "parser.Y"
+#line 112 "parser.Y"
     {ff->setpExt((yyvsp[(2) - (3)].str));;}
     break;
 
   case 24:
-#line 112 "parser.Y"
+#line 113 "parser.Y"
     {ff->setpIndex((yyvsp[(2) - (3)].integer));;}
     break;
 
   case 25:
-#line 115 "parser.Y"
+#line 116 "parser.Y"
     {ff->setpExt((yyvsp[(1) - (2)].str));;}
     break;
 
   case 26:
-#line 116 "parser.Y"
+#line 117 "parser.Y"
     {ff->setpIndex((yyvsp[(1) - (2)].integer));;}
     break;
 
   case 30:
-#line 124 "parser.Y"
+#line 125 "parser.Y"
     {
 	  ff->setXMin((yyvsp[(3) - (5)].integer)-(yyvsp[(1) - (5)].integer)/2); ff->setXMax((yyvsp[(3) - (5)].integer)+(yyvsp[(1) - (5)].integer)/2); ff->setXValid(1);
 	  ff->setYMin((yyvsp[(5) - (5)].integer)-(yyvsp[(1) - (5)].integer)/2); ff->setYMax((yyvsp[(5) - (5)].integer)+(yyvsp[(1) - (5)].integer)/2); ff->setYValid(1);
@@ -1653,7 +1653,7 @@ yyreduce:
     break;
 
   case 31:
-#line 129 "parser.Y"
+#line 130 "parser.Y"
     {
 	  ff->setXMin((yyvsp[(3) - (7)].integer)-(yyvsp[(1) - (7)].integer)/2); ff->setXMax((yyvsp[(3) - (7)].integer)+(yyvsp[(1) - (7)].integer)/2); ff->setXValid(1);
 	  ff->setYMin((yyvsp[(5) - (7)].integer)-(yyvsp[(1) - (7)].integer)/2); ff->setYMax((yyvsp[(5) - (7)].integer)+(yyvsp[(1) - (7)].integer)/2); ff->setYValid(1);
@@ -1662,7 +1662,7 @@ yyreduce:
     break;
 
   case 32:
-#line 135 "parser.Y"
+#line 136 "parser.Y"
     {
 	  ff->setXMin((yyvsp[(3) - (5)].integer)-(yyvsp[(1) - (5)].integer)/2); ff->setXMax((yyvsp[(3) - (5)].integer)+(yyvsp[(1) - (5)].integer)/2); ff->setXValid(1);
 	  ff->setYMin((yyvsp[(5) - (5)].integer)-(yyvsp[(1) - (5)].integer)/2); ff->setYMax((yyvsp[(5) - (5)].integer)+(yyvsp[(1) - (5)].integer)/2); ff->setYValid(1);
@@ -1671,7 +1671,7 @@ yyreduce:
     break;
 
   case 33:
-#line 141 "parser.Y"
+#line 142 "parser.Y"
     {
 	  ff->setXMin((yyvsp[(3) - (7)].integer)-(yyvsp[(1) - (7)].integer)/2); ff->setXMax((yyvsp[(3) - (7)].integer)+(yyvsp[(1) - (7)].integer)/2); ff->setXValid(1);
 	  ff->setYMin((yyvsp[(5) - (7)].integer)-(yyvsp[(1) - (7)].integer)/2); ff->setYMax((yyvsp[(5) - (7)].integer)+(yyvsp[(1) - (7)].integer)/2); ff->setYValid(1);
@@ -1681,12 +1681,12 @@ yyreduce:
     break;
 
   case 34:
-#line 150 "parser.Y"
+#line 151 "parser.Y"
     {ff->setXMin((yyvsp[(1) - (3)].integer)); ff->setXMax((yyvsp[(3) - (3)].integer)); ff->setXValid(1);;}
     break;
 
   case 35:
-#line 152 "parser.Y"
+#line 153 "parser.Y"
     {
 	  ff->setXMin((yyvsp[(1) - (3)].integer)); ff->setXMax((yyvsp[(3) - (3)].integer)); ff->setXValid(1);
 	  ff->setCoord(1);
@@ -1694,12 +1694,12 @@ yyreduce:
     break;
 
   case 36:
-#line 157 "parser.Y"
+#line 158 "parser.Y"
     {ff->setXMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setXMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setXValid(1);;}
     break;
 
   case 37:
-#line 159 "parser.Y"
+#line 160 "parser.Y"
     {
 	  ff->setXMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setXMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setXValid(1);
 	  ff->setCoord(1);
@@ -1707,17 +1707,17 @@ yyreduce:
     break;
 
   case 38:
-#line 163 "parser.Y"
+#line 164 "parser.Y"
     {ff->setXValid(0);;}
     break;
 
   case 39:
-#line 167 "parser.Y"
+#line 168 "parser.Y"
     {ff->setYMin((yyvsp[(1) - (3)].integer)); ff->setYMax((yyvsp[(3) - (3)].integer)); ff->setYValid(1);;}
     break;
 
   case 40:
-#line 169 "parser.Y"
+#line 170 "parser.Y"
     {
 	  ff->setYMin((yyvsp[(1) - (3)].integer)); ff->setYMax((yyvsp[(3) - (3)].integer)); ff->setYValid(1);
 	  ff->setCoord(1);
@@ -1725,12 +1725,12 @@ yyreduce:
     break;
 
   case 41:
-#line 174 "parser.Y"
+#line 175 "parser.Y"
     {ff->setYMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setYMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setYValid(1);;}
     break;
 
   case 42:
-#line 176 "parser.Y"
+#line 177 "parser.Y"
     {
 	  ff->setYMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setYMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setYValid(1);
 	  ff->setCoord(1);
@@ -1738,17 +1738,17 @@ yyreduce:
     break;
 
   case 43:
-#line 180 "parser.Y"
+#line 181 "parser.Y"
     {ff->setYValid(0);;}
     break;
 
   case 44:
-#line 184 "parser.Y"
+#line 185 "parser.Y"
     {ff->setZMin((yyvsp[(1) - (3)].integer)); ff->setZMax((yyvsp[(3) - (3)].integer)); ff->setZValid(1);;}
     break;
 
   case 45:
-#line 186 "parser.Y"
+#line 187 "parser.Y"
     {
 	  ff->setZMin((yyvsp[(1) - (3)].integer)); ff->setZMax((yyvsp[(3) - (3)].integer)); ff->setZValid(1);
 	  ff->setCoord(1);
@@ -1756,12 +1756,12 @@ yyreduce:
     break;
 
   case 46:
-#line 191 "parser.Y"
+#line 192 "parser.Y"
     {ff->setZMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setZMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setZValid(1);;}
     break;
 
   case 47:
-#line 193 "parser.Y"
+#line 194 "parser.Y"
     {
 	  ff->setZMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setZMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setZValid(1);
 	  ff->setCoord(1);
@@ -1769,243 +1769,238 @@ yyreduce:
     break;
 
   case 48:
-#line 197 "parser.Y"
+#line 198 "parser.Y"
     {ff->setZValid(0);;}
     break;
 
   case 56:
-#line 212 "parser.Y"
+#line 213 "parser.Y"
     {ff->setpBinXY((yyvsp[(2) - (5)].str),(yyvsp[(4) - (5)].str));;}
     break;
 
   case 57:
-#line 213 "parser.Y"
+#line 214 "parser.Y"
     {ff->setpBinXY((yyvsp[(1) - (3)].str),(yyvsp[(3) - (3)].str));;}
     break;
 
   case 58:
-#line 214 "parser.Y"
+#line 215 "parser.Y"
     {ff->setpBinXYZ((yyvsp[(2) - (7)].str),(yyvsp[(4) - (7)].str),(yyvsp[(6) - (7)].str));;}
     break;
 
   case 59:
-#line 215 "parser.Y"
+#line 216 "parser.Y"
     {ff->setpBinXYZ((yyvsp[(1) - (5)].str),(yyvsp[(3) - (5)].str),(yyvsp[(5) - (5)].str));;}
     break;
 
   case 60:
-#line 216 "parser.Y"
+#line 217 "parser.Y"
     {ff->setpBinZ((yyvsp[(2) - (3)].str));;}
     break;
 
   case 61:
-#line 217 "parser.Y"
+#line 218 "parser.Y"
     {ff->setpBinZ((yyvsp[(1) - (1)].str));;}
     break;
 
   case 64:
-#line 224 "parser.Y"
+#line 225 "parser.Y"
     {ff->setpWidth((yyvsp[(3) - (3)].integer));;}
     break;
 
   case 65:
-#line 225 "parser.Y"
+#line 226 "parser.Y"
     {ff->setpHeight((yyvsp[(3) - (3)].integer));;}
     break;
 
   case 66:
-#line 226 "parser.Y"
+#line 227 "parser.Y"
     {ff->setpDepth((yyvsp[(3) - (3)].integer));;}
     break;
 
   case 67:
-#line 227 "parser.Y"
+#line 228 "parser.Y"
     {ff->setpWidth((yyvsp[(3) - (3)].integer));ff->setpHeight((yyvsp[(3) - (3)].integer));;}
     break;
 
   case 68:
-#line 228 "parser.Y"
+#line 229 "parser.Y"
     {ff->setpWidth((yyvsp[(3) - (3)].integer));ff->setpHeight((yyvsp[(3) - (3)].integer));;}
     break;
 
   case 69:
-#line 229 "parser.Y"
+#line 230 "parser.Y"
     {ff->setpBitpix((yyvsp[(3) - (3)].integer));;}
     break;
 
   case 70:
-#line 230 "parser.Y"
+#line 231 "parser.Y"
     {ff->setpSkip((yyvsp[(3) - (3)].integer));;}
     break;
 
   case 71:
-#line 231 "parser.Y"
+#line 232 "parser.Y"
     {ff->setpArch((FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;}
     break;
 
   case 72:
-#line 232 "parser.Y"
+#line 233 "parser.Y"
     {ff->setpArch((FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;}
     break;
 
   case 73:
-#line 233 "parser.Y"
+#line 234 "parser.Y"
     {ff->setpArch((FitsFile::ArchType)(yyvsp[(1) - (1)].integer));;}
     break;
 
   case 74:
-#line 236 "parser.Y"
-    {(yyval.integer) = FitsFile::BIG;;}
-    break;
-
-  case 75:
 #line 237 "parser.Y"
     {(yyval.integer) = FitsFile::BIG;;}
     break;
 
-  case 76:
+  case 75:
 #line 238 "parser.Y"
     {(yyval.integer) = FitsFile::BIG;;}
     break;
 
-  case 77:
+  case 76:
 #line 239 "parser.Y"
     {(yyval.integer) = FitsFile::LITTLE;;}
     break;
 
-  case 78:
+  case 77:
 #line 240 "parser.Y"
     {(yyval.integer) = FitsFile::LITTLE;;}
     break;
 
-  case 80:
+  case 79:
 #line 246 "parser.Y"
     {ff->setpBitpix(8);;}
     break;
 
-  case 81:
+  case 80:
 #line 247 "parser.Y"
     {ff->setpBitpix(16);;}
     break;
 
-  case 82:
+  case 81:
 #line 248 "parser.Y"
     {ff->setpBitpix(-16);;}
     break;
 
-  case 83:
+  case 82:
 #line 249 "parser.Y"
     {ff->setpBitpix(32);;}
     break;
 
-  case 84:
+  case 83:
 #line 250 "parser.Y"
     {ff->setpBitpix(64);;}
     break;
 
-  case 85:
+  case 84:
 #line 251 "parser.Y"
     {ff->setpBitpix(-32);;}
     break;
 
-  case 86:
+  case 85:
 #line 252 "parser.Y"
     {ff->setpBitpix(-32);;}
     break;
 
-  case 87:
+  case 86:
 #line 253 "parser.Y"
     {ff->setpBitpix(-64);;}
     break;
 
-  case 88:
+  case 87:
 #line 256 "parser.Y"
     {ff->setpWidth((yyvsp[(1) - (1)].integer));ff->setpHeight((yyvsp[(1) - (1)].integer));;}
     break;
 
-  case 89:
+  case 88:
 #line 257 "parser.Y"
     {ff->setpWidth((yyvsp[(1) - (3)].integer));ff->setpHeight((yyvsp[(3) - (3)].integer));;}
     break;
 
-  case 90:
+  case 89:
 #line 259 "parser.Y"
     {ff->setpWidth((yyvsp[(1) - (5)].integer));ff->setpHeight((yyvsp[(3) - (5)].integer));ff->setpDepth((yyvsp[(5) - (5)].integer));;}
     break;
 
-  case 92:
+  case 91:
 #line 263 "parser.Y"
     {ff->setpSkip((yyvsp[(2) - (2)].integer));;}
     break;
 
-  case 94:
+  case 93:
 #line 267 "parser.Y"
     {ff->setpArch(FitsFile::LITTLE);;}
     break;
 
-  case 95:
+  case 94:
 #line 268 "parser.Y"
     {ff->setpArch(FitsFile::BIG);;}
     break;
 
-  case 101:
+  case 100:
 #line 278 "parser.Y"
     {ff->setpHPXColumn((yyvsp[(3) - (3)].integer));;}
     break;
 
-  case 102:
+  case 101:
 #line 279 "parser.Y"
     {ff->setpHPXQuad((yyvsp[(3) - (3)].integer));;}
     break;
 
-  case 103:
+  case 102:
 #line 282 "parser.Y"
     {ff->setpHPXSystem(FitsHPX::EQU);;}
     break;
 
-  case 104:
+  case 103:
 #line 283 "parser.Y"
     {ff->setpHPXSystem(FitsHPX::GAL);;}
     break;
 
-  case 105:
+  case 104:
 #line 284 "parser.Y"
     {ff->setpHPXSystem(FitsHPX::ECL);;}
     break;
 
-  case 106:
+  case 105:
 #line 285 "parser.Y"
     {ff->setpHPXSystem(FitsHPX::UNKNOWN);;}
     break;
 
-  case 107:
+  case 106:
 #line 288 "parser.Y"
     {ff->setpHPXOrder(FitsHPX::RING);;}
     break;
 
-  case 108:
+  case 107:
 #line 289 "parser.Y"
     {ff->setpHPXOrder(FitsHPX::NESTED);;}
     break;
 
-  case 109:
+  case 108:
 #line 292 "parser.Y"
     {ff->setpHPXLayout(FitsHPX::EQUATOR);;}
     break;
 
-  case 110:
+  case 109:
 #line 293 "parser.Y"
     {ff->setpHPXLayout(FitsHPX::NORTH);;}
     break;
 
-  case 111:
+  case 110:
 #line 294 "parser.Y"
     {ff->setpHPXLayout(FitsHPX::SOUTH);;}
     break;
 
 
 /* Line 1267 of yacc.c.  */
-#line 2009 "parser.C"
+#line 2004 "parser.C"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
diff --git a/saotk/fitsy++/parser.Y b/saotk/fitsy++/parser.Y
index 91171d8..70f6d43 100644
--- a/saotk/fitsy++/parser.Y
+++ b/saotk/fitsy++/parser.Y
@@ -95,7 +95,8 @@ command	: filename
 	| filename '[' hpxs ']'
 	| filename '[' hpxs ']' sect
 	| filename '[' extb hpxs ']'
-	| error {GOTOFILT(0)} STRING {ff->setpFilter(ff_filter);}
+	| error {GOTOFILT(0)} STRING 
+	  {ff->setValid(1); ff->setpFilter(ff_filter);}
 	;
 
 filename : /* empty */
@@ -233,8 +234,7 @@ arr	: XDIM_ '=' INT {ff->setpWidth($3);}
 	| endian {ff->setpArch((FitsFile::ArchType)$1);} 
 	;
 
-endian	: /* empty */ {$$ = FitsFile::BIG;}
-	| BIG_ {$$ = FitsFile::BIG;}
+endian	: BIG_ {$$ = FitsFile::BIG;}
 	| BIGENDIAN_ {$$ = FitsFile::BIG;}
 	| LITTLE_ {$$ = FitsFile::LITTLE;}
 	| LITTLEENDIAN_ {$$ = FitsFile::LITTLE;}
diff --git a/saotk/fitsy++/photo.C b/saotk/fitsy++/photo.C
index 3ca380e..9e20c9d 100644
--- a/saotk/fitsy++/photo.C
+++ b/saotk/fitsy++/photo.C
@@ -7,6 +7,8 @@
 #include <iomanip>
 using namespace std;
 
+#include <tk.h>
+
 #include "photo.h"
 
 FitsPhoto::FitsPhoto(Tcl_Interp* interp, const char* ph)
@@ -60,8 +62,8 @@ FitsPhoto::FitsPhoto(Tcl_Interp* interp, const char* ph)
 
   // made it this far, must be valid
   byteswap_ = 0;
+  endian_ = lsb() ? LITTLE : BIG;
   valid_ = 1;
-  orgFits_ = 0;
 }
 
 FitsPhoto::~FitsPhoto()
@@ -118,8 +120,8 @@ FitsPhotoCube::FitsPhotoCube(Tcl_Interp* interp, const char* ph)
 
   // made it this far, must be valid
   byteswap_ = 0;
+  endian_ = lsb() ? LITTLE : BIG;
   valid_ = 1;
-  orgFits_ = 0;
 }
 
 FitsPhotoCube::~FitsPhotoCube()
@@ -144,15 +146,8 @@ FitsPhotoCubeNext::FitsPhotoCubeNext(FitsFile* prev)
   ext_ = prev->ext();
   inherit_ = head_->inherit();
   byteswap_ = prev->byteswap();
-  orgFits_ = prev->orgFits();
+  endian_ = prev->endian();
   valid_ = 1;
 
-  pWidth_ = prev->pWidth();
-  pHeight_ = prev->pHeight();
-  pDepth_ = prev->pDepth();
-  pBitpix_ = prev->pBitpix();
-  pSkip_ = prev->pSkip();
-  pArch_ = prev->pArch();
-
   return;
 }
diff --git a/saotk/fitsy++/photo.h b/saotk/fitsy++/photo.h
index 95df744..eee2d66 100644
--- a/saotk/fitsy++/photo.h
+++ b/saotk/fitsy++/photo.h
@@ -5,6 +5,8 @@
 #ifndef __fitsphoto_h__
 #define __fitsphoto_h__
 
+#include <tcl.h>
+
 #include "vector.h"
 #include "file.h"
 
diff --git a/saotk/fitsy++/savefits.C b/saotk/fitsy++/savefits.C
index 9d87000..bc17c44 100644
--- a/saotk/fitsy++/savefits.C
+++ b/saotk/fitsy++/savefits.C
@@ -7,6 +7,8 @@
 #include <iomanip>
 using namespace std;
 
+#include <tcl.h>
+
 #include "file.h"
 #include "outfile.h"
 #include "outchannel.h"
@@ -225,23 +227,13 @@ int FitsFile::saveFits(OutFitsStream& str)
 {
   FitsImageHDU* hdu = (FitsImageHDU*)(head()->hdu());
 
-  if (orgFits_)
+  switch (endian_) {
+  case BIG:
     str.write((char*)data(), hdu->imgbytes());
-  else {
-    switch (pArch_) {
-    case NATIVE:
-      if (!lsb())
-	str.write((char*)data(), hdu->imgbytes());
-      else
-	str.writeSwap((char*)data(), hdu->imgbytes(), head()->bitpix());
-      break;
-    case BIG:
-      str.write((char*)data(), hdu->imgbytes());
-      break;
-    case LITTLE:
-      str.writeSwap((char*)data(), hdu->imgbytes(), head()->bitpix());
-      break;
-    }
+    break;
+  case LITTLE:
+    str.writeSwap((char*)data(), hdu->imgbytes(), head()->bitpix());
+    break;
   }
   
   return hdu->imgbytes();
@@ -277,23 +269,13 @@ int FitsFile::saveFitsTable(OutFitsStream& str)
   // our data may be short (mmap or bad fits), so write valid data
   // then write the pad, becareful with arch, if array
 
-  if (orgFits_)
+  switch (endian_) {
+  case BIG:
     str.write((char*)data(), head()->allbytes());
-  else {
-    switch (pArch_) {
-    case NATIVE:
-      if (!lsb())
-	str.write((char*)data(), head()->allbytes());
-      else
-	str.writeSwap((char*)data(), head()->allbytes(), head()->bitpix());
-      break;
-    case BIG:
-      str.write((char*)data(), head()->allbytes());
-      break;
-    case LITTLE:
-      str.writeSwap((char*)data(), head()->allbytes(), head()->bitpix());
-      break;
-    }
+    break;
+  case LITTLE:
+    str.writeSwap((char*)data(), head()->allbytes(), head()->bitpix());
+    break;
   }
   cnt += head()->allbytes();
 
@@ -367,59 +349,16 @@ int FitsFile::saveFitsIIS(OutFitsStream& str, Vector& iisz)
   return size*sizeof(float);
 }
 
-int FitsFile::saveArray(OutFitsStream& str, ArchType endian)
+int FitsFile::saveArray(OutFitsStream& str, ArchType which)
 {
   // only save one slice
   size_t size = head_->naxis(0)*head_->naxis(1)*abs(head_->bitpix()/8);
   int bitpix = head_->bitpix();
 
-  switch (endian) {
-  case NATIVE:
-  case BIG:
-    {
-      if (orgFits_)
-	str.write((char*)data(), size);
-      else {
-	switch (pArch_) {
-	case NATIVE:
-	  if (!lsb())
-	    str.write((char*)data(), size);
-	  else
-	    str.writeSwap((char*)data(), size, bitpix);
-	  break;
-	case BIG:
-	  str.write((char*)data(), size);
-	  break;
-	case LITTLE:
-	  str.writeSwap((char*)data(), size, bitpix);
-	  break;
-	}
-      }
-    }
-    break;
-  case LITTLE:
-    {
-      if (orgFits_)
-	str.writeSwap((char*)data(), size, bitpix);
-      else {
-	switch (pArch_) {
-	case NATIVE:
-	  if (!lsb())
-	    str.writeSwap((char*)data(), size, bitpix);
-	  else
-	    str.write((char*)data(), size);
-	  break;
-	case BIG:
-	  str.writeSwap((char*)data(), size, bitpix);
-	  break;
-	case LITTLE:
-	  str.write((char*)data(), size);
-	  break;
-	}
-      }
-    }
-    break;
-  }
+  if (which == endian_)
+    str.write((char*)data(), size);
+  else
+    str.writeSwap((char*)data(), size, bitpix);
 
   return size;
 }
diff --git a/saotk/fitsy++/smap.C b/saotk/fitsy++/smap.C
index f2e93b6..5a0e3ea 100644
--- a/saotk/fitsy++/smap.C
+++ b/saotk/fitsy++/smap.C
@@ -139,10 +139,9 @@ FitsENVISMap::FitsENVISMap()
   }
 
   // do we byteswap?
+  endian_ = pArch_;
   setByteSwap();
 
-  orgFits_ = 0;
-
   // so far, so good
   valid_ = 1;
 }
@@ -165,16 +164,9 @@ FitsFitsNextSMap::FitsFitsNextSMap(FitsFile* p)
   ext_ = prev->ext();
   inherit_ = prev->inherit();
   byteswap_ = prev->byteswap();
-  orgFits_ = prev->orgFits();
+  endian_ = prev->endian();
   valid_ = 1;
 
-  pWidth_ = prev->pWidth();
-  pHeight_ = prev->pHeight();
-  pDepth_ = prev->pDepth();
-  pBitpix_ = prev->pBitpix();
-  pSkip_ = prev->pSkip();
-  pArch_ = prev->pArch();
-
   coord_ = prev->coord();
   xvalid_ = prev->xvalid();
   xmin_ = prev->xmin();
diff --git a/saotk/fitsy++/strm.C b/saotk/fitsy++/strm.C
index 3bc72b2..7dbfa1a 100644
--- a/saotk/fitsy++/strm.C
+++ b/saotk/fitsy++/strm.C
@@ -6,6 +6,8 @@
 #include <stdio.h>
 #include <sys/socket.h>
 
+#include <tcl.h>
+
 #include "strm.h"
 #include "util.h"
 
@@ -566,16 +568,9 @@ template<class T> FitsFitsNextStream<T>::FitsFitsNextStream(FitsFile* p)
   this->ext_ = prev->ext();
   this->inherit_ = prev->inherit();
   this->byteswap_ = prev->byteswap();
-  this->orgFits_ = prev->orgFits();
+  this->endian_ = prev->endian();
   this->valid_ = 1;
 
-  this->pWidth_ = prev->pWidth();
-  this->pHeight_ = prev->pHeight();
-  this->pDepth_ = prev->pDepth();
-  this->pBitpix_ = prev->pBitpix();
-  this->pSkip_ = prev->pSkip();
-  this->pArch_ = prev->pArch();
-
   this->coord_ = prev->coord();
   this->xvalid_ = prev->xvalid();
   this->xmin_ = prev->xmin();
@@ -632,11 +627,11 @@ template<class T> FitsArrStream<T>::FitsArrStream(FitsFile::FlushMode f)
   }
 
   // do we need to byteswap?
+  this->endian_ = this->pArch_;
   this->setByteSwap();
 
   // made it this far, must be good
   this->valid_ = 1;
-  this->orgFits_ = 0;
 
   if (this->flush_ == this->FLUSH)
     this->skipEnd();
@@ -693,11 +688,11 @@ template<class T> FitsNRRDStream<T>::FitsNRRDStream(FitsFile::FlushMode f)
   }
 
   // do we need to byteswap?
+  this->endian_ = this->pArch_;
   this->setByteSwap();
 
   // made it this far, must be good
   this->valid_ = 1;
-  this->orgFits_ = 0;
 
   if (this->flush_ == this->FLUSH)
     this->skipEnd();
diff --git a/saotk/fitsy++/var.C b/saotk/fitsy++/var.C
index 64d7273..82b1386 100644
--- a/saotk/fitsy++/var.C
+++ b/saotk/fitsy++/var.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tcl.h>
+
 #include "var.h"
 
 FitsVar::FitsVar(Tcl_Interp* interp, const char* var, const char* fn)
diff --git a/saotk/frame/Makefile b/saotk/frame/Makefile
index ade9fe0..a054bf7 100644
--- a/saotk/frame/Makefile
+++ b/saotk/frame/Makefile
@@ -8,7 +8,7 @@ CXXFLAGS = $(CXXOPT) -w \
 	-I/usr/include/libxml2 \
 	-I../../$(ASTDIR)
 
-SS	= \
+SRC	= \
 	annulus.C \
 	base.C \
 	basecommand.C \
@@ -91,17 +91,7 @@ SS	= \
 	segment.C \
 	tag.C \
 	text.C \
-	vect.C
-
-ifeq ($(OS),unix)
-SSP =	\
-	colorscalepseudo8.C \
-	framepseudo.C \
-	framepseudocolor.C \
-	framepseudocolor8.C
-endif
-
-SRC	= $(SS) $(SSP) \
+	vect.C \
 	ciaoparser.C \
 	ciaolex.C \
 	ds9parser.C \
@@ -120,20 +110,13 @@ SRC	= $(SS) $(SSP) \
 INCLS	= $(wildcard *.h)
 OBJS	= $(SRC:%.C=%.o)
 
-all	: $(OBJS) TAGS
+all	: $(OBJS)
 
 clean	: FORCE
 	rm -f core *~ *#
 
 distclean : clean
-	rm -f TAGS *.o parser.output ds9parser.output ciaoparser.output prosparser.output tngparser.output saoparser.output xyparser.output
-
-ifdef DEPENDS
-TAGS	: $(SS) $(INCLS)
-	etags $+
-else
-TAGS	: FORCE
-endif
+	rm -f *.o parser.output ds9parser.output ciaoparser.output prosparser.output tngparser.output saoparser.output xyparser.output
 
 parsers	: ciaoparser ds9parser parser prosparser saoparser tngparser xyparser
 
@@ -166,12 +149,3 @@ xyparser : FORCE
 	flex -Pxy -oxylex.C xylex.L
 
 FORCE	:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SS:.C=.d)
-endif
diff --git a/saotk/frame/annulus.C b/saotk/frame/annulus.C
index b447921..8f90673 100644
--- a/saotk/frame/annulus.C
+++ b/saotk/frame/annulus.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "annulus.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/base.C b/saotk/frame/base.C
index d8d77b2..69777df 100644
--- a/saotk/frame/base.C
+++ b/saotk/frame/base.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tk.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
@@ -2163,7 +2163,7 @@ void Base::macosxCrosshair()
   if (!useCrosshair)
     return;
 
-  Vector rr = mapFromRef(crosshair,WIDGET);
+  Vector rr = mapFromRef(crosshair,Coord::WIDGET);
   Vector aa = Vector(rr[0],1) * widgetToCanvas;
   Vector bb = Vector(rr[0],options->height) * widgetToCanvas;
   Vector cc = Vector(1,rr[1]) * widgetToCanvas;
diff --git a/saotk/frame/base.h b/saotk/frame/base.h
index f79df88..b7c3563 100644
--- a/saotk/frame/base.h
+++ b/saotk/frame/base.h
@@ -120,7 +120,7 @@ public:
   enum UpdateType {MATRIX, BASE, PIXMAP, NOUPDATE};
 
   enum MemType {ALLOC, ALLOCGZ, CHANNEL, MMAP, SMMAP, MMAPINCR, 
-		SHARE, SSHARE, SOCKET, SOCKETGZ, VAR, HIST, COMPRESS, PHOTO};
+		SHARE, SSHARE, SOCKET, SOCKETGZ, VAR, HIST, POST, PHOTO};
   enum MosaicType {NOMOSAIC, IRAF, WCSMOSAIC, WFPC2};
   enum LayerType {IMG, MASK};
   enum LoadMethod {LOADALL, INCR};
@@ -516,7 +516,7 @@ public:
   void macosxContours();
   void macosxCrosshair();
   virtual void macosxGraphics() {}
-  void macosxImage(float, int, int, const Vector&, const Vector&)
+  void macosxImage(float, int, int, const Vector&, const Vector&);
   void macosxMarkers(List<Marker>* ml);
 #endif
 #ifdef _GWIN32
diff --git a/saotk/frame/basebox.C b/saotk/frame/basebox.C
index 59a241d..4845e98 100644
--- a/saotk/frame/basebox.C
+++ b/saotk/frame/basebox.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "basebox.h"
 #include "fitsimage.h"
 
@@ -81,7 +83,7 @@ void BaseBox::renderMACOSX()
   for (int ii=0; ii<numAnnuli_; ii++) {
     Vector vv[numPoints_];
     for (int jj=0; jj<numPoints_; jj++)
-      vv[jj] = parent->mapFromRef(vertices_[ii][jj],CANVAS);
+      vv[jj] = parent->mapFromRef(vertices_[ii][jj],Coord::CANVAS);
     macosxDrawLines(vv, numPoints_);
   }
   deleteVertices();
@@ -135,7 +137,8 @@ void BaseBox::updateHandles()
       handle[ii+4] = fwdMap(Vector((annuli_[ii][0])/2.,0),Coord::CANVAS);
 }
 
-int BaseBox::isIn(const Vector& vv, Coord::InternalSystem sys, int nn)
+
+int BaseBox::isInRef(const Vector& vv, int nn)
 {
   // during resize, annuli_ can be negative
   Vector ss = annuli_[nn].abs();
@@ -144,8 +147,7 @@ int BaseBox::isIn(const Vector& vv, Coord::InternalSystem sys, int nn)
   if (!ss[0] || !ss[1])
     return 0;
 
-  Vector pp = bckMap(vv,sys);
-
+  Vector pp = (Vector&)vv;
   if (pp[0]<-ss[0]/2 || pp[0]>=ss[0]/2 || pp[1]<=-ss[1]/2 || pp[1]>ss[1]/2)
     return 0;
   else
diff --git a/saotk/frame/basebox.h b/saotk/frame/basebox.h
index 9c5d12c..18c7184 100644
--- a/saotk/frame/basebox.h
+++ b/saotk/frame/basebox.h
@@ -23,6 +23,8 @@ class BaseBox : public BaseMarker {
   void vertBPrep(double a1, double a2, double ll, double ul, int ii, int* cnt);
   void vertBSeg(double ang1, double ang2, int ii, int* cnt);
 
+  int isInRef(const Vector& vv, int);
+
 protected:
   virtual void updateHandles();
   Vector intersect(Vector, double);
@@ -52,7 +54,14 @@ public:
   {return isIn(vv, Coord::CANVAS);}
   int isIn(const Vector& vv, Coord::InternalSystem sys)
   {return isIn(vv,sys,numAnnuli_-1);}
-  int isIn(const Vector&, Coord::InternalSystem, int);
+  int isIn(const Vector& vv, Coord::InternalSystem sys, int nn)
+  {return isInRef(bckMap(vv,sys),nn);}
+
+  // valid for non-fixed only
+  int isIn(const Vector& vv, const Matrix& bck)
+  {return isIn(vv,bck,numAnnuli_-1);}
+  int isIn(const Vector& vv, const Matrix& bck, int nn)
+  {return isInRef(vv*bck,nn);}
 };
 
 #endif
diff --git a/saotk/frame/basecommand.C b/saotk/frame/basecommand.C
index 843b908..2de5375 100644
--- a/saotk/frame/basecommand.C
+++ b/saotk/frame/basecommand.C
@@ -5,7 +5,7 @@
 #include <fstream>
 #include "fdstream.hpp"
 
-#include "tcl.h"
+#include <tk.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
diff --git a/saotk/frame/baseellipse.C b/saotk/frame/baseellipse.C
index 092b476..122e09d 100644
--- a/saotk/frame/baseellipse.C
+++ b/saotk/frame/baseellipse.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "baseellipse.h"
 #include "fitsimage.h"
 
@@ -640,7 +642,7 @@ void BaseEllipse::updateHandles()
       handle[ii+4] = fwdMap(Vector(annuli_[ii][0],0),Coord::CANVAS);
 }
 
-int BaseEllipse::isIn(const Vector& vv, Coord::InternalSystem sys, int nn)
+int BaseEllipse::isInRef(const Vector& vv, int nn)
 {
   Vector rr = annuli_[nn];
 
@@ -648,7 +650,7 @@ int BaseEllipse::isIn(const Vector& vv, Coord::InternalSystem sys, int nn)
   if (!rr[0] || !rr[1])
     return 0;
 
-  Vector pp = bckMap(vv,sys);
+  Vector& pp = (Vector&)vv;
   if ((pp[0]*pp[0])/(rr[0]*rr[0]) + (pp[1]*pp[1])/(rr[1]*rr[1]) <= 1)
     return 1;
   else
diff --git a/saotk/frame/baseellipse.h b/saotk/frame/baseellipse.h
index 49a973c..6e053cd 100644
--- a/saotk/frame/baseellipse.h
+++ b/saotk/frame/baseellipse.h
@@ -55,6 +55,8 @@ class BaseEllipse : public BaseMarker {
   virtual void updateHandles();
   Vector intersect(Vector, double);
 
+  int isInRef(const Vector& vv, int);
+
  public:
   BaseEllipse(const BaseEllipse&);
   BaseEllipse(Base* p, const Vector& ctr, 
@@ -71,7 +73,14 @@ class BaseEllipse : public BaseMarker {
   {return isIn(vv, Coord::CANVAS);}
   int isIn(const Vector& vv, Coord::InternalSystem sys)
   {return isIn(vv,sys,numAnnuli_-1);}
-  int isIn(const Vector&, Coord::InternalSystem, int);
+  int isIn(const Vector& vv, Coord::InternalSystem sys, int nn)
+  {return isInRef(bckMap(vv,sys),nn);}
+
+  // valid for non-fixed only
+  int isIn(const Vector& vv, const Matrix& bck)
+  {return isIn(vv,bck,numAnnuli_-1);}
+  int isIn(const Vector& vv, const Matrix& bck, int nn)
+  {return isInRef(vv*bck,nn);}
 };
 
 #endif
diff --git a/saotk/frame/baseline.C b/saotk/frame/baseline.C
index e2a121b..bac82fa 100644
--- a/saotk/frame/baseline.C
+++ b/saotk/frame/baseline.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "baseline.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/basemarker.C b/saotk/frame/basemarker.C
index 191915d..7a70a00 100644
--- a/saotk/frame/basemarker.C
+++ b/saotk/frame/basemarker.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "basemarker.h"
 #include "base.h"
 
diff --git a/saotk/frame/box.C b/saotk/frame/box.C
index d32a815..e211bf8 100644
--- a/saotk/frame/box.C
+++ b/saotk/frame/box.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "box.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/boxannulus.C b/saotk/frame/boxannulus.C
index 0f18adf..817217e 100644
--- a/saotk/frame/boxannulus.C
+++ b/saotk/frame/boxannulus.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "boxannulus.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/bpanda.C b/saotk/frame/bpanda.C
index cb860bf..dd8310d 100644
--- a/saotk/frame/bpanda.C
+++ b/saotk/frame/bpanda.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "bpanda.h"
 #include "fitsimage.h"
 
@@ -123,8 +125,8 @@ void Bpanda::renderMACOSX()
   Vector r1 = annuli_[numAnnuli_-1]/2;
 
   for (int ii=0; ii<numAngles_; ii++) {
-    Vector rr0 = fwdMap(intersect(r0,angles_[ii]),CANVAS);
-    Vector rr1 = fwdMap(intersect(r1,angles_[ii]),CANVAS);
+    Vector rr0 = fwdMap(intersect(r0,angles_[ii]),Coord::CANVAS);
+    Vector rr1 = fwdMap(intersect(r1,angles_[ii]),Coord::CANVAS);
 
     macosxDrawLine(rr0,rr1);
   }
diff --git a/saotk/frame/circle.C b/saotk/frame/circle.C
index 02c7b53..f6d1c9a 100644
--- a/saotk/frame/circle.C
+++ b/saotk/frame/circle.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "circle.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/colorscale.h b/saotk/frame/colorscale.h
index 3d87066..f95edfa 100644
--- a/saotk/frame/colorscale.h
+++ b/saotk/frame/colorscale.h
@@ -5,9 +5,6 @@
 #ifndef __colorscale_h__
 #define __colorscale_h__
 
-#include <tcl.h>
-#include <X11/Xlib.h>
-
 #include "util.h"
 
 // 0 background (white)
diff --git a/saotk/frame/colorscalepseudo8.C b/saotk/frame/colorscalepseudo8.C
deleted file mode 100644
index 1c317bf..0000000
--- a/saotk/frame/colorscalepseudo8.C
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#include "colorscalepseudo8.h"
-#include "base.h"
-
-ColorScalePseudoColor8::ColorScalePseudoColor8(int s) : ColorScale(s)
-{
-  colors_ = new unsigned char[s];
-
-  for (int i=0; i<s; i++)
-    colors_[i] = psIndex_[i];
-}
-
-ColorScalePseudoColor8::~ColorScalePseudoColor8()
-{
-  if (colors_)
-    delete [] colors_;
-}
-
-LinearScalePseudoColor8::LinearScalePseudoColor8(int s, 
-						 unsigned short* indexCells, 
-						 unsigned char* colorCells,
-						 int count)
-  : LinearScale(s, indexCells, colorCells, count), 
-    ColorScalePseudoColor8(s), 
-    ColorScale(s) {}
-
-LogScalePseudoColor8::LogScalePseudoColor8(int s, 
-					   unsigned short* indexCells,
-					   unsigned char* colorCells,
-					   int count, double exp)
-  : LogScale(s, indexCells, colorCells, count, exp),
-    ColorScalePseudoColor8(s),
-    ColorScale(s) {}
-
-PowScalePseudoColor8::PowScalePseudoColor8(int s, 
-					   unsigned short* indexCells,
-					   unsigned char* colorCells,
-					   int count, double exp)
-  : PowScale(s, indexCells, colorCells, count, exp),
-    ColorScalePseudoColor8(s),
-    ColorScale(s) {}
-
-SqrtScalePseudoColor8::SqrtScalePseudoColor8(int s,
-					     unsigned short* indexCells,
-					     unsigned char* colorCells,
-					     int count)
-  : SqrtScale(s, indexCells, colorCells, count),
-    ColorScalePseudoColor8(s),
-    ColorScale(s) {}
-
-SquaredScalePseudoColor8::SquaredScalePseudoColor8(int s, 
-						   unsigned short* indexCells,
-						   unsigned char* colorCells,
-						   int count)
-  : SquaredScale(s, indexCells, colorCells, count), 
-    ColorScalePseudoColor8(s),
-    ColorScale(s) {}
-
-AsinhScalePseudoColor8::AsinhScalePseudoColor8(int s, 
-					       unsigned short* indexCells,
-					       unsigned char* colorCells,
-					       int count)
-  : AsinhScale(s, indexCells, colorCells, count), 
-    ColorScalePseudoColor8(s),
-    ColorScale(s) {}
-
-SinhScalePseudoColor8::SinhScalePseudoColor8(int s, 
-					     unsigned short* indexCells,
-					     unsigned char* colorCells,
-					     int count)
-  : SinhScale(s, indexCells, colorCells, count), 
-    ColorScalePseudoColor8(s),
-    ColorScale(s) {}
-
-IISScalePseudoColor8::IISScalePseudoColor8(Base* parent,
-					   unsigned short* indexCells, 
-					   unsigned char* colorCells,
-					   int count)
-  : IISScale(indexCells, colorCells, count), 
-    ColorScalePseudoColor8(IISSIZE), 
-    ColorScale(IISSIZE)
-{
-  colors_[200] = psIndex_[200] = parent->getColor("black");
-  colors_[201] = psIndex_[201] = parent->getColor("black");
-  colors_[202] = psIndex_[202] = parent->getColor("white");
-  colors_[203] = psIndex_[203] = parent->getColor("red");
-  colors_[204] = psIndex_[204] = parent->getColor("green");
-  colors_[205] = psIndex_[205] = parent->getColor("blue");
-  colors_[206] = psIndex_[206] = parent->getColor("yellow");
-  colors_[207] = psIndex_[207] = parent->getColor("cyan");
-  colors_[208] = psIndex_[208] = parent->getColor("magenta");
-  colors_[209] = psIndex_[209] = parent->getColor("coral");
-  colors_[210] = psIndex_[210] = parent->getColor("maroon");
-  colors_[211] = psIndex_[211] = parent->getColor("orange");
-  colors_[212] = psIndex_[212] = parent->getColor("khaki");
-  colors_[213] = psIndex_[213] = parent->getColor("orchid");
-  colors_[214] = psIndex_[214] = parent->getColor("turquoise");
-  colors_[215] = psIndex_[215] = parent->getColor("violet");
-  colors_[216] = psIndex_[216] = parent->getColor("wheat");
-}
-
-HistEquScalePseudoColor8::HistEquScalePseudoColor8(int s, 
-						   unsigned short* indexCells, 
-						   unsigned char* colorCells,
-						   int count, 
-						   double* hist, int histsize)
-  : HistEquScale(s, indexCells, colorCells, count, hist, histsize), 
-    ColorScalePseudoColor8(s), 
-    ColorScale(s) {}
diff --git a/saotk/frame/colorscalepseudo8.h b/saotk/frame/colorscalepseudo8.h
deleted file mode 100644
index dc16f38..0000000
--- a/saotk/frame/colorscalepseudo8.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#ifndef __colorscalepseudo8_h__
-#define __colorscalepseudo8_h__
-
-#include "colorscale.h"
-
-class Base;
-
-class ColorScalePseudoColor8 : public virtual ColorScale {
-public:
-  ColorScalePseudoColor8(int);
-  virtual ~ColorScalePseudoColor8();
-};
-
-class LinearScalePseudoColor8 : 
-public virtual ColorScale, 
-public LinearScale, 
-public ColorScalePseudoColor8 {
-public:
-  LinearScalePseudoColor8(int, unsigned short*, unsigned char*, int);
-};
-
-class LogScalePseudoColor8 :
-public virtual ColorScale, 
-public LogScale, 
-public ColorScalePseudoColor8 {
-public:
-  LogScalePseudoColor8(int, unsigned short*, unsigned char*, int, double);
-};
-
-class PowScalePseudoColor8 :
-public virtual ColorScale, 
-public PowScale, 
-public ColorScalePseudoColor8 {
-public:
-  PowScalePseudoColor8(int, unsigned short*, unsigned char*, int, double);
-};
-
-class SqrtScalePseudoColor8 :
-public virtual ColorScale, 
-public SqrtScale, 
-public ColorScalePseudoColor8 {
-public:
-  SqrtScalePseudoColor8(int, unsigned short*, unsigned char*, int);
-};
-
-class SquaredScalePseudoColor8 :
-public virtual ColorScale, 
-public SquaredScale, 
-public ColorScalePseudoColor8 {
-public:
-  SquaredScalePseudoColor8(int, unsigned short*, unsigned char*, int);
-};
-
-class AsinhScalePseudoColor8 :
-public virtual ColorScale, 
-public AsinhScale, 
-public ColorScalePseudoColor8 {
-public:
-  AsinhScalePseudoColor8(int, unsigned short*, unsigned char*, int);
-};
-
-class SinhScalePseudoColor8 :
-public virtual ColorScale, 
-public SinhScale, 
-public ColorScalePseudoColor8 {
-public:
-  SinhScalePseudoColor8(int, unsigned short*, unsigned char*, int);
-};
-
-class IISScalePseudoColor8 :
-public virtual ColorScale, 
-public IISScale, 
-public ColorScalePseudoColor8 {
-public:
-  IISScalePseudoColor8(Base*,unsigned short*, unsigned char*, int);
-};
-
-class HistEquScalePseudoColor8 : 
-public virtual ColorScale, 
-public HistEquScale, 
-public ColorScalePseudoColor8 {
-public:
-  HistEquScalePseudoColor8(int, unsigned short*, unsigned char*, int, 
-			   double*, int);
-};
-
-#endif
diff --git a/saotk/frame/colorscalergb.h b/saotk/frame/colorscalergb.h
index 1db0e63..a69b61d 100644
--- a/saotk/frame/colorscalergb.h
+++ b/saotk/frame/colorscalergb.h
@@ -5,9 +5,6 @@
 #ifndef __colorscalergb_h__
 #define __colorscalergb_h__
 
-#include <tcl.h>
-#include <X11/Xlib.h>
-
 #include "util.h"
 
 class ColorScaleRGB {
diff --git a/saotk/frame/colorscaletrue32.C b/saotk/frame/colorscaletrue32.C
index 189e096..4604ea3 100644
--- a/saotk/frame/colorscaletrue32.C
+++ b/saotk/frame/colorscaletrue32.C
@@ -16,6 +16,9 @@ ColorScaleTrueColor32::ColorScaleTrueColor32(int s, Visual* visual, int msb)
       unsigned int g = psColors_[i*3+1];
       unsigned int b = psColors_[i*3];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= r << rs_;
       a |= g << gs_;
       a |= b << bs_;
@@ -28,6 +31,9 @@ ColorScaleTrueColor32::ColorScaleTrueColor32(int s, Visual* visual, int msb)
       unsigned int g = psColors_[i*3+1];
       unsigned int b = psColors_[i*3];
       unsigned int a = 0;
+#ifdef _MACOSX
+      a |= 0xff << 24;
+#endif
       a |= r << rs_;
       a |= g << gs_;
       a |= b << bs_;
diff --git a/saotk/frame/compass.C b/saotk/frame/compass.C
index 39d714f..3a41c59 100644
--- a/saotk/frame/compass.C
+++ b/saotk/frame/compass.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "compass.h"
 #include "fitsimage.h"
 
@@ -298,7 +300,7 @@ void Compass::renderMACOSX()
     if (eastText) {
       float r1 = Tk_TextWidth(psfont_, eastText, strlen(eastText))/2.;
       float r2 = metrics.linespace/2.;
-      double angle = (c-a).angle();
+      double angle = (cc-aa).angle();
       Vector eee = ee *
 	Translate(r1*cos(angle),r2*sin(angle)) * 
 	Translate(-r1,(metrics.ascent-metrics.descent)/2.);
diff --git a/saotk/frame/composite.C b/saotk/frame/composite.C
index 9c672b6..de7952c 100644
--- a/saotk/frame/composite.C
+++ b/saotk/frame/composite.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "composite.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/context.C b/saotk/frame/context.C
index 476accd..7500777 100644
--- a/saotk/frame/context.C
+++ b/saotk/frame/context.C
@@ -3,8 +3,6 @@
 // For conditions of distribution and use, see copyright notice in "copyright"
 
 #include "context.h"
-#include "blt.h"
-#include "bltVector.h"
 #include "fitsimage.h"
 #include "fvcontour.h"
 
@@ -19,6 +17,10 @@
 #include "socketgz.h"
 #include "var.h"
 
+extern "C" {
+#include "bltVector.h"
+}
+
 Context::Context()
 {
   parent_ = NULL;
@@ -483,8 +485,8 @@ int Context::load(Base* parent, Base::MemType which,
 
   if (img->isHist())
     which = Base::HIST;
-  else if (img->isCompress())
-    which = Base::COMPRESS;
+  else if (img->isPost())
+    which = Base::POST;
 
   FitsImage* ptr = img;
   for (int ii=1; ii<img->nhdu(); ii++) {
@@ -526,8 +528,8 @@ int Context::load(Base* parent, Base::MemType which,
     case Base::HIST:
       next = new FitsImageFitsNextHist(parent, img, ptr->baseFile(), ii+1);
       break;
-    case Base::COMPRESS:
-      next = new FitsImageFitsNextCompress(parent, img, ptr->baseFile(), ii+1);
+    case Base::POST:
+      next = new FitsImageFitsNextPost(parent, img, ptr->baseFile(), ii+1);
       break;
     case Base::PHOTO:
       next = new FitsImagePhotoCubeNext(parent, fn, ptr->baseFile(), ii+1);
@@ -620,7 +622,7 @@ int Context::loadExtCube(Base* parent, Base::MemType which,
       break;
     }
 
-    if (next && next->isValid() && (next->isImage() || next->isCompress())) {
+    if (next && next->isValid() && (next->isImage() || next->isPost())) {
       ptr->setNextSlice(next);
       ptr = next;
       naxis_[2]++;
@@ -749,8 +751,8 @@ int Context::loadMosaic(Base* parent, Base::MemType which,
     break;
   }
 
-  if (img->isCompress())
-    which = Base::COMPRESS;
+  if (img->isPost())
+    which = Base::POST;
 
   // get the rest of slices
   FitsImage* sptr = img;
@@ -790,8 +792,8 @@ int Context::loadMosaic(Base* parent, Base::MemType which,
     case Base::VAR:
       next = new FitsImageFitsNextVar(parent, fn, sptr->fitsFile(), ii+1);
       break;
-    case Base::COMPRESS:
-      next = new FitsImageFitsNextCompress(parent, img, sptr->baseFile(), ii+1);
+    case Base::POST:
+      next = new FitsImageFitsNextPost(parent, img, sptr->baseFile(), ii+1);
       break;
     case Base::PHOTO:
       next = new FitsImagePhotoCubeNext(parent, fn, sptr->baseFile(), ii+1);
@@ -886,8 +888,8 @@ int Context::loadMosaicImage(Base* parent, Base::MemType which,
 
   // get the rest of slices
   FitsImage* sptr = img;
-  if (img->isCompress())
-    which = Base::COMPRESS;
+  if (img->isPost())
+    which = Base::POST;
 
   for (int ii=1; ii<img->nhdu(); ii++) {
     FitsImage* next = NULL;
@@ -925,8 +927,8 @@ int Context::loadMosaicImage(Base* parent, Base::MemType which,
     case Base::VAR:
       next = new FitsImageFitsNextVar(parent, fn, sptr->fitsFile(), ii+1);
       break;
-    case Base::COMPRESS:
-      next = new FitsImageFitsNextCompress(parent, img, sptr->baseFile(), ii+1);
+    case Base::POST:
+      next = new FitsImageFitsNextPost(parent, img, sptr->baseFile(), ii+1);
       break;
     }
 
@@ -998,7 +1000,7 @@ int Context::loadMosaicImage(Base* parent, Base::MemType which,
       break;
     }
 
-    if (next && next->isValid() && (next->isImage() || next->isCompress())) {
+    if (next && next->isValid() && (next->isImage() || next->isPost())) {
       ptr->setNextMosaic(next);
       ptr = next;
 
@@ -1020,8 +1022,8 @@ int Context::loadMosaicImage(Base* parent, Base::MemType which,
       if (ll == Base::IMG)
 	mosaicCount_++;
 
-      if (img->isCompress())
-	which = Base::COMPRESS;
+      if (img->isPost())
+	which = Base::POST;
 
       // get rest of slices
       for (int ii=1; ii<img->nhdu(); ii++) {
@@ -1060,8 +1062,8 @@ int Context::loadMosaicImage(Base* parent, Base::MemType which,
 	case Base::VAR:
 	  snext = new FitsImageFitsNextVar(parent, fn, next->fitsFile(), ii+1);
 	  break;
-	case Base::COMPRESS:
-	  snext = new FitsImageFitsNextCompress(parent, ptr, next->baseFile(), ii+1);
+	case Base::POST:
+	  snext = new FitsImageFitsNextPost(parent, ptr, next->baseFile(), ii+1);
 	  break;
 	}
 
@@ -1131,8 +1133,8 @@ int Context::loadMosaicWFPC2(Base* parent, Base::MemType which,
   // remember in case of compress
   Base::MemType sav = which;
 
-  if (img->isCompress())
-    which = Base::COMPRESS;
+  if (img->isPost())
+    which = Base::POST;
 
   // get the rest
   {
@@ -1167,8 +1169,8 @@ int Context::loadMosaicWFPC2(Base* parent, Base::MemType which,
       case Base::VAR:
 	next = new FitsImageFitsNextVar(parent, fn, ptr->fitsFile(), 1);
 	break;
-      case Base::COMPRESS:
-	next = new FitsImageFitsNextCompress(parent, img, ptr->baseFile(), 1);
+      case Base::POST:
+	next = new FitsImageFitsNextPost(parent, img, ptr->baseFile(), 1);
 	break;
       }
 
diff --git a/saotk/frame/context.h b/saotk/frame/context.h
index 8f6004d..f1fd192 100644
--- a/saotk/frame/context.h
+++ b/saotk/frame/context.h
@@ -5,7 +5,6 @@
 #ifndef __context_h__
 #define __context_h__
 
-#include "tcl.h"
 #include "base.h"
 #include "coord.h"
 #include "frscale.h"
diff --git a/saotk/frame/contour.h b/saotk/frame/contour.h
index 1301b51..70a968d 100644
--- a/saotk/frame/contour.h
+++ b/saotk/frame/contour.h
@@ -5,6 +5,9 @@
 #ifndef __contour_h__
 #define __contour_h__
 
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
 #include "vector.h"
 #include "vector3d.h"
 #include "list.h"
diff --git a/saotk/frame/cpanda.C b/saotk/frame/cpanda.C
index c43fd0e..d62ad68 100644
--- a/saotk/frame/cpanda.C
+++ b/saotk/frame/cpanda.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "cpanda.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/ellipse.C b/saotk/frame/ellipse.C
index 8c40348..e329869 100644
--- a/saotk/frame/ellipse.C
+++ b/saotk/frame/ellipse.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "ellipse.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/ellipseannulus.C b/saotk/frame/ellipseannulus.C
index 5e5518a..421f418 100644
--- a/saotk/frame/ellipseannulus.C
+++ b/saotk/frame/ellipseannulus.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "ellipseannulus.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/epanda.C b/saotk/frame/epanda.C
index f9945c8..a08a675 100644
--- a/saotk/frame/epanda.C
+++ b/saotk/frame/epanda.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "epanda.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/fitscompress.C b/saotk/frame/fitscompress.C
index e0cd36a..35ad182 100644
--- a/saotk/frame/fitscompress.C
+++ b/saotk/frame/fitscompress.C
@@ -19,104 +19,104 @@ void FitsImage::initCompress()
     return ;
   }
 
-  if (compress_)
-    delete compress_;
-  compress_ = NULL;
+  if (post_)
+    delete post_;
+  post_ = NULL;
 
   if (!strncmp(type,"RICE",4))
     switch (bitpix) {
     case 8: 
-      compress_ = new FitsRicem<unsigned char>(fits_);
+      post_ = new FitsRicem<unsigned char>(fits_);
       break;
     case 16:
-      compress_ = new FitsRicem<short>(fits_);
+      post_ = new FitsRicem<short>(fits_);
       break;
     case -16:
-      compress_ = new FitsRicem<unsigned short>(fits_);
+      post_ = new FitsRicem<unsigned short>(fits_);
       break;
     case 32:
-      compress_ = new FitsRicem<int>(fits_);
+      post_ = new FitsRicem<int>(fits_);
       break;
     case 64:
-      compress_ = new FitsRicem<long long>(fits_);
+      post_ = new FitsRicem<long long>(fits_);
       break;
     case -32:
-      compress_ = new FitsRicem<float>(fits_);
+      post_ = new FitsRicem<float>(fits_);
       break;
     case -64:
-      compress_ = new FitsRicem<double>(fits_);
+      post_ = new FitsRicem<double>(fits_);
       break;
     }
   else if (!strncmp(type,"GZIP",4))
     switch (bitpix) {
     case 8: 
-      compress_ = new FitsGzipm<unsigned char>(fits_);
+      post_ = new FitsGzipm<unsigned char>(fits_);
       break;
     case 16:
-      compress_ = new FitsGzipm<short>(fits_);
+      post_ = new FitsGzipm<short>(fits_);
       break;
     case -16:
-      compress_ = new FitsGzipm<unsigned short>(fits_);
+      post_ = new FitsGzipm<unsigned short>(fits_);
       break;
     case 32:
-      compress_ = new FitsGzipm<int>(fits_);
+      post_ = new FitsGzipm<int>(fits_);
       break;
     case 64:
-      compress_ = new FitsGzipm<long long>(fits_);
+      post_ = new FitsGzipm<long long>(fits_);
       break;
     case -32:
-      compress_ = new FitsGzipm<float>(fits_);
+      post_ = new FitsGzipm<float>(fits_);
       break;
     case -64:
-      compress_ = new FitsGzipm<double>(fits_);
+      post_ = new FitsGzipm<double>(fits_);
       break;
     }
   else if (!strncmp(type,"PLIO",4))
     switch (bitpix) {
     case 8: 
-      compress_ = new FitsPliom<unsigned char>(fits_);
+      post_ = new FitsPliom<unsigned char>(fits_);
       break;
     case 16:
-      compress_ = new FitsPliom<short>(fits_);
+      post_ = new FitsPliom<short>(fits_);
       break;
     case -16:
-      compress_ = new FitsPliom<unsigned short>(fits_);
+      post_ = new FitsPliom<unsigned short>(fits_);
       break;
     case 32:
-      compress_ = new FitsPliom<int>(fits_);
+      post_ = new FitsPliom<int>(fits_);
       break;
     case 64:
-      compress_ = new FitsPliom<long long>(fits_);
+      post_ = new FitsPliom<long long>(fits_);
       break;
     case -32:
-      compress_ = new FitsPliom<float>(fits_);
+      post_ = new FitsPliom<float>(fits_);
       break;
     case -64:
-      compress_ = new FitsPliom<double>(fits_);
+      post_ = new FitsPliom<double>(fits_);
       break;
     }
   else if (!strncmp(type,"HCOMPRESS",4))
     switch (bitpix) {
     case 8: 
-      compress_ = new FitsHcompressm<unsigned char>(fits_);
+      post_ = new FitsHcompressm<unsigned char>(fits_);
       break;
     case 16:
-      compress_ = new FitsHcompressm<short>(fits_);
+      post_ = new FitsHcompressm<short>(fits_);
       break;
     case -16:
-      compress_ = new FitsHcompressm<unsigned short>(fits_);
+      post_ = new FitsHcompressm<unsigned short>(fits_);
       break;
     case 32:
-      compress_ = new FitsHcompressm<int>(fits_);
+      post_ = new FitsHcompressm<int>(fits_);
       break;
     case 64:
-      compress_ = new FitsHcompressm<long long>(fits_);
+      post_ = new FitsHcompressm<long long>(fits_);
       break;
     case -32:
-      compress_ = new FitsHcompressm<float>(fits_);
+      post_ = new FitsHcompressm<float>(fits_);
       break;
     case -64:
-      compress_ = new FitsHcompressm<double>(fits_);
+      post_ = new FitsHcompressm<double>(fits_);
       break;
     }
 
diff --git a/saotk/frame/fitsenvi.C b/saotk/frame/fitsenvi.C
index 4f76908..fd7113c 100644
--- a/saotk/frame/fitsenvi.C
+++ b/saotk/frame/fitsenvi.C
@@ -7,9 +7,9 @@
 
 void FitsImage::initENVI()
 {
-  if (compress_)
-    delete compress_;
-  compress_ = NULL;
+  if (post_)
+    delete post_;
+  post_ = NULL;
 
   switch (fits_->pEncoding()) {
   case FitsFile::BSQ:
@@ -18,50 +18,50 @@ void FitsImage::initENVI()
   case FitsFile::BIL:
     switch (fits_->pBitpix()) {
     case 8: 
-      compress_ = new FitsENVIBILm<unsigned char>(fits_);
+      post_ = new FitsENVIBILm<unsigned char>(fits_);
       break;
     case 16:
-      compress_ = new FitsENVIBILm<short>(fits_);
+      post_ = new FitsENVIBILm<short>(fits_);
       break;
     case -16:
-      compress_ = new FitsENVIBILm<unsigned short>(fits_);
+      post_ = new FitsENVIBILm<unsigned short>(fits_);
       break;
     case 32:
-      compress_ = new FitsENVIBILm<int>(fits_);
+      post_ = new FitsENVIBILm<int>(fits_);
       break;
     case 64:
-      compress_ = new FitsENVIBILm<long long>(fits_);
+      post_ = new FitsENVIBILm<long long>(fits_);
       break;
     case -32:
-      compress_ = new FitsENVIBILm<float>(fits_);
+      post_ = new FitsENVIBILm<float>(fits_);
       break;
     case -64:
-      compress_ = new FitsENVIBILm<double>(fits_);
+      post_ = new FitsENVIBILm<double>(fits_);
       break;
     }
     break;
   case FitsFile::BIP:
     switch (fits_->pBitpix()) {
     case 8: 
-      compress_ = new FitsENVIBIPm<unsigned char>(fits_);
+      post_ = new FitsENVIBIPm<unsigned char>(fits_);
       break;
     case 16:
-      compress_ = new FitsENVIBIPm<short>(fits_);
+      post_ = new FitsENVIBIPm<short>(fits_);
       break;
     case -16:
-      compress_ = new FitsENVIBIPm<unsigned short>(fits_);
+      post_ = new FitsENVIBIPm<unsigned short>(fits_);
       break;
     case 32:
-      compress_ = new FitsENVIBIPm<int>(fits_);
+      post_ = new FitsENVIBIPm<int>(fits_);
       break;
     case 64:
-      compress_ = new FitsENVIBIPm<long long>(fits_);
+      post_ = new FitsENVIBIPm<long long>(fits_);
       break;
     case -32:
-      compress_ = new FitsENVIBIPm<float>(fits_);
+      post_ = new FitsENVIBIPm<float>(fits_);
       break;
     case -64:
-      compress_ = new FitsENVIBIPm<double>(fits_);
+      post_ = new FitsENVIBIPm<double>(fits_);
       break;
     }
     break;
diff --git a/saotk/frame/fitsimage.C b/saotk/frame/fitsimage.C
index f0de139..67b0528 100644
--- a/saotk/frame/fitsimage.C
+++ b/saotk/frame/fitsimage.C
@@ -63,7 +63,7 @@ FitsImage::FitsImage(Base* p)
   iisFileName = NULL;
 
   fits_ = NULL;
-  compress_ = NULL;
+  post_ = NULL;
   hist_ = NULL;
   hpx_ = NULL;
 
@@ -147,8 +147,8 @@ FitsImage::~FitsImage()
   if (fits_)
     delete fits_;
 
-  if (compress_)
-    delete compress_;
+  if (post_)
+    delete post_;
 
   if (hist_)
     delete hist_;
@@ -409,12 +409,12 @@ FitsImageFitsNextHist::FitsImageFitsNextHist(Base* p,
   iisFileName = dupstr(fi->getFullBaseFileName());
 }
 
-FitsImageFitsNextCompress::FitsImageFitsNextCompress(Base* p, 
-						     FitsImage* fi,
-						     FitsFile* prev, int id)
+FitsImageFitsNextPost::FitsImageFitsNextPost(Base* p, 
+					     FitsImage* fi,
+					     FitsFile* prev, int id)
   : FitsImage(p)
 {
-  fits_ = new FitsCompressNext(prev);
+  fits_ = new FitsPostNext(prev);
   process(NULL,id);
 
   rootBaseFileName = dupstr(fi->getRootBaseFileName());
@@ -1195,8 +1195,8 @@ void FitsImage::initWCS0(const Vector& pix)
 
 void FitsImage::load()
 {
-  if (compress_)
-    base_ = compress_;
+  if (post_)
+    base_ = post_;
   else if (hpx_)
     base_ = hpx_;
   else if (hist_)
@@ -1478,7 +1478,7 @@ void FitsImage::process(const char* fn, int id)
       break;
     case FitsFile::GZIP:
       initNRRD();
-      if (!compress_->isValid()) {
+      if (!post_->isValid()) {
 	reset();
 	return;
       }
@@ -1486,7 +1486,7 @@ void FitsImage::process(const char* fn, int id)
     case FitsFile::BIL:
     case FitsFile::BIP:
       initENVI();
-      if (!compress_->isValid()) {
+      if (!post_->isValid()) {
 	reset();
 	return;
       }
@@ -1502,7 +1502,7 @@ void FitsImage::process(const char* fn, int id)
     // Compress
     if (fits_->find("ZIMAGE")) {
       initCompress();
-      if (!compress_->isValid()) {
+      if (!post_->isValid()) {
 	reset();
 	return;
       }
@@ -1883,9 +1883,9 @@ void FitsImage::reset()
     delete fits_;
   fits_ = NULL;
 
-  if (compress_)
-    delete compress_;
-  compress_ = NULL;
+  if (post_)
+    delete post_;
+  post_ = NULL;
   if (hpx_)
     delete hpx_;
   hpx_ = NULL;
@@ -2101,7 +2101,7 @@ void FitsImage::setFileName(const char* fn)
   // strip any '[]'
   char* ffn = strip(fn);
 
-  FitsFile* ptr = compress_ ? compress_ : fits_;
+  FitsFile* ptr = post_ ? post_ : fits_;
   if (!ptr)
     return;
 
@@ -3050,7 +3050,8 @@ void FitsImage::astinit(int ii, FitsHead* hh)
     return;
   }
 
-  // DSS,PLT,HPX,TAB goes straight to AST
+  // DSS,PLT,LIN goes straight to AST
+  // we can't send 3D directly to AST
   if (wcs[ii]->prjcode==WCS_DSS || 
       wcs[ii]->prjcode==WCS_PLT || 
       (wcs[ii]->prjcode==WCS_LIN && !strncmp(wcs[ii]->ptype,"HPX",3)) ||
@@ -3279,9 +3280,14 @@ AstFrameSet* FitsImage::wcs2ast(int ww)
     pc << "PC1_1" << alt << ends;
 
     if (fits->find(cd.str().c_str(), wcsHeader)) {
-      if (!wcs[ww]->cd[1] && !wcs[ww]->cd[2] && !wcs[ww]->rot &&
-	  wcs[ww]->latpole == 999 && wcs[ww]->longpole == 999) {
-	// simple case
+      // simple case CD
+      // no rotation, no poles, no LIN, no inner cd values
+      if (!wcs[ww]->cd[1] && !wcs[ww]->cd[2] && 
+	  !wcs[ww]->rot &&
+	  wcs[ww]->latpole == 999 && 
+	  wcs[ww]->longpole == 999 &&
+	  wcs[ww]->prjcode != WCS_PIX && 
+	  wcs[ww]->prjcode != WCS_LIN) {
 	putFitsCard(chan, "CDELT1", wcs[ww]->cdelt[0]);
 	putFitsCard(chan, "CDELT2", wcs[ww]->cdelt[1]);
       }
@@ -3292,6 +3298,7 @@ AstFrameSet* FitsImage::wcs2ast(int ww)
 	putFitsCard(chan, "CD2_2", wcs[ww]->cd[3]);
       }
     }
+    // CDELT
     else if (fits->find(cdelt.str().c_str(), wcsHeader)) {
       putFitsCard(chan, "CDELT1", wcs[ww]->cdelt[0]);
       putFitsCard(chan, "CDELT2", wcs[ww]->cdelt[1]);
@@ -3315,11 +3322,11 @@ AstFrameSet* FitsImage::wcs2ast(int ww)
 	  putFitsCard(chan, "CROTA2", wcs[ww]->rot);
       }
     }
+    // sanity check
     else if (!wcs[ww]->cd[0] && 
 	     !wcs[ww]->cd[1] && 
 	     !wcs[ww]->cd[2] && 
 	     !wcs[ww]->cd[3]) {
-      // sanity check
       putFitsCard(chan, "CDELT1", wcs[ww]->cdelt[0]);
       putFitsCard(chan, "CDELT2", wcs[ww]->cdelt[1]);
       putFitsCard(chan, "PC1_1", wcs[ww]->pc[0]);
@@ -3327,6 +3334,7 @@ AstFrameSet* FitsImage::wcs2ast(int ww)
       putFitsCard(chan, "PC2_1", wcs[ww]->pc[2]);
       putFitsCard(chan, "PC2_2", wcs[ww]->pc[3]);
     } 
+    // fall back
     else {
       putFitsCard(chan, "CD1_1", wcs[ww]->cd[0]);
       putFitsCard(chan, "CD1_2", wcs[ww]->cd[1]);
diff --git a/saotk/frame/fitsimage.h b/saotk/frame/fitsimage.h
index 17949d0..ff0e38e 100644
--- a/saotk/frame/fitsimage.h
+++ b/saotk/frame/fitsimage.h
@@ -39,7 +39,7 @@ class FitsImage {
   FitsFile* fits_;
 
   // base
-  FitsFile* compress_;      // fits compressed
+  FitsFile* post_;          // fits post processing
   FitsFile* hist_;          // fits bin
   FitsFile* hpx_;           // healpix
 
@@ -218,7 +218,7 @@ class FitsImage {
   FitsFile* imageFile() {return image_;}
 
   int isValid() {return image_ ? 1 : 0;}
-  int isCompress() {return compress_ ? 1 : 0;}
+  int isPost() {return post_ ? 1 : 0;}
   int isHist() {return hist_ ? 1 : 0;}
   int isHPX() {return hpx_ ? 1 : 0;}
 
@@ -585,9 +585,9 @@ public:
   FitsImageFitsNextHist(Base*, FitsImage*, FitsFile*, int);
 };
 
-class FitsImageFitsNextCompress : public FitsImage {
+class FitsImageFitsNextPost : public FitsImage {
 public:
-  FitsImageFitsNextCompress(Base*, FitsImage*, FitsFile*, int);
+  FitsImageFitsNextPost(Base*, FitsImage*, FitsFile*, int);
 };
 
 // Array
diff --git a/saotk/frame/fitsmask.C b/saotk/frame/fitsmask.C
index e025e07..feced2b 100644
--- a/saotk/frame/fitsmask.C
+++ b/saotk/frame/fitsmask.C
@@ -2,6 +2,10 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
 #include "fitsmask.h"
 #include "base.h"
 #include "fitsimage.h"
diff --git a/saotk/frame/fitsmask.h b/saotk/frame/fitsmask.h
index 5eb2e5f..b56e8fe 100644
--- a/saotk/frame/fitsmask.h
+++ b/saotk/frame/fitsmask.h
@@ -5,7 +5,6 @@
 #ifndef __fitsmask_h__
 #define __fitsmask_h__
 
-#include "tcl.h"
 #include <X11/Xlib.h>
 
 class Base;
diff --git a/saotk/frame/fitsnrrd.C b/saotk/frame/fitsnrrd.C
index 613d7fd..bd1607c 100644
--- a/saotk/frame/fitsnrrd.C
+++ b/saotk/frame/fitsnrrd.C
@@ -7,9 +7,9 @@
 
 void FitsImage::initNRRD()
 {
-  if (compress_)
-    delete compress_;
-  compress_ = NULL;
+  if (post_)
+    delete post_;
+  post_ = NULL;
 
   switch (fits_->pEncoding()) {
   case FitsFile::RAW:
@@ -17,25 +17,25 @@ void FitsImage::initNRRD()
   case FitsFile::GZIP:
     switch (fits_->pBitpix()) {
     case 8: 
-      compress_ = new FitsNRRDGzipm<unsigned char>(fits_);
+      post_ = new FitsNRRDGzipm<unsigned char>(fits_);
       break;
     case 16:
-      compress_ = new FitsNRRDGzipm<short>(fits_);
+      post_ = new FitsNRRDGzipm<short>(fits_);
       break;
     case -16:
-      compress_ = new FitsNRRDGzipm<unsigned short>(fits_);
+      post_ = new FitsNRRDGzipm<unsigned short>(fits_);
       break;
     case 32:
-      compress_ = new FitsNRRDGzipm<int>(fits_);
+      post_ = new FitsNRRDGzipm<int>(fits_);
       break;
     case 64:
-      compress_ = new FitsNRRDGzipm<long long>(fits_);
+      post_ = new FitsNRRDGzipm<long long>(fits_);
       break;
     case -32:
-      compress_ = new FitsNRRDGzipm<float>(fits_);
+      post_ = new FitsNRRDGzipm<float>(fits_);
       break;
     case -64:
-      compress_ = new FitsNRRDGzipm<double>(fits_);
+      post_ = new FitsNRRDGzipm<double>(fits_);
       break;
     }
     break;
diff --git a/saotk/frame/fr3dcommand.C b/saotk/frame/fr3dcommand.C
index 1acf396..da98df5 100644
--- a/saotk/frame/fr3dcommand.C
+++ b/saotk/frame/fr3dcommand.C
@@ -2,8 +2,6 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
-
 #include "frame3dbase.h"
 #include "fitsimage.h"
 #include "context.h"
diff --git a/saotk/frame/frame3dbase.C b/saotk/frame/frame3dbase.C
index 9764fdd..1d2da29 100644
--- a/saotk/frame/frame3dbase.C
+++ b/saotk/frame/frame3dbase.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tk.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
@@ -1023,10 +1023,10 @@ void Frame3dBase::ximageToPixmapMagnifier()
   XImage* srcXImage = XGetImage(display, basePixmap, uu[0], uu[1], 
 				zz[0], zz[1], AllPlanes, ZPixmap);
 
-  char* src = XImageData(srcXImage);
+  char* src = srcXImage->data;
   int srcBytesPerLine =  srcXImage->bytes_per_line;
 
-  char* dst = XImageData(magnifierXImage);
+  char* dst = magnifierXImage->data;
   int dstBytesPerLine =  magnifierXImage->bytes_per_line;
   int bytesPerPixel = magnifierXImage->bits_per_pixel/8;
 
@@ -1140,7 +1140,7 @@ void Frame3dBase::macosxHighlite()
 {
   Vector vv[4];
   int rr[4];
-  calcHighlite(CANVAS,vv,rr);
+  calcHighlite(Coord::CANVAS,vv,rr);
 
   macosxColor(getXColor(highliteColorName_));
   macosxWidth(1);
diff --git a/saotk/frame/frame3dtrue.C b/saotk/frame/frame3dtrue.C
index 2a70f33..071b77c 100644
--- a/saotk/frame/frame3dtrue.C
+++ b/saotk/frame/frame3dtrue.C
@@ -2,10 +2,6 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
 #include "frame3dtrue.h"
 
 Frame3dTrue::Frame3dTrue(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item)
diff --git a/saotk/frame/frame3dtruecolor.C b/saotk/frame/frame3dtruecolor.C
index 07e1c58..e9a6c3c 100644
--- a/saotk/frame/frame3dtruecolor.C
+++ b/saotk/frame/frame3dtruecolor.C
@@ -2,10 +2,6 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
 #include "frame3dtruecolor.h"
 #include "fitsimage.h"
 #include "ps.h"
diff --git a/saotk/frame/framebase.C b/saotk/frame/framebase.C
index 9171c93..b899314 100644
--- a/saotk/frame/framebase.C
+++ b/saotk/frame/framebase.C
@@ -2,10 +2,6 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
 #include "framebase.h"
 #include "fitsimage.h"
 #include "marker.h"
diff --git a/saotk/frame/framepseudo.C b/saotk/frame/framepseudo.C
deleted file mode 100644
index b1ef1de..0000000
--- a/saotk/frame/framepseudo.C
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#include "framepseudo.h"
-
-FramePseudo::FramePseudo(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item)
-  : FrameBase(i, c, item)
-{
-}
-
-FramePseudo::~FramePseudo()
-{
-}
-
-void FramePseudo::rotateMotion()
-{
-  // Rotate from src to dest
-  Vector c = Vector(options->width,options->height)/2;
-  Matrix m = (Translate(-c) * 
-	      Rotate(rotation-rotateRotation) * Translate(c)).invert();
-  double* mm = m.mm();
-  unsigned long bgc = getColor(bgColorName);
-
-  int& width = options->width;
-  int& height = options->height;
-  char* src = XImageData(rotateSrcXM);
-
-  for (int j=0; j<height; j++) {
-    // the line may be padded at the end
-    char* dest = XImageData(rotateDestXM) + j*rotateDestXM->bytes_per_line;
-
-    for (int i=0; i<width; i++, dest++) {
-      double x = i*mm[0] + j*mm[3] + mm[6];
-      double y = i*mm[1] + j*mm[4] + mm[7];
-
-      if (x >= 0 && x < width && y >= 0 && y < height)
-	*dest = src[((int)y)*rotateSrcXM->bytes_per_line + (int)x];
-      else
-	*dest = bgc;
-    }
-  }
-
-  // XImage to Pixmap
-  XPutImage(display, rotatePM, gc, rotateDestXM,
-	    0, 0, 0, 0, options->width, options->height);
-
-  // Display Pixmap
-  Vector dd = Vector() * widgetToWindow;
-  XCopyArea(display, rotatePM, Tk_WindowId(tkwin), rotateGCXOR, 0, 0, 
-	    options->width, options->height, dd[0], dd[1]);
-}
-
diff --git a/saotk/frame/framepseudo.h b/saotk/frame/framepseudo.h
deleted file mode 100644
index e64f0e7..0000000
--- a/saotk/frame/framepseudo.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#ifndef __framepseudo_h__
-#define __framepseudo_h__
-
-#include "framebase.h"
-
-class FramePseudo : public virtual FrameBase {
- protected:
-  void encodeTrueColor(int,int) {}
-  void rotateMotion();
-
- public:
-  FramePseudo(Tcl_Interp*, Tk_Canvas, Tk_Item*);
-  virtual ~FramePseudo();
-};
-
-#endif
diff --git a/saotk/frame/framepseudocolor.C b/saotk/frame/framepseudocolor.C
deleted file mode 100644
index 9dfc751..0000000
--- a/saotk/frame/framepseudocolor.C
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#include "framepseudocolor.h"
-#include "fitsimage.h"
-#include "ps.h"
-
-#include "sigbus.h"
-
-FramePseudoColor::FramePseudoColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item)
-  : FrameBase(i,c,item), Frame(i,c,item), FramePseudo(i,c,item)
-{
-}
-
-void FramePseudoColor::buildXImage(XImage* xmap, Coord::InternalSystem sys)
-{
-  // we need a colorScale before we can render
-  if (!validColorScale())
-    return;
-
-  // make sure we have an image
-  if (!context->cfits)
-    return;
-
-  int& width = xmap->width;
-  int& height = xmap->height;
-  int& bytesPerLine = xmap->bytes_per_line;
-  char* data = XImageData(xmap);
-  unsigned long bgc = getColor(bgColorName);
-  unsigned long nanc = getColor(nanColorName);
-
-  // set bg
-  memset(data, bgc, bytesPerLine * height);
-
-  // basics
-  int length = colorScale->size() - 1;
-  const unsigned char* table = colorScale->colors();
-
-  FitsImage* sptr = context->cfits;
-  int mosaic = isMosaic();
-
-  // variable
-  double* mm = sptr->matrixToData(sys).mm();
-  FitsBound* params = sptr->getDataParams(context->frScale.scanMode());
-  int srcw = sptr->width();
-
-  double ll = sptr->getLowDouble();
-  double hh = sptr->getHighDouble();
-  double diff = hh - ll;
-
-  // main loop
-  SETSIGBUS
-  for (long jj=0; jj<height; jj++) {
-    char* dest = data + jj*bytesPerLine; // may be padded at the end
-
-    for (long ii=0; ii<width; ii++,dest++) {
-
-      if (mosaic) {
-	sptr = context->cfits;
-
-	mm = sptr->matrixToData(sys).mm();
-	params = sptr->getDataParams(context->frScale.scanMode());
-	srcw = sptr->width();
-
-	ll = sptr->getLowDouble();
-	hh = sptr->getHighDouble();
-	diff = hh - ll;
-      }
-
-      do {
-	double xx = ii*mm[0] + jj*mm[3] + mm[6];
-	double yy = ii*mm[1] + jj*mm[4] + mm[7];
-
-	if (xx>=params->xmin && xx<params->xmax && 
-	    yy>=params->ymin && yy<params->ymax) {
-	  double value = sptr->getValueDouble(long(yy)*srcw + long(xx));
-       
-	  if (isfinite(value)) {
-	    if (value <= ll)
-	      *dest = table[0];
-	    else if (value >= hh)
-	      *dest = table[length];
-	    else
-	      *dest = table[(int)(((value - ll)/diff * length) + .5)];
-	  }
-	  else
-	    *dest = nanc;
-
-	  break;
-	}
-	else {
-	  if (mosaic) {
-	    sptr = sptr->nextMosaic();
-
-	    if (sptr) {
-	      mm = sptr->matrixToData(sys).mm();
-	      params = sptr->getDataParams(context->frScale.scanMode());
-	      srcw = sptr->width();
-
-	      ll = sptr->getLowDouble();
-	      hh = sptr->getHighDouble();
-	      diff = hh - ll;
-	    }
-	  }
-	}
-      }
-      while (mosaic && sptr);
-    }
-  }
-  CLEARSIGBUS
-}
-
-// Commands
-
-void FramePseudoColor::colormapCmd(int id, float b, float c, int i, 
-				    unsigned short* index, 
-				    unsigned char* cells, int cnt)
-{
-  cmapID = id;
-  bias = b;
-  contrast = c;
-  invert = i;
-
-  updateColorCells(index, cells, cnt);
-  updateColorScale();
-}
-
-void FramePseudoColor::colormapMotionCmd(int id, float b, float c, int i, 
-					 unsigned short* index, 
-					 unsigned char* cells, int cnt)
-{
-  // just remember for getColorbarCmd()
-  cmapID = id;
-  bias = b;
-  contrast = c;
-  invert = i;
-}
-
-void FramePseudoColor::colormapEndCmd()
-{
-  update(BASE); // always update
-}
diff --git a/saotk/frame/framepseudocolor.h b/saotk/frame/framepseudocolor.h
deleted file mode 100644
index ae6f870..0000000
--- a/saotk/frame/framepseudocolor.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#ifndef __framepseudocolor_h__
-#define __framepseudocolor_h__
-
-#include "frame.h"
-#include "framepseudo.h"
-
-class FramePseudoColor : public virtual FrameBase, public Frame, public FramePseudo {
-private:
-  void buildXImage(XImage* xmap, Coord::InternalSystem);
-
-public:
-  FramePseudoColor(Tcl_Interp*, Tk_Canvas, Tk_Item*);
-
-  void colormapCmd(int, float, float, int, unsigned short*, 
-		   unsigned char*, int);
-  void colormapMotionCmd(int id, float b, float c, int i, 
-			 unsigned short* index, 
-			 unsigned char* cells, int cnt);
-  void colormapEndCmd();
-};
-
-#endif
diff --git a/saotk/frame/framepseudocolor8.C b/saotk/frame/framepseudocolor8.C
deleted file mode 100644
index 80d338f..0000000
--- a/saotk/frame/framepseudocolor8.C
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#include "framepseudocolor8.h"
-#include "colorscalepseudo8.h"
-
-// Tk Canvas Widget Function Declarations
-
-int FramePseudoColor8CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, 
-				Tcl_Obj *const []);
-
-// FramePseudoColor8 Specs
-
-static Tk_CustomOption tagsOption = {
-  Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
-};
-
-static Tk_ConfigSpec framePseudoColor8Specs[] = {
-
-  {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "frame",
-   Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1",
-   Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1",
-   Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512",
-   Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512",
-   Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw",
-   Tk_Offset(WidgetOptions, anchor), 0, NULL},
-  {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL,
-   0, TK_CONFIG_NULL_OK, &tagsOption},
-
-  {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica",
-   Tk_Offset(WidgetOptions, helvetica), 0, NULL},
-  {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier",
-   Tk_Offset(WidgetOptions, courier), 0, NULL},
-  {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times",
-   Tk_Offset(WidgetOptions, times), 0, NULL},
-
-  {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL},
-};
-
-// Tk Static Structure
-
-static Tk_ItemType framePseudoColor8Type = {
-  (char*)"framepseudocolor8",          // name
-  sizeof(WidgetOptions),        // item size
-  FramePseudoColor8CreateProc,  // configProc
-  framePseudoColor8Specs,       // configSpecs
-  WidgetConfigProc,             // configProc
-  WidgetCoordProc,              // coordProc
-  WidgetDeleteProc,             // deleteProc
-  WidgetDisplayProc,            // displayProc
-  0,                            // alwaysRedraw
-  WidgetPointProc,              // pointProc
-  WidgetAreaProc,               // areaProc
-  WidgetPostscriptProc,         // postscriptProc
-  WidgetScaleProc,              // scaleProc
-  WidgetTranslateProc,          // translateProc
-  (Tk_ItemIndexProc*)NULL,      // indexProc
-  WidgetICursorProc,            // icursorProc
-  (Tk_ItemSelectionProc*)NULL,  // selectionProc
-  (Tk_ItemInsertProc*)NULL,     // insertProc
-  (Tk_ItemDCharsProc*)NULL,     // dCharsProc
-  (Tk_ItemType*)NULL            // nextPtr
-};
-
-// Non-Member Functions
-
-int FramePseudoColor8_Init(Tcl_Interp* interp)
-{
-  Tk_CreateItemType(&framePseudoColor8Type);
-  return TCL_OK;
-}
-
-int FramePseudoColor8CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, 
-				Tk_Item* item, int argc, Tcl_Obj *const argv[])
-{
-  FramePseudoColor8* frame = new FramePseudoColor8(interp, canvas, item);
-
-  // and set default configuration
-
-  if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) {
-    delete frame;
-    Tcl_AppendResult(interp, " error occured while creating frame.", NULL);
-    return TCL_ERROR;
-  }
-
-  return TCL_OK;
-}
-
-// FramePseudoColor8 Member Functions
-
-FramePseudoColor8::FramePseudoColor8(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item)
-  : FrameBase(i,c,item), FramePseudoColor(i,c,item)
-{
-  configSpecs = framePseudoColor8Specs;  // frame configure options
-}
-
-FramePseudoColor8::~FramePseudoColor8()
-{
-  // we must do this at this level, because updateColorScale is called
-  unloadAllFits();
-}
-
-void FramePseudoColor8::updateColorScale()
-{
-  // we need colors before we can construct a scale
-
-  if (!indexCells || !colorCells)
-    return;
-
-  if (colorScale)
-    delete colorScale;
-
-  switch (context->frScale.colorScaleType()) {
-  case FrScale::LINEARSCALE:
-    colorScale =
-      new LinearScalePseudoColor8(colorCount, indexCells, colorCells, 
-				  colorCount);
-    break;
-  case FrScale::LOGSCALE:
-    colorScale = new LogScalePseudoColor8(SCALESIZE, indexCells, colorCells, 
-					  colorCount, context->frScale.expo());
-    break;
-  case FrScale::POWSCALE:
-    colorScale = new PowScalePseudoColor8(SCALESIZE, indexCells, colorCells, 
-					  colorCount, context->frScale.expo());
-    break;
-  case FrScale::SQRTSCALE:
-    colorScale = 
-      new SqrtScalePseudoColor8(SCALESIZE, indexCells, colorCells, 
-				colorCount);
-    break;
-  case FrScale::SQUAREDSCALE:
-    colorScale =
-      new SquaredScalePseudoColor8(SCALESIZE, indexCells, colorCells, 
-				   colorCount);
-    break;
-  case FrScale::ASINHSCALE:
-    colorScale =
-      new AsinhScalePseudoColor8(SCALESIZE, indexCells, colorCells, 
-				 colorCount);
-    break;
-  case FrScale::SINHSCALE:
-    colorScale =
-      new SinhScalePseudoColor8(SCALESIZE, indexCells, colorCells, 
-				colorCount);
-    break;
-  case FrScale::HISTEQUSCALE:
-    colorScale =
-      new HistEquScalePseudoColor8(SCALESIZE, indexCells, colorCells, 
-				   colorCount, context->histequ(),
-				   HISTEQUSIZE);
-    break;
-  case FrScale::IISSCALE:
-    colorScale =
-      new IISScalePseudoColor8(this,indexCells, colorCells, 
-			       colorCount);
-    break;
-  }
-}
-
-
diff --git a/saotk/frame/framepseudocolor8.h b/saotk/frame/framepseudocolor8.h
deleted file mode 100644
index 33b29f8..0000000
--- a/saotk/frame/framepseudocolor8.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#ifndef __framepseudocolor8_h__
-#define __framepseudocolor8_h__
-
-#include "framepseudocolor.h"
-
-class FramePseudoColor8 : public virtual FrameBase, public FramePseudoColor {
-private:
-  void encodeTrueColor(XColor*, char*) {}
-  void encodeTrueColor(unsigned char*, XImage*) {}
-  void updateColorScale();
-
-public:
-  FramePseudoColor8(Tcl_Interp*, Tk_Canvas, Tk_Item*);
-  ~FramePseudoColor8();
-};
-
-#endif
diff --git a/saotk/frame/framergb.C b/saotk/frame/framergb.C
index dbebf6a..70a55f8 100644
--- a/saotk/frame/framergb.C
+++ b/saotk/frame/framergb.C
@@ -264,13 +264,13 @@ BBox FrameRGB::imageBBox(FrScale::ScanMode mode)
 
 void FrameRGB::loadRGBCube(MemType which, const char* fn, FitsImage* img)
 {
-  if (!img || !img->isValid() || !(img->isImage() || img->isCompress()) || (img->depth() != 3))
+  if (!img || !img->isValid() || !(img->isImage() || img->isPost()) || (img->depth() != 3))
     goto error;
 
   context[0].fits = img;
 
-  if (img->isCompress())
-    which = COMPRESS;
+  if (img->isPost())
+    which = POST;
 
   switch (which) {
   case ALLOC:
@@ -339,11 +339,11 @@ void FrameRGB::loadRGBCube(MemType which, const char* fn, FitsImage* img)
     if (context[1].fits && context[1].fits->isValid())
       context[2].fits = new FitsImageFitsNextVar(this, fn, context[1].fits->fitsFile(),3);
     break;
-  case COMPRESS:
+  case POST:
     if (context[0].fits && context[0].fits->isValid())
-      context[1].fits = new FitsImageFitsNextCompress(this, img,context[0].fits->baseFile(),2);
+      context[1].fits = new FitsImageFitsNextPost(this, img,context[0].fits->baseFile(),2);
     if (context[1].fits && context[1].fits->isValid())
-      context[2].fits = new FitsImageFitsNextCompress(this, img,context[1].fits->baseFile(),3);
+      context[2].fits = new FitsImageFitsNextPost(this, img,context[1].fits->baseFile(),3);
     break;
   case PHOTO:
     if (context[0].fits && context[0].fits->isValid())
@@ -355,11 +355,11 @@ void FrameRGB::loadRGBCube(MemType which, const char* fn, FitsImage* img)
 
   // is everything ok?
   if (context[0].fits && context[0].fits->isValid() &&
-      (context[0].fits->isImage() || context[0].fits->isCompress()) &&
+      (context[0].fits->isImage() || context[0].fits->isPost()) &&
       context[1].fits && context[1].fits->isValid() &&
-      (context[1].fits->isImage() || context[1].fits->isCompress()) &&
+      (context[1].fits->isImage() || context[1].fits->isPost()) &&
       context[2].fits && context[2].fits->isValid() &&
-      (context[2].fits->isImage() || context[2].fits->isCompress())) {
+      (context[2].fits->isImage() || context[2].fits->isPost())) {
 
     loadRGBFinish();
     return;
@@ -384,7 +384,7 @@ void FrameRGB::loadRGBImage(MemType which, const char* fn, FitsImage* img)
   FitsImage* g = NULL;
   FitsImage* b = NULL;
 
-  if (!img || !img->isValid() || !(img->isImage() || img->isCompress()))
+  if (!img || !img->isValid() || !(img->isImage() || img->isPost()))
     goto error;
 
   switch (which) {
@@ -507,11 +507,11 @@ void FrameRGB::loadRGBImage(MemType which, const char* fn, FitsImage* img)
 
   // is everything ok?
   if (context[0].fits && context[0].fits->isValid() && 
-      (context[0].fits->isImage() || context[0].fits->isCompress()) &&
+      (context[0].fits->isImage() || context[0].fits->isPost()) &&
       context[1].fits && context[1].fits->isValid() && 
-      (context[1].fits->isImage() || context[1].fits->isCompress()) &&
+      (context[1].fits->isImage() || context[1].fits->isPost()) &&
       context[2].fits && context[2].fits->isValid() && 
-      (context[2].fits->isImage() || context[2].fits->isCompress())) {
+      (context[2].fits->isImage() || context[2].fits->isPost())) {
 
     loadRGBFinish();
     return;
diff --git a/saotk/frame/framergbtruecolor.C b/saotk/frame/framergbtruecolor.C
index f99c461..2d11afb 100644
--- a/saotk/frame/framergbtruecolor.C
+++ b/saotk/frame/framergbtruecolor.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tk.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
diff --git a/saotk/frame/frametrue.C b/saotk/frame/frametrue.C
index e9836fd..f5dd617 100644
--- a/saotk/frame/frametrue.C
+++ b/saotk/frame/frametrue.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tk.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
@@ -41,13 +41,13 @@ void FrameTrue::rotateMotion()
 
   int& width = options->width;
   int& height = options->height;
-  char* src = XImageData(rotateSrcXM);
+  char* src = rotateSrcXM->data;
 
   int bytesPerPixel = rotateDestXM->bits_per_pixel/8;
 
   for (int j=0; j<height; j++) {
     // the line may be padded at the end
-    char* dest = XImageData(rotateDestXM) + j*rotateDestXM->bytes_per_line;
+    char* dest = rotateDestXM->data + j*rotateDestXM->bytes_per_line;
 
     for (int i=0; i<width; i++, dest+=bytesPerPixel) {
       double x = i*mm[0] + j*mm[3] + mm[6];
diff --git a/saotk/frame/frametruecolor.C b/saotk/frame/frametruecolor.C
index a444108..ca72b9b 100644
--- a/saotk/frame/frametruecolor.C
+++ b/saotk/frame/frametruecolor.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tk.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
@@ -227,7 +227,7 @@ void FrameTrueColor::colormapMotionCmd(int id, float b, float c, int i,
   // clear ximage
   int& width = colormapXM->width;
   int& height = colormapXM->height;
-  char* data = XImageData(colormapXM);
+  char* data = colormapXM->data;
   int bytesPerPixel = colormapXM->bits_per_pixel/8;
   int& bytesPerLine = colormapXM->bytes_per_line;
 
diff --git a/saotk/frame/frblt.C b/saotk/frame/frblt.C
index 3795664..358f356 100644
--- a/saotk/frame/frblt.C
+++ b/saotk/frame/frblt.C
@@ -5,9 +5,11 @@
 #include "base.h"
 #include "context.h"
 #include "fitsimage.h"
-#include "blt.h"
-#include "bltVector.h"
+
 #include "projection.h"
+extern "C" {
+#include "bltVector.h"
+}
 
 #include "sigbus.h"
 
@@ -127,38 +129,73 @@ int Base::markerAnalysisPlot3d(Marker* pp, double** x, double** y,
   }
 
   // init
-  int cnt[srcd];
   *x = (double*)malloc(srcd*sizeof(double));
   *y = (double*)malloc(srcd*sizeof(double));
-  for (long kk=0; kk<srcd; kk++) {
-    (*x)[kk] = 0;
-    (*y)[kk] = 0;
-    cnt[kk] = 0;
-  }
+  memset(*x,0,srcd*sizeof(double));
+  memset(*y,0,srcd*sizeof(double));
+
+  int* cnt = new int[srcd];
+  memset(cnt,0,srcd*sizeof(int));
 
   // take the bbox and extend to lower/upper pixel boundaries
   Vector ll = (bb.ll*ptr->refToData).floor();
   Vector ur = (bb.ur*ptr->refToData).ceil();
 
+  // mask
+  int ss = (ur[0]-ll[0])*(ur[1]-ll[1]);
+  bool* msk = new bool[ss];
+  long* idx = new long[ss];
+  memset(msk,0,ss*sizeof(bool));
+  memset(idx,0,ss*sizeof(long));
+
+  bool* mptr=msk;
+  long* iptr=idx;
+  if (!pp->isFixed()) {
+    Matrix bck = pp->bckMatrix();
+    for (int jj=ll[1]; jj<ur[1]; jj++) {
+      for (int ii=ll[0]; ii<ur[0]; ii++,mptr++,iptr++) {
+	if (ii>=params->xmin && ii<params->xmax && 
+	    jj>=params->ymin && jj<params->ymax) {
+	  // shift to center of pixel in DATA
+	  Vector rr = Vector(ii,jj)+Vector(.5,.5);
+	  if (pp->isIn(rr*ptr->dataToRef,bck)) {
+	    *mptr=1;
+	    *iptr=long(jj)*srcw+long(ii);
+	  }
+	}
+      }
+    }
+  }
+  else {
+    for (int jj=ll[1]; jj<ur[1]; jj++) {
+      for (int ii=ll[0]; ii<ur[0]; ii++,mptr++,iptr++) {
+	if (ii>=params->xmin && ii<params->xmax && 
+	    jj>=params->ymin && jj<params->ymax) {
+	  // shift to center of pixel in DATA
+	  Vector rr = Vector(ii,jj)+Vector(.5,.5);
+	  if (pp->isIn(rr*ptr->dataToRef,Coord::REF)) {
+	    *mptr=1;
+	    *iptr=long(jj)*srcw+long(ii);
+	  }
+	}
+      }
+    }
+  }
+
   // main loop
   SETSIGBUS
     for (int kk=0; kk<srcd; kk++) {
       (*x)[kk] = ptr->mapFromRef3(kk+.5+params->zmin, sys, 2);
 
-      for (int jj=ll[1]; jj<ur[1]; jj++) {
-	for (int ii=ll[0]; ii<ur[0]; ii++) {
-	  if (ii>=params->xmin && ii<params->xmax && 
-	      jj>=params->ymin && jj<params->ymax) {
-	    // shift to center of pixel in DATA
-	    Vector rr = Vector(ii,jj)+Vector(.5,.5);
-	    if (pp->isIn(rr*ptr->dataToRef,Coord::REF)) {
-	      double val =sjv[kk]->getValueDouble(long(jj)*srcw+long(ii));
-	      // check for nan
-	      if (isfinite(val)) {
-		(*y)[kk] += val;
-		cnt[kk]++;
-	      }
-	    }
+      bool* mptr=msk;
+      long* iptr=idx;
+      for (int ll=0; ll<ss; ll++,mptr++,iptr++) {
+	if (*mptr) {
+	  double val =sjv[kk]->getValueDouble(*iptr);
+	  // check for nan
+	  if (isfinite(val)) {
+	    (*y)[kk] += val;
+	    cnt[kk]++;
 	  }
 	}
       }
@@ -171,6 +208,13 @@ int Base::markerAnalysisPlot3d(Marker* pp, double** x, double** y,
       if (cnt[kk]!=0)
 	(*y)[kk] /= cnt[kk];
 
+  if (cnt)
+    delete [] cnt;
+  if (msk)
+    delete [] msk;
+  if (idx)
+    delete [] idx;
+
   return srcd;
 }
 
diff --git a/saotk/frame/frcommand.C b/saotk/frame/frcommand.C
index c178f79..4e4d3f3 100644
--- a/saotk/frame/frcommand.C
+++ b/saotk/frame/frcommand.C
@@ -5,7 +5,7 @@
 #include <fstream>
 #include "fdstream.hpp"
 
-#include "tcl.h"
+#include <tk.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
diff --git a/saotk/frame/grid.h b/saotk/frame/grid.h
index 4bd978b..bfe4286 100644
--- a/saotk/frame/grid.h
+++ b/saotk/frame/grid.h
@@ -5,8 +5,6 @@
 #ifndef __grid_h__
 #define __grid_h__
 
-#include <tk.h>
-
 #include "coord.h"
 
 class Grid {
diff --git a/saotk/frame/grid25d.h b/saotk/frame/grid25d.h
index e706a5f..ce3dca5 100644
--- a/saotk/frame/grid25d.h
+++ b/saotk/frame/grid25d.h
@@ -5,8 +5,6 @@
 #ifndef __grid25d_h__
 #define __grid25d_h__
 
-#include <tk.h>
-
 #include "grid.h"
 #include "grid25dbase.h"
 #include "coord.h"
diff --git a/saotk/frame/grid2d.h b/saotk/frame/grid2d.h
index 7d1941d..b540ebc 100644
--- a/saotk/frame/grid2d.h
+++ b/saotk/frame/grid2d.h
@@ -5,8 +5,6 @@
 #ifndef __grid2d_h__
 #define __grid2d_h__
 
-#include <tk.h>
-
 #include "grid.h"
 #include "grid2dbase.h"
 #include "coord.h"
diff --git a/saotk/frame/grid3d.h b/saotk/frame/grid3d.h
index f6a5820..9a47484 100644
--- a/saotk/frame/grid3d.h
+++ b/saotk/frame/grid3d.h
@@ -5,8 +5,6 @@
 #ifndef __grid3d_h__
 #define __grid3d_h__
 
-#include <tk.h>
-
 #include "grid.h"
 #include "grid3dbase.h"
 #include "coord.h"
diff --git a/saotk/frame/line.C b/saotk/frame/line.C
index ef5cff1..01084d0 100644
--- a/saotk/frame/line.C
+++ b/saotk/frame/line.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "line.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/marker.C b/saotk/frame/marker.C
index e780ed8..257f6d7 100644
--- a/saotk/frame/marker.C
+++ b/saotk/frame/marker.C
@@ -2,10 +2,14 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "marker.h"
 #include "fitsimage.h"
-#include "blt.h"
+
+extern "C" {
 #include "bltVector.h"
+}
 
 static int markerSeqID = 1;
 
@@ -479,7 +483,7 @@ void Marker::renderMACOSXText()
 }
 
 void Marker::renderMACOSXArrow(const Vector& p1, const Vector& p2, 
-			       InternalSystem sys)
+			       Coord::InternalSystem sys)
 {
   Vector* vv = arrow(p1,p2,sys);
   Vector dd[6];
@@ -1051,6 +1055,13 @@ int Marker::isIn(const Vector& vv, Coord::InternalSystem sys)
   return bbox.isIn(ss);
 }
 
+// assume Coord::REF
+int Marker::isIn(const Vector& vv, const Matrix& bck)
+{
+  Vector ss = parent->mapFromRef(vv,Coord::CANVAS);
+  return bbox.isIn(ss);
+}
+
 int Marker::isVisible(const BBox& b)
 {
   // assume visible, prove otherwise
diff --git a/saotk/frame/marker.h b/saotk/frame/marker.h
index 8206f82..0a798f9 100644
--- a/saotk/frame/marker.h
+++ b/saotk/frame/marker.h
@@ -166,11 +166,6 @@ protected:
   void listProps(ostream&);
   void listProperties(ostream&, int);
 
-  virtual Matrix fwdMatrix();
-  virtual Matrix bckMatrix();
-  virtual Vector fwdMap(const Vector&, Coord::InternalSystem);
-  virtual Vector bckMap(const Vector&, Coord::InternalSystem);
-
   void XMLRowInit();
   void XMLRow(XMLColName,int);
   void XMLRow(XMLColName,int*,int);
@@ -201,6 +196,11 @@ protected:
 	 const List<Tag>& tag, const List<CallBack>& cb);
   virtual ~Marker();
 
+  virtual Matrix fwdMatrix();
+  virtual Matrix bckMatrix();
+  virtual Vector fwdMap(const Vector&, Coord::InternalSystem);
+  virtual Vector bckMap(const Vector&, Coord::InternalSystem);
+
   virtual void x11(Drawable, Coord::InternalSystem, int, RenderMode,HandleMode);
   virtual void ps(int,int);
 #ifdef _MACOSX
@@ -232,13 +232,22 @@ protected:
   virtual void rotate(const Vector& v, int h);
   virtual void rotateEnd();
 
+  // assume Coord::CANVAS
   virtual int isIn(const Vector& vv) {return bbox.isIn(vv);}
+
   virtual int isIn(const Vector& vv, Coord::InternalSystem sys);
   virtual int isIn(const Vector& vv, Coord::InternalSystem sys, int nn)
   {return isIn(vv,sys);}
   virtual int isIn(const Vector& vv, Coord::InternalSystem sys, int nn, int aa)
   {return isIn(vv,sys);}
 
+  // assume Coord::REF
+  virtual int isIn(const Vector& vv, const Matrix& bck);
+  virtual int isIn(const Vector& vv, const Matrix& bck, int nn)
+  {return isIn(vv,bck);}
+  virtual int isIn(const Vector& vv, const Matrix& bck, int nn, int aa)
+  {return isIn(vv,bck);}
+
   void setAngle(double);
   double getAngle() {return angle;}
 
diff --git a/saotk/frame/point.C b/saotk/frame/point.C
index 93c0474..1d44bac 100644
--- a/saotk/frame/point.C
+++ b/saotk/frame/point.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "point.h"
 #include "fitsimage.h"
 
@@ -260,6 +262,7 @@ void Point::renderPSLineDash()
 void Point::renderMACOSX() 
 {
   renderMACOSXGC();
+  Vector* vv = NULL;
 
   switch (shape_) {
   case CIRCLE:
@@ -692,9 +695,9 @@ void Point::analysisPlot3d(char* xname, char* yname,
   analysisPlot3dResult(xname, yname, x, y, num);
 }
 
-int Point::isIn(const Vector& vv, Coord::InternalSystem sys)
+int Point::isInRef(const Vector& vv)
 {
-  Vector pp = bckMap(vv,sys);
+  Vector& pp = (Vector&)vv;
 
   if (pp[0]<-.5 || pp[0]>=.5 || pp[1]<-.5 || pp[1]>=.5)
     return 0;
diff --git a/saotk/frame/point.h b/saotk/frame/point.h
index 3ba5c0e..73b8021 100644
--- a/saotk/frame/point.h
+++ b/saotk/frame/point.h
@@ -46,6 +46,8 @@ class Point : public Marker {
   void shapeStr(PointShape);
   void updateHandles();
 
+  int isInRef(const Vector&);
+
  public:
   Point(const Point&);
   Point(Base* p, const Vector& ctr, 
@@ -75,8 +77,6 @@ class Point : public Marker {
   int size() {return size_;}
   void setSize(int);
 
-  int isIn(const Vector&, Coord::InternalSystem);
-
   void editBegin(int) {}
   void edit(const Vector& v, int h) {}
   void editEnd() {}
@@ -89,6 +89,11 @@ class Point : public Marker {
   void analysisPlot3d(char*, char*, Coord::CoordSystem sys, 
 		      Marker::AnalysisMethod);
 
+  int isIn(const Vector& vv, Coord::InternalSystem sys)
+  {return isInRef(bckMap(vv,sys));}
+  int isIn(const Vector& vv, const Matrix& bck)
+  {return isInRef(vv*bck);}
+
   void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int);
   void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat);
   void listPost(ostream&, int, int);
diff --git a/saotk/frame/polygon.C b/saotk/frame/polygon.C
index 48a7674..789683d 100644
--- a/saotk/frame/polygon.C
+++ b/saotk/frame/polygon.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "polygon.h"
 #include "fitsimage.h"
 
@@ -257,7 +259,7 @@ void Polygon::reset(const Vector& b)
   updateBBox();
 }
 
-int Polygon::isIn(const Vector& vv, Coord::InternalSystem sys)
+int Polygon::isInRef(const Vector& v)
 {
   /*
     v[0]-- x value of point being tested
@@ -273,7 +275,6 @@ int Polygon::isIn(const Vector& vv, Coord::InternalSystem sys)
     Points on a edge are considered inside.
   */
 
-  Vector v = bckMap(vv,sys);
   int crossings = 0;   // number of crossings
 
   vertex.head();
diff --git a/saotk/frame/polygon.h b/saotk/frame/polygon.h
index bca52a3..457db75 100644
--- a/saotk/frame/polygon.h
+++ b/saotk/frame/polygon.h
@@ -26,6 +26,8 @@ class Polygon : public Marker {
   void moveVertex(const Vector&, int);
   void recalcCenter();
 
+  int isInRef(const Vector& v);
+
 public:
   Polygon(const Polygon&);
   Polygon(Base* p, const Vector& ctr,
@@ -46,9 +48,6 @@ public:
   void edit(const Vector&, int);
   void rotate(const Vector&, int);
 
-  int isIn(const Vector& vv) {return isIn(vv, Coord::CANVAS);}
-  int isIn(const Vector&, Coord::InternalSystem);
-
   void analysis(AnalysisTask, int);
   void analysisPlot3d(char*, char*, Coord::CoordSystem, Marker::AnalysisMethod);
   void analysisStats(Coord::CoordSystem);
@@ -58,6 +57,13 @@ public:
   int getSegment(const Vector&);
   void reset(const Vector&);
 
+  int isIn(const Vector& vv) {return isIn(vv, Coord::CANVAS);}
+  int isIn(const Vector& vv, Coord::InternalSystem sys)
+  {return isInRef(bckMap(vv,sys));}
+
+  int isIn(const Vector& vv, const Matrix& bck)
+  {return isInRef(vv*bck);}
+
   void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int);
   void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat);
   virtual void listCiao(ostream&, Coord::CoordSystem, int);
diff --git a/saotk/frame/projection.C b/saotk/frame/projection.C
index 317a95d..ad8478f 100644
--- a/saotk/frame/projection.C
+++ b/saotk/frame/projection.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "projection.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/ruler.C b/saotk/frame/ruler.C
index 53f9409..9f75e8c 100644
--- a/saotk/frame/ruler.C
+++ b/saotk/frame/ruler.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "ruler.h"
 #include "fitsimage.h"
 
@@ -204,7 +206,7 @@ void Ruler::renderMACOSX()
       Tk_FontMetrics metrics;
       Tk_GetFontMetrics(psfont_, &metrics);
       char* buf = dupstr(vstr.str().c_str());
-      int width = Tk_TextWidth(psfont_, vbuf, strlen(buf));
+      int width = Tk_TextWidth(psfont_, buf, strlen(buf));
 
       Vector tt = ((bb-aa)/2 + aa) * Translate(-width/2., -metrics.descent);
       macosxDrawText(tt, 0, buf);
diff --git a/saotk/frame/segment.C b/saotk/frame/segment.C
index 5476b7d..a3a4421 100644
--- a/saotk/frame/segment.C
+++ b/saotk/frame/segment.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "segment.h"
 #include "fitsimage.h"
 
diff --git a/saotk/frame/text.C b/saotk/frame/text.C
index 6701d4f..0f68ece 100644
--- a/saotk/frame/text.C
+++ b/saotk/frame/text.C
@@ -2,14 +2,12 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "text.h"
 #include "fitsimage.h"
 #include "rotstr.h"
 
-#include <tcl.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
 Text::Text(const Text& a) : Marker(a) 
 {
   rotate = a.rotate;
@@ -51,9 +49,13 @@ void Text::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode
       Translate(cc);
     Vector vv = cc * mm;
 
-#if !(_GWIN32 || _MACOSX)
+#if !(_MACOSX || _GWIN32)
     XDrawRotString(display, drawable, lgc, vv, ang, text, tkfont_, parent);
-#else
+#endif
+#ifdef _MACOSX
+    XDrawRotString(display, drawable, lgc, vv, ang, text, tkfont_);
+#endif
+#ifdef _GWIN32
     XDrawRotString(display, drawable, lgc, vv, ang, text);
 #endif
   }
diff --git a/saotk/frame/vect.C b/saotk/frame/vect.C
index 31b40d5..d753051 100644
--- a/saotk/frame/vect.C
+++ b/saotk/frame/vect.C
@@ -2,6 +2,8 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "vect.h"
 #include "fitsimage.h"
 
diff --git a/saotk/list/Makefile b/saotk/list/Makefile
index bc4f3ec..379ab39 100644
--- a/saotk/list/Makefile
+++ b/saotk/list/Makefile
@@ -8,28 +8,12 @@ SRC	= list.C
 INCLS	= $(wildcard *.h)
 OBJS	= $(SRC:%.C=%.o)
 
-all	: $(OBJS) TAGS
+all	: $(OBJS)
 
 clean	: FORCE
 	rm -f core *~ *#
 
 distclean : clean
-	rm -f TAGS *.o $(LIB)
-
-ifdef DEPENDS
-TAGS	: $(SS) $(INCLS)
-	etags $+
-else
-TAGS	: FORCE
-endif
+	rm -f *.o $(LIB)
 
 FORCE	:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SRC:.C=.d)
-endif
diff --git a/saotk/magnifier/Makefile b/saotk/magnifier/Makefile
index 32aa0c1..7ba2c78 100644
--- a/saotk/magnifier/Makefile
+++ b/saotk/magnifier/Makefile
@@ -4,36 +4,22 @@ CXXFLAGS = $(CXXOPT) \
 	-I. -I.. -I../widget -I../vector -I../util \
 	-I../../include -I$(X11INCLUDE)
 
-SS	= \
+SRC	= \
 	magnifier.C \
-	magnifiertrue.C
-
-ifeq ($(OS),unix)
-SSP =	\
-	magnifierpseudo.C
-endif
-
-SRC	= $(SS) $(SSP) \
+	magnifiertrue.C \
 	parser.C \
 	lex.C
 
 INCLS	= $(wildcard *.h)
 OBJS	= $(SRC:%.C=%.o)
 
-all	: $(OBJS) TAGS
+all	: $(OBJS)
 
 clean	: FORCE
 	rm -f core *~ *#
 
 distclean : clean
-	rm -f TAGS *.o $(LIB) parser.output
-
-ifdef DEPENDS
-TAGS	: $(SS) $(INCLS)
-	etags $+
-else
-TAGS	: FORCE
-endif
+	rm -f *.o $(LIB) parser.output
 
 parsers	: parser
 
@@ -42,12 +28,3 @@ parser	: FORCE
 	flex -Pmg -olex.C lex.L
 
 FORCE	:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SRC:.C=.d)
-endif
diff --git a/saotk/magnifier/magnifierpseudo.C b/saotk/magnifier/magnifierpseudo.C
deleted file mode 100644
index 9333e76..0000000
--- a/saotk/magnifier/magnifierpseudo.C
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#include "magnifierpseudo.h"
-
-// Tk Canvas Widget Function Declarations
-
-int MagnifierPseudoColorCreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, 
-				   Tcl_Obj *const []);
-
-// MagnifierPseudoColor Specs
-
-static Tk_CustomOption tagsOption = {
-  Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
-};
-
-static Tk_ConfigSpec magnifierPseudoColorSpecs[] = {
-
-  {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "magnifier",
-   Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1",
-   Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1",
-   Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "256",
-   Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "256",
-   Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw",
-   Tk_Offset(WidgetOptions, anchor), 0, NULL},
-  {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL,
-   0, TK_CONFIG_NULL_OK, &tagsOption},
-
-  {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica",
-   Tk_Offset(WidgetOptions, helvetica), 0, NULL},
-  {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier",
-   Tk_Offset(WidgetOptions, courier), 0, NULL},
-  {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times",
-   Tk_Offset(WidgetOptions, times), 0, NULL},
-
-  {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL},
-};
-
-// Tk Static Structure
-
-static Tk_ItemType magnifierPseudoColorType = {
-  (char*)"magnifierpseudocolor",       // name
-  sizeof(WidgetOptions),        // size
-  MagnifierPseudoColorCreateProc,  // configProc
-  magnifierPseudoColorSpecs,    // configSpecs
-  WidgetConfigProc,             // configProc
-  WidgetCoordProc,              // coordProc
-  WidgetDeleteProc,             // deleteProc
-  WidgetDisplayProc,            // displayProc
-  0,                            // alwaysRedraw
-  WidgetPointProc,              // pointProc
-  WidgetAreaProc,               // areaProc
-  WidgetPostscriptProc,         // postscriptProc
-  WidgetScaleProc,              // scaleProc
-  WidgetTranslateProc,          // translateProc
-  (Tk_ItemIndexProc*)NULL,      // indexProc
-  (Tk_ItemCursorProc*)NULL,     // icursorProc
-  (Tk_ItemSelectionProc*)NULL,  // selectionProc
-  (Tk_ItemInsertProc*)NULL,     // insertProc
-  (Tk_ItemDCharsProc*)NULL,     // dCharsProc
-  (Tk_ItemType*)NULL            // nextPtr
-};
-
-// Non-Member Functions
-
-int MagnifierPseudoColor_Init(Tcl_Interp* interp)
-{
-  Tk_CreateItemType(&magnifierPseudoColorType);
-  return TCL_OK;
-}
-
-int MagnifierPseudoColorCreateProc(Tcl_Interp* interp, Tk_Canvas canvas, 
-				   Tk_Item* item, 
-				   int argc, Tcl_Obj *const argv[])
-{
-  MagnifierPseudoColor* magnifier = 
-    new MagnifierPseudoColor(interp, canvas, item);
-
-  // and set default configuration
-
-  if (magnifier->configure(argc, (const char**)argv, 0) != TCL_OK) {
-    delete magnifier;
-    Tcl_AppendResult(interp, " error occured while creating magnifier.", NULL);
-    return TCL_ERROR;
-  }
-
-  return TCL_OK;
-}
-
-MagnifierPseudoColor::MagnifierPseudoColor(Tcl_Interp* i, Tk_Canvas c, 
-					   Tk_Item* item)
-  : Magnifier(i, c, item)
-{
-  configSpecs = magnifierPseudoColorSpecs;  // magnifier configure options
-}
-
-void MagnifierPseudoColor::clearPixmap()
-{
-  XSetForeground(display, gc, getColor("white"));
-  XFillRectangle(display, pixmap, gc, 0, 0, options->width, options->height);
-}
diff --git a/saotk/magnifier/magnifierpseudo.h b/saotk/magnifier/magnifierpseudo.h
deleted file mode 100644
index 2ee950a..0000000
--- a/saotk/magnifier/magnifierpseudo.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#ifndef __magnifierpseudo_h__
-#define __magnifierpseudo_h__
-
-#include "magnifier.h"
-
-class MagnifierPseudoColor : public Magnifier {
-private:
-  void clearPixmap();
-
-public:
-  MagnifierPseudoColor(Tcl_Interp*, Tk_Canvas, Tk_Item*);
-};
-
-#endif
diff --git a/saotk/magnifier/magnifiertrue.C b/saotk/magnifier/magnifiertrue.C
index 961e5ef..4683703 100644
--- a/saotk/magnifier/magnifiertrue.C
+++ b/saotk/magnifier/magnifiertrue.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tcl.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
@@ -111,7 +111,7 @@ void MagnifierTrueColor::clearPixmap()
     return;
   }
 
-  memset(XImageData(xmap), 255, xmap->bytes_per_line * xmap->height);
+  memset(xmap->data, 255, xmap->bytes_per_line * xmap->height);
 
   XPutImage(display, pixmap, gc, xmap, 0, 0, 0, 0, options->width, 
 	    options->height);
diff --git a/saotk/panner/Makefile b/saotk/panner/Makefile
index 894dc36..8a02ec4 100644
--- a/saotk/panner/Makefile
+++ b/saotk/panner/Makefile
@@ -4,32 +4,22 @@ CXXFLAGS = $(CXXOPT) \
 	-I. -I.. -I../widget -I../vector -I../util \
 	-I../../include -I$(X11INCLUDE)
 
-SS	= \
+SRC	= \
 	panner.C \
-	pannerpseudo.C \
-	pannertrue.C
-
-SRC	= $(SS) \
+	pannertrue.C \
 	parser.C \
 	lex.C
 
 INCLS	= $(wildcard *.h)
 OBJS	= $(SRC:%.C=%.o)
 
-all	: $(OBJS) TAGS
+all	: $(OBJS)
 
 clean	: FORCE
 	rm -f core *~ *#
 
 distclean : clean
-	rm -f TAGS *.o $(LIB) parser.output
-
-ifdef DEPENDS
-TAGS	: $(SS) $(INCLS)
-	etags $+
-else
-TAGS	: FORCE
-endif
+	rm -f *.o $(LIB) parser.output
 
 parsers	: parser
 
@@ -38,12 +28,3 @@ parser	: FORCE
 	flex -Ppn -olex.C lex.L
 
 FORCE	:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SRC:.C=.d)
-endif
diff --git a/saotk/panner/panner.C b/saotk/panner/panner.C
index 57e9fbb..f74e58f 100644
--- a/saotk/panner/panner.C
+++ b/saotk/panner/panner.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
+#include <tcl.h>
 #include <X11/Xlib.h>
 
 #include "panner.h"
diff --git a/saotk/panner/pannerpseudo.C b/saotk/panner/pannerpseudo.C
deleted file mode 100644
index dbe54f7..0000000
--- a/saotk/panner/pannerpseudo.C
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#include "pannerpseudo.h"
-
-// Tk Canvas Widget Function Declarations
-
-int PannerPseudoColorCreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, 
-				Tcl_Obj *const []);
-
-// PannerPseudoColor Specs
-
-static Tk_CustomOption tagsOption = {
-  Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
-};
-
-static Tk_ConfigSpec pannerPseudoColorSpecs[] = {
-
-  {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "panner",
-   Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1",
-   Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1",
-   Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "256",
-   Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "256",
-   Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL},
-  {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw",
-   Tk_Offset(WidgetOptions, anchor), 0, NULL},
-  {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL,
-   0, TK_CONFIG_NULL_OK, &tagsOption},
-
-  {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica",
-   Tk_Offset(WidgetOptions, helvetica), 0, NULL},
-  {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier",
-   Tk_Offset(WidgetOptions, courier), 0, NULL},
-  {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times",
-   Tk_Offset(WidgetOptions, times), 0, NULL},
-
-  {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL},
-};
-
-// Tk Static Structure
-
-static Tk_ItemType pannerPseudoColorType = {
-  (char*)"pannerpseudocolor",         // name
-  sizeof(WidgetOptions),        // size
-  PannerPseudoColorCreateProc, // configProc
-  pannerPseudoColorSpecs,      // configSpecs
-  WidgetConfigProc,             // configProc
-  WidgetCoordProc,              // coordProc
-  WidgetDeleteProc,             // deleteProc
-  WidgetDisplayProc,            // displayProc
-  0,                            // alwaysRedraw
-  WidgetPointProc,              // pointProc
-  WidgetAreaProc,               // areaProc
-  WidgetPostscriptProc,         // postscriptProc
-  WidgetScaleProc,              // scaleProc
-  WidgetTranslateProc,          // translateProc
-  (Tk_ItemIndexProc*)NULL,      // indexProc
-  WidgetICursorProc,            // icursorProc
-  (Tk_ItemSelectionProc*)NULL,  // selectionProc
-  (Tk_ItemInsertProc*)NULL,     // insertProc
-  (Tk_ItemDCharsProc*)NULL,     // dCharsProc
-  (Tk_ItemType*)NULL            // nextPtr
-};
-
-// Non-Member Functions
-
-int PannerPseudoColor_Init(Tcl_Interp* interp)
-{
-  Tk_CreateItemType(&pannerPseudoColorType);
-  return TCL_OK;
-}
-
-int PannerPseudoColorCreateProc(Tcl_Interp* interp, Tk_Canvas canvas, 
-				Tk_Item* item, int argc, Tcl_Obj *const argv[])
-{
-  PannerPseudoColor* panner = new PannerPseudoColor(interp, canvas, item);
-
-  // and set default configuration
-
-  if (panner->configure(argc, (const char**)argv, 0) != TCL_OK) {
-    delete panner;
-    Tcl_AppendResult(interp, 
-		     " error occured while creating pannerPseudoColor.", NULL);
-    return TCL_ERROR;
-  }
-
-  return TCL_OK;
-}
-
-PannerPseudoColor::PannerPseudoColor(Tcl_Interp* i, Tk_Canvas c, 
-				     Tk_Item* item) : Panner(i, c, item)
-{
-  configSpecs = pannerPseudoColorSpecs;  // panner configure options
-}
-
-void PannerPseudoColor::clearPixmap()
-{
-  XFillRectangle(display, pixmap, gc, 0, 0, options->width, options->height);
-}
diff --git a/saotk/panner/pannerpseudo.h b/saotk/panner/pannerpseudo.h
deleted file mode 100644
index e8a2738..0000000
--- a/saotk/panner/pannerpseudo.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (C) 1999-2012
-// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
-// For conditions of distribution and use, see copyright notice in "copyright"
-
-#ifndef __pannerpseudo_h__
-#define __pannerpseudo_h__
-
-#include "panner.h"
-
-class PannerPseudoColor : public Panner {
-private:
-  void clearPixmap();
-
-public:
-  PannerPseudoColor(Tcl_Interp*, Tk_Canvas, Tk_Item*);
-};
-
-#endif
-
diff --git a/saotk/panner/pannertrue.C b/saotk/panner/pannertrue.C
index e3b10d6..4edbbf8 100644
--- a/saotk/panner/pannertrue.C
+++ b/saotk/panner/pannertrue.C
@@ -2,8 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tcl.h"
-
+#include <tcl.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
@@ -114,7 +113,7 @@ void PannerTrueColor::clearPixmap()
     return;
   }
 
-  memset(XImageData(xmap), 255, xmap->bytes_per_line * xmap->height);
+  memset(xmap->data, 255, xmap->bytes_per_line * xmap->height);
 
   XPutImage(display, pixmap, gc, xmap, 0, 0, 0, 0, options->width, options->height);
   XDestroyImage(xmap);
diff --git a/saotk/util/Makefile b/saotk/util/Makefile
index 592572c..09f5ec8 100644
--- a/saotk/util/Makefile
+++ b/saotk/util/Makefile
@@ -24,28 +24,12 @@ INCLS	= smooth.h \
 
 OBJS	= $(SRC:%.C=%.o)
 
-all	: $(OBJS) TAGS
+all	: $(OBJS)
 
 clean	: FORCE
 	rm -f core *~ *#
 
 distclean : clean
-	rm -f TAGS *.o 
-
-ifdef DEPENDS
-TAGS	: $(SS) $(INCLS)
-	etags $+
-else
-TAGS	: FORCE
-endif
+	rm -f *.o 
 
 FORCE	:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SRC:.C=.d)
-endif
diff --git a/saotk/util/grid25dbase.h b/saotk/util/grid25dbase.h
index cf79594..aacca74 100644
--- a/saotk/util/grid25dbase.h
+++ b/saotk/util/grid25dbase.h
@@ -5,8 +5,6 @@
 #ifndef __grid25dbase_h__
 #define __grid25dbase_h__
 
-#include <tk.h>
-
 #include "gridbase.h"
 
 class Grid25dBase : public GridBase {
diff --git a/saotk/util/grid2dbase.h b/saotk/util/grid2dbase.h
index 26b38e1..a551773 100644
--- a/saotk/util/grid2dbase.h
+++ b/saotk/util/grid2dbase.h
@@ -5,8 +5,6 @@
 #ifndef __grid2dbase_h__
 #define __grid2dbase_h__
 
-#include <tk.h>
-
 #include "gridbase.h"
 
 class Grid2dBase : public GridBase {
diff --git a/saotk/util/gridbase.C b/saotk/util/gridbase.C
index 96b3cc8..0803830 100644
--- a/saotk/util/gridbase.C
+++ b/saotk/util/gridbase.C
@@ -175,10 +175,15 @@ int GridBase::x11Text(const char* txt, float x, float y,
   double angle = calcTextAngle(just, up);
   Vector cc = vv * calcTextPos(vv, angle, txt, just, up, text_->tkfont());
 
-#if !(_GWIN32 || _MACOSX)
+#if !(_MACOSX || _GWIN32)
   XDrawRotString(parent_->getDisplay(), pixmap_, gc_, cc, angle, txt, 
 		 text_->tkfont(), parent_);
-#else
+#endif
+#ifdef _MACOSX
+  XDrawRotString(parent_->getDisplay(), pixmap_, gc_, cc, angle, txt, 
+		 text_->tkfont());
+#endif
+#ifdef _GWIN32
   XDrawRotString(parent_->getDisplay(), pixmap_, gc_, cc, angle, txt);
 #endif
   return 1;
diff --git a/saotk/util/saotk.C b/saotk/util/saotk.C
index ee6a955..0ab3dda 100644
--- a/saotk/util/saotk.C
+++ b/saotk/util/saotk.C
@@ -2,7 +2,7 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
-#include "tk.h"
+#include <tcl.h>
 
 extern int FrameTrueColor8_Init(Tcl_Interp*);
 extern int FrameTrueColor16_Init(Tcl_Interp*);
@@ -28,13 +28,6 @@ extern int PannerTrueColor_Init(Tcl_Interp*);
 
 extern int MagnifierTrueColor_Init(Tcl_Interp*);
 
-#if !(_GWIN32 || _MACOSX)
-extern int FramePseudoColor8_Init(Tcl_Interp*);
-extern int ColorbarPseudoColor8_Init(Tcl_Interp*);
-extern int MagnifierPseudoColor_Init(Tcl_Interp*);
-extern int PannerPseudoColor_Init(Tcl_Interp*);
-#endif
-
 extern "C" {
   int Saotk_Init(Tcl_Interp* interp);
   int SaotkCmd(ClientData data, Tcl_Interp *interp, int argc, 
@@ -85,18 +78,6 @@ int Saotk_Init(Tcl_Interp* interp) {
   if (ColorbarRGBTrueColor24_Init(interp) == TCL_ERROR)
     return TCL_ERROR;
 
-  // PseudoColor
-#if !(_GWIN32 || _MACOSX)
-  if (FramePseudoColor8_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  if (ColorbarPseudoColor8_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  if (PannerPseudoColor_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-  if (MagnifierPseudoColor_Init(interp) == TCL_ERROR)
-    return TCL_ERROR;
-#endif
-
   // dummy command 
   // needed for auto_load, since all of our real work are canvas widgets, 
   // tcl commands
diff --git a/saotk/util/util.C b/saotk/util/util.C
index 8a44002..341887d 100644
--- a/saotk/util/util.C
+++ b/saotk/util/util.C
@@ -4,10 +4,6 @@
 
 #include "util.h"
 
-#ifdef _MACOSX
-void macosxGetMasks(long*,long*,long*);
-#endif
-
 // Error in mapping
 int maperr= 0;
 
diff --git a/saotk/util/util.h b/saotk/util/util.h
index 053264d..ac525f5 100644
--- a/saotk/util/util.h
+++ b/saotk/util/util.h
@@ -16,6 +16,9 @@
 #include <iomanip>
 using namespace std;
 
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
 #include "fuzzy.h"
 #include "vector.h"
 
@@ -23,8 +26,6 @@ using namespace std;
 #define PATH_MAX 1024
 #endif
 
-#define XImageData(x) x->data
-
 #ifdef _GWIN32
 #include <xxlib.h>
 #include <win32lib.h>
@@ -33,10 +34,8 @@ using namespace std;
 #endif
 
 #ifdef _MACOSX
-#undef XImageData
 #include <xxlib.h>
 #include <macosxlib.h>
-#define XGetImage XXGetImage
 #define XQueryPointer XXQueryPointer
 #define XWarpPointer XXWarpPointer
 #endif
@@ -118,8 +117,4 @@ extern int dCompare(const void*, const void*);
 
 extern Vector mapLen(const Vector& v, const Matrix& mx);
 
-extern "C" {
-extern void conputs(FILE *fd, char *format, ...);
-}
-
 #endif
diff --git a/saotk/vector/Makefile b/saotk/vector/Makefile
index 24c43cd..9851f55 100644
--- a/saotk/vector/Makefile
+++ b/saotk/vector/Makefile
@@ -7,28 +7,12 @@ SRC	= vector.C vector3d.C
 INCLS	= $(wildcard *.h)
 OBJS	= $(SRC:%.C=%.o)
 
-all	: $(OBJS) TAGS
+all	: $(OBJS)
 
 clean	: FORCE
 	rm -f core *~ *# 
 
 distclean : clean
-	rm -f TAGS *.o $(LIB)
-
-ifdef DEPENDS
-TAGS	: $(SS) $(INCLS)
-	etags $+
-else
-TAGS	: FORCE
-endif
+	rm -f *.o $(LIB)
 
 FORCE	:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SRC:.C=.d)
-endif
diff --git a/saotk/vector/vector.C b/saotk/vector/vector.C
index 07b8d2c..4d5fc60 100644
--- a/saotk/vector/vector.C
+++ b/saotk/vector/vector.C
@@ -2,9 +2,10 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "vector.h"
 #include "vector3d.h"
-
 #include "fuzzy.h"
 
 // Vector
@@ -39,6 +40,11 @@ Vector& Vector::clip(const BBox& bb)
   return *this;
 }
 
+Vector Vector::TkCanvasPs(void* canvas)
+{
+  return Vector(v[0], Tk_CanvasPsY((Tk_Canvas)canvas, v[1]));
+}
+
 ostream& operator<<(ostream& s, const Vector& v)
 {
   s << ' ' << v.v[0] << ' ' << v.v[1] << ' ';
diff --git a/saotk/vector/vector.h b/saotk/vector/vector.h
index c48c503..4ace2bc 100644
--- a/saotk/vector/vector.h
+++ b/saotk/vector/vector.h
@@ -11,8 +11,6 @@
 #include <iostream>
 using namespace std;
 
-#include "tk.h"
-
 class Vector3d;
 class Matrix;
 class BBox;
@@ -71,8 +69,7 @@ class Vector {
     return d ? Vector(v[0]/d,v[1]/d) : Vector();}
   Vector& clip(const BBox&);
 
-  Vector TkCanvasPs(Tk_Canvas canvas)
-  {return Vector(v[0], Tk_CanvasPsY(canvas, v[1]));}
+  Vector TkCanvasPs(void* canvas);
 };
 ostream& operator<<(ostream&, const Vector&);
 istream& operator>>(istream&, Vector&);
@@ -310,7 +307,6 @@ inline BBox operator-(const BBox& b, const Vector& v) {return BBox(b) -= v;}
 inline BBox operator*(const BBox& b, const Matrix& m) {return BBox(b) *= m;}
 
 BBox intersect(const BBox&, const BBox&);
-
 #endif
 
 
diff --git a/saotk/vector/vector3d.C b/saotk/vector/vector3d.C
index 1e18e2c..cb2837c 100644
--- a/saotk/vector/vector3d.C
+++ b/saotk/vector/vector3d.C
@@ -2,9 +2,10 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <tk.h>
+
 #include "vector3d.h"
 #include "vector.h"
-
 #include "fuzzy.h"
 
 // Vector3d
@@ -34,9 +35,9 @@ Vector3d& Vector3d::operator=(const Vector& a)
   return *this;
 }
 
-Vector Vector3d::TkCanvasPs(Tk_Canvas canvas)
+Vector Vector3d::TkCanvasPs(void* canvas)
 {
-  return Vector(v[0], Tk_CanvasPsY(canvas, v[1]));
+  return Vector(v[0], Tk_CanvasPsY((Tk_Canvas)canvas, v[1]));
 }
 
 ostream& operator<<(ostream& s, const Vector3d& v)
diff --git a/saotk/vector/vector3d.h b/saotk/vector/vector3d.h
index 22ad908..68c474e 100644
--- a/saotk/vector/vector3d.h
+++ b/saotk/vector/vector3d.h
@@ -11,8 +11,6 @@
 #include <iostream>
 using namespace std;
 
-#include "tk.h"
-
 class Vector;
 class Matrix;
 class Matrix3d;
@@ -76,7 +74,7 @@ class Vector3d {
     return d ? Vector3d(v[0]/d,v[1]/d,v[2]/d) : Vector3d();}
   Vector3d project()
   {return (v[3]!=1) ? Vector3d(v[0]/v[3],v[1]/v[3],v[2]/v[3]) : *this;}
-  Vector TkCanvasPs(Tk_Canvas canvas);
+  Vector TkCanvasPs(void* canvas);
 };
 ostream& operator<<(ostream&, const Vector3d&);
 istream& operator>>(istream&, Vector3d&);
diff --git a/saotk/vector/vectorold.h b/saotk/vector/vectorold.h
index feadd2a..1dffa48 100644
--- a/saotk/vector/vectorold.h
+++ b/saotk/vector/vectorold.h
@@ -11,7 +11,7 @@
 #include <iostream>
 using namespace std;
 
-#include "tk.h"
+#include <tk.h>
 
 class Vector;
 class Vertex;
diff --git a/saotk/widget/Makefile b/saotk/widget/Makefile
index ecde084..4cd3ff9 100644
--- a/saotk/widget/Makefile
+++ b/saotk/widget/Makefile
@@ -12,28 +12,12 @@ SRC	= truecolor8.C \
 INCLS	= $(wildcard *.h)
 OBJS	= $(SRC:%.C=%.o)
 
-all	: $(OBJS) TAGS
+all	: $(OBJS)
 
 clean	: FORCE
 	rm -f core *~ *#
 
 distclean : clean
-	rm -f TAGS *.o $(LIB)
-
-ifdef DEPENDS
-TAGS	: $(SS) $(INCLS)
-	etags $+
-else
-TAGS	: FORCE
-endif
+	rm -f *.o $(LIB)
 
 FORCE:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SRC:.C=.d)
-endif
diff --git a/saotk/widget/truecolor16.C b/saotk/widget/truecolor16.C
index b2dd665..34adabf 100644
--- a/saotk/widget/truecolor16.C
+++ b/saotk/widget/truecolor16.C
@@ -5,27 +5,13 @@
 #include "truecolor16.h"
 #include "util.h"
 
-#ifdef _MACOSX
-extern void macosxGetMasks(unsigned long*, unsigned long*, 
-			   unsigned long*, unsigned long*);
-#endif
-
 TrueColor16::TrueColor16(Visual* visual)
 {
-#if !(_WIN32 || _MACOSX)
+#if !(_WIN32)
   rx_ = visual->red_mask;
   gx_ = visual->green_mask;
   bx_ = visual->blue_mask;
 #endif
-#if _MACOSX
-  // tk visual masks are bogus
-  unsigned long red_mask, green_mask, blue_mask, alpha_mask;
-  macosxGetMasks(&red_mask, &green_mask, &blue_mask, &alpha_mask);
-
-  rx_ = red_mask;
-  gx_ = green_mask;
-  bx_ = blue_mask;
-#endif
 #if _WIN32
   // windows masks are plain wrong
   rx_ = 0x7C00;
@@ -119,7 +105,7 @@ void TrueColor16::encodeTrueColor(unsigned char* src, XImage* ximage)
 {
   int& width = ximage->width;
   int& height = ximage->height;
-  char* data = XImageData(ximage);
+  char* data = ximage->data;
   int msb = ximage->byte_order;
 
   const unsigned char* ptr = src;
diff --git a/saotk/widget/truecolor24.C b/saotk/widget/truecolor24.C
index 8f65558..b71655b 100644
--- a/saotk/widget/truecolor24.C
+++ b/saotk/widget/truecolor24.C
@@ -5,35 +5,26 @@
 #include "truecolor24.h"
 #include "util.h"
 
-#ifdef _MACOSX
-extern void macosxGetMasks(unsigned long*, unsigned long*, 
-			   unsigned long*, unsigned long*);
-#endif
-
 TrueColor24::TrueColor24(Visual* visual)
 {
 #if !(_WIN32 || _MACOSX)
+  ax_ = 0;
   rx_ = visual->red_mask;
   gx_ = visual->green_mask;
   bx_ = visual->blue_mask;
-  ax_ = 0;
 #endif
 #if _MACOSX
-  // tk visual masks are bogus
-  unsigned long red_mask, green_mask, blue_mask, alpha_mask;
-  macosxGetMasks(&red_mask, &green_mask, &blue_mask, &alpha_mask);
-
-  rx_ = red_mask;
-  gx_ = green_mask;
-  bx_ = blue_mask;
-  ax_ = alpha_mask;
+  ax_ = 0xFF000000;
+  rx_ = 0x00FF0000;
+  gx_ = 0x0000FF00;
+  bx_ = 0x000000FF;
 #endif
 #if _WIN32
   // windows masks are plain wrong
+  ax_ = 0;
   rx_ = 0x00FF0000;
   gx_ = 0x0000FF00;
   bx_ = 0x000000FF;
-  ax_ = 0;
 #endif
 
   rs_ = decodeMask((unsigned long)rx_);
@@ -137,6 +128,10 @@ void TrueColor24::encodeTrueColor32(XColor* src, char* dest, XImage* ximage)
   unsigned int g = (unsigned char)src->green;
   unsigned int b = (unsigned char)src->blue;
   unsigned int v = 0;
+#ifdef _MACOSX
+  unsigned int a = 0xff;
+  v |= a << as_;
+#endif
   v |= r << rs_;
   v |= g << gs_;
   v |= b << bs_;
@@ -190,7 +185,7 @@ void TrueColor24::encodeTrueColor24(unsigned char* src, XImage* ximage)
 {
   int& width = ximage->width;
   int& height = ximage->height;
-  char* data = XImageData(ximage);
+  char* data = ximage->data;
   int bytesPerPixel = ximage->bits_per_pixel/8;
   int msb = ximage->byte_order;
 
@@ -238,7 +233,7 @@ void TrueColor24::encodeTrueColor32(unsigned char* src, XImage* ximage)
 {
   int& width = ximage->width;
   int& height = ximage->height;
-  char* data = XImageData(ximage);
+  char* data = ximage->data;
   int bytesPerPixel = ximage->bits_per_pixel/8;
   int msb = ximage->byte_order;
 
diff --git a/saotk/widget/truecolor8.C b/saotk/widget/truecolor8.C
index 38f6821..49401fa 100644
--- a/saotk/widget/truecolor8.C
+++ b/saotk/widget/truecolor8.C
@@ -5,28 +5,14 @@
 #include "truecolor8.h"
 #include "util.h"
 
-#ifdef _MACOSX
-extern void macosxGetMasks(unsigned long*, unsigned long*, 
-			   unsigned long*, unsigned long*);
-#endif
-
 TrueColor8::TrueColor8(Visual* visual)
 {
 
-#if !(_WIN32 || _MACOSX)
+#if !(_WIN32)
   rx_ = visual->red_mask;
   gx_ = visual->green_mask;
   bx_ = visual->blue_mask;
 #endif
-#if _MACOSX
-  // tk visual masks are bogus
-  unsigned long red_mask, green_mask, blue_mask, alpha_mask;
-  macosxGetMasks(&red_mask, &green_mask, &blue_mask, &alpha_mask);
-
-  rx_ = red_mask;
-  gx_ = green_mask;
-  bx_ = blue_mask;
-#endif
 #if _WIN32
   // windows masks are plain wrong
   rx_ = 0xE0;
@@ -69,7 +55,7 @@ void TrueColor8::encodeTrueColor(unsigned char* src, XImage* ximage)
 {
   int& width = ximage->width;
   int& height = ximage->height;
-  char* data = XImageData(ximage);
+  char* data = ximage->data;
 
   const unsigned char* ptr = src;
   for (int j=0; j<height; j++) {
diff --git a/saotk/widget/widget.h b/saotk/widget/widget.h
index acc8b26..1f99e56 100644
--- a/saotk/widget/widget.h
+++ b/saotk/widget/widget.h
@@ -23,7 +23,6 @@ using namespace std;
 
 class Attribute;
 
-// in tkCanvasPs.c
 extern float psScale;
 
 // General Defines
diff --git a/src/3d.tcl b/src/3d.tcl
index 12b34e6..5f05817 100644
--- a/src/3d.tcl
+++ b/src/3d.tcl
@@ -47,7 +47,6 @@ proc 3DDialog {} {
     set mb $ithreed(mb)
 
     Toplevel $w $mb 6 [msgcat::mc {3D}] 3DDestroyDialog
-
     $mb add cascade -label [msgcat::mc {File}] -menu $mb.file
     $mb add cascade -label [msgcat::mc {Method}] -menu $mb.method
     $mb add cascade -label [msgcat::mc {Highlite}] -menu $mb.highlite
diff --git a/src/Makefile b/src/Makefile
index 637ce39..bb6007f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -104,6 +104,8 @@ SCRIPTS = \
 	mfile.tcl \
 	mframe.tcl \
 	mhelp.tcl \
+	macosx.tcl \
+	macosxextra.tcl \
 	mosaicimage.tcl \
 	mosaicimageiraf.tcl \
 	mosaicimagewcs.tcl \
@@ -175,14 +177,10 @@ SCRIPTS = \
 	vector.tcl \
 	vo.tcl \
 	wcs.tcl \
+	win32.tcl \
 	xmfbox.tcl \
 	xpa.tcl
 
-INDEX	= pkgIndex.tcl
-
-index	: $(SCRIPTS)
-	echo "pkg_mkIndex . $(SCRIPTS)" | ../bin/tclsh8.4
-
 msgs	: FORCE
 	grep 'msgcat::mc' $(SCRIPTS) | cut -d[ -f2 | sed -e 's/::mc/::mcset AAA /' -e 's/]/ ""/' | sort | uniq > ../msgs/tmpl.tcl
 
@@ -190,6 +188,5 @@ clean	: FORCE
 	$(RM) core *~ *# 
 
 distclean : clean
-	$(RM) $(INDEX)
 
 FORCE	:
diff --git a/src/analysis.tcl b/src/analysis.tcl
index 0c6c353..b87c40d 100644
--- a/src/analysis.tcl
+++ b/src/analysis.tcl
@@ -1736,7 +1736,7 @@ proc AnalysisEntry {message resultvar} {
 proc AnalysisPrefOpen {varname} {
     upvar $varname var
 
-    FileLastFull analysisfbox $var
+    FileLast analysisfbox $var
     set var [OpenFileDialog analysisfbox]
 }
 
diff --git a/src/backup.tcl b/src/backup.tcl
index 9d919e0..8388b50 100644
--- a/src/backup.tcl
+++ b/src/backup.tcl
@@ -101,15 +101,8 @@ proc Backup {fn} {
 
     # Colorbar
     ColorbarBackupCmaps $ch $dir
-    switch -- $ds9(visual) {
-	pseudocolor {
-	    ColorbarBackup $ch colorbar
-	}
-	truecolor {
-	    ColorbarBackup $ch colorbar
-	    ColorbarBackup $ch colorbarrgb
-	}
-    }
+    ColorbarBackup $ch colorbar
+    ColorbarBackup $ch colorbarrgb
 
     # Frames
     foreach ff $ds9(frames) {
diff --git a/src/bin.tcl b/src/bin.tcl
index e5e2add..c37ed5b 100644
--- a/src/bin.tcl
+++ b/src/bin.tcl
@@ -204,7 +204,6 @@ proc BinDialog {} {
     set mb $ibin(mb)
 
     Toplevel $w $mb 6 [msgcat::mc {Binning Parameters}] BinDestroyDialog
-
     $mb add cascade -label [msgcat::mc {File}] -menu $mb.file
     $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit
     $mb add cascade -label [msgcat::mc {Method}] -menu $mb.method
diff --git a/src/buttons.tcl b/src/buttons.tcl
index a40d62d..5a54706 100644
--- a/src/buttons.tcl
+++ b/src/buttons.tcl
@@ -170,11 +170,25 @@ proc RadioButtonCB {button value varname id op} {
     upvar #0 $varname var
     global $varname
 
+    global ds9
+
     if {[$button cget -state] != {disabled}} {
-	if {$var($id) == $value} {
-	    $button configure -state active
-	} else {
-	    $button configure -state normal
+	switch $ds9(wm) {
+	    x11 {
+		if {$var($id) == $value} {
+		    $button configure -state active
+		} else {
+		    $button configure -state normal
+		}
+	    }
+	    win32 -
+	    aqua {
+		if {$var($id) == $value} {
+		    $button configure -default active
+		} else {
+		    $button configure -default normal
+		}
+	    }
 	}
     }
 }
@@ -189,11 +203,25 @@ proc CheckButtonCB {button varname id op} {
     upvar #0 $varname var
     global $varname
 
+    global ds9
+
     if {[$button cget -state] != {disabled}} {
-	if {$var($id)} {
-	    $button configure -state active
-	} else {
-	    $button configure -state normal
+	switch $ds9(wm) {
+	    x11 {
+		if {$var($id)} {
+		    $button configure -state active
+		} else {
+		    $button configure -state normal
+		}
+	    }
+	    win32 -
+	    aqua {
+		if {$var($id)} {
+		    $button configure -default active
+		} else {
+		    $button configure -default normal
+		}
+	    }
 	}
     }
 }
diff --git a/src/catcmd.tcl b/src/catcmd.tcl
index fd5b3f7..052a563 100644
--- a/src/catcmd.tcl
+++ b/src/catcmd.tcl
@@ -55,6 +55,8 @@ proc CATSelectBrowseCmd {varname ss rc} {
     upvar #0 $varname var
     global $varname
 
+    puts stderr "CATSelectBrowseCmd $varname ss=$ss rc=$rc"
+
     # starts at 1
     global debug
     if {$debug(tcl,cat)} {
@@ -88,6 +90,17 @@ proc CATSelectBrowseCmd {varname ss rc} {
 	lappend rowlist $rr
     }
     set rowlist [lsort -unique $rowlist]
+
+    # kludge
+    # tktable can return bogus numbers if arrow keys are used
+    # try to fix
+    if {$row == 0} {
+	set row 1
+    }
+    if {[llength $rowlist] <= 1} {
+	set rowlist $row
+    }
+
     foreach rr $rowlist {
 	lappend ${varname}(blink,marker) "\{${varname}.${rr}\}"
     }
diff --git a/src/catdialog.tcl b/src/catdialog.tcl
index 6e8c2c8..dcfa4f4 100644
--- a/src/catdialog.tcl
+++ b/src/catdialog.tcl
@@ -98,8 +98,8 @@ proc CATDialog {varname format catalog title action} {
     } else {
 	set tt [msgcat::mc {Catalog Tool}]
     }
-    Toplevel $w $mb 7 $tt "CATDestroy $varname"
 
+    Toplevel $w $mb 7 $tt "CATDestroy $varname"
     $mb add cascade -label [msgcat::mc {File}] -menu $mb.file
     $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit
     CATServerMenu $varname
diff --git a/src/catsym.tcl b/src/catsym.tcl
index 609cc7f..b455f20 100644
--- a/src/catsym.tcl
+++ b/src/catsym.tcl
@@ -72,9 +72,9 @@ proc CATSymDialog {parent} {
     set mb $var(mb)
 
     Toplevel $w $mb 7 [msgcat::mc {Symbol Editor}] "CATSymDestroy $varname"
+    $mb add cascade -label [msgcat::mc {File}] -menu $mb.file
 
     # menu
-    $mb add cascade -label [msgcat::mc {File}] -menu $mb.file
     menu $mb.file
     $mb.file add command -label [msgcat::mc {Apply}] \
 	-command "CATSymApply $varname"
diff --git a/src/centroid.tcl b/src/centroid.tcl
index 7451201..5fb9276 100644
--- a/src/centroid.tcl
+++ b/src/centroid.tcl
@@ -29,7 +29,6 @@ proc CentroidDialog {} {
     set mb $icentroid(mb)
 
     Toplevel $w $mb 6 [msgcat::mc {Centroid Parameters}] CentroidDestroyDialog
-
     $mb add cascade -label [msgcat::mc {File}] -menu $mb.file
     $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit
 
diff --git a/src/colorbar.tcl b/src/colorbar.tcl
index e48f249..84cfbe7 100644
--- a/src/colorbar.tcl
+++ b/src/colorbar.tcl
@@ -49,69 +49,42 @@ proc CreateColorbar {} {
     global canvas
     global view
 
-    switch -- $ds9(visual) {
-	pseudocolor {
-	    $ds9(canvas) create colorbar$ds9(visual)$ds9(depth) \
-		-private $icolorbar(private) \
-		-tag colorbar \
-		-anchor nw \
-		-helvetica $ds9(helvetica) \
-		-courier $ds9(courier) \
-		-times $ds9(times)
-
-	    # And set the two windows that where created before the 
-	    # colorbar was created, to the new colormap
-
-	    colorbar colormap window "$ds9(main)"
-
-	    $ds9(canvas) bind colorbar <Motion> [list MotionColorbar %x %y]
-	    $ds9(canvas) bind colorbar <Enter> [list EnterColorbar %x %y]
-	    $ds9(canvas) bind colorbar <Leave> [list LeaveColorbar]
-
-	    $ds9(canvas) bind colorbar <Button-1> [list Button1Colorbar %x %y]
-	    $ds9(canvas) bind colorbar <B1-Motion> [list Motion1Colorbar %x %y]
-	    $ds9(canvas) bind colorbar <ButtonRelease-1> [list Release1Colorbar %x %y]
-	    $ds9(canvas) bind colorbar <Key> [list KeyColorbar %K %A %x %y]
-	    $ds9(canvas) bind colorbar <KeyRelease> [list KeyReleaseColorbar %K %A %x %y]
-	}
-	truecolor {
-	    $ds9(canvas) create colorbar$ds9(visual)$ds9(depth) \
-		-colors 2048 \
-		-tag colorbar \
-		-anchor nw \
-		-helvetica $ds9(helvetica) \
-		-courier $ds9(courier) \
-		-times $ds9(times)
-
-	    $ds9(canvas) bind colorbar <Motion> [list MotionColorbar %x %y]
-	    $ds9(canvas) bind colorbar <Enter> [list EnterColorbar %x %y]
-	    $ds9(canvas) bind colorbar <Leave> [list LeaveColorbar]
-
-	    $ds9(canvas) bind colorbar <Button-1> [list Button1Colorbar %x %y]
-	    $ds9(canvas) bind colorbar <B1-Motion> [list Motion1Colorbar %x %y]
-	    $ds9(canvas) bind colorbar <ButtonRelease-1> \
-		[list Release1Colorbar %x %y]
-	    $ds9(canvas) bind colorbar <Double-1> [list Double1Colorbar %x %y]
-	    $ds9(canvas) bind colorbar <Double-ButtonRelease-1> \
-		[list DoubleRelease1Colorbar %x %y]
-
-	    $ds9(canvas) bind colorbar <Key> [list KeyColorbar %K %A %x %y]
-	    $ds9(canvas) bind colorbar <KeyRelease> \
-		[list KeyReleaseColorbar %K %A %x %y]
-
-	    $ds9(canvas) create colorbarrgb$ds9(visual)$ds9(depth) \
-		-colors 2048 \
-		-tag colorbarrgb \
-		-anchor nw \
-		-helvetica $ds9(helvetica) \
-		-courier $ds9(courier) \
-		-times $ds9(times)
-
-	    $ds9(canvas) bind colorbarrgb <Motion> [list MotionColorbar %x %y]
-	    $ds9(canvas) bind colorbarrgb <Enter> [list EnterColorbar %x %y]
-	    $ds9(canvas) bind colorbarrgb <Leave> [list LeaveColorbar]
-	}
-    }
+    $ds9(canvas) create colorbar$ds9(visual)$ds9(depth) \
+	-colors 2048 \
+	-tag colorbar \
+	-anchor nw \
+	-helvetica $ds9(helvetica) \
+	-courier $ds9(courier) \
+	-times $ds9(times)
+
+    $ds9(canvas) bind colorbar <Motion> [list MotionColorbar %x %y]
+    $ds9(canvas) bind colorbar <Enter> [list EnterColorbar %x %y]
+    $ds9(canvas) bind colorbar <Leave> [list LeaveColorbar]
+
+    $ds9(canvas) bind colorbar <Button-1> [list Button1Colorbar %x %y]
+    $ds9(canvas) bind colorbar <B1-Motion> [list Motion1Colorbar %x %y]
+    $ds9(canvas) bind colorbar <ButtonRelease-1> \
+	[list Release1Colorbar %x %y]
+    $ds9(canvas) bind colorbar <Double-1> [list Double1Colorbar %x %y]
+    $ds9(canvas) bind colorbar <Double-ButtonRelease-1> \
+	[list DoubleRelease1Colorbar %x %y]
+
+    $ds9(canvas) bind colorbar <Key> [list KeyColorbar %K %A %x %y]
+    $ds9(canvas) bind colorbar <KeyRelease> \
+	[list KeyReleaseColorbar %K %A %x %y]
+
+    $ds9(canvas) create colorbarrgb$ds9(visual)$ds9(depth) \
+	-colors 2048 \
+	-tag colorbarrgb \
+	-anchor nw \
+	-helvetica $ds9(helvetica) \
+	-courier $ds9(courier) \
+	-times $ds9(times)
+
+    $ds9(canvas) bind colorbarrgb <Motion> [list MotionColorbar %x %y]
+    $ds9(canvas) bind colorbarrgb <Enter> [list EnterColorbar %x %y]
+    $ds9(canvas) bind colorbarrgb <Leave> [list LeaveColorbar]
+
     LayoutColorbar
 }
 
@@ -988,6 +961,7 @@ proc UpdateColorDialog {} {
     if {[winfo exists $icolorbar(top)]} {
 	set dcolorbar(contrast) [$current(colorbar) get contrast]
 	set dcolorbar(bias) [$current(colorbar) get bias]
+	set end [expr $icolorbar(contrib)+$icolorbar(start)]
 
 	if {$current(frame) != {}} {
 	    switch -- [$current(frame) get type] {
@@ -997,7 +971,7 @@ proc UpdateColorDialog {} {
 			"[msgcat::mc {Load Colormap}]..." -state normal
 		    $icolorbar(mb).file entryconfig \
 			"[msgcat::mc {Save Colormap}]..." -state normal
-		    for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} {
+		    for {set ii $icolorbar(start)} {$ii<$end} {incr ii} {
 			$icolorbar(mb).colormap entryconfig $ii -state normal
 		    }
 		    $icolorbar(mb).colormap entryconfig \
@@ -1010,7 +984,7 @@ proc UpdateColorDialog {} {
 			"[msgcat::mc {Load Colormap}]..." -state disabled
 		    $icolorbar(mb).file entryconfig \
 			"[msgcat::mc {Save Colormap}]..." -state disabled
-		    for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} {
+		    for {set ii $icolorbar(start)} {$ii<$end} {incr ii} {
 			$icolorbar(mb).colormap entryconfig $ii -state disabled
 		    }
 		    $icolorbar(mb).colormap entryconfig \
@@ -1024,7 +998,7 @@ proc UpdateColorDialog {} {
 		"[msgcat::mc {Load Colormap}]..." -state normal
 	    $icolorbar(mb).file entryconfig \
 		"[msgcat::mc {Save Colormap}]..." -state normal
-	    for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} {
+	    for {set ii $icolorbar(start)} {$ii<$end(contrib)} {incr ii} {
 		$icolorbar(mb).colormap entryconfig $ii -state normal
 	    }
 	    $icolorbar(mb).colormap entryconfig [msgcat::mc {Contributed}] \
@@ -1052,17 +1026,15 @@ proc LayoutColorbar {} {
 	-fontweight $colorbar(font,weight) \
 	-fontslant $colorbar(font,slant) \
 
-    if {$ds9(visual) == {truecolor}} {
-	colorbarrgb configure \
-	    -size $colorbar(size) \
-	    -ticks $colorbar(ticks) \
-	    -numerics $colorbar(numerics) \
-	    -space $colorbar(space) \
-	    -font $colorbar(font) \
-	    -fontsize $colorbar(font,size) \
-	    -fontweight $colorbar(font,weight) \
-	    -fontslant $colorbar(font,slant) \
-    }
+    colorbarrgb configure \
+	-size $colorbar(size) \
+	-ticks $colorbar(ticks) \
+	-numerics $colorbar(numerics) \
+	-space $colorbar(space) \
+	-font $colorbar(font) \
+	-fontsize $colorbar(font,size) \
+	-fontweight $colorbar(font,weight) \
+	-fontslant $colorbar(font,slant) \
 
     switch -- $colorbar(orientation) {
 	horizontal {
@@ -1074,12 +1046,10 @@ proc LayoutColorbar {} {
 		-height $icolorbar(horizontal,height) \
 		-orientation 0
 
-	    if {$ds9(visual) == {truecolor}} {
-		colorbarrgb configure -x $xx -y $yy \
-		    -width $canvas(width) \
-		    -height $icolorbar(horizontal,height) \
-		    -orientation 0
-	    }
+	    colorbarrgb configure -x $xx -y $yy \
+		-width $canvas(width) \
+		-height $icolorbar(horizontal,height) \
+		-orientation 0
 	}
 	vertical {
 	    set xx [expr $canvas(width) + $canvas(gap)]
@@ -1090,12 +1060,10 @@ proc LayoutColorbar {} {
 		-height $canvas(height) \
 		-orientation 1
 
-	    if {$ds9(visual) == {truecolor}} {
-		colorbarrgb configure -x $xx -y $yy \
-		    -width $icolorbar(vertical,width) \
-		    -height $canvas(height) \
-		    -orientation 1
-	    }
+	    colorbarrgb configure -x $xx -y $yy \
+		-width $icolorbar(vertical,width) \
+		-height $canvas(height) \
+		-orientation 1
 	}
     }
 }
diff --git a/src/command.tcl b/src/command.tcl
index 9d07cbb..6108776 100644
--- a/src/command.tcl
+++ b/src/command.tcl
@@ -7,7 +7,7 @@ package provide DS9 1.0
 proc BadVisualError {} {
     global ds9
 
-    Error [msgcat::mc {Sorry, DS9 requires a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual be available}]
+    Error [msgcat::mc {Sorry, DS9 requires a Truecolor8, Truecolor16, Truecolor24 visual be available}]
     exit
 }
 
diff --git a/src/ds9.tcl b/src/ds9.tcl
index 456ea9f..531345a 100755
--- a/src/ds9.tcl
+++ b/src/ds9.tcl
@@ -7,7 +7,7 @@ proc DS9Def {} {
     global pds9
 
     set ds9(title) "$ds9(app)"
-    set ds9(version) {7.3 beta 2}
+    set ds9(version) {7.3 beta 3}
 
     set ds9(top) .
     set ds9(mb) .mb
@@ -51,7 +51,6 @@ proc DS9Def {} {
     set ds9(event,opendoc) {}
     set ds9(event,printdoc) {}
 
-    set ds9(dialog,dir) {}
     set ds9(tmpdir) {}
 
     switch $ds9(wm) {
@@ -159,75 +158,122 @@ proc DS9Def {} {
     set pds9(threads) 8
 }
 
-# who are we?
-set ds9(app) [file rootname [file tail $argv0]]
+proc DEBUGS {str} {
+    set ch [open "/Users/joye/debug.txt" "a+"]
+    puts $ch $str
+    close $ch
+}
+
 # if we have a problem at this point, dump simple message and exit
 if {[catch {tk windowingsystem} ds9(wm)]} {
     puts stderr "Unable to initialize window system."
     exit
 }
 
-# Styles
+# who are we?
+set ds9(app) [file tail [info nameofexecutable]]
 set ds9(app,bg) [ttk::style lookup "." -background]
 
 switch $ds9(wm) {
     x11 {
-	# change just default style
-	ttk::style theme settings default \
-	    [list ;
-	     ttk::style configure TLabel -borderwidth 2 -padding 1;
-	     ttk::style configure TEntry -fieldbackground $ds9(app,bg) -padding 1;
-	    ]
-    }
-    win32 {}
-    aqua {}
-}
+	# set to absolute path so that if -cd command is used,
+	# so we can still find our files
+	set ds9(root) [file normalize [file join [pwd] zvfsmntpt]]
 
-# set to absolute path so that if -cd command is used,
-# so we can still find our files
-set ds9(root) "[pwd]/zvfsmntpt"
-#set ds9(root) "/tmp/zvfsmntpt"
+	if {![namespace exists msgcat]} {
+	    source $ds9(root)/tcl8/8.5/msgcat-1.5.0.tm
+	}
+	if {![namespace exists http]} {
+	    source $ds9(root)/tcl8/8.6/http-2.8.5.tm
+	}
 
-# tcl modules
-if {![namespace exists msgcat]} {
-    source $ds9(root)/tcl8/8.5/msgcat-1.5.0.tm
-}
-if {![namespace exists http]} {
-    source $ds9(root)/tcl8/8.6/http-2.8.5.tm
-}
+	source $ds9(root)/tk8.6/tearoff.tcl
+	source $ds9(root)/tk8.6/comdlg.tcl
+	source $ds9(root)/tk8.6/focus.tcl
+	source $ds9(root)/tk8.6/mkpsenc.tcl
+	source $ds9(root)/tk8.6/msgbox.tcl
+	source $ds9(root)/tk8.6/optMenu.tcl
+	source $ds9(root)/tk8.6/unsupported.tcl
+
+	source $ds9(root)/tcllib1.15/base64/base64.tcl
+	source $ds9(root)/tcllib1.15/log/log.tcl
+	source $ds9(root)/tcllib1.15/ftp/ftp.tcl
+	source $ds9(root)/tcllib1.15/textutil/repeat.tcl
+	source $ds9(root)/tcllib1.15/textutil/tabify.tcl
+	source $ds9(root)/tcllib1.15/math/fuzzy.tcl
+
+	source $ds9(root)/tkcon2.5/tkcon.tcl
+	source $ds9(root)/xmlrpc0.3/xmlrpc.tcl
+	source $ds9(root)/tlt3.0/graph.tcl
+
+	source $ds9(root)/src/source.tcl
+
+	set tlt_library $ds9(root)/tlt3.0
 
-source $ds9(root)/tk8.6/tearoff.tcl
-source $ds9(root)/tk8.6/comdlg.tcl
-source $ds9(root)/tk8.6/focus.tcl
-source $ds9(root)/tk8.6/mkpsenc.tcl
-source $ds9(root)/tk8.6/msgbox.tcl
-source $ds9(root)/tk8.6/optMenu.tcl
-source $ds9(root)/tk8.6/unsupported.tcl
+	# fix ::tk and msgcat
+	rename ::tk::msgcat::mc {}
+	rename ::tk::msgcat::mcmax {}
 
-source $ds9(root)/tcllib1.15/base64/base64.tcl
-source $ds9(root)/tcllib1.15/log/log.tcl
-source $ds9(root)/tcllib1.15/ftp/ftp.tcl
-source $ds9(root)/tcllib1.15/textutil/repeat.tcl
-source $ds9(root)/tcllib1.15/textutil/tabify.tcl
-source $ds9(root)/tcllib1.15/math/fuzzy.tcl
+	namespace import ::msgcat::mc
+	namespace import ::msgcat::mcmax
+	::msgcat::mcload [file join $::tk_library msgs]
 
-source $ds9(root)/tkcon2.5/tkcon.tcl
-source $ds9(root)/xmlrpc0.3/xmlrpc.tcl
-source $ds9(root)/blt3.0/graph.tcl
+	# fix ::tk::dialog::file
+	set ::tk::dialog::file::showHiddenVar 0
+	set ::tk::dialog::file::showHiddenBtn 1
 
-source $ds9(root)/src/source.tcl
+	# change just default style
+	ttk::style theme settings default [list ; ttk::style configure TLabel -borderwidth 2 -padding 1; ttk::style configure TEntry -fieldbackground $ds9(app,bg) -padding 1;]
+    }
+    aqua {
+	set res [file normalize [file dirname [file dirname $argv0]]]
+	lappend auto_path $res
+	# tlt uses tclIndex
+	lappend auto_path [file normalize [file join $res tlt3.0]]
+	set ds9(root) [file normalize [file join [file dirname $argv0] ".."]]
+
+	set tlt_library [file normalize [file join $res tlt3.0]]
+
+	package require http
+	package require msgcat
+	package require DS9
+	package require base64
+	package require log
+	package require ftp
+	package require textutil
+	package require math
+	package require tkcon
+	package require xmlrpc
+
+	proc ::tk::mac::OpenDocument {args} {
+	    global ds9
+
+	    set ds9(event,opendoc) $args
+	    if {!$ds9(init)} {
+		MacOSXOpenDocEvent 1
+	    }
+	}
+
+	proc ::tk::mac::PrintDocument {args} {
+	    global ds9
 
-# fix ::tk and msgcat
-rename ::tk::msgcat::mc {}
-rename ::tk::msgcat::mcmax {}
+	    set ds9(event,printdoc) $args
+	    if {!$ds9(init)} {
+		MacOSXPrintDocEvent 0
+	    }
+	}
 
-namespace import ::msgcat::mc
-namespace import ::msgcat::mcmax
-::msgcat::mcload [file join $::tk_library msgs]
+	proc ::tk::mac::ShowPreferences {} {
+	    PrefsDialog
+	}
 
-# fix ::tk::dialog::file
-set ::tk::dialog::file::showHiddenVar 0
-set ::tk::dialog::file::showHiddenBtn 1
+	proc ::tk::mac::Quit {args} {
+	    QuitDS9
+	}
+    }
+    win32 {
+    }
+}
 
 # Define Variables
 DS9Def
@@ -302,9 +348,6 @@ switch $tcl_platform(platform) {
     windows {}
 }
 
-# set the appname
-tk appname $ds9(app)
-
 # environment vars
 # we don't want to see any error messages if xpa is not available
 if { [info exists env(XPA_VERBOSITY)] == 0 } {
@@ -368,7 +411,6 @@ wm withdraw $ds9(top)
 wm title $ds9(top) "SAOImage $ds9(title)"
 wm iconname $ds9(top) "SAOImage $ds9(title)"
 wm protocol $ds9(top) WM_DELETE_WINDOW QuitDS9
-$ds9(top) configure -menu $ds9(mb)
 
 # Theme
 PrefsTheme
@@ -430,7 +472,6 @@ switch $ds9(wm) {
 }
 
 switch -- $ds9(visual)$ds9(depth) {
-    pseudocolor8 {}
     truecolor8 {}
     truecolor16 {}
     truecolor24 {}
@@ -539,4 +580,3 @@ after $ds9(msg,timeout) [list ErrorTimer]
 
 # ok, we're done
 set ds9(init) 0
-
diff --git a/src/frame.tcl b/src/frame.tcl
index 322a75e..6d5637d 100644
--- a/src/frame.tcl
+++ b/src/frame.tcl
@@ -86,38 +86,21 @@ proc CreateNameNumberFrame {which type} {
     set active($ds9(next)) 1
 
     # and create the frame
-    switch -- $ds9(visual) {
-	pseudocolor {
-	    switch -- $type {
-		base {
-		    $ds9(canvas) create frame$ds9(visual)$ds9(depth) \
-			-command $ds9(next)
-		    $ds9(next) colormap [colorbar get colormap]
-		}
-		rgb -
-		3d {
-		    Error [msgcat::mc {Unable to create RGB or 3D frame with pseudocolor visual}]
-		}
-	    }
+    switch -- $type {
+	base {
+	    $ds9(canvas) create frame$ds9(visual)$ds9(depth) \
+		-command $ds9(next)
+	    $ds9(next) colormap [colorbar get colormap]
 	}
-    	truecolor {
-	    switch -- $type {
-		base {
-		    $ds9(canvas) create frame$ds9(visual)$ds9(depth) \
-			-command $ds9(next)
-		    $ds9(next) colormap [colorbar get colormap]
-		}
-		rgb {
-		    $ds9(canvas) create framergb$ds9(visual)$ds9(depth) \
-			-command $ds9(next)
-		    $ds9(next) colormap [colorbarrgb get colormap]
-		}
-		3d {
-		    $ds9(canvas) create frame3d$ds9(visual)$ds9(depth) \
-			-command $ds9(next)
-		    $ds9(next) colormap [colorbar get colormap]
-		}
-	    }
+	rgb {
+	    $ds9(canvas) create framergb$ds9(visual)$ds9(depth) \
+		-command $ds9(next)
+	    $ds9(next) colormap [colorbarrgb get colormap]
+	}
+	3d {
+	    $ds9(canvas) create frame3d$ds9(visual)$ds9(depth) \
+		-command $ds9(next)
+	    $ds9(next) colormap [colorbar get colormap]
 	}
     }
 
@@ -550,7 +533,7 @@ proc EnterFrame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "EnterFrame"
+	puts stderr "EnterFrame $which"
     }
 
     # check to see if this event was generated while processing other events
@@ -603,7 +586,7 @@ proc LeaveFrame {which} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "LeaveFrame"
+	puts stderr "LeaveFrame $which"
     }
 
     # check to see if this event was generated while processing other events
@@ -639,7 +622,7 @@ proc LeaveFrame {which} {
 proc MotionFrame {which x y} {
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "MotionFrame"
+	puts stderr "MotionFrame $which"
     }
 
     DoMotion $which $x $y sizing fleur
@@ -648,7 +631,7 @@ proc MotionFrame {which x y} {
 proc ShiftMotionFrame {which x y} {
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "ShiftMotionFrame"
+	puts stderr "ShiftMotionFrame $which"
     }
 
     DoMotion $which $x $y exchange fleur
@@ -657,7 +640,7 @@ proc ShiftMotionFrame {which x y} {
 proc ControlMotionFrame {which x y} {
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "ControlMotionFrame"
+	puts stderr "ControlMotionFrame $which"
     }
 
     DoMotion $which $x $y sizing draped_box
@@ -711,7 +694,7 @@ proc Button1Frame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "Button1Frame"
+	puts stderr "Button1Frame $which"
     }
 
     # let others know that the mouse is down
@@ -812,7 +795,7 @@ proc ShiftButton1Frame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "ShiftButton1Frame"
+	puts stderr "ShiftButton1Frame $which"
     }
 
     # let others know that the mouse is down
@@ -853,7 +836,7 @@ proc ControlButton1Frame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "ControlButton1Frame"
+	puts stderr "ControlButton1Frame $which"
     }
 
     # let others know that the mouse is down
@@ -895,7 +878,7 @@ proc ControlShiftButton1Frame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "ControlShiftButton1Frame"
+	puts stderr "ControlShiftButton1Frame $which"
     }
 
     # let others know that the mouse is down
@@ -933,7 +916,7 @@ proc Motion1Frame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "Motion1Frame"
+	puts stderr "Motion1Frame $which"
     }
 
     # abort if we are here by accident (such as a double click)
@@ -1014,7 +997,7 @@ proc Release1Frame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "Release1Frame"
+	puts stderr "Release1Frame $which"
     }
 
     # abort if we are here by accident (such as a double click)
@@ -1091,7 +1074,7 @@ proc Double1Frame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "Double1Frame"
+	puts stderr "Double1Frame $which"
     }
 
     switch -- $current(mode) {
@@ -1119,7 +1102,7 @@ proc DoubleRelease1Frame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "DoubleRelease1Frame"
+	puts stderr "DoubleRelease1Frame $which"
     }
 
     switch -- $current(mode) {
@@ -1157,7 +1140,7 @@ proc ShiftButton2Frame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "ShiftButton2Frame"
+	puts stderr "ShiftButton2Frame $which"
     }
 
     set ds9(sb2) 1
@@ -1166,7 +1149,7 @@ proc ShiftButton2Frame {which x y} {
 proc Motion2Frame {which x y} {
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "Motion2Frame"
+	puts stderr "Motion2Frame $which"
     }
 
     MotionPan $which $x $y
@@ -1177,7 +1160,7 @@ proc Release2Frame {which x y} {
 
     global debug
     if {$debug(tcl,events)} {
-	puts stderr "Release2Frame"
+	puts stderr "Release2Frame $which"
     }
 
     ReleasePan $which $x $y
@@ -1806,52 +1789,36 @@ proc FrameToFront {} {
     set which $current(frame)
 
     # process proper colorbar
-    switch -- $ds9(visual) {
-	pseudocolor {
+    switch -- [$which get type] {
+	base -
+	3d {
 	    if {$view(colorbar)} {
 		colorbar show
 	    } else {
 		colorbar hide
 	    }
+	    colorbarrgb hide
 	    set current(colorbar) colorbar
 
 	    colorbar colorbar [$which get colorbar]
 	    colorbar tag "\{[$which get colorbar tag]\}"
 	    set colorbar(map) [colorbar get name]
-	}
-	truecolor {
-	    switch -- [$which get type] {
-		base -
-		3d {
-		    if {$view(colorbar)} {
-			colorbar show
-		    } else {
-			colorbar hide
-		    }
-		    colorbarrgb hide
-		    set current(colorbar) colorbar
 
-		    colorbar colorbar [$which get colorbar]
-		    colorbar tag "\{[$which get colorbar tag]\}"
-		    set colorbar(map) [colorbar get name]
-
-		    $ds9(canvas) raise colorbar colorbarrgb
-		}
-		rgb {
-		    colorbar hide
-		    if {$view(colorbar)} {
-			colorbarrgb show
-		    } else {
-			colorbarrgb hide
-		    }
-		    set current(colorbar) colorbarrgb
+	    $ds9(canvas) raise colorbar colorbarrgb
+	}
+	rgb {
+	    colorbar hide
+	    if {$view(colorbar)} {
+		colorbarrgb show
+	    } else {
+		colorbarrgb hide
+	    }
+	    set current(colorbar) colorbarrgb
 
-		    colorbarrgb colorbar [$which get colorbar]
-		    colorbarrgb rgb channel [$which get rgb channel]
+	    colorbarrgb colorbar [$which get colorbar]
+	    colorbarrgb rgb channel [$which get rgb channel]
 
-		    $ds9(canvas) raise colorbarrgb colorbar
-		}
-	    }
+	    $ds9(canvas) raise colorbarrgb colorbar
 	}
     }
     set colorbar(invert) [$current(colorbar) get invert]
diff --git a/src/group.tcl b/src/group.tcl
index 97f3431..5598beb 100644
--- a/src/group.tcl
+++ b/src/group.tcl
@@ -78,7 +78,7 @@ proc GroupDialog {} {
     set dgroup(list) [listbox $f.box \
 			  -yscroll [list $f.scroll set] \
 			  -setgrid true \
-			  -selectmode single \
+			  -selectmode multiple \
 			  ]
     grid $f.box $f.scroll -sticky news
     grid rowconfigure $f 0 -weight 1
@@ -108,9 +108,11 @@ proc GroupButtonDialog {} {
 
     if {$current(frame) != {}} {
 	$current(frame) marker unselect all
-	set i [$dgroup(list) curselection]
-	if {[string length $i] != 0} {
-	    $current(frame) marker "\{[$dgroup(list) get $i]\}" select
+	set rr [$dgroup(list) curselection]
+	foreach ii $rr {
+	    if {[string length $ii] != 0} {
+		$current(frame) marker "\{[$dgroup(list) get $ii]\}" select
+	    }
 	}
     }
 }
diff --git a/src/hvsup.tcl b/src/hvsup.tcl
index 7d57665..686a155 100644
--- a/src/hvsup.tcl
+++ b/src/hvsup.tcl
@@ -1149,6 +1149,9 @@ proc HVParseHTML {varname} {
     if {[string length $r(query)] != 0} {
 	append base "?$r(query)"
     }
+    # spaces?
+    regsub { } $base {\ } base
+
     $var(widget) config -base $base
 
     if {$debug(tcl,hv)} {
diff --git a/src/layout.tcl b/src/layout.tcl
index 0b64f7b..a77f236 100644
--- a/src/layout.tcl
+++ b/src/layout.tcl
@@ -620,23 +620,13 @@ proc LayoutFrames {} {
 	}
 
 	# process proper colorbar
-	switch -- $ds9(visual) {
-	    pseudocolor {
-		colorbar show
-		set current(colorbar) colorbar
-		set colorbar(map) [colorbar get name]
-		set colorbar(invert) [colorbar get invert]
-	    }
-	    truecolor {
-		colorbar show
-		colorbarrgb hide
-		$ds9(canvas) raise colorbar colorbarrgb
-
-		set current(colorbar) colorbar
-		set colorbar(map) [colorbar get name]
-		set colorbar(invert) [colorbar get invert]
-	    }
-	}
+	colorbar show
+	colorbarrgb hide
+	$ds9(canvas) raise colorbar colorbarrgb
+
+	set current(colorbar) colorbar
+	set colorbar(map) [colorbar get name]
+	set colorbar(invert) [colorbar get invert]
 
 	# update menus/dialogs
 	UpdateDS9
diff --git a/src/macosx.tcl b/src/macosx.tcl
index 6318702..362fa0e 100644
--- a/src/macosx.tcl
+++ b/src/macosx.tcl
@@ -4,35 +4,6 @@
 
 package provide DS9 1.0
 
-# ::tk::mac::OpenApplication
-# ::tk::mac::ReopenApplication
-
-proc ::tk::mac::OpenDocument {args} {
-    global ds9
-
-    set ds9(event,opendoc) $args
-    if {!$ds9(init)} {
-	MacOSXOpenDocEvent 1
-    }
-}
-
-proc ::tk::mac::PrintDocument {args} {
-    global ds9
-
-    set ds9(event,printdoc) $args
-    if {!$ds9(init)} {
-	MacOSXPrintDocEvent 0
-    }
-}
-
-proc ::tk::mac::ShowPreferences {} {
-    PrefsDialog
-}
-
-proc ::tk::mac::Quit {args} {
-    QuitDS9
-}
-
 proc MacOSXOpenDocEvent {fc} {
     global ds9
 
@@ -41,7 +12,7 @@ proc MacOSXOpenDocEvent {fc} {
 	foreach f $ds9(event,opendoc) {
 	    MultiLoad
 	    LoadFitsFile $f {} {}
-	    FileLastFull fitsfbox $f
+	    FileLast fitsfbox $f
 
 	}
 	FinishLoad
@@ -60,7 +31,7 @@ proc MacOSXPrintDocEvent {bye} {
 
 	    MultiLoad
 	    LoadFitsFile $f {} {}
-	    FileLastFull fitsfbox $f
+	    FileLast fitsfbox $f
 
 	    FinishLoad
 	    MacOSXPrintPre
diff --git a/src/marker.tcl b/src/marker.tcl
index b0aeb07..7dbd375 100644
--- a/src/marker.tcl
+++ b/src/marker.tcl
@@ -1150,6 +1150,7 @@ proc MarkerLoadFile {filename which format sys sky} {
 	}
     }
 
+    FileLast markerfbox $filename
     UpdateGroupDialog
 }
 
diff --git a/src/mask.tcl b/src/mask.tcl
index a55dfec..9b04720 100644
--- a/src/mask.tcl
+++ b/src/mask.tcl
@@ -152,16 +152,8 @@ proc UpdateMaskMenu {} {
 
     switch -- [$current(frame) get type] {
 	base {
-	    switch -- $ds9(visual) {
-		pseudocolor {
-		    $ds9(mb).analysis entryconfig \
-			"[msgcat::mc {Mask Parameters}]..." -state disabled
-		}
-		truecolor {
-		    $ds9(mb).analysis entryconfig \
-			"[msgcat::mc {Mask Parameters}]..." -state normal
-		}
-	    }
+	    $ds9(mb).analysis entryconfig \
+		"[msgcat::mc {Mask Parameters}]..." -state normal
 	}
 	3d -
 	rgb {
diff --git a/src/mcolor.tcl b/src/mcolor.tcl
index 87daa36..d75d2a8 100644
--- a/src/mcolor.tcl
+++ b/src/mcolor.tcl
@@ -392,13 +392,14 @@ proc UpdateColorMenu {} {
 	puts stderr "UpdateColorMenu"
     }
 
+    set end [expr $icolorbar(contrib)+$icolorbar(start)]
     if {$current(frame) != {}} {
 	switch [$current(frame) get type] {
 	    base -
 	    3d {
 		# menus
 		# base
-		for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} {
+		for {set ii $icolorbar(start)} {$ii<$end} {incr ii} {
 		    $ds9(mb).color entryconfig $ii -state normal
 		}
 		$ds9(mb).color entryconfig [msgcat::mc {Contributed}] \
@@ -418,7 +419,7 @@ proc UpdateColorMenu {} {
 	    rgb {
 		# menus
 		# base
-		for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} {
+		for {set ii $icolorbar(start)} {$ii<$end} {incr ii} {
 		    $ds9(mb).color entryconfig $ii -state disabled
 		}
 		$ds9(mb).color entryconfig [msgcat::mc {Contributed}] \
@@ -439,7 +440,7 @@ proc UpdateColorMenu {} {
     } else {
 	# menus
 	# base
-	for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} {
+	for {set ii $icolorbar(start)} {$ii<$end} {incr ii} {
 	    $ds9(mb).color entryconfig $ii -state normal
 	}
 	$ds9(mb).color entryconfig [msgcat::mc {Contributed}] -state normal
diff --git a/src/menu.tcl b/src/menu.tcl
index 3b8b196..1d33ac2 100644
--- a/src/menu.tcl
+++ b/src/menu.tcl
@@ -7,7 +7,11 @@ package provide DS9 1.0
 proc CreateMenuBar {} {
     global ds9
 
+    # we need this first, before the configure command
     menu $ds9(mb) 
+    AppleMenu $ds9(mb)
+    $ds9(top) configure -menu $ds9(mb)
+
     $ds9(mb) add cascade -label [msgcat::mc {File}] -menu $ds9(mb).file
     $ds9(mb) add cascade -label [msgcat::mc {Edit}] -menu $ds9(mb).edit
     $ds9(mb) add cascade -label [msgcat::mc {View}] -menu $ds9(mb).view
@@ -20,7 +24,6 @@ proc CreateMenuBar {} {
     $ds9(mb) add cascade -label [msgcat::mc {WCS}] -menu $ds9(mb).wcs
     $ds9(mb) add cascade -label [msgcat::mc {Analysis}] -menu $ds9(mb).analysis
 
-    AppleMainMenu $ds9(mb)
     FileMainMenu
     EditMainMenu
     ViewMainMenu
@@ -32,15 +35,10 @@ proc CreateMenuBar {} {
     RegionMainMenu
     WCSMainMenu
     AnalysisMainMenu
-
-    switch $ds9(wm) {
-	x11 -
-	win32 {HelpMenu $ds9(mb)}
-	aqua {}
-    }
+    HelpMainMenu
 }
 
-proc AppleMainMenu {mb} {
+proc AppleMenu {mb} {
     global ds9
 
     switch $ds9(wm) {
@@ -48,14 +46,11 @@ proc AppleMainMenu {mb} {
 	win32 {}
 	aqua {
 	    # apple menu
-	    $mb add cascade -menu $mb.apple
 	    menu $mb.apple
+	    $mb add cascade -menu $mb.apple
 	    $mb.apple add command \
 		-label [msgcat::mc {About SAOImage DS9}] \
 		-command AboutBox
-
-	    # help menu
-	    HelpMenu $mb
 	}
     }
 }
diff --git a/src/mframe.tcl b/src/mframe.tcl
index d7b6d77..3218848 100644
--- a/src/mframe.tcl
+++ b/src/mframe.tcl
@@ -928,18 +928,8 @@ proc UpdateFrameMenuStatic {} {
 	puts stderr "UpdateFrameMenuStatic"
     }
 
-    switch -- $ds9(visual) {
-	pseudocolor {
-	    $ds9(mb).frame entryconfig [msgcat::mc {New Frame RGB}] \
-		-state disabled
-	    $ds9(buttons).frame.newrgb configure -state disabled
-	}
-	truecolor {
-	    $ds9(mb).frame entryconfig [msgcat::mc {New Frame RGB}] \
-		-state normal
-	    $ds9(buttons).frame.newrgb configure -state normal
-	}
-    }
+    $ds9(mb).frame entryconfig [msgcat::mc {New Frame RGB}] -state normal
+    $ds9(buttons).frame.newrgb configure -state normal
 
     if {$ds9(active,num) > 0} {
 	$ds9(mb).frame entryconfig [msgcat::mc {Delete Frame}] -state normal
diff --git a/src/mhelp.tcl b/src/mhelp.tcl
index 7d9f5fc..dbd0439 100644
--- a/src/mhelp.tcl
+++ b/src/mhelp.tcl
@@ -6,38 +6,48 @@ package provide DS9 1.0
 
 # Menu
 
-proc HelpMenu {mb} {
+proc HelpMainMenu {} {
     global ds9
 
-    $mb add cascade -label [msgcat::mc {Help}] -menu $mb.help
+    switch $ds9(wm) {
+ 	x11 -
+ 	win32 {}
+ 	aqua {
+	    # window menu
+	    menu $ds9(mb).window
+	    $ds9(mb) add cascade -label [msgcat::mc {Window}] \
+		-menu $ds9(mb).window
+	}
+    }
 
-    menu $mb.help
-    $mb.help add command -label [msgcat::mc {Reference Manual}]\
+    $ds9(mb) add cascade -label [msgcat::mc {Help}] -menu $ds9(mb).help
+    menu $ds9(mb).help
+    $ds9(mb).help add command -label [msgcat::mc {Reference Manual}]\
 	-command HelpRef
-    $mb.help add command -label [msgcat::mc {User Manual}]\
+    $ds9(mb).help add command -label [msgcat::mc {User Manual}]\
 	-command HelpUser
-    $mb.help add command -label [msgcat::mc {Mouse & Keyboard}] \
+    $ds9(mb).help add command -label [msgcat::mc {Mouse & Keyboard}] \
 	-command HelpKeyboard
-    $mb.help add separator
-    $mb.help add command -label [msgcat::mc {FAQ}] \
+    $ds9(mb).help add separator
+    $ds9(mb).help add command -label [msgcat::mc {FAQ}] \
 	-command HelpFAQ
-    $mb.help add command -label [msgcat::mc {New Features}] \
+    $ds9(mb).help add command -label [msgcat::mc {New Features}] \
 	-command HelpNew
-    $mb.help add command -label [msgcat::mc {Release Notes}] \
+    $ds9(mb).help add command -label [msgcat::mc {Release Notes}] \
 	-command HelpRelease
-    $mb.help add command -label [msgcat::mc {Help Desk}] \
+    $ds9(mb).help add command -label [msgcat::mc {Help Desk}] \
 	-command HelpDesk
-    $mb.help add separator
-    $mb.help add command -label [msgcat::mc {Story of SAOImage DS9}] \
+    $ds9(mb).help add separator
+    $ds9(mb).help add command -label [msgcat::mc {Story of SAOImage DS9}] \
 	-command HelpStory
-    $mb.help add command -label [msgcat::mc {Acknowledgment}] \
+    $ds9(mb).help add command -label [msgcat::mc {Acknowledgment}] \
 	-command HelpAck
 
     switch $ds9(wm) {
 	x11 -
 	win32 {
-	    $mb.help add separator
-	    $mb.help add command \
+	    $ds9(mb).help add separator
+	    $ds9(mb).help add command \
 		-label "[msgcat::mc {About SAOImage DS9}]..." \
 		-command AboutBox
 	}
diff --git a/src/print.tcl b/src/print.tcl
index 4f4e4d0..f5b6df4 100644
--- a/src/print.tcl
+++ b/src/print.tcl
@@ -99,22 +99,13 @@ proc PostScript {} {
     }
 
     # set color specific postscript options
-    switch -- $ds9(visual) {
-	pseudocolor {
-	    colorbar postscript level $ps(level)
-	    colorbar postscript colorspace $ps(color)
-	    colorbar postscript resolution $ps(resolution)
-	}
-	truecolor {
-	    colorbar postscript level $ps(level)
-	    colorbar postscript colorspace $ps(color)
-	    colorbar postscript resolution $ps(resolution)
-
-	    colorbarrgb postscript level $ps(level)
-	    colorbarrgb postscript colorspace $ps(color)
-	    colorbarrgb postscript resolution $ps(resolution)
-	}
-    }
+    colorbar postscript level $ps(level)
+    colorbar postscript colorspace $ps(color)
+    colorbar postscript resolution $ps(resolution)
+
+    colorbarrgb postscript level $ps(level)
+    colorbarrgb postscript colorspace $ps(color)
+    colorbarrgb postscript resolution $ps(resolution)
 
     # set frame specific postscript options
     foreach f $ds9(frames) {
@@ -193,22 +184,13 @@ proc EPS {fn} {
     append options " -file \{$fn\}"
 
     # set color specific postscript options
-    switch -- $ds9(visual) {
-	pseudocolor {
-	    colorbar postscript level $level
-	    colorbar postscript colorspace $color
-	    colorbar postscript resolution $resolution
-	}
-	truecolor {
-	    colorbar postscript level $level
-	    colorbar postscript colorspace $color
-	    colorbar postscript resolution $resolution
-
-	    colorbarrgb postscript level $level
-	    colorbarrgb postscript colorspace $color
-	    colorbarrgb postscript resolution $resolution
-	}
-    }
+    colorbar postscript level $level
+    colorbar postscript colorspace $color
+    colorbar postscript resolution $resolution
+
+    colorbarrgb postscript level $level
+    colorbarrgb postscript colorspace $color
+    colorbarrgb postscript resolution $resolution
 
     # set frame specific postscript options
     foreach f $ds9(frames) {
@@ -363,7 +345,7 @@ proc PSPrintDialog {which} {
 proc PSPrintBrowse {varname} {
     upvar $varname var
 
-    FileLastFull pssavfbox $var
+    FileLast pssavfbox $var
     set var [SaveFileDialog pssavfbox]
 }
 
@@ -442,7 +424,7 @@ proc PlotPrintDialog {} {
 proc PlotPrintBrowse {varname} {
     upvar $varname var
 
-    FileLastFull apsavfbox $var
+    FileLast apsavfbox $var
     set var [SaveFileDialog apsavfbox]
 }
 
@@ -508,7 +490,7 @@ proc PRPrintDialog {} {
 proc PRPrintBrowse {varname} {
     upvar $varname var
 
-    FileLastFull prsavfbox $var
+    FileLast prsavfbox $var
     set var [SaveFileDialog prsavfbox]
 }
 
diff --git a/src/stdfbox.tcl b/src/stdfbox.tcl
index 415f81d..f460633 100644
--- a/src/stdfbox.tcl
+++ b/src/stdfbox.tcl
@@ -10,29 +10,12 @@ proc InitDialogBox {} {
     global pds9
     global env
 
-    switch $ds9(wm) {
-	x11 {}
-	win32 {set ds9(dialog,dir) [GetEnvHome]}
-	aqua {
-	    switch -- $pds9(dialog) {
-		native {}
-		motif -
-		windows {
-		    # try to determine if invoked from 
-		    # command line or double click
-		    if {![info exists env(TERM)]} {
-			set ds9(dialog,dir) [GetEnvHome]
-		    }
-		}
-	    }
-	}
-    }
-
     global fitsurl
     set fitsurl {}
 
     global fitsfbox
     set fitsfbox(file) {ds9.fits}
+    set fitsfbox(dir) {}
     set fitsfbox(types) [list \
 			     [list {FITS} {*.fits}] \
 			     [list {FITS} {*.FITS}] \
@@ -56,6 +39,7 @@ proc InitDialogBox {} {
 
     global savefitsfbox
     set savefitsfbox(file) {ds9.fits}
+    set savefitsfbox(dir) {}
     set savefitsfbox(types) [list \
 				 [list {FITS} {*.fits}] \
 				 [list {FITS} {*.fit}] \
@@ -68,31 +52,37 @@ proc InitDialogBox {} {
 
     global epsfbox
     set epsfbox(file) {ds9.eps}
+    set epsfbox(dir) {}
     set epsfbox(types) [list \
 			    [list {EPS} {*.eps}] \
 			   ]
     global arrayfbox
     set arrayfbox(file) {ds9.arr}
+    set arrayfbox(dir) {}
     set arrayfbox(types) [list \
 			      [list [::msgcat::mc {Array}] {*.arr}] \
 			  ]
     global rgbarrayfbox
     set rgbarrayfbox(file) {ds9.rgb}
+    set rgbarrayfbox(dir) {}
     set rgbarrayfbox(types) [list \
 				 [list [::msgcat::mc {RGB Array}] {*.rgb}] \
 				]
     global nrrdfbox
     set nrrdfbox(file) {ds9.nrrd}
+    set nrrdfbox(dir) {}
     set nrrdfbox(types) [list \
 			     [list {NRRD} {*.nrrd}] \
 			    ]
     global envifbox
     set envifbox(file) {ds9.hdr}
+    set envifbox(dir) {}
     set envifbox(types) [list \
 			     [list {ENVI} {*.hdr}] \
 			    ]
     global envi2fbox
     set envi2fbox(file) {ds9.raw}
+    set envi2fbox(dir) {}
     set envi2fbox(types) [list \
 			     [list {ENVI2} {*.bil}] \
 			     [list {ENVI2} {*.bip}] \
@@ -102,28 +92,33 @@ proc InitDialogBox {} {
 			    ]
     global giffbox
     set giffbox(file) {ds9.gif}
+    set giffbox(dir) {}
     set giffbox(types) [list \
 			    [list {GIF} {*.gif}] \
 			   ]
     global jpegfbox
     set jpegfbox(file) {ds9.jpeg}
+    set jpegfbox(dir) {}
     set jpegfbox(types) [list \
 			     [list {JPEG} {*.jpeg}] \
 			     [list {JPEG} {*.jpg}] \
 			    ]
     global tifffbox
     set tifffbox(file) {ds9.tiff}
+    set tifffbox(dir) {}
     set tifffbox(types) [list \
 			     [list {TIFF} {*.tiff}] \
 			     [list {TIFF} {*.tif}] \
 			    ]
     global pngfbox
     set pngfbox(file) {ds9.png}
+    set pngfbox(dir) {}
     set pngfbox(types) [list \
 			    [list {PNG} {*.png}] \
 			   ]
     global mpegfbox
     set mpegfbox(file) {ds9.mpeg}
+    set mpegfbox(dir) {}
     set mpegfbox(types) [list \
 				 [list {MPEG} {*.mpeg}] \
 				 [list {MPEG} {*.mpg}] \
@@ -131,12 +126,14 @@ proc InitDialogBox {} {
 
     global pixelfbox
     set pixelfbox(file) {ds9.pix}
+    set pixelfbox(dir) {}
     set pixelfbox(types) [list \
 			      [list {PIX} {*.pix}] \
 			      ]
 
     global markerfbox
     set markerfbox(file) {ds9.reg}
+    set markerfbox(dir) {}
     set markerfbox(types) [list \
 			       [list {REG} {*.reg}] \
 			       [list {FITS} {*.fits}] \
@@ -145,11 +142,13 @@ proc InitDialogBox {} {
 
     global templatefbox
     set templatefbox(file) {ds9.tpl}
+    set templatefbox(dir) {}
     set templatefbox(types) \
 	[list [list {TPL} {*.tpl}] [list [::msgcat::mc {All}] {*}] ]
 
     global colorbarfbox
     set colorbarfbox(file) {ds9.sao}
+    set colorbarfbox(dir) {}
     set colorbarfbox(types) [list \
 				 [list [::msgcat::mc {Colormap}] {*.sao}] \
 				 [list [::msgcat::mc {Colormap}]  {*.lut}] \
@@ -157,48 +156,56 @@ proc InitDialogBox {} {
 
     global contrastbiasfbox
     set contrastbiasfbox(file) {ds9.cb}
+    set contrastbiasfbox(dir) {}
     set contrastbiasfbox(types) [list \
 				     [list {CB} {*.cb}] \
 				     ]
 
     global colortagfbox
     set colortagfbox(file) {ds9.tag}
+    set colortagfbox(dir) {}
     set colortagfbox(types) [list \
 				 [list {Colortag} {*.tag}] \
 				]
 
     global pssavfbox
     set pssavfbox(file) {ds9.ps}
+    set pssavfbox(dir) {}
     set pssavfbox(types) [list \
 			      [list {PS} {*.ps}] \
 			      ]
 
     global prsavfbox
     set prsavfbox(file) {ds9.txt}
+    set prsavfbox(dir) {}
     set prsavfbox(types) [list \
 			      [list {TXT} {*.txt}] \
 			      ]
 
     global contourfbox
     set contourfbox(file) {ds9.con}
+    set contourfbox(dir) {}
     set contourfbox(types) [list \
 				[list {CON} {*.con}] \
 				]
 
     global contourlevfbox
     set contourlevfbox(file) {ds9.lev}
+    set contourlevfbox(dir) {}
     set contourlevfbox(types) [list \
 				   [list {LEV} {*.lev}] \
 				   ]
 
     global gridfbox
     set gridfbox(file) {ds9.grd}
+    set gridfbox(dir) {}
     set gridfbox(types) [list \
 			     [list {GRD} {*.grd}] \
 			    ]
 
     global catfbox
     set catfbox(file) {ds9.cat}
+    set catfbox(dir) {}
     set catfbox(types) [list \
 			    [list [::msgcat::mc {Catalog}] {*.cat}] \
 			    [list [::msgcat::mc {Catalog}] {*.rdb}] \
@@ -206,6 +213,7 @@ proc InitDialogBox {} {
 
     global cattsvfbox
     set cattsvfbox(file) {ds9.tsv}
+    set cattsvfbox(dir) {}
     set cattsvfbox(types) [list \
 			       [list [::msgcat::mc {Catalog}] {*.tsv}] \
 			       [list [::msgcat::mc {Catalog}] {*.csv}] \
@@ -213,6 +221,7 @@ proc InitDialogBox {} {
 
     global catvotfbox
     set catvotfbox(file) {ds9.xml}
+    set catvotfbox(dir) {}
     set catvotfbox(types) [list \
 			       [list [::msgcat::mc {Catalog}] {*.xml}] \
 			       [list [::msgcat::mc {Catalog}] {*.vot}] \
@@ -221,24 +230,28 @@ proc InitDialogBox {} {
 
     global catfltfbox
     set catfltfbox(file) {ds9.flt}
+    set catfltfbox(dir) {}
     set catfltfbox(types) [list \
 			       [list {FLT} {*.flt}] \
 			       ]
 
     global catsymfbox
     set catsymfbox(file) {ds9.sym}
+    set catsymfbox(dir) {}
     set catsymfbox(types) [list \
 			       [list {SYM} {*.sym}] \
 			       ]
 
     global catcdssrchfbox
     set catcdssrchfbox(file) {ds9.cds}
+    set catcdssrchfbox(dir) {}
     set catcdssrchfbox(types) [list \
 				   [list {CDS} {*.cds}] \
 				   ]
 
     global analysisfbox
     set analysisfbox(file) {ds9.ans}
+    set analysisfbox(dir) {}
     set analysisfbox(types) [list \
 				 [list [::msgcat::mc {Analysis}] {*.ans}] \
 				 [list [::msgcat::mc {Analysis}] {*.ds9}] \
@@ -246,54 +259,63 @@ proc InitDialogBox {} {
 
     global analysisparamfbox
     set analysisparamfbox(file) {}
+    set analysisparamfbox(dir) {}
     set analysisparamfbox(types) [list \
 				]
 
     global apsavfbox
     set apsavfbox(file) {ds9.ps}
+    set apsavfbox(dir) {}
     set apsavfbox(types) [list \
 			      [list {PS} {*.ps}] \
 			      ]
 
     global apdatafbox
     set apdatafbox(file) {ds9.dat}
+    set apdatafbox(dir) {}
     set apdatafbox(types) [list \
 			       [list {DAT} {*.dat}] \
 			       ]
 
     global apconfigfbox
     set apconfigfbox(file) {ds9.plt}
+    set apconfigfbox(dir) {}
     set apconfigfbox(types) [list \
 				 [list {PLT} {*.plt}] \
 				 ]
 
     global textfbox
     set textfbox(file) {ds9.txt}
+    set textfbox(dir) {}
     set textfbox(types) [list \
 			     [list {TXT} {*.txt}] \
 			     ]
 
     global tclfbox
     set tclfbox(file) {ds9.tcl}
+    set tclfbox(dir) {}
     set tclfbox(types) [list \
 			    [list {TCL} {*.tcl}] \
 			    ]
 
     global hvhtmlfbox
     set hvhtmlfbox(file) {ds9.html}
-    set  hvhtmlfbox(types) [list \
+    set hvhtmlfbox(dir) {}
+    set hvhtmlfbox(types) [list \
 				[list {HTML} {*.html}] \
 				[list {HTML} {*.htm}] \
 			       ]
 
     global wcsfbox
     set wcsfbox(file) {ds9.wcs}
+    set wcsfbox(dir) {}
     set wcsfbox(types) [list \
 			    [list {WCS} {*.wcs}] \
 			    ]
 
     global backupfbox
     set backupfbox(file) {ds9.bck}
+    set backupfbox(dir) {}
     set backupfbox(types) [list \
 			       [list {BCK} {*.bck}] \
 			      ]
@@ -313,6 +335,7 @@ proc SetFileLast {format item} {
     global jpegfbox
     global pngfbox
     global mpegfbox
+
     switch $format {
 	fits {FileLast fitsfbox $item}
 	eps {FileLast epsfbox $item}
@@ -404,13 +427,13 @@ proc FileDialogMotif {varname which} {
 
     set result [::tk::MotifFDialog $type \
 		    -filetypes $types \
-		    -initialdir $ds9(dialog,dir) \
+		    -initialdir $var(dir) \
 		    -initialfile $var(file) \
 		    -parent $ds9(top)]
 
     if {$result != {}} {
 	set var(file) [file tail $result]
-	set ds9(dialog,dir) [file dirname $result]
+	set var(dir) [file dirname $result]
     }
 
     return $result
@@ -434,13 +457,13 @@ proc FileDialogWindows {varname which} {
 
     set result [::tk::dialog::file:: $type \
 		    -filetypes $types \
-		    -initialdir $ds9(dialog,dir) \
+		    -initialdir $var(dir) \
 		    -initialfile $var(file) \
 		    -parent $ds9(top)]
 
     if {$result != {}} {
 	set var(file) [file tail $result]
-	set ds9(dialog,dir) [file dirname $result]
+	set var(dir) [file dirname $result]
     }
 
     return $result
@@ -459,13 +482,13 @@ proc FileDialogNative {varname which} {
 
     if [catch {$which \
 		   -filetypes $types \
-		   -initialdir $ds9(dialog,dir) \
+		   -initialdir $var(dir) \
 		   -initialfile $var(file) \
 		   -parent $ds9(top)} result] {
 
 	# must have a bad file name, just clear and try again
 	set var(file) {}
-	set ds9(dialog,dir) {}
+	set var(dir) {}
 	if [catch {$which \
 		       -filetypes $types \
 		       -parent $ds9(top)} result] {
@@ -477,7 +500,7 @@ proc FileDialogNative {varname which} {
 
     if {$result != {}} {
 	set var(file) [file tail $result]
-	set ds9(dialog,dir) [file dirname $result]
+	set var(dir) [file dirname $result]
     }
 
     return $result
@@ -486,14 +509,8 @@ proc FileDialogNative {varname which} {
 
 proc FileLast {varname fn} {
     upvar #0 $varname var
-
-    set var(file) [file tail $fn]
-}
-
-proc FileLastFull {varname fn} {
-    upvar #0 $varname var
     global ds9
 
     set var(file) [file tail $fn]
-    set ds9(dialog,dir) [file dirname $fn]
+    set var(dir) [file dirname $fn]
 }
diff --git a/src/util.tcl b/src/util.tcl
index 59c52a8..db74444 100644
--- a/src/util.tcl
+++ b/src/util.tcl
@@ -190,9 +190,10 @@ proc Toplevel {w mb style title proc} {
     wm group $w $ds9(top)
     wm protocol $w WM_DELETE_WINDOW $proc
 
-    $w configure -menu $mb
+    # we need this first, before the configure command
     menu $mb
-    AppleMainMenu $mb
+    AppleMenu $mb
+    $w configure -menu $mb
 
     global pds9
     if {$pds9(dialog,center)} {
@@ -860,27 +861,28 @@ proc PrefsTheme {} {
     switch $pds9(theme) {
 	native {
 	    switch $ds9(wm) {
-		x11 {ttk::style theme use default}
+		x11 {
+		    ttk::style theme use default
+		    # set bg for non ttk widgets
+		    set ds9(app,bg) [ttk::style lookup "." -background]
+
+		    option add {*Bbutton.Background} $ds9(app,bg)
+		    option add {*Radiobutton.Background} $ds9(app,bg)
+		    option add {*Checkbutton.Background} $ds9(app,bg)
+		    option add {*Text.Background} $ds9(app,bg)
+		    option add {*Listbox.Background} $ds9(app,bg)
+		    option add {*Scale.Background} $ds9(app,bg)
+		    option add {*Menu.background} $ds9(app,bg)
+		    option add {*Table.Background} $ds9(app,bg)
+		    option add {*Graph.Background} $ds9(app,bg)
+		    option add {*Barchart.Background} $ds9(app,bg)
+		}
 		win32 {ttk::style theme use xpnative}
 		aqua {}
 	    }
 	}
 	default {ttk::style theme use $pds9(theme)}
     }
-
-    # set bg for non ttk widgets
-    set ds9(app,bg) [ttk::style lookup "." -background]
-
-    option add {*Bbutton.Background} $ds9(app,bg)
-    option add {*Radiobutton.Background} $ds9(app,bg)
-    option add {*Checkbutton.Background} $ds9(app,bg)
-    option add {*Text.Background} $ds9(app,bg)
-    option add {*Listbox.Background} $ds9(app,bg)
-    option add {*Scale.Background} $ds9(app,bg)
-    option add {*Menu.background} $ds9(app,bg)
-    option add {*Table.Background} $ds9(app,bg)
-    option add {*Graph.Background} $ds9(app,bg)
-    option add {*Barchart.Background} $ds9(app,bg)
 }
 
 proc PrefsDefaultFont {} {
diff --git a/tests/parse.sh b/tests/parse.sh
index 7512350..84b9082 100755
--- a/tests/parse.sh
+++ b/tests/parse.sh
@@ -138,13 +138,15 @@ ds9 fits/wmap.fits[100:200,100:200] &
 KillIt
 
 echo ".. hpx[system=equatorial,order=north,layout=equatorial,col=1,quad=1]"
-ds9 fits/wmap.fits[system=equatorial,order=north,layout=equatorial,col=1,quad=1] &
+ds9 fits/wmap.fits[system=equatorial,order=nested,layout=equatorial,col=1,quad=1] &
 KillIt
 
 echo ".. nrrd[100:200,100:200]"
-ds9 -nrrd nrrd/float_big_raw.nrrd[100:200,100:200]
+ds9 -nrrd nrrd/float_big_raw.nrrd[100:200,100:200] &
+KillIt
 
 echo ".. envi[100:200,100:200]"
-ds9 -envi envi/float_big.hdr envi/float_big.bsq[100:200,100:200]
+ds9 -envi envi/float_big.hdr envi/float_big.bsq[100:200,100:200] &
+KillIt
 
 echo "DONE"
diff --git a/tlt3.0/Makefile.in b/tlt3.0/Makefile.in
new file mode 100755
index 0000000..e4d16a8
--- /dev/null
+++ b/tlt3.0/Makefile.in
@@ -0,0 +1,449 @@
+# Makefile.in --
+#
+#	This file is a Makefile for Sample TEA Extension.  If it has the name
+#	"Makefile.in" then it is a template for a Makefile;  to generate the
+#	actual Makefile, run "./configure", which is a configuration script
+#	generated by the "autoconf" program (constructs like "@foo@" will get
+#	replaced in the actual Makefile.
+#
+# Copyright (c) 1999 Scriptics Corporation.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+#========================================================================
+# Add additional lines to handle any additional AC_SUBST cases that
+# have been added in a customized configure script.
+#========================================================================
+
+#SAMPLE_NEW_VAR	= @SAMPLE_NEW_VAR@
+
+#========================================================================
+# Nothing of the variables below this line should need to be changed.
+# Please check the TARGETS section below to make sure the make targets
+# are correct.
+#========================================================================
+
+#========================================================================
+# The names of the source files is defined in the configure script.
+# The object files are used for linking into the final library.
+# This will be used when a dist target is added to the Makefile.
+# It is not important to specify the directory, as long as it is the
+# $(srcdir) or in the generic, win or unix subdirectory.
+#========================================================================
+
+PKG_SOURCES	= @PKG_SOURCES@
+PKG_OBJECTS	= @PKG_OBJECTS@
+
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
+#========================================================================
+# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
+# this package that need to be installed, if any.
+#========================================================================
+
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
+
+#========================================================================
+# This is a list of public header files to be installed, if any.
+#========================================================================
+
+PKG_HEADERS	= @PKG_HEADERS@
+
+#========================================================================
+# "PKG_LIB_FILE" refers to the library (dynamic or static as per
+# configuration options) composed of the named objects.
+#========================================================================
+
+PKG_LIB_FILE	= @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+
+lib_BINARIES	= $(PKG_LIB_FILE)
+BINARIES	= $(lib_BINARIES)
+
+SHELL		= @SHELL@
+
+srcdir		= @srcdir@
+prefix		= @prefix@
+exec_prefix	= @exec_prefix@
+
+bindir		= @bindir@
+libdir		= @libdir@
+includedir	= @includedir@
+datarootdir	= @datarootdir@
+datadir		= @datadir@
+mandir		= @mandir@
+
+DESTDIR		=
+
+PKG_DIR		= $(PACKAGE_NAME)$(PACKAGE_VERSION)
+pkgdatadir	= $(datadir)/$(PKG_DIR)
+pkglibdir	= $(libdir)/$(PKG_DIR)
+pkgincludedir	= $(includedir)/$(PKG_DIR)
+
+top_builddir	= .
+
+INSTALL_OPTIONS	=
+INSTALL		= $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS}
+INSTALL_DATA_DIR = ${INSTALL} -d -m 755
+INSTALL_PROGRAM	= ${INSTALL} -m 555
+INSTALL_DATA	= ${INSTALL} -m 444
+INSTALL_SCRIPT	= ${INSTALL_PROGRAM}
+INSTALL_LIBRARY	= ${INSTALL_DATA}
+
+PACKAGE_NAME	= @PACKAGE_NAME@
+PACKAGE_VERSION	= @PACKAGE_VERSION@
+CC		= @CC@
+CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@
+CFLAGS_WARNING	= @CFLAGS_WARNING@
+EXEEXT		= @EXEEXT@
+LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@
+MAKE_LIB	= @MAKE_LIB@
+MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@
+MAKE_STUB_LIB	= @MAKE_STUB_LIB@
+OBJEXT		= @OBJEXT@
+RANLIB		= @RANLIB@
+RANLIB_STUB	= @RANLIB_STUB@
+SHLIB_CFLAGS	= @SHLIB_CFLAGS@
+SHLIB_LD	= @SHLIB_LD@
+SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
+STLIB_LD	= @STLIB_LD@
+#TCL_DEFS	= @TCL_DEFS@
+TCL_BIN_DIR	= @TCL_BIN_DIR@
+TCL_SRC_DIR	= @TCL_SRC_DIR@
+TK_BIN_DIR	= @TK_BIN_DIR@
+TK_SRC_DIR	= @TK_SRC_DIR@
+
+# Not used, but retained for reference of what libs Tcl required
+#TCL_LIBS	= @TCL_LIBS@
+
+#========================================================================
+# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
+# package without installing.  The other environment variables allow us
+# to test against an uninstalled Tcl.  Add special env vars that you
+# require for testing here (like TCLX_LIBRARY).
+#========================================================================
+
+#EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
+EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
+TCLLIBPATH	= $(top_builddir)
+TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
+PKG_ENV		= @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+		  PATH="$(EXTRA_PATH):$(PATH)" \
+		  TCLLIBPATH="$(TCLLIBPATH)"
+
+TCLSH_PROG	= @TCLSH_PROG@
+TCLSH		= $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
+
+WISH_ENV	= TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
+WISH_PROG	= @WISH_PROG@
+WISH		= $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)
+
+SHARED_BUILD	= @SHARED_BUILD@
+
+#INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@
+INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@ @XFT_CFLAGS@
+
+PKG_CFLAGS	= @PKG_CFLAGS@
+
+# TCL_DEFS is not strictly need here, but if you remove it, then you
+# must make sure that configure.in checks for the necessary components
+# that your library may use.  TCL_DEFS can actually be a problem if
+# you do not compile with a similar machine setup as the Tcl core was
+# compiled with.
+#DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
+DEFS		= @DEFS@ $(PKG_CFLAGS)
+
+# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
+CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
+CLEANFILES	= @CLEANFILES@
+
+CPPFLAGS	= @CPPFLAGS@
+LIBS		= @PKG_LIBS@ @LIBS@
+AR		= @AR@
+CFLAGS		= @CFLAGS@
+COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+.SUFFIXES: .c .$(OBJEXT)
+
+#========================================================================
+# Start of user-definable TARGETS section
+#========================================================================
+
+#========================================================================
+# TEA TARGETS.  Please note that the "libraries:" target refers to platform
+# independent files, and the "binaries:" target includes executable programs and
+# platform-dependent libraries.  Modify these targets so that they install
+# the various pieces of your package.  The make and install rules
+# for the BINARIES that you specified above have already been done.
+#========================================================================
+
+all: binaries libraries doc
+
+#========================================================================
+# The binaries target builds executable programs, Windows .dll's, unix
+# shared/static libraries, and any other platform-dependent files.
+# The list of targets to build for "binaries:" is specified at the top
+# of the Makefile, in the "BINARIES" variable.
+#========================================================================
+
+binaries: $(BINARIES)
+
+libraries:
+
+#========================================================================
+# Your doc target should differentiate from doc builds (by the developer)
+# and doc installs (see install-doc), which just install the docs on the
+# end user machine when building from source.
+#========================================================================
+
+doc:
+#	@echo "If you have documentation to create, place the commands to"
+#	@echo "build the docs in the 'doc:' target.  For example:"
+#	@echo "        xml2nroff sample.xml > sample.n"
+#	@echo "        xml2html sample.xml > sample.html"
+
+install: all install-binaries install-libraries install-doc
+
+install-binaries: binaries install-lib-binaries install-bin-binaries
+
+#========================================================================
+# This rule installs platform-independent files, such as header files.
+# The list=...; for p in $$list handles the empty list case x-platform.
+#========================================================================
+
+install-libraries: libraries
+	@$(INSTALL_DATA_DIR) $(DESTDIR)$(includedir)
+	@echo "Installing header files in $(DESTDIR)$(includedir)"
+	@list='$(PKG_HEADERS)'; for i in $$list; do \
+	    echo "Installing $(srcdir)/$$i" ; \
+	    $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
+	done;
+
+#========================================================================
+# Install documentation.  Unix manpages should go in the $(mandir)
+# directory.
+#========================================================================
+
+install-doc: doc
+	@$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann
+	@echo "Installing documentation in $(DESTDIR)$(mandir)"
+	@list='$(srcdir)/doc/*.n'; for i in $$list; do \
+	    echo "Installing $$i"; \
+	    $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
+	done
+
+test: binaries libraries
+	$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
+		-load "package ifneeded ${PACKAGE_NAME} ${PACKAGE_VERSION} \
+			[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
+
+shell: binaries libraries
+	@$(TCLSH) $(SCRIPT)
+
+gdb:
+	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+
+VALGRINDARGS =	--tool=memcheck --num-callers=8 --leak-resolution=high \
+		--leak-check=yes --show-reachable=yes -v
+
+valgrind: binaries libraries
+	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \
+		`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+
+valgrindshell: binaries libraries
+	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
+
+depend:
+
+#========================================================================
+# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
+# mentioned above.  That will ensure that this target is built when you
+# run "make binaries".
+#
+# The $(PKG_OBJECTS) objects are created and linked into the final
+# library.  In most cases these object files will correspond to the
+# source files above.
+#========================================================================
+
+$(PKG_LIB_FILE): $(PKG_OBJECTS)
+	-rm -f $(PKG_LIB_FILE)
+	${MAKE_LIB}
+	$(RANLIB) $(PKG_LIB_FILE)
+
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+	-rm -f $(PKG_STUB_LIB_FILE)
+	${MAKE_STUB_LIB}
+	$(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
+#========================================================================
+# We need to enumerate the list of .c to .o lines here.
+#
+# In the following lines, $(srcdir) refers to the toplevel directory
+# containing your extension.  If your sources are in a subdirectory,
+# you will have to modify the paths to reflect this:
+#
+# sample.$(OBJEXT): $(srcdir)/generic/sample.c
+# 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
+#
+# Setting the VPATH variable to a list of paths will cause the makefile
+# to look into these paths when resolving .c to .obj dependencies.
+# As necessary, add $(srcdir):$(srcdir)/compat:....
+#========================================================================
+
+VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx
+
+.c. at OBJEXT@:
+	$(COMPILE) -c `@CYGPATH@ $<` -o $@
+
+#========================================================================
+# Distribution creation
+# You may need to tweak this target to make it work correctly.
+#========================================================================
+
+#COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
+COMPRESS	= tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
+DIST_ROOT	= /tmp/dist
+DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)
+
+dist-clean:
+	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
+
+dist: dist-clean
+	$(INSTALL_DATA_DIR) $(DIST_DIR)
+	cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
+		$(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
+		$(DIST_DIR)/
+	chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
+	chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
+
+	for i in $(srcdir)/*.[ch]; do \
+	    if [ -f $$i ]; then \
+		cp -p $$i $(DIST_DIR)/ ; \
+	    fi; \
+	done;
+
+	$(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
+	cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
+		$(DIST_DIR)/tclconfig/
+	chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
+	chmod +x $(DIST_DIR)/tclconfig/install-sh
+
+	list='demos doc generic library mac tests unix win'; \
+	for p in $$list; do \
+	    if test -d $(srcdir)/$$p ; then \
+		$(INSTALL_DATA_DIR) $(DIST_DIR)/$$p; \
+		cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
+	    fi; \
+	done
+
+	(cd $(DIST_ROOT); $(COMPRESS);)
+
+#========================================================================
+# End of user-definable section
+#========================================================================
+
+#========================================================================
+# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
+# variable in configure.in
+#========================================================================
+
+clean:
+	-test -z "$(BINARIES)" || rm -f $(BINARIES)
+	-rm -f *.$(OBJEXT) core *.core
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean: clean
+	-rm -f *.tab.c
+	-rm -f $(CONFIG_CLEAN_FILES)
+	-rm -f config.cache config.log config.status
+
+#========================================================================
+# Install binary object libraries.  On Windows this includes both .dll and
+# .lib files.  Because the .lib files are not explicitly listed anywhere,
+# we need to deduce their existence from the .dll file of the same name.
+# Library files go into the lib directory.
+# In addition, this will generate the pkgIndex.tcl
+# file in the install location (assuming it can find a usable tclsh shell)
+#
+# You should not have to modify this target.
+#========================================================================
+
+install-lib-binaries: binaries
+	@$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)
+	@list='$(lib_BINARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+	    $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
+	    if test "x$$stub" = "xstub"; then \
+		echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
+		$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
+	    else \
+		echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
+		$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
+	    fi; \
+	    ext=`echo $$p|sed -e "s/.*\.//"`; \
+	    if test "x$$ext" = "xdll"; then \
+		lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
+		if test -f $$lib; then \
+		    echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
+	            $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
+		fi; \
+	    fi; \
+	  fi; \
+	done
+	@list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+	  if test -f $(srcdir)/$$p; then \
+	    destp=`basename $$p`; \
+	    echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
+	    $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
+	  fi; \
+	done
+	@if test "x$(SHARED_BUILD)" = "x1"; then \
+	    echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
+	    $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
+	fi
+
+#========================================================================
+# Install binary executables (e.g. .exe files and dependent .dll files)
+# This is for files that must go in the bin directory (located next to
+# wish and tclsh), like dependent .dll files on Windows.
+#
+# You should not have to modify this target, except to define bin_BINARIES
+# above if necessary.
+#========================================================================
+
+install-bin-binaries: binaries
+	@$(INSTALL_DATA_DIR) $(DESTDIR)$(bindir)
+	@list='$(bin_BINARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
+	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
+	  fi; \
+	done
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+	cd $(top_builddir) \
+	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+uninstall-binaries:
+	list='$(lib_BINARIES)'; for p in $$list; do \
+	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+	done
+	list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+	  p=`basename $$p`; \
+	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+	done
+	list='$(bin_BINARIES)'; for p in $$list; do \
+	  rm -f $(DESTDIR)$(bindir)/$$p; \
+	done
+
+.PHONY: all binaries clean depend distclean doc install libraries test
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tlt3.0/aclocal.m4 b/tlt3.0/aclocal.m4
new file mode 100755
index 0000000..1a391a5
--- /dev/null
+++ b/tlt3.0/aclocal.m4
@@ -0,0 +1,96 @@
+#
+# Include the TEA standard macro set
+#
+
+builtin(include,tclconfig/tcl.m4)
+
+#
+# Add here whatever m4 macros you want to define for your package
+#
+
+#--------------------------------------------------------------------
+# SC_PATH_X
+#
+#	Locate the X11 header files and the X11 library archive.  Try
+#	the ac_path_x macro first, but if it doesn't find the X stuff
+#	(e.g. because there's no xmkmf program) then check through
+#	a list of possible directories.  Under some conditions the
+#	autoconf macro will return an include directory that contains
+#	no include files, so double-check its result just to be safe.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Sets the following vars:
+#		XINCLUDES
+#		XLIBSW
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([SC_PATH_X], [
+    AC_PATH_X
+    not_really_there=""
+    if test "$no_x" = ""; then
+	if test "$x_includes" = ""; then
+	    AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
+	else
+	    if test ! -r $x_includes/X11/Intrinsic.h; then
+		not_really_there="yes"
+	    fi
+	fi
+    fi
+    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+	AC_MSG_CHECKING([for X11 header files])
+	found_xincludes="no"
+	AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
+	if test "$found_xincludes" = "no"; then
+	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+	    for i in $dirs ; do
+		if test -r $i/X11/Intrinsic.h; then
+		    AC_MSG_RESULT([$i])
+		    XINCLUDES=" -I$i"
+		    found_xincludes="yes"
+		    break
+		fi
+	    done
+	fi
+    else
+	if test "$x_includes" != ""; then
+	    XINCLUDES="-I$x_includes"
+	    found_xincludes="yes"
+	fi
+    fi
+    if test "$found_xincludes" = "no"; then
+	AC_MSG_RESULT([couldn't find any!])
+    fi
+
+    if test "$no_x" = yes; then
+	AC_MSG_CHECKING([for X11 libraries])
+	XLIBSW=nope
+	dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+	for i in $dirs ; do
+	    if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+		AC_MSG_RESULT([$i])
+		XLIBSW="-L$i -lX11"
+		x_libraries="$i"
+		break
+	    fi
+	done
+    else
+	if test "$x_libraries" = ""; then
+	    XLIBSW=-lX11
+	else
+	    XLIBSW="-L$x_libraries -lX11"
+	fi
+    fi
+    if test "$XLIBSW" = nope ; then
+	AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+    fi
+    if test "$XLIBSW" = nope ; then
+	AC_MSG_RESULT([could not find any!  Using -lX11.])
+	XLIBSW=-lX11
+    fi
+])
+
diff --git a/tlt3.0/bltBase64.c b/tlt3.0/bltBase64.c
new file mode 100644
index 0000000..dccdd8d
--- /dev/null
+++ b/tlt3.0/bltBase64.c
@@ -0,0 +1,285 @@
+
+/*
+ * bltBase64.c --
+ *
+ * This module implements base64 processing procedures for the BLT toolkit.
+ *
+ *	Copyright 1991-2005 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "bltInt.h"
+#include "bltBase64.h"
+
+/*
+ * Table for encoding base64.  
+ */
+static char encode64[64] = {
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+};
+
+/*
+ * Table for decoding base64.  
+ *
+ * Note that NUL and '=' also return 0.  This is so we can blindly decode 4
+ * octets without requiring special handing of left-over bytes (i.e. when the
+ * encoded buffer did not end on a 3-byte boundary).
+ */
+#define NA	127
+
+static char decode64[256] = {
+    0 /* '\0' */, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    62  /* + */, 
+    NA, NA, NA, 
+    63  /* / */,
+    52  /* 0 */, 53  /* 1 */, 54  /* 2 */, 55  /* 3 */, 56  /* 4 */, 
+    57  /* 5 */, 58  /* 6 */, 59  /* 7 */, 60  /* 8 */, 61  /* 9 */, 
+    NA, NA, NA, 
+    0 /* = */, 
+    NA, NA, NA, 
+    0   /* A */, 1   /* B */, 2   /* C */, 3   /* D */, 4   /* E */, 
+    5   /* F */, 6   /* G */, 7   /* H */, 8   /* I */, 9   /* J */, 
+    10  /* K */, 11  /* L */, 12  /* M */, 13  /* N */, 14  /* O */, 
+    15  /* P */, 16  /* Q */, 17  /* R */, 18  /* S */, 19  /* T */, 
+    20  /* U */, 21  /* V */, 22  /* W */, 23  /* X */, 24  /* Y */, 
+    25  /* Z */, 
+    NA, NA, NA, NA, NA, NA, 
+    26  /* a */, 27  /* b */, 28  /* c */, 29  /* d */, 30  /* e */, 
+    31  /* f */, 32  /* g */, 33  /* h */, 34  /* i */, 35  /* j */, 
+    36  /* k */, 37  /* l */, 38  /* m */, 39  /* n */, 40  /* o */, 
+    41  /* p */, 42  /* q */, 43  /* r */, 44  /* s */, 45  /* t */, 
+    46  /* u */, 47  /* v */, 48  /* w */, 49  /* x */, 50  /* y */, 
+    51  /* z */, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
+    NA, NA, NA, NA, NA
+};
+
+int
+Blt_IsBase64(const unsigned char *bytes, size_t nBytes)
+{
+    const unsigned char *bp, *bend;
+
+    for (bp = bytes, bend = bp + nBytes; bp < bend; bp++) {
+	unsigned int byte;
+
+	byte = *bp;
+	if ((decode64[byte] == NA) && (!isspace(byte))) {
+	    return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+static INLINE unsigned char
+NextChar(const unsigned char **bp, const unsigned char *lastPtr) 
+{
+    char c;
+
+    /* Skip whitespace and invalid characters. Let's see if being fault-tolerant
+     * is better than erroring out here.*/
+    while (((*bp) < lastPtr) &&  (decode64[(**bp)] == NA)) {
+	(*bp)++;
+    }
+    c = ((*bp) < lastPtr) ? **bp : 0;
+    if ((c != '\0') && (c != '=')) {
+	(*bp)++;
+    }
+    return c;				/* Valid symbol */
+}
+
+unsigned char *
+Blt_Base64_Decode(Tcl_Interp *interp, const char *string, size_t *lengthPtr)
+{
+    size_t nBytes;
+    unsigned char *bp;
+    unsigned char *buffer;
+    const unsigned char *p, *pend;
+    nBytes = *lengthPtr;
+
+    /* 
+     * Assuming that the string contains no padding or whitespace, allocate a
+     * buffer with a worst-case length.
+     */
+    nBytes = ((nBytes + 1) * 3)  / 4; 
+    buffer = malloc(nBytes);
+    if (buffer == NULL) {
+	Tcl_AppendResult(interp, "can't allocate ", Blt_Itoa(nBytes), 
+			 " for buffer", (char *)NULL);
+	return NULL;
+    }
+    bp = buffer;
+    for (p = (unsigned char *)string, pend = p + *lengthPtr; p < pend; 
+	 /*empty*/) {
+	unsigned char a, b, c, d;
+	unsigned int u1, u2, u3;
+
+	a = NextChar(&p, pend);
+	b = NextChar(&p, pend);
+	c = NextChar(&p, pend);
+	d = NextChar(&p, pend);
+
+	if (d == '\0') {
+	    if (a != '\0') {
+		Tcl_AppendResult(interp, "premature end of base64 data",
+			(char *)NULL);
+		free(buffer);
+		return NULL;
+	    }
+	    break;
+        }
+
+	/*
+	 * in:     a      b      c     d
+	 *       ------.......-------......
+	 *      |54321054|32105432|10543210|
+	 * out:    u1       u2       u3
+	 */
+
+	/* a = [543210xx] | [xxxxxx54] >> 4 */
+	u1 = (decode64[a] << 2) | ((decode64[b] & 0x30) >> 4);
+	/* b = [3210xxxx] | [xxxx5432]  */
+	u2 = ((decode64[b] & 0x0F) << 4) |((decode64[c] & 0x3C) >> 2);
+	/* c = [10xxxxxx] | [xx543210]  */
+	u3 = ((decode64[c] & 0x03) << 6) | decode64[d];
+
+	if (d == '=') {
+	    if ((a == '=') || (b == '=')) {
+		break;			/* This should not be possible. */
+	    }
+	    if (c == '=') {
+		*bp++ = (unsigned char)u1;
+	    } else {
+		*bp++ = (unsigned char)u1;
+		*bp++ = (unsigned char)u2;
+	    }
+	    break;
+	}
+	bp[0] = (unsigned char)u1;
+	bp[1] = (unsigned char)u2;
+	bp[2] = (unsigned char)u3;
+	bp += 3;
+    }
+    nBytes = bp - buffer;
+    /* Reset the fill point to the number of bytes processed. */
+    *lengthPtr = nBytes;
+    return buffer;
+}
+
+char *
+Blt_Base64_Encode(Tcl_Interp *interp, const unsigned char *buffer, 
+		  size_t bufsize) 
+{
+    char *dest, *dp;
+    int count, remainder;
+    size_t length;
+    const unsigned char *sp, *send;
+
+    /* Compute worst-case length. */
+    length = (((bufsize + 1) * 4) + 2) / 3; 
+    length += (length + 59) / 60;	/* Add space for newlines. */
+    length++;				/* NUL byte */
+
+    dest = malloc(sizeof(char) * length);
+    if (dest == NULL) {
+	Tcl_AppendResult(interp, "can't allocate \"", Blt_Itoa(length), 
+		"\" bytes for buffer", (char *)NULL);
+	return NULL;
+    }
+    count = 0;
+    remainder = bufsize % 3;
+    send = buffer + (bufsize - remainder);
+    dp = dest;
+    for (sp = buffer; sp < send; sp += 3) {
+	int a, b, c, d;
+
+	/*
+	 * in:        0        1        2
+	 *       |76543210|76543210|76543210|
+	 *        ------.......-------......
+	 * out:     a      b      c     d
+	 */
+	/* a = [xx765432] */
+	a = sp[0] >> 2;
+	/* b = [xx10xxxx] | [xxxx7654]  */
+	b = ((sp[0] & 0x03) << 4) | ((sp[1] & 0xF0) >> 4);
+	/* c = [xx3210xx] | [xxxxxx76]  */
+	c = ((sp[1] & 0x0F) << 2) | ((sp[2] & 0xC0) >> 6);
+	/* d = [xx543210]  */
+	d = (sp[2] & 0x3F);
+
+	dp[0] = encode64[a];
+	dp[1] = encode64[b];
+	dp[2] = encode64[c];
+	dp[3] = encode64[d];
+
+	dp += 4;
+	count += 4;
+	if (count > 60) {
+	    *dp++ = '\n';
+	    count = 0;
+	}
+    }
+
+    if (remainder > 0) {
+	int a, b, c;
+
+	/* 
+	 * Handle the two cases where the input buffer doesn't end on a 3-byte
+	 * boundary.
+	 */
+	if (remainder == 2) {
+	    a = sp[0] >> 2;
+	    b = ((sp[0] & 0x03) << 4) | ((sp[1] & 0xF0) >> 4);
+	    c = ((sp[1] & 0x0F) << 2);
+	    dp[0] = encode64[a];
+	    dp[1] = encode64[b];
+	    dp[2] = encode64[c];
+	    dp[3] = '=';
+	} else if (remainder == 1) {
+	    a = sp[0] >> 2;
+	    b = ((sp[0] & 0x03) << 4);
+	    dp[0] = encode64[a];
+	    dp[1] = encode64[b];
+	    dp[2] = dp[3] = '=';
+	}
+	dp += 4;
+	count += 4;
+	if (count > 60) {
+	    *dp++ = '\n';
+	}
+    }
+    assert((size_t)(dp - dest) < length);
+    *dp = '\0';
+    return dest;
+}
+
diff --git a/tlt3.0/bltBase64.h b/tlt3.0/bltBase64.h
new file mode 100644
index 0000000..6dad753
--- /dev/null
+++ b/tlt3.0/bltBase64.h
@@ -0,0 +1,39 @@
+/*
+ * bltBase64.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_BASE64_H
+#define _BLT_BASE64_H
+
+#include <tcl.h>
+
+extern unsigned char *Blt_Base64_Decode(Tcl_Interp *interp, 
+	const char *string, size_t *lengthPtr);
+
+extern char *Blt_Base64_Encode(Tcl_Interp *interp, 
+	const unsigned char *buffer, size_t bufsize);
+
+extern int Blt_IsBase64(const unsigned char *buf, size_t length);
+
+#endif
diff --git a/tlt3.0/bltBgStyle.c b/tlt3.0/bltBgStyle.c
new file mode 100644
index 0000000..b866495
--- /dev/null
+++ b/tlt3.0/bltBgStyle.c
@@ -0,0 +1,2018 @@
+/*
+ * bltBgPattern.c --
+ *
+ * This module creates background patterns for the BLT toolkit.
+ *
+ *	Copyright 1995-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <X11/Xutil.h>
+
+#include "bltInt.h"
+#include "bltWindow.h"
+#include "bltMath.h"
+#include "bltChain.h"
+#include "bltImage.h"
+#include "bltHash.h"
+#include "bltBgStyle.h"
+
+#define BG_PATTERN_THREAD_KEY	"BLT Background Pattern Data"
+#define TEXTURE_CHECKERED 1
+#define TEXTURE_STRIPED   0
+
+enum PatternTypes {
+  PATTERN_GRADIENT,			/* Color gradient. */
+  PATTERN_TILE,			/* Tiled or resizable color picture. */
+  PATTERN_SOLID,			/* General pattern. */
+  PATTERN_TEXTURE,			/* Procedural texture. */
+};
+
+
+enum ReferenceTypes {
+  REFERENCE_SELF,			/* Current window. */
+  REFERENCE_TOPLEVEL,			/* Toplevel of current window. */
+  REFERENCE_WINDOW,			/* Specifically named window. */
+  REFERENCE_NONE,		        /* Don't use reference
+					 * window. Background region will be
+					 * defined by user. */
+};
+
+typedef struct {
+  int x, y;
+  unsigned int w, h;
+  Tk_Window tkwin;
+} Reference;
+
+typedef struct {
+  int x, y, width, height;
+} BgRegion;
+
+typedef struct {
+  Blt_HashTable patternTable;		/* Hash table of pattern structures
+					 * keyed by the name of the image. */
+  Tcl_Interp *interp;			/* Interpreter associated with this set
+					 * of background patterns. */
+  int nextId;				/* Serial number of the identifier to be
+					 * used for next background pattern
+					 * created.  */
+} BackgroundInterpData;
+
+typedef struct _Pattern Pattern;
+
+typedef void (DestroyPatternProc)(Pattern *patternPtr);
+typedef int (ConfigurePatternProc)(Tcl_Interp *interp, Pattern *patternPtr,
+				   int objc, Tcl_Obj *const *objv, unsigned int flags);
+typedef void (DrawRectangleProc)(Tk_Window tkwin, Drawable drawable, 
+				 Pattern *patternPtr, int x, int y, int w, int h);
+typedef void (DrawPolygonProc)(Tk_Window tkwin, Drawable drawable, 
+			       Pattern *patternPtr, int nPoints, XPoint *points);
+
+typedef struct {
+  enum PatternTypes type;		/* Type of pattern style: solid, tile,
+					 * texture, or gradient. */
+  Blt_ConfigSpec *configSpecs;
+  DestroyPatternProc *destroyProc;
+  ConfigurePatternProc *configProc;
+  DrawRectangleProc *drawRectangleProc;
+  DrawPolygonProc *drawPolygonProc;
+} PatternClass;
+
+
+struct _Pattern {
+  const char *name;			/* Generated name of background
+					 * pattern. */
+  PatternClass *classPtr;
+  BackgroundInterpData *dataPtr;
+  Tk_Window tkwin;			/* Main window. Used to query background
+					 * pattern options. */
+  Display *display;			/* Display of this background
+					 * pattern. */
+  unsigned int flags;			/* See definitions below. */
+  Blt_HashEntry *hashPtr;		/* Hash entry in pattern table. */
+  Blt_Chain chain;			/* List of pattern tokens.  Used to
+					 * register callbacks for each client of
+					 * the background pattern. */
+  Blt_ChainLink link;			/* Background token that is associated
+					 * with the pattern creation "bgpattern
+					 * create...". */
+  Tk_3DBorder border;			/* 3D Border.  May be used for all
+					 * background types. */
+  Tk_Window refWindow;		/* Refer to coordinates in this window
+				 * when determining the tile/gradient
+				 * origin. */
+  BgRegion refRegion;
+  Blt_HashTable pictTable;		/* Table of pictures cached for each
+					 * pattern reference. */
+  int reference;			/* "self", "toplevel", or "window". */
+  int xOrigin, yOrigin;
+};
+
+typedef struct {
+  const char *name;			/* Generated name of background
+					 * pattern. */
+  PatternClass *classPtr;
+  BackgroundInterpData *dataPtr;
+  Tk_Window tkwin;			/* Main window. Used to query background
+					 * pattern options. */
+  Display *display;			/* Display of this background
+					 * pattern. */
+  unsigned int flags;			/* See definitions below. */
+  Blt_HashEntry *hashPtr;		/* Link to original client. */
+  Blt_Chain chain;			/* List of pattern tokens.  Used to
+					 * register callbacks for each client of
+					 * the background pattern. */
+  Blt_ChainLink link;			/* Background token that is associated
+					 * with the pattern creation "bgpattern
+					 * create...". */
+  Tk_3DBorder border;			/* 3D Border.  May be used for all
+					 * pattern types. */
+  Tk_Window refWindow;		/* Refer to coordinates in this window
+				 * when determining the tile/gradient
+				 * origin. */
+  BgRegion refRegion;
+  Blt_HashTable pictTable;		/* Table of pictures cached for each
+					 * pattern reference. */
+  int reference;			/* "self", "toplevel", or "window". */
+  int xOrigin, yOrigin;
+
+  /* Solid pattern specific fields. */
+  int alpha;				/* Transparency value. */
+} SolidPattern;
+
+typedef struct {
+  const char *name;			/* Generated name of background
+					 * pattern. */
+  PatternClass *classPtr;
+  BackgroundInterpData *dataPtr;
+  Tk_Window tkwin;			/* Main window. Used to query background
+					 * pattern options. */
+  Display *display;			/* Display of this background
+					 * pattern. */
+  unsigned int flags;			/* See definitions below. */
+  Blt_HashEntry *hashPtr;		/* Link to original client. */
+  Blt_Chain chain;			/* List of pattern tokens.  Used to
+					 * register callbacks for each client of
+					 * the background pattern. */
+  Blt_ChainLink link;			/* Background token that is associated
+					 * with the pattern creation "bgpattern
+					 * create...". */
+  Tk_3DBorder border;			/* 3D Border.  May be used for all
+					 * pattern types. */
+  Tk_Window refWindow;		/* Refer to coordinates in this window
+				 * when determining the tile/gradient
+				 * origin. */
+  BgRegion refRegion;
+  Blt_HashTable pictTable;		/* Table of pictures cached for each
+					 * pattern reference. */
+  int reference;			/* "self", "toplevel", or "window". */
+  int xOrigin, yOrigin;
+  /* Image pattern specific fields. */
+  Tk_Image tkImage;			/* Original image (before
+					 * resampling). */
+} TilePattern;
+
+typedef struct {
+  const char *name;			/* Generated name of background
+					 * pattern. */
+  PatternClass *classPtr;
+  BackgroundInterpData *dataPtr;
+  Tk_Window tkwin;			/* Main window. Used to query background
+					 * pattern options. */
+  Display *display;			/* Display of this background
+					 * pattern. */
+  unsigned int flags;			/* See definitions below. */
+  Blt_HashEntry *hashPtr;		/* Link to original client. */
+  Blt_Chain chain;			/* List of pattern tokens.  Used to
+					 * register callbacks for each client of
+					 * the background pattern. */
+  Blt_ChainLink link;			/* Background token that is associated
+					 * with the pattern creation "bgpattern
+					 * create...". */
+  Tk_3DBorder border;			/* 3D Border.  May be used for all
+					 * pattern types. */
+  Tk_Window refWindow;		/* Refer to coordinates in this window
+				 * when determining the tile/gradient
+				 * origin. */
+  BgRegion refRegion;
+  Blt_HashTable pictTable;		/* Table of pictures cached for each
+					 * pattern reference. */
+  int reference;			/* "self", "toplevel", or "window". */
+  int xOrigin, yOrigin;
+  /* Gradient pattern specific fields. */
+  int alpha;				/* Transparency value. */
+} GradientPattern;
+
+typedef struct {
+  const char *name;			/* Generated name of background
+					 * pattern. */
+  PatternClass *classPtr;
+  BackgroundInterpData *dataPtr;
+  Tk_Window tkwin;			/* Main window. Used to query background
+					 * pattern options. */
+  Display *display;			/* Display of this background
+					 * pattern. */
+  unsigned int flags;			/* See definitions below. */
+  Blt_HashEntry *hashPtr;		/* Link to original client. */
+  Blt_Chain chain;			/* List of pattern tokens.  Used to
+					 * register callbacks for each client of
+					 * the background pattern. */
+  Blt_ChainLink link;			/* Background token that is associated
+					 * with the pattern creation "bgpattern
+					 * create...". */
+  Tk_3DBorder border;			/* 3D Border.  May be used for all
+					 * pattern types. */
+  Tk_Window refWindow;		/* Refer to coordinates in this window
+				 * when determining the tile/gradient
+				 * origin. */
+  BgRegion refRegion;
+  Blt_HashTable pictTable;		/* Table of pictures cached for each
+					 * pattern reference. */
+  int reference;			/* "self", "toplevel", or "window". */
+  int xOrigin, yOrigin;
+
+  /* Texture pattern specific fields. */
+  int alpha;				/* Transparency value. */
+  int type;
+} TexturePattern;
+
+struct _Blt_Background {
+  Pattern *corePtr;			/* Pointer to master background pattern
+					 * object. */
+  Blt_BackgroundChangedProc *notifyProc;
+  ClientData clientData;		/* Data to be passed on notifier
+					 * callbacks.  */
+  Blt_ChainLink link;			/* Entry in notifier list. */
+};
+
+#define DELETE_PENDING		(1<<0)
+#define BG_CENTER		(1<<2)
+#define BG_SCALE		(1<<3)
+
+typedef struct _Blt_Background Background;
+
+#define DEF_OPACITY		"100.0"
+#define DEF_ORIGIN_X		"0"
+#define DEF_ORIGIN_Y		"0"
+#define DEF_BORDER		STD_NORMAL_BACKGROUND
+#define DEF_GRADIENT_PATH	"y"
+#define DEF_GRADIENT_HIGH	"grey90"
+#define DEF_GRADIENT_JITTER	"no"
+#define DEF_GRADIENT_LOGSCALE	"yes"
+#define DEF_GRADIENT_LOW	"grey50"
+#define DEF_GRADIENT_MODE	"xlinear"
+#define DEF_GRADIENT_SHAPE	"linear"
+#define DEF_REFERENCE		"toplevel"
+#define DEF_RESAMPLE_FILTER	"box"
+#define DEF_SCALE		"no"
+#define DEF_CENTER		"no"
+#define DEF_TILE		"no"
+
+static Blt_OptionParseProc ObjToImageProc;
+static Blt_OptionPrintProc ImageToObjProc;
+static Blt_OptionFreeProc FreeImageProc;
+static Blt_CustomOption imageOption =
+  {
+    ObjToImageProc, ImageToObjProc, FreeImageProc, (ClientData)0
+  };
+
+extern Blt_CustomOption bltFilterOption;
+
+static Blt_OptionParseProc ObjToReferenceProc;
+static Blt_OptionPrintProc ReferenceToObjProc;
+static Blt_CustomOption referenceToOption =
+  {
+    ObjToReferenceProc, ReferenceToObjProc, NULL, (ClientData)0
+  };
+
+static Blt_OptionParseProc ObjToOpacityProc;
+static Blt_OptionPrintProc OpacityToObjProc;
+static Blt_CustomOption opacityOption =
+  {
+    ObjToOpacityProc, OpacityToObjProc, NULL, (ClientData)0
+  };
+
+static Blt_OptionParseProc ObjToTypeProc;
+static Blt_OptionPrintProc TypeToObjProc;
+static Blt_CustomOption typeOption =
+  {
+    ObjToTypeProc, TypeToObjProc, NULL, (ClientData)0
+  };
+
+static Blt_ConfigSpec solidConfigSpecs[] =
+  {
+    {BLT_CONFIG_SYNONYM, "-background", "color", (char *)NULL, (char *)NULL, 
+     0, 0},
+    {BLT_CONFIG_SYNONYM, "-bg", "color", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_BORDER, "-color", "color", "Color", DEF_BORDER, 
+     Blt_Offset(SolidPattern, border), 0},
+    {BLT_CONFIG_CUSTOM, "-opacity", "opacity", "Opacity", "100.0", 
+     Blt_Offset(SolidPattern, alpha), BLT_CONFIG_DONT_SET_DEFAULT, 
+     &opacityOption},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+  };
+
+static Blt_ConfigSpec tileConfigSpecs[] =
+  {
+    {BLT_CONFIG_BITMASK, "-center", "center", "Center", DEF_CENTER,
+     Blt_Offset(TilePattern, flags), BLT_CONFIG_DONT_SET_DEFAULT, 
+     (Blt_CustomOption *)BG_CENTER},
+    {BLT_CONFIG_BORDER, "-color", "color", "Color", DEF_BORDER, 
+     Blt_Offset(TilePattern, border), 0},
+    {BLT_CONFIG_BORDER, "-darkcolor", "darkColor", "DarkColor", DEF_BORDER, 
+     Blt_Offset(TilePattern, border), 0},
+    {BLT_CONFIG_CUSTOM, "-image", "image", "Image", (char *)NULL,
+     Blt_Offset(TilePattern, tkImage), BLT_CONFIG_DONT_SET_DEFAULT, 
+     &imageOption},
+    {BLT_CONFIG_BORDER, "-lightcolor", "lightColor", "LightColor", DEF_BORDER, 
+     Blt_Offset(TilePattern, border), 0},
+    {BLT_CONFIG_CUSTOM, "-relativeto", "relativeTo", "RelativeTo", 
+     DEF_REFERENCE, Blt_Offset(TilePattern, reference), 
+     BLT_CONFIG_DONT_SET_DEFAULT, &referenceToOption},
+    {BLT_CONFIG_BITMASK, "-scale", "scale", "scale", DEF_SCALE,
+     Blt_Offset(TilePattern, flags), BLT_CONFIG_DONT_SET_DEFAULT, 
+     (Blt_CustomOption *)BG_SCALE},
+    {BLT_CONFIG_PIXELS, "-xorigin", "xOrigin", "XOrigin", DEF_ORIGIN_X,
+     Blt_Offset(TilePattern, xOrigin), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-yorigin", "yOrigin", "YOrigin", DEF_ORIGIN_Y,
+     Blt_Offset(TilePattern, yOrigin), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+  };
+
+static Blt_ConfigSpec gradientConfigSpecs[] =
+  {
+    {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_BORDER,
+     Blt_Offset(GradientPattern, border), 0},
+    {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_CUSTOM, "-opacity", "opacity", "Opacity", "100.0", 
+     Blt_Offset(GradientPattern, alpha), BLT_CONFIG_DONT_SET_DEFAULT, 
+     &opacityOption},
+    {BLT_CONFIG_CUSTOM, "-relativeto", "relativeTo", "RelativeTo", 
+     DEF_REFERENCE, Blt_Offset(GradientPattern, reference), 
+     BLT_CONFIG_DONT_SET_DEFAULT, &referenceToOption},
+    {BLT_CONFIG_PIXELS, "-xorigin", "xOrigin", "XOrigin", DEF_ORIGIN_X,
+     Blt_Offset(GradientPattern, xOrigin), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-yorigin", "yOrigin", "YOrigin", DEF_ORIGIN_Y,
+     Blt_Offset(GradientPattern, yOrigin), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+  };
+
+static Blt_ConfigSpec textureConfigSpecs[] =
+  {
+    {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_BORDER,
+     Blt_Offset(TexturePattern, border), 0},
+    {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_CUSTOM, "-relativeto", "relativeTo", "RelativeTo", 
+     DEF_REFERENCE, Blt_Offset(TexturePattern, reference), 
+     BLT_CONFIG_DONT_SET_DEFAULT, &referenceToOption},
+    {BLT_CONFIG_CUSTOM, "-type", "type", "Type", 
+     DEF_REFERENCE, Blt_Offset(TexturePattern, type), 
+     BLT_CONFIG_DONT_SET_DEFAULT, &typeOption},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+  };
+
+static void NotifyClients(Pattern *corePtr);
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ImageChangedProc
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static void
+ImageChangedProc(
+		 ClientData clientData,
+		 int x, int y, int width, int height, /* Not used. */
+		 int imageWidth, int imageHeight)	 /* Not used. */
+{
+  Pattern *corePtr = clientData;
+
+  /* Propagate the change in the image to all the clients. */
+  NotifyClients(corePtr);
+}
+
+/*ARGSUSED*/
+static void
+FreeImageProc(
+	      ClientData clientData,
+	      Display *display,			/* Not used. */
+	      char *widgRec,
+	      int offset)
+{
+  TilePattern *patternPtr = (TilePattern *)(widgRec);
+
+  if (patternPtr->tkImage != NULL) {
+    Tk_FreeImage(patternPtr->tkImage);
+    patternPtr->tkImage = NULL;
+  }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToImageProc --
+ *
+ *	Given an image name, get the Tk image associated with it.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToImageProc(
+	       ClientData clientData,		/* Not used. */
+	       Tcl_Interp *interp,		        /* Interpreter to send results back
+							 * to */
+	       Tk_Window tkwin,			/* Not used. */
+	       Tcl_Obj *objPtr,			/* String representation of value. */
+	       char *widgRec,			/* Widget record. */
+	       int offset,				/* Offset to field in structure */
+	       int flags)	
+{
+  TilePattern *patternPtr = (TilePattern *)(widgRec);
+  Tk_Image tkImage;
+
+  tkImage = Tk_GetImage(interp, patternPtr->tkwin, Tcl_GetString(objPtr), 
+			ImageChangedProc, patternPtr);
+  if (tkImage == NULL) {
+    return TCL_ERROR;
+  }
+  patternPtr->tkImage = tkImage;
+  return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ImageToObjProc --
+ *
+ *	Convert the image name into a string Tcl_Obj.
+ *
+ * Results:
+ *	The string representation of the image is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+ImageToObjProc(
+	       ClientData clientData,		/* Not used. */
+	       Tcl_Interp *interp,
+	       Tk_Window tkwin,			/* Not used. */
+	       char *widgRec,			/* Widget record */
+	       int offset,				/* Offset to field in structure */
+	       int flags)	
+{
+  TilePattern *patternPtr = (TilePattern *)(widgRec);
+
+  if (patternPtr->tkImage == NULL) {
+    return Tcl_NewStringObj("", -1);
+  }
+  return Tcl_NewStringObj(Blt_Image_Name(patternPtr->tkImage), -1);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToReference --
+ *
+ *	Given a string name, get the resample filter associated with it.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToReferenceProc(
+		   ClientData clientData,		/* Not used. */
+		   Tcl_Interp *interp,		        /* Interpreter to send results back
+							 * to */
+		   Tk_Window tkwin,			/* Not used. */
+		   Tcl_Obj *objPtr,			/* String representation of value. */
+		   char *widgRec,			/* Widget record. */
+		   int offset,				/* Offset to field in structure */
+		   int flags)	
+{
+  Pattern *patternPtr = (Pattern *)(widgRec);
+  int *referencePtr = (int *)(widgRec + offset);
+  const char *string;
+  char c;
+  int refType;
+  int length;
+
+  string = Tcl_GetStringFromObj(objPtr, &length);
+  c = string[0];
+  if ((c == 's') && (strncmp(string, "self", length) == 0)) {
+    refType = REFERENCE_SELF;
+  } else if ((c == 't') && (strncmp(string, "toplevel", length) == 0)) {
+    refType = REFERENCE_TOPLEVEL;
+  } else if ((c == 'n') && (strncmp(string, "none", length) == 0)) {
+    refType = REFERENCE_NONE;
+  } else if (c == '.') {
+    Tk_Window tkwin, tkMain;
+
+    tkMain = Tk_MainWindow(interp);
+    tkwin = Tk_NameToWindow(interp, string, tkMain);
+    if (tkwin == NULL) {
+      return TCL_ERROR;
+    }
+    refType = REFERENCE_WINDOW;
+    patternPtr->refWindow = tkwin;
+  } else {
+    Tcl_AppendResult(interp, "unknown reference type \"", string, "\"",
+		     (char *)NULL);
+    return TCL_ERROR;
+  }
+  *referencePtr = refType;
+  return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ReferenceToObjProc --
+ *
+ *	Convert the picture filter into a string Tcl_Obj.
+ *
+ * Results:
+ *	The string representation of the filter is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+ReferenceToObjProc(
+		   ClientData clientData,		/* Not used. */
+		   Tcl_Interp *interp,
+		   Tk_Window tkwin,			/* Not used. */
+		   char *widgRec,			/* Widget record */
+		   int offset,				/* Offset to field in structure */
+		   int flags)	
+{
+  int reference = *(int *)(widgRec + offset);
+  const char *string;
+
+  switch (reference) {
+  case REFERENCE_SELF:
+    string = "self";
+    break;
+
+  case REFERENCE_TOPLEVEL:
+    string = "toplevel";
+    break;
+
+  case REFERENCE_NONE:
+    string = "none";
+    break;
+
+  case REFERENCE_WINDOW:
+    {
+      Pattern *patternPtr = (Pattern *)(widgRec);
+
+      string = Tk_PathName(patternPtr->refWindow);
+    }
+    break;
+
+  default:
+    string = "???";
+    break;
+  }
+  return Tcl_NewStringObj(string, -1);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToOpacity --
+ *
+ *	Given a string name, get the resample filter associated with it.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToOpacityProc(
+		 ClientData clientData,		/* Not used. */
+		 Tcl_Interp *interp,			/* Interpreter to send results back
+							 * to */
+		 Tk_Window tkwin,			/* Not used. */
+		 Tcl_Obj *objPtr,			/* String representation of value. */
+		 char *widgRec,			/* Widget record. */
+		 int offset,				/* Offset to field in structure */
+		 int flags)	
+{
+  int *alphaPtr = (int *)(widgRec + offset);
+  double opacity;
+
+  if (Tcl_GetDoubleFromObj(interp, objPtr, &opacity) != TCL_OK) {
+    return TCL_ERROR;
+  }
+  if ((opacity < 0.0) || (opacity > 100.0)) {
+    Tcl_AppendResult(interp, "invalid percent opacity \"", 
+		     Tcl_GetString(objPtr), "\" should be 0 to 100", (char *)NULL);
+    return TCL_ERROR;
+  }
+  opacity = (opacity / 100.0) * 255.0;
+  *alphaPtr = ROUND(opacity);
+  return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * OpacityToObj --
+ *
+ *	Convert the picture filter into a string Tcl_Obj.
+ *
+ * Results:
+ *	The string representation of the filter is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+OpacityToObjProc(
+		 ClientData clientData,		/* Not used. */
+		 Tcl_Interp *interp,
+		 Tk_Window tkwin,			/* Not used. */
+		 char *widgRec,			/* Widget record */
+		 int offset,				/* Offset to field in structure */
+		 int flags)	
+{
+  int *alphaPtr = (int *)(widgRec + offset);
+  double opacity;
+
+  opacity = (*alphaPtr / 255.0) * 100.0;
+  return Tcl_NewDoubleObj(opacity);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToTypeProc --
+ *
+ *	Translate the given string to the gradient shape is represents.  Value
+ *	shapes are "linear", "bilinear", "radial", and "rectangular".
+ *
+ * Results:
+ *	The return value is a standard TCL result.  
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToTypeProc(
+	      ClientData clientData,		/* Not used. */
+	      Tcl_Interp *interp,			/* Interpreter to send results back
+							 * to */
+	      Tk_Window tkwin,			/* Not used. */
+	      Tcl_Obj *objPtr,			/* String representation of value. */
+	      char *widgRec,			/* Widget record. */
+	      int offset,				/* Offset to field in structure */
+	      int flags)	
+{
+  int *typePtr = (int *)(widgRec + offset);
+  char *string;
+
+  string = Tcl_GetString(objPtr);
+  if (strcmp(string, "striped") == 0) {
+    *typePtr = TEXTURE_STRIPED;
+  } else if (strcmp(string, "checkered") == 0) {
+    *typePtr = TEXTURE_CHECKERED;
+  } else {
+    Tcl_AppendResult(interp, "unknown pattern type \"", string, "\"",
+		     (char *)NULL);
+    return TCL_ERROR;
+  }
+  return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TypeToObjProc --
+ *
+ *	Returns the string representing the current pattern type.
+ *
+ * Results:
+ *	The string representation of the pattern is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+TypeToObjProc(
+	      ClientData clientData,		/* Not used. */
+	      Tcl_Interp *interp,
+	      Tk_Window tkwin,			/* Not used. */
+	      char *widgRec,			/* Widget record */
+	      int offset,				/* Offset to field in structure */
+	      int flags)	
+{
+  int type = *(int *)(widgRec + offset);
+  const char *string;
+    
+  switch (type) {
+  case TEXTURE_STRIPED:
+    string = "striped";
+    break;
+
+  case TEXTURE_CHECKERED:
+    string = "checkered";
+    break;
+
+  default:
+    string = "???";
+  }
+  return Tcl_NewStringObj(string, -1);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NotifyClients --
+ *
+ *	Notify each client that the background pattern has changed.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+NotifyClients(Pattern *patternPtr)
+{
+  Blt_ChainLink link;
+
+  for (link = Blt_Chain_FirstLink(patternPtr->chain); link != NULL;
+       link = Blt_Chain_NextLink(link)) {
+    Background *bgPtr;
+
+    /* Notify each client that the background pattern has changed. The
+     * client should schedule itself for redrawing.  */
+    bgPtr = Blt_Chain_GetValue(link);
+    if (bgPtr->notifyProc != NULL) {
+      (*bgPtr->notifyProc)(bgPtr->clientData);
+    }
+  }
+}
+
+/* 
+ * The following routines are directly from tk3d.c.  
+ *
+ *       tk3d.c --
+ *
+ *	This module provides procedures to draw borders in
+ *	the three-dimensional Motif style.
+ *
+ *      Copyright (c) 1990-1994 The Regents of the University of California.
+ *      Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ *
+ *      See the file "license.terms" for information on usage and redistribution
+ *      of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ *  They fix a problem in the Intersect procedure when the polygon is big (e.q
+ *  1600x1200).  The computation overflows the 32-bit integers used.
+ */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ShiftLine --
+ *
+ *	Given two points on a line, compute a point on a new line that is
+ *	parallel to the given line and a given distance away from it.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+ShiftLine(
+	  XPoint *p,				/* First point on line. */
+	  XPoint *q,				/* Second point on line. */
+	  int distance,			/* New line is to be this many units
+					 * to the left of original line, when
+					 * looking from p1 to p2.  May be
+					 * negative. */
+	  XPoint *r)				/* Store coords of point on new line
+						 * here. */
+{
+  int dx, dy, dxNeg, dyNeg;
+
+  /*
+   * The table below is used for a quick approximation in computing the new
+   * point.  An index into the table is 128 times the slope of the original
+   * line (the slope must always be between 0 and 1).  The value of the
+   * table entry is 128 times the amount to displace the new line in y for
+   * each unit of perpendicular distance.  In other words, the table maps
+   * from the tangent of an angle to the inverse of its cosine.  If the
+   * slope of the original line is greater than 1, then the displacement is
+   * done in x rather than in y.
+   */
+  static int shiftTable[129];
+
+  /*
+   * Initialize the table if this is the first time it is
+   * used.
+   */
+
+  if (shiftTable[0] == 0) {
+    int i;
+    double tangent, cosine;
+
+    for (i = 0; i <= 128; i++) {
+      tangent = i/128.0;
+      cosine = 128/cos(atan(tangent)) + .5;
+      shiftTable[i] = (int) cosine;
+    }
+  }
+
+  *r = *p;
+  dx = q->x - p->x;
+  dy = q->y - p->y;
+  if (dy < 0) {
+    dyNeg = 1;
+    dy = -dy;
+  } else {
+    dyNeg = 0;
+  }
+  if (dx < 0) {
+    dxNeg = 1;
+    dx = -dx;
+  } else {
+    dxNeg = 0;
+  }
+  if (dy <= dx) {
+    dy = ((distance * shiftTable[(dy<<7)/dx]) + 64) >> 7;
+    if (!dxNeg) {
+      dy = -dy;
+    }
+    r->y += dy;
+  } else {
+    dx = ((distance * shiftTable[(dx<<7)/dy]) + 64) >> 7;
+    if (dyNeg) {
+      dx = -dx;
+    }
+    r->x += dx;
+  }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * Intersect --
+ *
+ *	Find the intersection point between two lines.
+ *
+ * Results:
+ *	Under normal conditions 0 is returned and the point at *iPtr is filled
+ *	in with the intersection between the two lines.  If the two lines are
+ *	parallel, then -1 is returned and *iPtr isn't modified.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------------
+ */
+static int
+Intersect(a1Ptr, a2Ptr, b1Ptr, b2Ptr, iPtr)
+     XPoint *a1Ptr;		/* First point of first line. */
+     XPoint *a2Ptr;		/* Second point of first line. */
+     XPoint *b1Ptr;		/* First point of second line. */
+     XPoint *b2Ptr;		/* Second point of second line. */
+     XPoint *iPtr;		/* Filled in with intersection point. */
+{
+  float dxadyb, dxbdya, dxadxb, dyadyb, p, q;
+
+  /*
+   * The code below is just a straightforward manipulation of two
+   * equations of the form y = (x-x1)*(y2-y1)/(x2-x1) + y1 to solve
+   * for the x-coordinate of intersection, then the y-coordinate.
+   */
+
+  dxadyb = (a2Ptr->x - a1Ptr->x)*(b2Ptr->y - b1Ptr->y);
+  dxbdya = (b2Ptr->x - b1Ptr->x)*(a2Ptr->y - a1Ptr->y);
+  dxadxb = (a2Ptr->x - a1Ptr->x)*(b2Ptr->x - b1Ptr->x);
+  dyadyb = (a2Ptr->y - a1Ptr->y)*(b2Ptr->y - b1Ptr->y);
+
+  if (dxadyb == dxbdya) {
+    return -1;
+  }
+  p = (a1Ptr->x*dxbdya - b1Ptr->x*dxadyb + (b1Ptr->y - a1Ptr->y)*dxadxb);
+  q = dxbdya - dxadyb;
+  if (q < 0) {
+    p = -p;
+    q = -q;
+  }
+  if (p < 0) {
+    iPtr->x = - ((-p + q/2)/q);
+  } else {
+    iPtr->x = (p + q/2)/q;
+  }
+  p = (a1Ptr->y*dxadyb - b1Ptr->y*dxbdya + (b1Ptr->x - a1Ptr->x)*dyadyb);
+  q = dxadyb - dxbdya;
+  if (q < 0) {
+    p = -p;
+    q = -q;
+  }
+  if (p < 0) {
+    iPtr->y = (int)(- ((-p + q/2)/q));
+  } else {
+    iPtr->y = (int)((p + q/2)/q);
+  }
+  return 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Draw3DPolygon --
+ *
+ *	Draw a border with 3-D appearance around the edge of a given polygon.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Information is drawn in "drawable" in the form of a 3-D border
+ *	borderWidth units width wide on the left of the trajectory given by
+ *	pointPtr and n (or -borderWidth units wide on the right side,
+ *	if borderWidth is negative).
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+Draw3DPolygon(
+	      Tk_Window tkwin,			/* Window for which border was
+						   allocated. */
+	      Drawable drawable,			/* X window or pixmap in which to
+							 * draw. */
+	      Tk_3DBorder border,			/* Token for border to draw. */
+	      XPoint *points,			/* Array of points describing polygon.
+						 * All points must be absolute
+						 * (CoordModeOrigin). */
+	      int n,				/* Number of points at *points. */
+	      int borderWidth,			/* Width of border, measured in
+						 * pixels to the left of the polygon's
+						 * trajectory.   May be negative. */
+	      int leftRelief)			/* TK_RELIEF_RAISED or
+						 * TK_RELIEF_SUNKEN: indicates how 
+						 * stuff to left of trajectory looks 
+						 * relative to stuff on right. */
+{
+  XPoint poly[4], b1, b2, newB1, newB2;
+  XPoint perp, c, shift1, shift2;	/* Used for handling parallel lines. */
+  XPoint *p, *q;
+  GC gc;
+  int i, lightOnLeft, dx, dy, parallel, pointsSeen;
+
+  /* Handle grooves and ridges with recursive calls. */
+  if ((leftRelief == TK_RELIEF_GROOVE) || (leftRelief == TK_RELIEF_RIDGE)) {
+    int halfWidth, relief;
+
+    halfWidth = borderWidth / 2;
+    relief = (leftRelief == TK_RELIEF_GROOVE) 
+      ? TK_RELIEF_RAISED : TK_RELIEF_SUNKEN;
+    Draw3DPolygon(tkwin, drawable, border, points, n, halfWidth, relief);
+    Draw3DPolygon(tkwin, drawable, border, points, n, -halfWidth, relief);
+    return;
+  }
+  /*
+   * If the polygon is already closed, drop the last point from it
+   * (we'll close it automatically).
+   */
+  p = points + (n-1);
+  q = points;
+  if ((p->x == q->x) && (p->y == q->y)) {
+    n--;
+  }
+
+  /*
+   * The loop below is executed once for each vertex in the polgon.
+   * At the beginning of each iteration things look like this:
+   *
+   *          poly[1]       /
+   *             *        /
+   *             |      /
+   *             b1   * poly[0] (points[i-1])
+   *             |    |
+   *             |    |
+   *             |    |
+   *             |    |
+   *             |    |
+   *             |    | *p            *q
+   *             b2   *--------------------*
+   *             |
+   *             |
+   *             x-------------------------
+   *
+   * The job of this iteration is to do the following:
+   * (a) Compute x (the border corner corresponding to
+   *     points[i]) and put it in poly[2].  As part of
+   *	   this, compute a new b1 and b2 value for the next
+   *	   side of the polygon.
+   * (b) Put points[i] into poly[3].
+   * (c) Draw the polygon given by poly[0..3].
+   * (d) Advance poly[0], poly[1], b1, and b2 for the
+   *     next side of the polygon.
+   */
+
+  /*
+   * The above situation doesn't first come into existence until two points
+   * have been processed; the first two points are used to "prime the pump",
+   * so some parts of the processing are ommitted for these points.  The
+   * variable "pointsSeen" keeps track of the priming process; it has to be
+   * separate from i in order to be able to ignore duplicate points in the
+   * polygon.
+   */
+  pointsSeen = 0;
+  for (i = -2, p = points + (n-2), q = p+1; i < n; i++, p = q, q++) {
+    if ((i == -1) || (i == n-1)) {
+      q = points;
+    }
+    if ((q->x == p->x) && (q->y == p->y)) {
+      /*
+       * Ignore duplicate points (they'd cause core dumps in
+       * ShiftLine calls below).
+       */
+      continue;
+    }
+    ShiftLine(p, q, borderWidth, &newB1);
+    newB2.x = newB1.x + (q->x - p->x);
+    newB2.y = newB1.y + (q->y - p->y);
+    poly[3] = *p;
+    parallel = 0;
+    if (pointsSeen >= 1) {
+      parallel = Intersect(&newB1, &newB2, &b1, &b2, &poly[2]);
+
+      /*
+       * If two consecutive segments of the polygon are parallel,
+       * then things get more complex.  Consider the following
+       * diagram:
+       *
+       * poly[1]
+       *    *----b1-----------b2------a
+       *                                \
+       *                                  \
+       *         *---------*----------*    b
+       *        poly[0]  *q   *p  /
+       *                                /
+       *              --*--------*----c
+       *              newB1    newB2
+       *
+       * Instead of using x and *p for poly[2] and poly[3], as
+       * in the original diagram, use a and b as above.  Then instead
+       * of using x and *p for the new poly[0] and poly[1], use
+       * b and c as above.
+       *
+       * Do the computation in three stages:
+       * 1. Compute a point "perp" such that the line p-perp
+       *    is perpendicular to p-q.
+       * 2. Compute the points a and c by intersecting the lines
+       *    b1-b2 and newB1-newB2 with p-perp.
+       * 3. Compute b by shifting p-perp to the right and
+       *    intersecting it with p-q.
+       */
+
+      if (parallel) {
+	perp.x = p->x + (q->y - p->y);
+	perp.y = p->y - (q->x - p->x);
+	Intersect(p, &perp, &b1, &b2, &poly[2]);
+	Intersect(p, &perp, &newB1, &newB2, &c);
+	ShiftLine(p, &perp, borderWidth, &shift1);
+	shift2.x = shift1.x + (perp.x - p->x);
+	shift2.y = shift1.y + (perp.y - p->y);
+	Intersect(p, q, &shift1, &shift2, &poly[3]);
+      }
+    }
+    if (pointsSeen >= 2) {
+      dx = poly[3].x - poly[0].x;
+      dy = poly[3].y - poly[0].y;
+      if (dx > 0) {
+	lightOnLeft = (dy <= dx);
+      } else {
+	lightOnLeft = (dy < dx);
+      }
+      if (lightOnLeft ^ (leftRelief == TK_RELIEF_RAISED)) {
+	gc = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
+      } else {
+	gc = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
+      }   
+      XFillPolygon(Tk_Display(tkwin), drawable, gc, poly, 4, Convex,
+		   CoordModeOrigin);
+    }
+    b1.x = newB1.x;
+    b1.y = newB1.y;
+    b2.x = newB2.x;
+    b2.y = newB2.y;
+    poly[0].x = poly[3].x;
+    poly[0].y = poly[3].y;
+    if (parallel) {
+      poly[1].x = c.x;
+      poly[1].y = c.y;
+    } else if (pointsSeen >= 1) {
+      poly[1].x = poly[2].x;
+      poly[1].y = poly[2].y;
+    }
+    pointsSeen++;
+  }
+}
+
+static int
+ConfigureSolidPattern(Tcl_Interp *interp, Pattern *corePtr, int objc, 
+		      Tcl_Obj *const *objv, unsigned int flags)
+{
+  SolidPattern *patternPtr = (SolidPattern *)corePtr;
+
+  if (Blt_ConfigureWidgetFromObj(interp, patternPtr->tkwin, 
+				 patternPtr->classPtr->configSpecs, objc, objv, (char *)patternPtr, 
+				 flags) != TCL_OK) {
+    return TCL_ERROR;
+  }
+  return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawSolidRectangle --
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawSolidRectangle(Tk_Window tkwin, Drawable drawable, Pattern *corePtr,
+		   int x, int y, int w, int h)
+{
+  SolidPattern *patternPtr = (SolidPattern *)corePtr;
+
+  if ((h <= 0) || (w <= 0)) {
+    return;
+  }
+  if (patternPtr->alpha == 0xFF) {
+    Tk_Fill3DRectangle(tkwin, drawable, patternPtr->border, x, y, w, h,
+		       0, TK_RELIEF_FLAT);
+  } else if (patternPtr->alpha != 0x00) {
+  }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawSolidRectangle --
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawSolidPolygon(Tk_Window tkwin, Drawable drawable, Pattern *corePtr, int n, 
+		 XPoint *points)
+{
+  SolidPattern *patternPtr = (SolidPattern *)corePtr;
+
+  if (n < 3) {
+    return;				/* Not enough points for polygon */
+  }
+  if (patternPtr->alpha == 0xFF) {
+    XFillPolygon(Tk_Display(tkwin), drawable, 
+		 Tk_3DBorderGC(tkwin, patternPtr->border, TK_3D_FLAT_GC),
+		 points, n, Complex, CoordModeOrigin);
+  } else if (patternPtr->alpha != 0x00) {
+  }
+}
+
+static PatternClass solidPatternClass = {
+  PATTERN_SOLID,
+  solidConfigSpecs,
+  NULL,				/* DestroySolidPattern */
+  ConfigureSolidPattern,
+  DrawSolidRectangle,
+  DrawSolidPolygon
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateSolidPattern --
+ *
+ *	Creates a new solid background pattern.
+ *
+ * Results:
+ *	Returns pointer to the new background pattern.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Pattern *
+CreateSolidPattern(void)
+{
+  SolidPattern *patternPtr;
+
+  patternPtr = calloc(1, sizeof(SolidPattern));
+  if (patternPtr == NULL) {
+    return NULL;
+  }
+  patternPtr->classPtr = &solidPatternClass;
+  patternPtr->alpha = 0xFF;
+  return (Pattern *)patternPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawTileRectangle --
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawTileRectangle(Tk_Window tkwin, Drawable drawable, Pattern *corePtr,
+		  int x, int y, int w, int h)
+{
+  TilePattern *patternPtr = (TilePattern *)corePtr;
+  //Tk_Window refWindow;
+
+  if ((h <= 0) || (w <= 0)) {
+    return;
+  }
+  if (patternPtr->tkImage == NULL) {
+    /* No image so draw solid color background using border. */
+    Tk_Fill3DRectangle(tkwin, drawable, patternPtr->border, x, y, w, h,
+		       0, TK_RELIEF_FLAT);
+    return;
+  }
+}
+
+static int
+ConfigureTilePattern(Tcl_Interp *interp, Pattern *corePtr, int objc, 
+		     Tcl_Obj *const *objv, unsigned int flags)
+{
+  TilePattern *patternPtr = (TilePattern *)corePtr;
+
+  if (Blt_ConfigureWidgetFromObj(interp, patternPtr->tkwin, 
+				 patternPtr->classPtr->configSpecs, objc, objv, (char *)patternPtr, 
+				 flags) != TCL_OK) {
+    return TCL_ERROR;
+  }
+  return TCL_OK;
+}
+
+static PatternClass tilePatternClass = {
+  PATTERN_TILE,
+  tileConfigSpecs,
+  NULL,				/* DestroyTilePattern, */
+  ConfigureTilePattern,
+  DrawTileRectangle,
+  DrawSolidPolygon
+
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateTilePattern --
+ *
+ *	Creates a new image background pattern.
+ *
+ * Results:
+ *	Returns pointer to the new background pattern.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Pattern *
+CreateTilePattern(void)
+{
+  TilePattern *patternPtr;
+
+  patternPtr = calloc(1, sizeof(TilePattern));
+  if (patternPtr == NULL) {
+    return NULL;
+  }
+  patternPtr->classPtr = &tilePatternClass;
+  patternPtr->reference = REFERENCE_TOPLEVEL;
+  return (Pattern *)patternPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawGradientRectangle --
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawGradientRectangle(Tk_Window tkwin, Drawable drawable, Pattern *corePtr, 
+		      int x, int y, int w, int h)
+{
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawGradientPolygon --
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawGradientPolygon(Tk_Window tkwin, Drawable drawable, Pattern *corePtr, 
+		    int n, XPoint *points)
+{
+  GradientPattern *patternPtr = (GradientPattern *)corePtr;
+  Tk_Window refWindow;
+
+  if (patternPtr->reference == REFERENCE_SELF) {
+    refWindow = tkwin;
+  } else if (patternPtr->reference == REFERENCE_TOPLEVEL) {
+    refWindow = Blt_Toplevel(tkwin);
+  } else if (patternPtr->reference == REFERENCE_WINDOW) {
+    refWindow = patternPtr->refWindow;
+  } else if (patternPtr->reference == REFERENCE_NONE) {
+    refWindow = NULL;
+  } else {
+    return;				/* Unknown reference window. */
+  }
+  if (n < 3) {
+    return;				/* Not enough points for polygon */
+  }
+  if (patternPtr->alpha == 0xFF) {
+    XFillPolygon(Tk_Display(tkwin), drawable, 
+		 Tk_3DBorderGC(tkwin, patternPtr->border, TK_3D_FLAT_GC),
+		 points, n, Complex, CoordModeOrigin);
+  } else if (patternPtr->alpha != 0x00) {
+  }
+}
+
+static int
+ConfigureGradientPattern(Tcl_Interp *interp, Pattern *corePtr, int objc, 
+			 Tcl_Obj *const *objv, unsigned int flags)
+{
+  GradientPattern *patternPtr = (GradientPattern *)corePtr;
+
+  if (Blt_ConfigureWidgetFromObj(interp, patternPtr->tkwin, 
+				 patternPtr->classPtr->configSpecs, 
+				 objc, objv, (char *)patternPtr, 
+				 flags) != TCL_OK) {
+    return TCL_ERROR;
+  }
+  if (patternPtr->alpha != 0xFF) {
+  }
+  return TCL_OK;
+}
+
+
+static PatternClass gradientPatternClass = {
+  PATTERN_GRADIENT,
+  gradientConfigSpecs,
+  NULL, /* DestroyGradientPattern, */
+  ConfigureGradientPattern, 
+  DrawGradientRectangle,
+  DrawGradientPolygon,
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateGradientPattern --
+ *
+ *	Creates a new solid background pattern.
+ *
+ * Results:
+ *	Returns pointer to the new background pattern.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Pattern *
+CreateGradientPattern(void)
+{
+  GradientPattern *patternPtr;
+
+  patternPtr = calloc(1, sizeof(GradientPattern));
+  if (patternPtr == NULL) {
+    return NULL;
+  }
+  patternPtr->classPtr = &gradientPatternClass;
+  patternPtr->reference = REFERENCE_TOPLEVEL;
+  //  patternPtr->gradient.shape = BLT_GRADIENT_SHAPE_LINEAR;
+  //  patternPtr->gradient.path = BLT_GRADIENT_PATH_Y;
+  //  patternPtr->gradient.jitter = FALSE;
+  //patternPtr->gradient.logScale = TRUE;
+  patternPtr->alpha = 255;
+  return (Pattern *)patternPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawTextureRectangle --
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawTextureRectangle(Tk_Window tkwin, Drawable drawable, Pattern *corePtr, 
+		     int x, int y, int w, int h)
+{
+}
+
+static int
+ConfigureTexturePattern(Tcl_Interp *interp, Pattern *corePtr, int objc, 
+			Tcl_Obj *const *objv, unsigned int flags)
+{
+  TexturePattern *patternPtr = (TexturePattern *)corePtr;
+
+  if (Blt_ConfigureWidgetFromObj(interp, patternPtr->tkwin, 
+				 patternPtr->classPtr->configSpecs, objc, objv, (char *)patternPtr, 
+				 flags) != TCL_OK) {
+    return TCL_ERROR;
+  }
+  return TCL_OK;
+}
+
+static PatternClass texturePatternClass = {
+  PATTERN_TEXTURE,
+  textureConfigSpecs,
+  NULL,				/* DestroyTexturePattern, */
+  ConfigureTexturePattern,
+  DrawTextureRectangle,
+  DrawSolidPolygon
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateTexturePattern --
+ *
+ *	Creates a new texture background pattern.
+ *
+ * Results:
+ *	Returns pointer to the new background pattern.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Pattern *
+CreateTexturePattern()
+{
+  TexturePattern *patternPtr;
+
+  patternPtr = calloc(1, sizeof(TexturePattern));
+  if (patternPtr == NULL) {
+    return NULL;
+  }
+  patternPtr->classPtr = &texturePatternClass;
+  patternPtr->reference = REFERENCE_TOPLEVEL;
+  return (Pattern *)patternPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreatePattern --
+ *
+ *	Creates a new background pattern.
+ *
+ * Results:
+ *	Returns pointer to the new background pattern.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Pattern *
+CreatePattern(BackgroundInterpData *dataPtr, Tcl_Interp *interp, int type)
+{
+  Pattern *patternPtr;
+
+  switch (type) {
+  case PATTERN_SOLID:
+    patternPtr = CreateSolidPattern();
+    break;
+  case PATTERN_TILE:
+    patternPtr = CreateTilePattern();
+    break;
+  case PATTERN_GRADIENT:
+    patternPtr = CreateGradientPattern();
+    break;
+  case PATTERN_TEXTURE:
+    patternPtr = CreateTexturePattern();
+    break;
+  default:
+    abort();
+    break;
+  }
+  if (patternPtr == NULL) {
+    Tcl_AppendResult(interp, "can't allocate background pattern", 
+		     (char *)NULL);
+    return NULL;
+  }
+  patternPtr->dataPtr = dataPtr;
+  Blt_InitHashTable(&patternPtr->pictTable, BLT_ONE_WORD_KEYS);
+  patternPtr->chain = Blt_Chain_Create();
+  patternPtr->tkwin = Tk_MainWindow(interp);
+  patternPtr->display = Tk_Display(patternPtr->tkwin);
+  return patternPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DestroyPattern --
+ *
+ *	Removes the client from the servers's list of clients and memory used
+ *	by the client token is released.  When the last client is deleted, the
+ *	server is also removed.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DestroyPattern(Pattern *patternPtr)
+{
+  Blt_FreeOptions(patternPtr->classPtr->configSpecs, (char *)patternPtr, 
+		  patternPtr->display, 0);
+  if (patternPtr->classPtr->destroyProc != NULL) {
+    (*patternPtr->classPtr->destroyProc)(patternPtr);
+  }
+  if (patternPtr->border != NULL) {
+    Tk_Free3DBorder(patternPtr->border);
+  }
+  if (patternPtr->hashPtr != NULL) {
+    Blt_DeleteHashEntry(&patternPtr->dataPtr->patternTable, 
+			patternPtr->hashPtr);
+  }
+  //    ClearCache(patternPtr);
+  Blt_Chain_Destroy(patternPtr->chain);
+  Blt_DeleteHashTable(&patternPtr->pictTable);
+  free(patternPtr);
+  patternPtr = NULL;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DestroyBackground --
+ *
+ *	Removes the client from the servers's list of clients and memory used
+ *	by the client token is released.  When the last client is deleted, the
+ *	server is also removed.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DestroyBackground(Background *bgPtr)
+{
+  Pattern *patternPtr = bgPtr->corePtr;
+
+  Blt_Chain_DeleteLink(patternPtr->chain, bgPtr->link);
+  if (Blt_Chain_GetLength(patternPtr->chain) <= 0) {
+    DestroyPattern(patternPtr);
+  }
+  free(bgPtr);
+  bgPtr = NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetBackgroundInterpData --
+ *
+ *---------------------------------------------------------------------------
+ */
+static BackgroundInterpData *
+GetBackgroundInterpData(Tcl_Interp *interp)
+{
+  BackgroundInterpData *dataPtr;
+  Tcl_InterpDeleteProc *proc;
+
+  dataPtr = (BackgroundInterpData *)
+    Tcl_GetAssocData(interp, BG_PATTERN_THREAD_KEY, &proc);
+  if (dataPtr == NULL) {
+    dataPtr = malloc(sizeof(BackgroundInterpData));
+    dataPtr->interp = interp;
+    dataPtr->nextId = 1;
+
+
+    /* FIXME: Create interp delete proc to teardown the hash table and
+     * data entry.  Must occur after all the widgets have been destroyed
+     * (clients of the background pattern). */
+
+    Tcl_SetAssocData(interp, BG_PATTERN_THREAD_KEY, 
+		     (Tcl_InterpDeleteProc *)NULL, dataPtr);
+    Blt_InitHashTable(&dataPtr->patternTable, BLT_STRING_KEYS);
+  }
+  return dataPtr;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetBackground
+ *
+ *	Creates a new background from the given pattern description.  The
+ *	background structure returned is a token for the client to use the
+ *	background.  If the pattern isn't a solid pattern (i.e. a solid color
+ *	that Tk_Get3DBorder will accept) then the pattern must already exist.
+ *	Solid patterns are the exception to this rule.  This lets "-background
+ *	#ffffff" work without already having allocated a background pattern
+ *	"#ffffff".
+ *
+ * Results:
+ *	Returns a background pattern token.
+ *
+ * Side Effects:
+ *	Memory is allocated for the new token.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_Background
+Blt_GetBackground(Tcl_Interp *interp, Tk_Window tkwin, const char *name)
+{
+  Pattern *patternPtr;
+  BackgroundInterpData *dataPtr;
+  Background *bgPtr;		/* Pattern container. */
+  Blt_HashEntry *hPtr;
+  int isNew;
+    
+  /* Create new token for the background. */
+  bgPtr = calloc(1, sizeof(Background));
+  if (bgPtr == NULL) {
+    Tcl_AppendResult(interp, "can't allocate background \"", name, "\".", 
+		     (char *)NULL);
+    return NULL;
+  }
+  dataPtr = GetBackgroundInterpData(interp);
+  hPtr = Blt_CreateHashEntry(&dataPtr->patternTable, name, &isNew);
+  if (isNew) {
+    Tk_3DBorder border;
+
+    /* Pattern doesn't already exist, see if it's a color name
+     * (i.e. something that Tk_Get3DBorder will accept). */
+    border = Tk_Get3DBorder(interp, tkwin, name);
+    if (border == NULL) {
+      goto error;			/* Nope. It's an error. */
+    } 
+    patternPtr = CreatePattern(dataPtr, interp, PATTERN_SOLID);
+    if (patternPtr == NULL) {
+      Tk_Free3DBorder(border);
+      goto error;			/* Can't allocate new pattern. */
+    }
+    patternPtr->border = border;
+    patternPtr->hashPtr = hPtr;
+    patternPtr->name = Blt_GetHashKey(&dataPtr->patternTable, hPtr);
+    patternPtr->link = NULL;
+    Blt_SetHashValue(hPtr, patternPtr);
+  } else {
+    patternPtr = Blt_GetHashValue(hPtr);
+    assert(patternPtr != NULL);
+  }
+  /* Add the new background to the pattern's list of clients. */
+  bgPtr->link = Blt_Chain_Append(patternPtr->chain, bgPtr);
+  bgPtr->corePtr = patternPtr;
+  return bgPtr;
+ error:
+  free(bgPtr);
+  Blt_DeleteHashEntry(&dataPtr->patternTable, hPtr);
+  return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetBackgroundFromObj
+ *
+ *	Retrieves a new token of a background pattern from the named background
+ *	pattern.
+ *
+ * Results:
+ *	Returns a background pattern token.
+ *
+ * Side Effects:
+ *	Memory is allocated for the new token.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_Background
+Blt_GetBackgroundFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+  return Blt_GetBackground(interp, tkwin, Tcl_GetString(objPtr));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_SetBackgroundChangedProc
+ *
+ *	Sets the routine to called when an image changes.  
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	The designated routine will be called the next time the image
+ *	associated with the tile changes.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+void
+Blt_SetBackgroundChangedProc(
+			     Background *bgPtr,			/* Background to register callback
+								 * with. */
+			     Blt_BackgroundChangedProc *notifyProc, /* Function to call when pattern
+								     * has changed. NULL indicates to
+								     * unset the callback.*/
+			     ClientData clientData)
+{
+  bgPtr->notifyProc = notifyProc;
+  bgPtr->clientData = clientData;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FreeBackground
+ *
+ *	Removes the background pattern token.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Memory is freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_FreeBackground(Background *bgPtr)
+{
+  Pattern *patternPtr = bgPtr->corePtr;
+
+  assert(patternPtr != NULL);
+  DestroyBackground(bgPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetBackgroundOrigin
+ *
+ *	Returns the coordinates of the origin of the background pattern
+ *	referenced by the token.
+ *
+ * Results:
+ *	Returns the coordinates of the origin.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_GetBackgroundOrigin(Background *bgPtr, int *xPtr, int *yPtr)
+{
+  *xPtr = bgPtr->corePtr->xOrigin;
+  *yPtr = bgPtr->corePtr->yOrigin;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_SetBackgroundOrigin
+ *
+ *	Sets the origin of the background pattern referenced by the token.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_SetBackgroundOrigin(Tk_Window tkwin, Background *bgPtr, int x, int y)
+{
+  Pattern *patternPtr = bgPtr->corePtr;
+  patternPtr->xOrigin = x;
+  patternPtr->yOrigin = y;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_NameOfBackground
+ *
+ *	Returns the name of the core background pattern referenced by the
+ *	token.
+ *
+ * Results:
+ *	Return the name of the background pattern.
+ *
+ *---------------------------------------------------------------------------
+ */
+const char *
+Blt_NameOfBackground(Background *bgPtr)
+{
+  if (bgPtr->corePtr->name == NULL) {
+    return "";
+  }
+  return bgPtr->corePtr->name;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_BackgroundBorderColor
+ *
+ *	Returns the border color of the background pattern referenced by the
+ *	token.
+ *
+ * Results:
+ *	Returns the XColor representing the border color of the pattern.
+ *
+ *---------------------------------------------------------------------------
+ */
+XColor *
+Blt_BackgroundBorderColor(Background *bgPtr)
+{
+  return Tk_3DBorderColor(bgPtr->corePtr->border);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_BackgroundBorder
+ *
+ *	Returns the border of the background pattern referenced by the token.
+ *
+ * Results:
+ *	Return the border of the background pattern.
+ *
+ *---------------------------------------------------------------------------
+ */
+Tk_3DBorder
+Blt_BackgroundBorder(Background *bgPtr)
+{
+  return bgPtr->corePtr->border;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DrawBackgroundRectangle
+ *
+ *	Draws the background pattern in the designated window.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DrawBackgroundRectangle(Tk_Window tkwin, Drawable drawable, 
+			    Background *bgPtr, int x, int y, int w, int h, 
+			    int borderWidth, int relief)
+{
+  Tk_Draw3DRectangle(tkwin, drawable, bgPtr->corePtr->border, x, y, w, h, 
+		     borderWidth, relief);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FillBackgroundRectangle
+ *
+ *	Draws the background pattern in the designated window.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_FillBackgroundRectangle(Tk_Window tkwin, Drawable drawable, 
+			    Background *bgPtr, int x, int y, int w, int h, 
+			    int borderWidth, int relief)
+{
+  Pattern *patternPtr;
+
+  if ((h < 1) || (w < 1)) {
+    return;
+  }
+  patternPtr = bgPtr->corePtr;
+  (*patternPtr->classPtr->drawRectangleProc)(tkwin, drawable, patternPtr, 
+					     x, y, w, h);
+  if ((relief != TK_RELIEF_FLAT) && (borderWidth > 0)) {
+    Tk_Draw3DRectangle(tkwin, drawable, patternPtr->border, x, y, w, h,
+		       borderWidth, relief);
+  }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FillBackgroundPolygon
+ *
+ *	Draws the background pattern in the designated window.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_FillBackgroundPolygon(Tk_Window tkwin, Drawable drawable, Background *bgPtr,
+			  XPoint *points, int n, int borderWidth, int relief)
+{
+  Pattern *patternPtr;
+
+  if (n < 3) {
+    return;
+  }
+  patternPtr = bgPtr->corePtr;
+  (*patternPtr->classPtr->drawPolygonProc)(tkwin, drawable, patternPtr, 
+					   n, points);
+  if ((relief != TK_RELIEF_FLAT) && (borderWidth != 0)) {
+    Draw3DPolygon(tkwin, drawable, patternPtr->border, points, n,
+		  borderWidth, relief);
+  }
+}
+
+void
+Blt_SetBackgroundClipRegion(Tk_Window tkwin, Background *bgPtr, TkRegion rgn)
+{
+  Display *display;
+  GC gc;
+
+  display = Tk_Display(tkwin);
+  gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_LIGHT_GC);
+  TkSetRegion(display, gc, rgn);
+  gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_DARK_GC);
+  TkSetRegion(display, gc, rgn);
+  gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_FLAT_GC);
+  TkSetRegion(display, gc, rgn);
+}
+
+
+void
+Blt_UnsetBackgroundClipRegion(Tk_Window tkwin, Background *bgPtr)
+{
+  Display *display;
+  GC gc;
+
+  display = Tk_Display(tkwin);
+  gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_LIGHT_GC);
+  XSetClipMask(display, gc, None);
+  gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_DARK_GC);
+  XSetClipMask(display, gc, None);
+  gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_FLAT_GC);
+  XSetClipMask(display, gc, None);
+}
diff --git a/tlt3.0/bltBgStyle.h b/tlt3.0/bltBgStyle.h
new file mode 100644
index 0000000..5ddbbab
--- /dev/null
+++ b/tlt3.0/bltBgStyle.h
@@ -0,0 +1,74 @@
+
+/*
+ * bltBgPattern.h --
+ *
+ *	Copyright 1995-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_BGPATTERN_H
+#define _BLT_BGPATTERN_H
+
+typedef struct _Blt_Background *Blt_Background;
+
+typedef void Blt_BackgroundChangedProc(ClientData clientData);
+
+extern Blt_Background Blt_GetBackground(Tcl_Interp *interp, Tk_Window tkwin,
+	const char *styleName);
+
+extern Blt_Background Blt_GetBackgroundFromObj(Tcl_Interp *interp, 
+	Tk_Window tkwin, Tcl_Obj *objPtr);
+
+extern XColor *Blt_BackgroundBorderColor(Blt_Background bg);
+
+extern Tk_3DBorder Blt_BackgroundBorder(Blt_Background bg);
+
+extern const char *Blt_NameOfBackground(Blt_Background bg);
+
+extern void Blt_FreeBackground(Blt_Background bg);
+
+extern void Blt_DrawBackgroundRectangle(Tk_Window tkwin, Drawable drawable,
+	Blt_Background bg, int x, int y, int width, int height, int borderWidth,
+	int relief);
+
+extern void Blt_FillBackgroundRectangle(Tk_Window tkwin, Drawable drawable,
+	Blt_Background bg, int x, int y, int width, int height, 
+	int borderWidth, int relief);
+
+extern void Blt_FillBackgroundPolygon(Tk_Window tkwin, Drawable drawable, 
+	Blt_Background bg, XPoint *points, int nPoints, int borderWidth, 
+	int leftRelief);
+
+extern void Blt_GetBackgroundOrigin(Blt_Background bg, int *xPtr,int *yPtr);
+
+extern void Blt_SetBackgroundChangedProc(Blt_Background bg, 
+	Blt_BackgroundChangedProc *notifyProc, ClientData clientData);
+
+extern void Blt_SetBackgroundOrigin(Tk_Window tkwin, Blt_Background bg, 
+	int x, int y);
+
+extern void Blt_UnsetBackgroundClipRegion(Tk_Window tkwin, 
+	Blt_Background bg);
+
+extern void Blt_SetBackgroundClipRegion(Tk_Window tkwin, Blt_Background bg,
+	TkRegion rgn);
+
+#endif /* BLT_BGPATTERN_H */
diff --git a/tlt3.0/bltBind.c b/tlt3.0/bltBind.c
new file mode 100644
index 0000000..e9bd3f8
--- /dev/null
+++ b/tlt3.0/bltBind.c
@@ -0,0 +1,776 @@
+
+/*
+ * bltBind.c --
+ *
+ *	This module implements object binding procedures for the BLT toolkit.
+ *
+ *	Copyright 1998 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "bltInt.h"
+#include "bltBind.h"
+
+static Tk_EventProc BindProc;
+
+typedef struct _Blt_BindTable BindTable;
+
+/*
+ * Binding table procedures.
+ */
+#define REPICK_IN_PROGRESS (1<<0)
+#define LEFT_GRABBED_ITEM  (1<<1)
+
+#define ALL_BUTTONS_MASK \
+	(Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask)
+
+#ifndef VirtualEventMask
+#define VirtualEventMask    (1L << 30)
+#endif
+
+#define ALL_VALID_EVENTS_MASK \
+	(ButtonMotionMask | Button1MotionMask | Button2MotionMask | \
+	 Button3MotionMask | Button4MotionMask | Button5MotionMask | \
+	 ButtonPressMask | ButtonReleaseMask | EnterWindowMask | \
+	 LeaveWindowMask | KeyPressMask | KeyReleaseMask | \
+	 PointerMotionMask | VirtualEventMask)
+
+static int buttonMasks[] =
+{
+    0,				/* No buttons pressed */
+    Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask,
+};
+
+
+/*
+ * How to make drag&drop work?
+ *
+ *	Right now we generate pseudo <Enter> <Leave> events within button grab
+ *	on an object.  They're marked NotifyVirtual instead of NotifyAncestor.
+ *	A better solution: generate new-style virtual <<DragEnter>>
+ *	<<DragMotion>> <<DragLeave>> events.  These virtual events don't have
+ *	to exist as "real" event sequences, like virtual events do now.
+ */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DoEvent --
+ *
+ *	This procedure is called to invoke binding processing for a new event
+ *	that is associated with the current item for a legend.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Depends on the bindings for the legend.  A binding script could delete
+ *	an entry, so callers should protect themselves with Tcl_Preserve and
+ *	Tcl_Release.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DoEvent(
+    BindTable *bindPtr,		/* Binding information for widget in which
+				 * event occurred. */
+    XEvent *eventPtr,		/* Real or simulated X event that is to be
+				 * processed. */
+    ClientData item,		/* Item picked. */
+    ClientData context)		/* Context of item.  */
+{
+    Blt_List tagList;
+
+    if ((bindPtr->tkwin == NULL) || (bindPtr->bindingTable == NULL)) {
+	return;
+    }
+    if ((eventPtr->type == KeyPress) || (eventPtr->type == KeyRelease)) {
+	item = bindPtr->focusItem;
+	context = bindPtr->focusContext;
+    }
+    if (item == NULL) {
+	return;
+    }
+    /*
+     * Invoke the binding system.
+     */
+    tagList = Blt_List_Create(BLT_ONE_WORD_KEYS);
+    if (bindPtr->tagProc == NULL) {
+	Blt_List_Append(tagList, Tk_GetUid("all"), 0);
+	Blt_List_Append(tagList, (char *)item, 0);
+    } else {
+	(*bindPtr->tagProc) (bindPtr, item, context, tagList);
+    }
+    if (Blt_List_GetLength(tagList) > 0) {
+	int nTags;
+	ClientData *tagArray;
+#define MAX_STATIC_TAGS	64
+	ClientData staticTags[MAX_STATIC_TAGS];
+	Blt_ListNode node;
+	
+	tagArray = staticTags;
+	nTags = Blt_List_GetLength(tagList);
+	if (nTags >= MAX_STATIC_TAGS) {
+	    tagArray = malloc(sizeof(ClientData) * nTags);
+	    
+	} 
+	nTags = 0;
+	for (node = Blt_List_FirstNode(tagList); node != NULL;
+	     node = Blt_List_NextNode(node)) {
+	    tagArray[nTags++] = (ClientData)Blt_List_GetKey(node);
+	}
+	Tk_BindEvent(bindPtr->bindingTable, eventPtr, bindPtr->tkwin, nTags, 
+		tagArray);
+	if (tagArray != staticTags) {
+	    free(tagArray);
+	}
+    }
+    Blt_List_Destroy(tagList);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PickCurrentItem --
+ *
+ *	Find the topmost item in a legend that contains a given location and
+ *	mark the the current item.  If the current item has changed, generate
+ *	a fake exit event on the old current item and a fake enter event on
+ *	the new current item.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The current item may change.  If it does, then the commands associated
+ *	with item entry and exit could do just about anything.  A binding
+ *	script could delete the legend, so callers should protect themselves
+ *	with Tcl_Preserve and Tcl_Release.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+PickCurrentItem(
+    BindTable *bindPtr,		/* Binding table information. */
+    XEvent *eventPtr)		/* Event describing location of mouse cursor.
+				 * Must be EnterWindow, LeaveWindow,
+				 * ButtonRelease, or MotionNotify. */
+{
+    int buttonDown;
+    ClientData newItem, oldItem;
+    ClientData newContext;
+
+    /*
+     * Check whether or not a button is down.  If so, we'll log entry and exit
+     * into and out of the current item, but not entry into any other item.
+     * This implements a form of grabbing equivalent to what the X server does
+     * for windows.
+     */
+    buttonDown = (bindPtr->state & ALL_BUTTONS_MASK);
+    if (!buttonDown) {
+	bindPtr->flags &= ~LEFT_GRABBED_ITEM;
+    }
+
+    /*
+     * Save information about this event in the widget.  The event in the
+     * widget is used for two purposes:
+     *
+     * 1. Event bindings: if the current item changes, fake events are
+     *    generated to allow item-enter and item-leave bindings to trigger.
+     * 2. Reselection: if the current item gets deleted, can use the
+     *    saved event to find a new current item.
+     * Translate MotionNotify events into EnterNotify events, since that's
+     * what gets reported to item handlers.
+     */
+
+    if (eventPtr != &bindPtr->pickEvent) {
+	if ((eventPtr->type == MotionNotify) ||
+	    (eventPtr->type == ButtonRelease)) {
+	    bindPtr->pickEvent.xcrossing.type = EnterNotify;
+	    bindPtr->pickEvent.xcrossing.serial = eventPtr->xmotion.serial;
+	    bindPtr->pickEvent.xcrossing.send_event =
+		eventPtr->xmotion.send_event;
+	    bindPtr->pickEvent.xcrossing.display = eventPtr->xmotion.display;
+	    bindPtr->pickEvent.xcrossing.window = eventPtr->xmotion.window;
+	    bindPtr->pickEvent.xcrossing.root = eventPtr->xmotion.root;
+	    bindPtr->pickEvent.xcrossing.subwindow = None;
+	    bindPtr->pickEvent.xcrossing.time = eventPtr->xmotion.time;
+	    bindPtr->pickEvent.xcrossing.x = eventPtr->xmotion.x;
+	    bindPtr->pickEvent.xcrossing.y = eventPtr->xmotion.y;
+	    bindPtr->pickEvent.xcrossing.x_root = eventPtr->xmotion.x_root;
+	    bindPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root;
+	    bindPtr->pickEvent.xcrossing.mode = NotifyNormal;
+	    bindPtr->pickEvent.xcrossing.detail = NotifyNonlinear;
+	    bindPtr->pickEvent.xcrossing.same_screen
+		= eventPtr->xmotion.same_screen;
+	    bindPtr->pickEvent.xcrossing.focus = False;
+	    bindPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state;
+	} else {
+	    bindPtr->pickEvent = *eventPtr;
+	}
+    }
+    bindPtr->activePick = TRUE;
+
+    /*
+     * If this is a recursive call (there's already a partially completed call
+     * pending on the stack; it's in the middle of processing a Leave event
+     * handler for the old current item) then just return; the pending call
+     * will do everything that's needed.
+     */
+    if (bindPtr->flags & REPICK_IN_PROGRESS) {
+	return;
+    }
+    /*
+     * A LeaveNotify event automatically means that there's no current item,
+     * so the check for closest item can be skipped.
+     */
+    newContext = NULL;
+    if (bindPtr->pickEvent.type != LeaveNotify) {
+	int x, y;
+
+	x = bindPtr->pickEvent.xcrossing.x;
+	y = bindPtr->pickEvent.xcrossing.y;
+	newItem = (*bindPtr->pickProc) (bindPtr->clientData, x, y, &newContext);
+    } else {
+	newItem = NULL;
+    }
+    if (((newItem == bindPtr->currentItem) && 
+	 (newContext == bindPtr->currentContext)) && 
+	((bindPtr->flags & LEFT_GRABBED_ITEM) == 0)) {
+	/*
+	 * Nothing to do:  the current item hasn't changed.
+	 */
+	return;
+    }
+    /*
+     * Simulate a LeaveNotify event on the previous current item and an
+     * EnterNotify event on the new current item.  Remove the "current" tag
+     * from the previous current item and place it on the new current item.
+     */
+    oldItem = bindPtr->currentItem;
+    Tcl_Preserve(oldItem);
+    Tcl_Preserve(newItem);
+
+    if ((bindPtr->currentItem != NULL) &&
+	((newItem != bindPtr->currentItem) || 
+	 (newContext != bindPtr->currentContext)) && 
+	((bindPtr->flags & LEFT_GRABBED_ITEM) == 0)) {
+	XEvent event;
+
+	event = bindPtr->pickEvent;
+	event.type = LeaveNotify;
+	/*
+	 * If the event's detail happens to be NotifyInferior the binding
+	 * mechanism will discard the event.  To be consistent, always use
+	 * NotifyAncestor.
+	 */
+	event.xcrossing.detail = NotifyAncestor;
+
+	bindPtr->flags |= REPICK_IN_PROGRESS;
+	DoEvent(bindPtr, &event, bindPtr->currentItem, bindPtr->currentContext);
+	bindPtr->flags &= ~REPICK_IN_PROGRESS;
+
+	/*
+	 * Note: during DoEvent above, it's possible that bindPtr->newItem got
+	 * reset to NULL because the item was deleted.
+	 */
+    }
+    if (((newItem != bindPtr->currentItem) || 
+	 (newContext != bindPtr->currentContext)) && 
+	(buttonDown)) {
+	XEvent event;
+
+	bindPtr->flags |= LEFT_GRABBED_ITEM;
+	event = bindPtr->pickEvent;
+	if ((newItem != bindPtr->newItem) || 
+	    (newContext != bindPtr->newContext)) {
+	    ClientData savedItem;
+	    ClientData savedContext;
+
+	    /*
+	     * Generate <Enter> and <Leave> events for objects during button
+	     * grabs.  This isn't standard. But for example, it allows one to
+	     * provide balloon help on the individual entries of the Hierbox
+	     * widget.
+	     */
+	    savedItem = bindPtr->currentItem;
+	    savedContext = bindPtr->currentContext;
+	    if (bindPtr->newItem != NULL) {
+		event.type = LeaveNotify;
+		event.xcrossing.detail = NotifyVirtual /* Ancestor */ ;
+		bindPtr->currentItem = bindPtr->newItem;
+		DoEvent(bindPtr, &event, bindPtr->newItem, bindPtr->newContext);
+	    }
+	    bindPtr->newItem = newItem;
+	    bindPtr->newContext = newContext;
+	    if (newItem != NULL) {
+		event.type = EnterNotify;
+		event.xcrossing.detail = NotifyVirtual /* Ancestor */ ;
+		bindPtr->currentItem = newItem;
+		DoEvent(bindPtr, &event, newItem, newContext);
+	    }
+	    bindPtr->currentItem = savedItem;
+	    bindPtr->currentContext = savedContext;
+	}
+	goto done;
+    }
+    /*
+     * Special note:  it's possible that
+     *		bindPtr->newItem == bindPtr->currentItem
+     * here.  This can happen, for example, if LEFT_GRABBED_ITEM was set.
+     */
+
+    bindPtr->flags &= ~LEFT_GRABBED_ITEM;
+    bindPtr->currentItem = bindPtr->newItem = newItem;
+    bindPtr->currentContext = bindPtr->newContext = newContext;
+    if (bindPtr->currentItem != NULL) {
+	XEvent event;
+
+	event = bindPtr->pickEvent;
+	event.type = EnterNotify;
+	event.xcrossing.detail = NotifyAncestor;
+	DoEvent(bindPtr, &event, newItem, newContext);
+    }
+ done:
+    Tcl_Release(newItem);
+    Tcl_Release(oldItem);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BindProc --
+ *
+ *	This procedure is invoked by the Tk dispatcher to handle events
+ *	associated with bindings on items.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Depends on the command invoked as part of the binding
+ *	(if there was any).
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+BindProc(
+    ClientData clientData,	/* Pointer to widget structure. */
+    XEvent *eventPtr)		/* Pointer to X event that just happened. */
+{
+    BindTable *bindPtr = clientData;
+    int mask;
+
+    Tcl_Preserve(bindPtr->clientData);
+    /*
+     * This code below keeps track of the current modifier state in
+     * bindPtr->state.  This information is used to defer repicks of the
+     * current item while buttons are down.
+     */
+    switch (eventPtr->type) {
+    case ButtonPress:
+    case ButtonRelease:
+	mask = 0;
+	if ((eventPtr->xbutton.button >= Button1) &&
+	    (eventPtr->xbutton.button <= Button5)) {
+	    mask = buttonMasks[eventPtr->xbutton.button];
+	}
+	/*
+	 * For button press events, repick the current item using the button
+	 * state before the event, then process the event.  For button release
+	 * events, first process the event, then repick the current item using
+	 * the button state *after* the event (the button has logically gone
+	 * up before we change the current item).
+	 */
+	if (eventPtr->type == ButtonPress) {
+
+	    /*
+	     * On a button press, first repick the current item using the
+	     * button state before the event, the process the event.
+	     */
+
+	    bindPtr->state = eventPtr->xbutton.state;
+	    PickCurrentItem(bindPtr, eventPtr);
+	    bindPtr->state ^= mask;
+	    DoEvent(bindPtr, eventPtr, bindPtr->currentItem, 
+		bindPtr->currentContext);
+
+	} else {
+
+	    /*
+	     * Button release: first process the event, with the button still
+	     * considered to be down.  Then repick the current item under the
+	     * assumption that the button is no longer down.
+	     */
+	    bindPtr->state = eventPtr->xbutton.state;
+	    DoEvent(bindPtr, eventPtr, bindPtr->currentItem, 
+		bindPtr->currentContext);
+	    eventPtr->xbutton.state ^= mask;
+	    bindPtr->state = eventPtr->xbutton.state;
+	    PickCurrentItem(bindPtr, eventPtr);
+	    eventPtr->xbutton.state ^= mask;
+	}
+	break;
+
+    case EnterNotify:
+    case LeaveNotify:
+	bindPtr->state = eventPtr->xcrossing.state;
+	PickCurrentItem(bindPtr, eventPtr);
+	break;
+
+    case MotionNotify:
+	bindPtr->state = eventPtr->xmotion.state;
+	PickCurrentItem(bindPtr, eventPtr);
+	DoEvent(bindPtr, eventPtr, bindPtr->currentItem, 
+		bindPtr->currentContext);
+	break;
+
+    case KeyPress:
+    case KeyRelease:
+	bindPtr->state = eventPtr->xkey.state;
+	PickCurrentItem(bindPtr, eventPtr);
+	DoEvent(bindPtr, eventPtr, bindPtr->currentItem, 
+		bindPtr->currentContext);
+	break;
+    }
+    Tcl_Release(bindPtr->clientData);
+}
+
+int
+Blt_ConfigureBindings(
+    Tcl_Interp *interp,
+    BindTable *bindPtr,
+    ClientData item,
+    int argc,
+    const char **argv)
+{
+    const char *command;
+    unsigned long mask;
+    const char *seq;
+
+    if (argc == 0) {
+	Tk_GetAllBindings(interp, bindPtr->bindingTable, item);
+	return TCL_OK;
+    }
+    if (argc == 1) {
+	command = Tk_GetBinding(interp, bindPtr->bindingTable, item, argv[0]);
+	if (command == NULL) {
+	    Tcl_AppendResult(interp, "can't find event \"", argv[0], "\"",
+			     (char *)NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_SetStringObj(Tcl_GetObjResult(interp), command, -1);
+	return TCL_OK;
+    }
+
+    seq = argv[0];
+    command = argv[1];
+
+    if (command[0] == '\0') {
+	return Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq);
+    }
+
+    if (command[0] == '+') {
+	mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq,
+		command + 1, TRUE);
+    } else {
+	mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq,
+		command, FALSE);
+    }
+    if (mask == 0) {
+	Tcl_AppendResult(interp, "event mask can't be zero for \"", item, "\"",
+			     (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (mask & (unsigned)~ALL_VALID_EVENTS_MASK) {
+	Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq);
+	Tcl_ResetResult(interp);
+	Tcl_AppendResult(interp, "requested illegal events; ",
+		 "only key, button, motion, enter, leave, and virtual ",
+		 "events may be used", (char *)NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+
+int
+Blt_ConfigureBindingsFromObj(
+    Tcl_Interp *interp,
+    BindTable *bindPtr,
+    ClientData item,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    const char *command;
+    unsigned long mask;
+    const char *seq;
+    const char *string;
+
+    if (objc == 0) {
+	Tk_GetAllBindings(interp, bindPtr->bindingTable, item);
+	return TCL_OK;
+    }
+    string = Tcl_GetString(objv[0]);
+    if (objc == 1) {
+	command = Tk_GetBinding(interp, bindPtr->bindingTable, item, string);
+	if (command == NULL) {
+	    Tcl_ResetResult(interp);
+	    Tcl_AppendResult(interp, "invalid binding event \"", string, "\"", 
+		(char *)NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_SetStringObj(Tcl_GetObjResult(interp), command, -1);
+	return TCL_OK;
+    }
+
+    seq = string;
+    command = Tcl_GetString(objv[1]);
+
+    if (command[0] == '\0') {
+	return Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq);
+    }
+
+    if (command[0] == '+') {
+	mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq,
+		command + 1, TRUE);
+    } else {
+	mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq,
+		command, FALSE);
+    }
+    if (mask == 0) {
+	return TCL_ERROR;
+    }
+    if (mask & (unsigned)~ALL_VALID_EVENTS_MASK) {
+	Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq);
+	Tcl_ResetResult(interp);
+	Tcl_AppendResult(interp, "requested illegal events; ",
+		 "only key, button, motion, enter, leave, and virtual ",
+		 "events may be used", (char *)NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+Blt_BindTable
+Blt_CreateBindingTable(
+    Tcl_Interp *interp,
+    Tk_Window tkwin,
+    ClientData clientData,
+    Blt_BindPickProc *pickProc,
+    Blt_BindTagProc *tagProc)
+{
+    unsigned int mask;
+    BindTable *bindPtr;
+
+    bindPtr = calloc(1, sizeof(BindTable));
+    bindPtr->bindingTable = Tk_CreateBindingTable(interp);
+    bindPtr->clientData = clientData;
+    bindPtr->tkwin = tkwin;
+    bindPtr->pickProc = pickProc;
+    bindPtr->tagProc = tagProc;
+    mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask |
+	ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
+	PointerMotionMask);
+    Tk_CreateEventHandler(tkwin, mask, BindProc, bindPtr);
+    return bindPtr;
+}
+
+void
+Blt_DestroyBindingTable(BindTable *bindPtr)
+{
+    unsigned int mask;
+
+    Tk_DeleteBindingTable(bindPtr->bindingTable);
+    mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask |
+	ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
+	PointerMotionMask);
+    Tk_DeleteEventHandler(bindPtr->tkwin, mask, BindProc, bindPtr);
+    free(bindPtr);
+    bindPtr = NULL;
+}
+
+void
+Blt_PickCurrentItem(BindTable *bindPtr)
+{
+    if (bindPtr->activePick) {
+	PickCurrentItem(bindPtr, &bindPtr->pickEvent);
+    }
+}
+
+void
+Blt_DeleteBindings(
+    BindTable *bindPtr,
+    ClientData object)
+{
+    Tk_DeleteAllBindings(bindPtr->bindingTable, object);
+
+    /*
+     * If this is the object currently picked, we need to repick one.
+     */
+    if (bindPtr->currentItem == object) {
+	bindPtr->currentItem = NULL;
+	bindPtr->currentContext = NULL;
+    }
+    if (bindPtr->newItem == object) {
+	bindPtr->newItem = NULL;
+	bindPtr->newContext = NULL;
+    }
+    if (bindPtr->focusItem == object) {
+	bindPtr->focusItem = NULL;
+	bindPtr->focusContext = NULL;
+    }
+}
+
+void
+Blt_MoveBindingTable(
+    BindTable *bindPtr,
+    Tk_Window tkwin)
+{
+    unsigned int mask;
+
+    mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask |
+	ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
+	PointerMotionMask);
+    if (bindPtr->tkwin != NULL) {
+	Tk_DeleteEventHandler(bindPtr->tkwin, mask, BindProc, bindPtr);
+    }
+    Tk_CreateEventHandler(tkwin, mask, BindProc, bindPtr);
+    bindPtr->tkwin = tkwin;
+}
+
+/*
+ * The following union is used to hold the detail information from an
+ * XEvent (including Tk's XVirtualEvent extension).
+ */
+typedef union {
+    KeySym	keySym;	    /* KeySym that corresponds to xkey.keycode. */
+    int		button;	    /* Button that was pressed (xbutton.button). */
+    Tk_Uid	name;	    /* Tk_Uid of virtual event. */
+    ClientData	clientData; /* Used when type of Detail is unknown, and to
+			     * ensure that all bytes of Detail are initialized
+			     * when this structure is used in a hash key. */
+} Detail;
+
+
+/*
+ * The following structure defines a pattern, which is matched against X
+ * events as part of the process of converting X events into TCL commands.
+ */
+typedef struct {
+    int eventType;		/* Type of X event, e.g. ButtonPress. */
+    int needMods;		/* Mask of modifiers that must be
+				 * present (0 means no modifiers are
+				 * required). */
+    Detail detail;		/* Additional information that must
+				 * match event.  Normally this is 0,
+				 * meaning no additional information
+				 * must match.  For KeyPress and
+				 * KeyRelease events, a keySym may
+				 * be specified to select a
+				 * particular keystroke (0 means any
+				 * keystrokes).  For button events,
+				 * specifies a particular button (0
+				 * means any buttons are OK).  For virtual
+				 * events, specifies the Tk_Uid of the
+				 * virtual event name (never 0). */
+} Pattern;
+
+typedef struct {
+    const char *name;		/* Name of modifier. */
+    int mask;			/* Button/modifier mask value, such as
+				 * Button1Mask. */
+    int flags;			/* Various flags; see below for
+				 * definitions. */
+} EventModifier;
+
+/*
+ * Flags for EventModifier structures:
+ *
+ * DOUBLE -		Non-zero means duplicate this event,
+ *			e.g. for double-clicks.
+ * TRIPLE -		Non-zero means triplicate this event,
+ *			e.g. for triple-clicks.
+ * QUADRUPLE -		Non-zero means quadruple this event,
+ *			e.g. for 4-fold-clicks.
+ * MULT_CLICKS -	Combination of all of above.
+ */
+
+#define DOUBLE		(1<<0)
+#define TRIPLE		(1<<1)
+#define QUADRUPLE	(1<<2)
+#define MULT_CLICKS	(DOUBLE|TRIPLE|QUADRUPLE)
+
+#define META_MASK	(AnyModifier<<1)
+#define ALT_MASK	(AnyModifier<<2)
+
+typedef struct {
+    const char *name;		/* Name of event. */
+    int type;			/* Event type for X, such as
+				 * ButtonPress. */
+    int eventMask;		/* Mask bits (for XSelectInput)
+				 * for this event type. */
+} EventInfo;
+
+/*
+ * Note:  some of the masks below are an OR-ed combination of
+ * several masks.  This is necessary because X doesn't report
+ * up events unless you also ask for down events.  Also, X
+ * doesn't report button state in motion events unless you've
+ * asked about button events.
+ */
+
+/*
+ * The defines and table below are used to classify events into
+ * various groups.  The reason for this is that logically identical
+ * fields (e.g. "state") appear at different places in different
+ * types of events.  The classification masks can be used to figure
+ * out quickly where to extract information from events.
+ */
+
+#define KEY			0x1
+#define BUTTON			0x2
+#define MOTION			0x4
+#define CROSSING		0x8
+#define FOCUS			0x10
+#define EXPOSE			0x20
+#define VISIBILITY		0x40
+#define CREATE			0x80
+#define DESTROY			0x100
+#define UNMAP			0x200
+#define MAP			0x400
+#define REPARENT		0x800
+#define CONFIG			0x1000
+#define GRAVITY			0x2000
+#define CIRC			0x4000
+#define PROP			0x8000
+#define COLORMAP		0x10000
+#define VIRTUAL			0x20000
+#define ACTIVATE		0x40000
+#define	MAPREQ			0x80000
+#define	CONFIGREQ		0x100000
+#define	RESIZEREQ		0x200000
+#define CIRCREQ			0x400000
+
+#define KEY_BUTTON_MOTION_VIRTUAL	(KEY|BUTTON|MOTION|VIRTUAL)
+#define KEY_BUTTON_MOTION_CROSSING	(KEY|BUTTON|MOTION|CROSSING|VIRTUAL)
+
+
diff --git a/tlt3.0/bltBind.h b/tlt3.0/bltBind.h
new file mode 100644
index 0000000..937e754
--- /dev/null
+++ b/tlt3.0/bltBind.h
@@ -0,0 +1,120 @@
+/*
+ * bltBind.h --
+ *
+ *	Copyright 1998-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_BIND_H
+#define _BLT_BIND_H
+
+#include <bltList.h>
+
+typedef struct _Blt_BindTable *Blt_BindTable;
+
+typedef ClientData (Blt_BindPickProc)(ClientData clientData, int x, int y, 
+	ClientData *contextPtr);
+
+typedef void (Blt_BindTagProc)(Blt_BindTable bindTable, ClientData object, 
+	ClientData context, Blt_List list);
+
+
+/*
+ *  Binding structure information:
+ */
+
+struct _Blt_BindTable {
+    unsigned int flags;
+    Tk_BindingTable bindingTable;
+				/* Table of all bindings currently defined.
+				 * NULL means that no bindings exist, so the
+				 * table hasn't been created.  Each "object"
+				 * used for this table is either a Tk_Uid for
+				 * a tag or the address of an item named by
+				 * id. */
+
+    ClientData currentItem;	/* The item currently containing the mouse
+				 * pointer, or NULL if none. */
+    ClientData currentContext;	/* One word indicating what kind of object was
+				 * picked. */
+
+    ClientData newItem;		/* The item that is about to become the
+				 * current one, or NULL.  This field is used
+				 * to detect deletions of the new current item
+				 * pointer that occur during Leave processing
+				 * of the previous current tab.  */
+    ClientData newContext;	/* One-word indicating what kind of object was
+				 * just picked. */
+
+    ClientData focusItem;
+    ClientData focusContext;
+
+    XEvent pickEvent;		/* The event upon which the current choice of
+				 * the current tab is based.  Must be saved so
+				 * that if the current item is deleted, we can
+				 * pick another. */
+    int activePick;		/* The pick event has been initialized so that
+				 * we can repick it */
+
+    int state;			/* Last known modifier state.  Used to defer
+				 * picking a new current object while buttons
+				 * are down. */
+
+    ClientData clientData;
+    Tk_Window tkwin;
+    Blt_BindPickProc *pickProc;	/* Routine to report the item the mouse is
+				 * currently over. */
+    Blt_BindTagProc *tagProc;	/* Routine to report tags picked items. */
+};
+
+extern void Blt_DestroyBindingTable(Blt_BindTable table);
+
+extern Blt_BindTable Blt_CreateBindingTable(Tcl_Interp *interp, 
+	Tk_Window tkwin, ClientData clientData, Blt_BindPickProc *pickProc,
+	Blt_BindTagProc *tagProc);
+
+extern int Blt_ConfigureBindings(Tcl_Interp *interp, Blt_BindTable table, 
+	ClientData item, int argc, const char **argv);
+
+extern int Blt_ConfigureBindingsFromObj(Tcl_Interp *interp, 
+	Blt_BindTable table, ClientData item, int objc, Tcl_Obj *const *objv);
+
+extern void Blt_PickCurrentItem(Blt_BindTable table);
+
+extern void Blt_DeleteBindings(Blt_BindTable table, ClientData object);
+
+extern void Blt_MoveBindingTable(Blt_BindTable table, Tk_Window tkwin);
+
+#define Blt_SetFocusItem(bindPtr, object, context) \
+	((bindPtr)->focusItem = (ClientData)(object),\
+	 (bindPtr)->focusContext = (ClientData)(context))
+
+#define Blt_SetCurrentItem(bindPtr, object, context) \
+	((bindPtr)->currentItem = (ClientData)(object),\
+	 (bindPtr)->currentContext = (ClientData)(context))
+
+#define Blt_GetCurrentItem(bindPtr)  ((bindPtr)->currentItem)
+#define Blt_GetCurrentContext(bindPtr)  ((bindPtr)->currentContext)
+#define Blt_GetLatestItem(bindPtr)  ((bindPtr)->newItem)
+
+#define Blt_GetBindingData(bindPtr)  ((bindPtr)->clientData)
+
+#endif /*_BLT_BIND_H*/
diff --git a/blt3.0.1/src/bltUnixBitmap.c b/tlt3.0/bltBitmap.c
similarity index 84%
copy from blt3.0.1/src/bltUnixBitmap.c
copy to tlt3.0/bltBitmap.c
index 98ce0f8..351ddc4 100644
--- a/blt3.0.1/src/bltUnixBitmap.c
+++ b/tlt3.0/bltBitmap.c
@@ -37,135 +37,19 @@
  * 
  */
 
-#include "bltInt.h"
-#include "bltHash.h"
-#ifdef notdef
-#include "bltPicture.h"
-#endif
 #include <X11/Xutil.h>
 #include <X11/Xproto.h>
+
+#include "bltInt.h"
 #include "bltBitmap.h"
+#include "bltMath.h"
+#include "bltHash.h"
 
 #define ROTATE_0	0
 #define ROTATE_90	1
 #define ROTATE_180	2
 #define ROTATE_270	3
 
-Pixmap
-Blt_PhotoImageMask(Tk_Window tkwin, Tk_PhotoImageBlock src)
-{
-    Pixmap bitmap;
-    int arraySize, bytes_per_line;
-    int offset, count;
-    int y;
-    unsigned char *bits;
-    unsigned char *dp;
-
-    bytes_per_line = (src.width + 7) / 8;
-    arraySize = src.height * bytes_per_line;
-    bits = Blt_AssertMalloc(sizeof(unsigned char) * arraySize);
-    dp = bits;
-    offset = count = 0;
-    for (y = 0; y < src.height; y++) {
-	int value, bitMask;
-	int x;
-	unsigned char *sp;
-
-	value = 0, bitMask = 1;
-	sp = src.pixelPtr + offset;
-	for (x = 0; x < src.width; /*empty*/ ) {
-	    unsigned long pixel;
-
-	    pixel = (sp[src.offset[3]] != 0x00);
-	    if (pixel) {
-		value |= bitMask;
-	    } else {
-		count++;	/* Count the number of transparent pixels. */
-	    }
-	    bitMask <<= 1;
-	    x++;
-	    if (!(x & 7)) {
-		*dp++ = (unsigned char)value;
-		value = 0, bitMask = 1;
-	    }
-	    sp += src.pixelSize;
-	}
-	if (x & 7) {
-	    *dp++ = (unsigned char)value;
-	}
-	offset += src.pitch;
-    }
-    if (count > 0) {
-	Tk_MakeWindowExist(tkwin);
-	bitmap = XCreateBitmapFromData(Tk_Display(tkwin), Tk_WindowId(tkwin),
-	    (char *)bits, (unsigned int)src.width, (unsigned int)src.height);
-    } else {
-	bitmap = None;		/* Image is opaque. */
-    }
-    Blt_Free(bits);
-    return bitmap;
-}
-
-#ifdef notdef
-Pixmap
-Blt_PictureMask(Tk_Window tkwin, Picture *srcPtr)
-{
-    Blt_Pixel *srcRowPtr;
-    Pixmap bitmap;
-    int bytesPerLine;
-    int count;
-    int x, y;
-    unsigned char *bits;
-    unsigned char *destRowPtr;
-
-    bytesPerLine = (srcPtr->width + 7) / 8;
-    bits = Blt_AssertMalloc(sizeof(unsigned char)*srcPtr->height*bytesPerLine);
-    count = 0;
-    srcRowPtr = srcPtr->bits;
-    destRowPtr = bits;
-    for (y = 0; y < srcPtr->height; y++) {
-	int value, bitMask;
-	Blt_Pixel *sp;
-	unsigned char *dp;
-
-	sp = srcRowPtr, dp = destRowPtr;
-	value = 0, bitMask = 1;
-	for (x = 0; x < srcPtr->width; /*empty*/ ) {
-	    unsigned long pixel;
-
-	    pixel = (sp->Alpha != ALPHA_TRANSPARENT);
-	    if (pixel) {
-		value |= bitMask;
-	    } else {
-		count++;	/* Count the number of transparent pixels. */
-	    }
-	    bitMask <<= 1;
-	    x++;
-	    if (!(x & 7)) {
-		*dp++ = (unsigned char)value;
-		value = 0, bitMask = 1;
-	    }
-	    sp++;
-	}
-	if (x & 7) {
-	    *dp++ = (unsigned char)value;
-	}
-	srcRowPtr += srcPtr->pixelsPerRow;
-	destRowPtr += bytesPerLine;
-    }
-    if (count > 0) {
-	Tk_MakeWindowExist(tkwin);
-	bitmap = XCreateBitmapFromData(Tk_Display(tkwin), Tk_WindowId(tkwin),
-		(char *)bits, (unsigned int)srcPtr->width, 
-		(unsigned int)srcPtr->height);
-    } else {
-	bitmap = None;		/* Image is opaque. */
-    }
-    Blt_Free(bits);
-    return bitmap;
-}
-#endif
-
 /*
  *---------------------------------------------------------------------------
  *
@@ -214,8 +98,8 @@ Blt_RotateBitmap(
 	ZPixmap);
     destImgPtr = XGetImage(display, destBitmap, 0, 0, destWidth, destHeight, 
 	1, ZPixmap);
-    angle = FMOD(angle, 360.0);
-    if (FMOD(angle, (double)90.0) == 0.0) {
+    angle = fmod(angle, 360.0);
+    if (fmod(angle, (double)90.0) == 0.0) {
 	int quadrant;
 	int y;
 
@@ -509,7 +393,7 @@ Blt_ScaleRotateBitmapArea(
 	ZPixmap);
     destImgPtr = XGetImage(display, destBitmap, 0, 0, regionWidth, 
 	regionHeight, 1, ZPixmap);
-    angle = FMOD(angle, 360.0);
+    angle = fmod(angle, 360.0);
 
     Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rotWidth, &rotHeight,
 	(Point2d *)NULL);
@@ -517,7 +401,7 @@ Blt_ScaleRotateBitmapArea(
     xScale = rotWidth / (double)destWidth;
     yScale = rotHeight / (double)destHeight;
 
-    if (FMOD(angle, (double)90.0) == 0.0) {
+    if (fmod(angle, (double)90.0) == 0.0) {
 	int quadrant;
 	int x, y;
 
diff --git a/tlt3.0/bltBitmap.h b/tlt3.0/bltBitmap.h
new file mode 100644
index 0000000..9de6b21
--- /dev/null
+++ b/tlt3.0/bltBitmap.h
@@ -0,0 +1,43 @@
+/*
+ * bltBitmap.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_BITMAP_H
+#define _BLT_BITMAP_H
+
+#include <tk.h>
+
+extern Pixmap Blt_ScaleBitmap(Tk_Window tkwin, Pixmap srcBitmap, int srcWidth, 
+	int srcHeight, int destWidth, int destHeight);
+
+extern Pixmap Blt_RotateBitmap(Tk_Window tkwin, Pixmap srcBitmap, 
+	int srcWidth, int srcHeight, float angle, int *destWidthPtr, 
+	int *destHeightPtr);
+
+extern Pixmap Blt_ScaleRotateBitmapArea(Tk_Window tkwin, Pixmap srcBitmap,
+	unsigned int srcWidth, unsigned int srcHeight, int regionX, int regionY,
+	unsigned int regionWidth, unsigned int regionHeight, 
+	unsigned int destWidth, unsigned int destHeight, float angle);
+
+#endif
diff --git a/tlt3.0/bltChain.c b/tlt3.0/bltChain.c
new file mode 100644
index 0000000..54797e1
--- /dev/null
+++ b/tlt3.0/bltChain.c
@@ -0,0 +1,520 @@
+
+/*
+ * bltChain.c --
+ *
+ * The module implements a generic linked list package.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "bltInt.h"
+#include "bltChain.h"
+
+#ifndef ALIGN
+#define ALIGN(a) \
+	(((size_t)a + (sizeof(double) - 1)) & (~(sizeof(double) - 1)))
+#endif /* ALIGN */
+
+typedef struct _Blt_ChainLink ChainLink;
+typedef struct _Blt_Chain Chain;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_Create --
+ *
+ *	Creates a new linked list (chain) structure and initializes its
+ *	pointers;
+ *
+ * Results:
+ *	Returns a pointer to the newly created chain structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_Chain
+Blt_Chain_Create(void)
+{
+    Chain *chainPtr;
+
+    chainPtr = malloc(sizeof(Chain));
+    if (chainPtr != NULL) {
+	Blt_Chain_Init(chainPtr);
+    }
+    return chainPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_AllocLink --
+ *
+ *	Creates a new chain link.  Unlink Blt_Chain_NewLink, this routine also
+ *	allocates extra memory in the node for data.
+ *
+ * Results:
+ *	The return value is the pointer to the newly created entry.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_ChainLink
+Blt_Chain_AllocLink(size_t extraSize)
+{
+    ChainLink *linkPtr;
+    size_t linkSize;
+
+    linkSize = ALIGN(sizeof(ChainLink));
+    linkPtr = calloc(1, linkSize + extraSize);
+    if (extraSize > 0) {
+	/* Point clientData at the memory beyond the normal structure. */
+	linkPtr->clientData = (ClientData)((char *)linkPtr + linkSize);
+    }
+    return linkPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_InitLink --
+ *
+ *	Initializes the new link.  This routine is for applications that use
+ *	their own memory allocation procedures to allocate links.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Chain_InitLink(ChainLink *linkPtr)
+{
+    linkPtr->clientData = NULL;
+    linkPtr->next = linkPtr->prev = NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_NewLink --
+ *
+ *	Creates a new link.
+ *
+ * Results:
+ *	The return value is the pointer to the newly created link.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_ChainLink
+Blt_Chain_NewLink(void)
+{
+    ChainLink *linkPtr;
+
+    linkPtr = malloc(sizeof(ChainLink));
+    linkPtr->clientData = NULL;
+    linkPtr->next = linkPtr->prev = NULL;
+    return linkPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_Reset --
+ *
+ *	Removes all the links in the chain, freeing the memory used for each
+ *	link.  Memory pointed to by the link (clientData) is not freed.  It's
+ *	the caller's responsibility to deallocate it.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Chain_Reset(Chain *chainPtr) /* Chain to clear */
+{
+    if (chainPtr != NULL) {
+	ChainLink *oldPtr;
+	ChainLink *linkPtr = chainPtr->head;
+
+	while (linkPtr != NULL) {
+	    oldPtr = linkPtr;
+	    linkPtr = linkPtr->next;
+	    free(oldPtr);
+	}
+	Blt_Chain_Init(chainPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_Destroy
+ *
+ *     Frees all the nodes in the chain and deallocates the memory used for
+ *     the chain structure itself.  It's assumed that the chain was previously
+ *     allocated by Blt_Chain_Create.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Chain_Destroy(Chain *chainPtr)
+{
+    if (chainPtr != NULL) {
+	Blt_Chain_Reset(chainPtr);
+	free(chainPtr);
+	chainPtr = NULL;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_Init --
+ *
+ *	Initializes a linked list.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Chain_Init(Chain *chainPtr)
+{
+    chainPtr->nLinks = 0;
+    chainPtr->head = chainPtr->tail = NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_LinkAfter --
+ *
+ *	Inserts a link after another link.  If afterPtr is NULL, then the new
+ *	link is prepended to the beginning of the chain.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Chain_LinkAfter(Chain *chainPtr, ChainLink *linkPtr, ChainLink *afterPtr)
+{
+    if (chainPtr->head == NULL) {
+	chainPtr->tail = chainPtr->head = linkPtr;
+    } else {
+	if (afterPtr == NULL) {
+	    /* Append to the end of the chain. */
+	    linkPtr->next = NULL;
+	    linkPtr->prev = chainPtr->tail;
+	    chainPtr->tail->next = linkPtr;
+	    chainPtr->tail = linkPtr;
+	} else {
+	    linkPtr->next = afterPtr->next;
+	    linkPtr->prev = afterPtr;
+	    if (afterPtr == chainPtr->tail) {
+		chainPtr->tail = linkPtr;
+	    } else {
+		afterPtr->next->prev = linkPtr;
+	    }
+	    afterPtr->next = linkPtr;
+	}
+    }
+    chainPtr->nLinks++;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_LinkBefore --
+ *
+ *	Inserts a new link preceding a given link in a chain.  If beforePtr is
+ *	NULL, then the new link is placed at the beginning of the list.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Chain_LinkBefore(Chain *chainPtr, ChainLink *linkPtr, ChainLink *beforePtr)
+{
+    if (chainPtr->head == NULL) {
+	chainPtr->tail = chainPtr->head = linkPtr;
+    } else {
+	if (beforePtr == NULL) {
+	    /* Prepend to the front of the chain */
+	    linkPtr->next = chainPtr->head;
+	    linkPtr->prev = NULL;
+	    chainPtr->head->prev = linkPtr;
+	    chainPtr->head = linkPtr;
+	} else {
+	    linkPtr->prev = beforePtr->prev;
+	    linkPtr->next = beforePtr;
+	    if (beforePtr == chainPtr->head) {
+		chainPtr->head = linkPtr;
+	    } else {
+		beforePtr->prev->next = linkPtr;
+	    }
+	    beforePtr->prev = linkPtr;
+	}
+    }
+    chainPtr->nLinks++;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_UnlinkLink --
+ *
+ *	Unlinks a link from the chain. The link is not deallocated, but only
+ *	removed from the chain.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Chain_UnlinkLink(Chain *chainPtr, ChainLink *linkPtr)
+{
+    int unlinked;		/* Indicates if the link is actually removed
+				 * from the chain. */
+
+    unlinked = FALSE;
+    if (chainPtr->head == linkPtr) {
+	chainPtr->head = linkPtr->next;
+	unlinked = TRUE;
+    }
+    if (chainPtr->tail == linkPtr) {
+	chainPtr->tail = linkPtr->prev;
+	unlinked = TRUE;
+    }
+    if (linkPtr->next != NULL) {
+	linkPtr->next->prev = linkPtr->prev;
+	unlinked = TRUE;
+    }
+    if (linkPtr->prev != NULL) {
+	linkPtr->prev->next = linkPtr->next;
+	unlinked = TRUE;
+    }
+    if (unlinked) {
+	chainPtr->nLinks--;
+    }
+    linkPtr->prev = linkPtr->next = NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_DeleteLink --
+ *
+ *	Unlinks and frees the given link from the chain.  It's assumed that
+ *	the link belong to the chain. No error checking is performed to verify
+ *	this.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Chain_DeleteLink(Blt_Chain chain, Blt_ChainLink link)
+{
+    Blt_Chain_UnlinkLink(chain, link);
+    free(link);
+    link = NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_Append
+ *
+ *	Creates and new link with the given data and appends it to the end of
+ *	the chain.
+ *
+ * Results:
+ *	Returns a pointer to the link created.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_ChainLink
+Blt_Chain_Append(Blt_Chain chain, ClientData clientData)
+{
+    Blt_ChainLink link;
+
+    link = Blt_Chain_NewLink();
+    Blt_Chain_LinkAfter(chain, link, (Blt_ChainLink)NULL);
+    Blt_Chain_SetValue(link, clientData);
+    return link;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_Prepend
+ *
+ *	Creates and new link with the given data and prepends it to beginning
+ *	of the chain.
+ *
+ * Results:
+ *	Returns a pointer to the link created.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_ChainLink 
+Blt_Chain_Prepend(Blt_Chain chain, ClientData clientData)
+{
+    Blt_ChainLink link;
+
+    link = Blt_Chain_NewLink();
+    Blt_Chain_LinkBefore(chain, link, (Blt_ChainLink)NULL);
+    Blt_Chain_SetValue(link, clientData);
+    return link;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_GetNthLink --
+ *
+ *	Find the link at the given position in the chain.  The position
+ *	is number from 0.  If position is negative is returns the nth
+ *	link from the back of the chain.
+ *
+ * Results:
+ *	Returns the pointer to the link, if that numbered link
+ *	exists. Otherwise NULL.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_ChainLink
+Blt_Chain_GetNthLink(Chain *chainPtr, long position)
+{
+    if (chainPtr != NULL) {
+	if (position < 0) {
+	    ChainLink *linkPtr;
+	    int i;
+
+	    position = -position;
+	    for (i = 0, linkPtr = chainPtr->tail; linkPtr != NULL; 
+		 linkPtr = linkPtr->prev, i++) {
+		if (i == position) {
+		    return linkPtr;
+		}
+	    }
+	} else {
+	    ChainLink *linkPtr;
+	    int i;
+
+	    linkPtr = chainPtr->head;
+	    for (i = 0, linkPtr = chainPtr->head; linkPtr != NULL; 
+		 linkPtr = linkPtr->next, i++) {
+		if (i == position) {
+		    return linkPtr;
+		}
+	    }
+	}
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_Sort --
+ *
+ *	Sorts the chain according to the given comparison routine.  
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	The chain is reordered.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Chain_Sort(Chain *chainPtr, Blt_ChainCompareProc *proc)
+{
+    ChainLink **linkArr;
+    ChainLink *linkPtr;
+    long i;
+
+    if (chainPtr->nLinks < 2) {
+	return;
+    }
+    linkArr = malloc(sizeof(Blt_ChainLink) * (chainPtr->nLinks + 1));
+    if (linkArr == NULL) {
+	return;			/* Out of memory. */
+    }
+    i = 0;
+    for (linkPtr = chainPtr->head; linkPtr != NULL; 
+	 linkPtr = linkPtr->next) { 
+	linkArr[i++] = linkPtr;
+    }
+    qsort((char *)linkArr, chainPtr->nLinks, sizeof(Blt_ChainLink),
+	(QSortCompareProc *)proc);
+
+    /* Rethread the chain. */
+    linkPtr = linkArr[0];
+    chainPtr->head = linkPtr;
+    linkPtr->prev = NULL;
+    for (i = 1; i < chainPtr->nLinks; i++) {
+	linkPtr->next = linkArr[i];
+	linkPtr->next->prev = linkPtr;
+	linkPtr = linkPtr->next;
+    }
+    chainPtr->tail = linkPtr;
+    linkPtr->next = NULL;
+    free(linkArr);
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Chain_IsBefore --
+ *
+ *
+ * Results:
+ *	Return boolean value if the first link comes before the second.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_Chain_IsBefore(ChainLink *firstPtr, ChainLink *lastPtr)
+{
+    ChainLink *linkPtr;
+
+    for (linkPtr = firstPtr; linkPtr != NULL; linkPtr = linkPtr->next) {
+	if (linkPtr == lastPtr) {
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
diff --git a/tlt3.0/bltChain.h b/tlt3.0/bltChain.h
new file mode 100644
index 0000000..7c7cbb0
--- /dev/null
+++ b/tlt3.0/bltChain.h
@@ -0,0 +1,90 @@
+
+/*
+ * bltChain.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _BLT_CHAIN_H
+#define _BLT_CHAIN_H
+
+typedef struct _Blt_Chain *Blt_Chain;
+typedef struct _Blt_ChainLink *Blt_ChainLink;
+
+/*
+ * A Blt_ChainLink is the container structure for the Blt_Chain.
+ */
+
+struct _Blt_ChainLink {
+    Blt_ChainLink prev;		/* Link to the previous link */
+    Blt_ChainLink next;		/* Link to the next link */
+    ClientData clientData;	/* Pointer to the data object */
+};
+
+typedef int (Blt_ChainCompareProc)(Blt_ChainLink *l1Ptr, Blt_ChainLink *l2Ptr);
+
+/*
+ * A Blt_Chain is a doubly chained list structure.
+ */
+struct _Blt_Chain {
+    Blt_ChainLink head;		/* Pointer to first element in chain */
+    Blt_ChainLink tail;		/* Pointer to last element in chain */
+    long nLinks;		/* Number of elements in chain */
+};
+
+extern void Blt_Chain_Init(Blt_Chain chain);
+extern Blt_Chain Blt_Chain_Create(void);
+extern void Blt_Chain_Destroy(Blt_Chain chain);
+extern Blt_ChainLink Blt_Chain_NewLink(void);
+extern Blt_ChainLink Blt_Chain_AllocLink(size_t size);
+extern Blt_ChainLink Blt_Chain_Append(Blt_Chain chain, 
+	ClientData clientData);
+extern Blt_ChainLink Blt_Chain_Prepend(Blt_Chain chain, 
+	ClientData clientData);
+extern void Blt_Chain_Reset(Blt_Chain chain);
+extern void Blt_Chain_InitLink(Blt_ChainLink link);
+extern void Blt_Chain_LinkAfter(Blt_Chain chain, Blt_ChainLink link, 
+	Blt_ChainLink after);
+extern void Blt_Chain_LinkBefore(Blt_Chain chain, Blt_ChainLink link, 
+	Blt_ChainLink before);
+extern void Blt_Chain_UnlinkLink(Blt_Chain chain, Blt_ChainLink link);
+extern void Blt_Chain_DeleteLink(Blt_Chain chain, Blt_ChainLink link);
+extern Blt_ChainLink Blt_Chain_GetNthLink(Blt_Chain chain, long position);
+extern void Blt_Chain_Sort(Blt_Chain chain, Blt_ChainCompareProc *proc);
+extern int Blt_Chain_IsBefore(Blt_ChainLink first, Blt_ChainLink last);
+
+#define Blt_Chain_GetLength(c)	(((c) == NULL) ? 0 : (c)->nLinks)
+#define Blt_Chain_FirstLink(c)	(((c) == NULL) ? NULL : (c)->head)
+#define Blt_Chain_LastLink(c)	(((c) == NULL) ? NULL : (c)->tail)
+#define Blt_Chain_PrevLink(l)	((l)->prev)
+#define Blt_Chain_NextLink(l) 	((l)->next)
+#define Blt_Chain_GetValue(l)  	((l)->clientData)
+#define Blt_Chain_FirstValue(c)	(((c)->head == NULL) ? NULL : (c)->head->clientData)
+#define Blt_Chain_SetValue(l, value) ((l)->clientData = (ClientData)(value))
+#define Blt_Chain_AppendLink(c, l) \
+	(Blt_Chain_LinkAfter((c), (l), (Blt_ChainLink)NULL))
+#define Blt_Chain_PrependLink(c, l) \
+	(Blt_Chain_LinkBefore((c), (l), (Blt_ChainLink)NULL))
+
+#endif /* _BLT_CHAIN_H */
diff --git a/tlt3.0/bltConfig.c b/tlt3.0/bltConfig.c
new file mode 100644
index 0000000..8ced073
--- /dev/null
+++ b/tlt3.0/bltConfig.c
@@ -0,0 +1,2024 @@
+
+/* 
+ * bltConfig.c --
+ *
+ * This file contains a Tcl_Obj based replacement for the widget
+ * configuration functions in Tk.
+ *
+ *	Copyright (c) 1990-1994 The Regents of the University of California.
+ *	Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ *
+ *	See the file "license.terms" for information on usage and redistribution
+ *	of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ *	Copyright 2003-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * This is a Tcl_Obj based replacement for the widget configuration
+ * functions in Tk.  
+ *
+ * What not use the new Tk_Option interface?
+ *
+ *	There were design changes in the new Tk_Option interface that
+ *	make it unwieldy.  
+ *
+ *	o You have to dynamically allocate, store, and deallocate
+ *	  your option table.  
+ *      o The Tk_FreeConfigOptions routine requires a tkwin argument.
+ *	  Unfortunately, most widgets save the display pointer and 
+ *	  de-reference their tkwin when the window is destroyed.  
+ *	o There's no TK_CONFIG_CUSTOM functionality.  This means that
+ *	  save special options must be saved as strings by 
+ *	  Tk_ConfigureWidget and processed later, thus losing the 
+ *	  benefits of Tcl_Objs.  It also make error handling 
+ *	  problematic, since you don't pick up certain errors like 
+ *	  
+ *	    .widget configure -myoption bad -myoption good
+ *        
+ *	  You will never see the first "bad" value.
+ *	o Especially compared to the former Tk_ConfigureWidget calls,
+ *	  the new interface is overly complex.  If there was a big
+ *	  performance win, it might be worth the effort.  But let's 
+ *	  face it, this biggest wins are in processing custom options
+ *	  values with thousands of elements.  Most common resources 
+ *	  (font, color, etc) have string tokens anyways.
+ *
+ *	On the other hand, the replacement functions in this file fell
+ *	into place quite easily both from the aspect of API writer and
+ *	user.  The biggest benefit is that you don't need to change lots
+ *	of working code just to get the benefits of Tcl_Objs.
+ * 
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+
+#include "bltInt.h"
+#include "bltWindow.h"
+#include "bltFont.h"
+#include "bltBgStyle.h"
+
+#define PIXELS_NNEG		0
+#define PIXELS_POS		1
+#define PIXELS_ANY		2
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetPixelsFromObj --
+ *
+ *	Like Tk_GetPixelsFromObj, but checks for negative, zero.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_GetPixelsFromObj(
+    Tcl_Interp *interp,
+    Tk_Window tkwin,
+    Tcl_Obj *objPtr,
+    int check,			/* Can be PIXELS_POS, PIXELS_NNEG,
+				 * or PIXELS_ANY, */
+    int *valuePtr)
+{
+    int length;
+
+    if (Tk_GetPixelsFromObj(interp, tkwin, objPtr, &length) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (length >= SHRT_MAX) {
+	Tcl_AppendResult(interp, "bad distance \"", Tcl_GetString(objPtr), 
+		 "\": too big to represent", (char *)NULL);
+	return TCL_ERROR;
+    }
+    switch (check) {
+    case PIXELS_NNEG:
+	if (length < 0) {
+	    Tcl_AppendResult(interp, "bad distance \"", Tcl_GetString(objPtr), 
+		     "\": can't be negative", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	break;
+
+    case PIXELS_POS:
+	if (length <= 0) {
+	    Tcl_AppendResult(interp, "bad distance \"", Tcl_GetString(objPtr), 
+		     "\": must be positive", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	break;
+
+    case PIXELS_ANY:
+	break;
+    }
+    *valuePtr = length;
+    return TCL_OK;
+}
+
+int
+Blt_GetPadFromObj(
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tk_Window tkwin,		/* Window */
+    Tcl_Obj *objPtr,		/* Pixel value string */
+    Blt_Pad *padPtr)
+{
+    int side1, side2;
+    int objc;
+    Tcl_Obj **objv;
+
+    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if ((objc < 1) || (objc > 2)) {
+	Tcl_AppendResult(interp, "wrong # elements in padding list",
+	    (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (Blt_GetPixelsFromObj(interp, tkwin, objv[0], PIXELS_NNEG, 
+	     &side1) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    side2 = side1;
+    if ((objc > 1) && 
+	(Blt_GetPixelsFromObj(interp, tkwin, objv[1], PIXELS_NNEG, 
+	      &side2) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    /* Don't update the pad structure until we know both values are okay. */
+    padPtr->side1 = side1;
+    padPtr->side2 = side2;
+    return TCL_OK;
+}
+
+int
+Blt_GetStateFromObj(
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tcl_Obj *objPtr,		/* Pixel value string */
+    int *statePtr)
+{
+    char c;
+    const char *string;
+    int length;
+
+    string = Tcl_GetStringFromObj(objPtr, &length);
+    c = string[0];
+    if ((c == 'n') && (strncmp(string, "normal", length) == 0)) {
+	*statePtr = STATE_NORMAL;
+    } else if ((c == 'd') && (strncmp(string, "disabled", length) == 0)) {
+	*statePtr = STATE_DISABLED;
+    } else if ((c == 'a') && (strncmp(string, "active", length) == 0)) {
+	*statePtr = STATE_ACTIVE;
+    } else {
+	Tcl_AppendResult(interp, "bad state \"", string,
+	    "\": should be normal, active, or disabled", (char *)NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+const char *
+Blt_NameOfState(int state)
+{
+    switch (state) {
+    case STATE_ACTIVE:
+	return "active";
+    case STATE_DISABLED:
+	return "disabled";
+    case STATE_NORMAL:
+	return "normal";
+    default:
+	return "???";
+    }
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_NameOfFill --
+ *
+ *	Converts the integer representing the fill style into a string.
+ *
+ *---------------------------------------------------------------------------
+ */
+const char *
+Blt_NameOfFill(int fill)
+{
+    switch (fill) {
+    case FILL_X:
+	return "x";
+    case FILL_Y:
+	return "y";
+    case FILL_NONE:
+	return "none";
+    case FILL_BOTH:
+	return "both";
+    default:
+	return "unknown value";
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetFillFromObj --
+ *
+ *	Converts the fill style string into its numeric representation.
+ *
+ *	Valid style strings are:
+ *
+ *	  "none"   Use neither plane.
+ * 	  "x"	   X-coordinate plane.
+ *	  "y"	   Y-coordinate plane.
+ *	  "both"   Use both coordinate planes.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+int
+Blt_GetFillFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *fillPtr)
+{
+    char c;
+    const char *string;
+    int length;
+
+    string = Tcl_GetStringFromObj(objPtr, &length);
+    c = string[0];
+    if ((c == 'n') && (strncmp(string, "none", length) == 0)) {
+	*fillPtr = FILL_NONE;
+    } else if ((c == 'x') && (strncmp(string, "x", length) == 0)) {
+	*fillPtr = FILL_X;
+    } else if ((c == 'y') && (strncmp(string, "y", length) == 0)) {
+	*fillPtr = FILL_Y;
+    } else if ((c == 'b') && (strncmp(string, "both", length) == 0)) {
+	*fillPtr = FILL_BOTH;
+    } else {
+	Tcl_AppendResult(interp, "bad argument \"", string,
+	    "\": should be \"none\", \"x\", \"y\", or \"both\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetDashesFromObj --
+ *
+ *	Converts a TCL list of dash values into a dash list ready for
+ *	use with XSetDashes.
+ *
+ * 	A valid list dash values can have zero through 11 elements
+ *	(PostScript limit).  Values must be between 1 and 255. Although
+ *	a list of 0 (like the empty string) means no dashes.
+ *
+ * Results:
+ *	A standard TCL result. If the list represented a valid dash
+ *	list TCL_OK is returned and *dashesPtr* will contain the
+ *	valid dash list. Otherwise, TCL_ERROR is returned and
+ *	interp->result will contain an error message.
+ *
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_GetDashesFromObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr,
+    Blt_Dashes *dashesPtr)
+{
+    const char *string;
+    char c;
+
+    string = Tcl_GetString(objPtr);
+    if (string == NULL) {
+	dashesPtr->values[0] = 0;
+	return TCL_OK;
+    }
+    c = string[0];
+    if (c == '\0') {
+	dashesPtr->values[0] = 0;
+    } else if ((c == 'd') && (strcmp(string, "dot") == 0)) {	
+	/* 1 */
+	dashesPtr->values[0] = 1;
+	dashesPtr->values[1] = 0;
+    } else if ((c == 'd') && (strcmp(string, "dash") == 0)) {	
+	/* 5 2 */
+	dashesPtr->values[0] = 5;
+	dashesPtr->values[1] = 2;
+	dashesPtr->values[2] = 0;
+    } else if ((c == 'd') && (strcmp(string, "dashdot") == 0)) { 
+	/* 2 4 2 */
+ 	dashesPtr->values[0] = 2;
+	dashesPtr->values[1] = 4;
+	dashesPtr->values[2] = 2;
+	dashesPtr->values[3] = 0;
+    } else if ((c == 'd') && (strcmp(string, "dashdotdot") == 0)) { 
+	/* 2 4 2 2 */
+	dashesPtr->values[0] = 2;
+	dashesPtr->values[1] = 4;
+	dashesPtr->values[2] = 2;
+	dashesPtr->values[3] = 2;
+	dashesPtr->values[4] = 0;
+    } else {
+	int objc;
+	Tcl_Obj **objv;
+	int i;
+
+	if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (objc > 11) {	/* This is the postscript limit */
+	    Tcl_AppendResult(interp, "too many values in dash list \"", 
+			     string, "\"", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	for (i = 0; i < objc; i++) {
+	    int value;
+
+	    if (Tcl_GetIntFromObj(interp, objv[i], &value) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    /*
+	     * Backward compatibility:
+	     * Allow list of 0 to turn off dashes
+	     */
+	    if ((value == 0) && (objc == 1)) {
+		break;
+	    }
+	    if ((value < 1) || (value > 255)) {
+		Tcl_AppendResult(interp, "dash value \"", 
+			 Tcl_GetString(objv[i]), "\" is out of range", 
+			 (char *)NULL);
+		return TCL_ERROR;
+	    }
+	    dashesPtr->values[i] = (unsigned char)value;
+	}
+	/* Make sure the array ends with a NUL byte  */
+	dashesPtr->values[i] = 0;
+    }
+    return TCL_OK;
+}
+
+const char *
+Blt_NameOfSide(int side)
+{
+    switch (side) {
+    case SIDE_LEFT:
+	return "left";
+    case SIDE_RIGHT:
+	return "right";
+    case SIDE_BOTTOM:
+	return "bottom";
+    case SIDE_TOP:
+	return "top";
+    }
+    return "unknown side value";
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetSideFromObj --
+ *
+ *	Converts the fill style string into its numeric representation.
+ *
+ *	Valid style strings are "left", "right", "top", or  "bottom".
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED */
+int
+Blt_GetSideFromObj(
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tcl_Obj *objPtr,		/* Value string */
+    int *sidePtr)		/* (out) Token representing side:
+				 * either SIDE_LEFT, SIDE_RIGHT,
+				 * SIDE_TOP, or SIDE_BOTTOM. */
+{
+    char c;
+    const char *string;
+    int length;
+
+    string = Tcl_GetStringFromObj(objPtr, &length);
+    c = string[0];
+    if ((c == 'l') && (strncmp(string, "left", length) == 0)) {
+	*sidePtr = SIDE_LEFT;
+    } else if ((c == 'r') && (strncmp(string, "right", length) == 0)) {
+	*sidePtr = SIDE_RIGHT;
+    } else if ((c == 't') && (strncmp(string, "top", length) == 0)) {
+	*sidePtr = SIDE_TOP;
+    } else if ((c == 'b') && (strncmp(string, "bottom", length) == 0)) {
+	*sidePtr = SIDE_BOTTOM;
+    } else {
+	Tcl_AppendResult(interp, "bad side \"", string,
+	    "\": should be left, right, top, or bottom", (char *)NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+int 
+Blt_GetLimitsFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, 
+		     Blt_Limits *limitsPtr)
+{
+    int values[3];
+    int nValues;
+    int limitsFlags;
+
+    /* Initialize limits to default values */
+    values[2] = LIMITS_NOM;
+    values[1] = LIMITS_MAX;
+    values[0] = LIMITS_MIN;
+    limitsFlags = 0;
+    nValues = 0;
+    if (objPtr != NULL) {
+	Tcl_Obj **objv;
+	int objc;
+	int i;
+
+	if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (objc > 3) {
+	    Tcl_AppendResult(interp, "wrong # limits \"", Tcl_GetString(objPtr),
+			     "\"", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	for (i = 0; i < objc; i++) {
+	    const char *string;
+	    int size;
+
+	    string = Tcl_GetString(objv[i]);
+	    if (string[0] == '\0') {
+		continue;		/* Empty string: use default value */
+	    }
+	    limitsFlags |= (1 << i);
+	    if (Tk_GetPixelsFromObj(interp, tkwin, objv[i], &size) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if ((size < LIMITS_MIN) || (size > LIMITS_MAX)) {
+		Tcl_AppendResult(interp, "bad limit \"", string, "\"",
+				 (char *)NULL);
+		return TCL_ERROR;
+	    }
+	    values[i] = size;
+	}
+	nValues = objc;
+    }
+    /*
+     * Check the limits specified.  We can't check the requested size of
+     * widgets.
+     */
+    switch (nValues) {
+    case 1:
+	limitsFlags |= (LIMITS_MIN_SET | LIMITS_MAX_SET);
+	values[1] = values[0];		/* Set minimum and maximum to value */
+	break;
+
+    case 2:
+	if (values[1] < values[0]) {
+	    Tcl_AppendResult(interp, "bad range \"", Tcl_GetString(objPtr),
+		"\": min > max", (char *)NULL);
+	    return TCL_ERROR;		/* Minimum is greater than maximum */
+	}
+	break;
+
+    case 3:
+	if (values[1] < values[0]) {
+	    Tcl_AppendResult(interp, "bad range \"", Tcl_GetString(objPtr),
+			     "\": min > max", (char *)NULL);
+	    return TCL_ERROR;		/* Minimum is greater than maximum */
+	}
+	if ((values[2] < values[0]) || (values[2] > values[1])) {
+	    Tcl_AppendResult(interp, "nominal value \"", Tcl_GetString(objPtr),
+		"\" out of range", (char *)NULL);
+	    return TCL_ERROR;		/* Nominal is outside of range defined
+					 * by minimum and maximum */
+	}
+	break;
+    }
+    limitsPtr->min = values[0];
+    limitsPtr->max = values[1];
+    limitsPtr->nom = values[2];
+    limitsPtr->flags = limitsFlags;
+    return TCL_OK;
+}
+
+/* Configuration option helper routines */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DoConfig --
+ *
+ *	This procedure applies a single configuration option
+ *	to a widget record.
+ *
+ * Results:
+ *	A standard TCL return value.
+ *
+ * Side effects:
+ *	WidgRec is modified as indicated by specPtr and value.
+ *	The old value is recycled, if that is appropriate for
+ *	the value type.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+DoConfig(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    Tk_Window tkwin,		/* Window containing widget (needed to
+				 * set up X resources). */
+    Blt_ConfigSpec *sp,		/* Specifier to apply. */
+    Tcl_Obj *objPtr,		/* Value to use to fill in widgRec. */
+    char *widgRec)		/* Record whose fields are to be
+				 * modified.  Values must be properly
+				 * initialized. */
+{
+    char *ptr;
+    int objIsEmpty;
+
+    objIsEmpty = FALSE;
+    if (objPtr == NULL) {
+	objIsEmpty = TRUE;
+    } else if (sp->specFlags & BLT_CONFIG_NULL_OK) {
+	int length;
+
+	if (objPtr->bytes != NULL) {
+	    length = objPtr->length;
+	} else {
+	    Tcl_GetStringFromObj(objPtr, &length);
+	}
+	objIsEmpty = (length == 0);
+    }
+    do {
+	ptr = widgRec + sp->offset;
+	switch (sp->type) {
+	case BLT_CONFIG_ANCHOR: 
+	    {
+		Tk_Anchor anchor;
+		
+		if (Tk_GetAnchorFromObj(interp, objPtr, &anchor) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(Tk_Anchor *)ptr = anchor;
+	    }
+	    break;
+
+	case BLT_CONFIG_BITMAP: 
+	    {
+		Pixmap bitmap;
+		
+		if (objIsEmpty) {
+		    bitmap = None;
+		} else {
+		    bitmap = Tk_AllocBitmapFromObj(interp, tkwin, objPtr);
+		    if (bitmap == None) {
+			return TCL_ERROR;
+		    }
+		}
+		if (*(Pixmap *)ptr != None) {
+		    Tk_FreeBitmap(Tk_Display(tkwin), *(Pixmap *)ptr);
+		}
+		*(Pixmap *)ptr = bitmap;
+	    }
+	    break;
+
+	case BLT_CONFIG_BOOLEAN: 
+	    {
+		int bool;
+		
+		if (Tcl_GetBooleanFromObj(interp, objPtr, &bool) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = bool;
+	    }
+	    break;
+
+	case BLT_CONFIG_BORDER: 
+	    {
+		Tk_3DBorder border;
+
+		if (objIsEmpty) {
+		    border = NULL;
+		} else {
+		    border = Tk_Alloc3DBorderFromObj(interp, tkwin, objPtr);
+		    if (border == NULL) {
+			return TCL_ERROR;
+		    }
+		}
+		if (*(Tk_3DBorder *)ptr != NULL) {
+		    Tk_Free3DBorder(*(Tk_3DBorder *)ptr);
+		}
+		*(Tk_3DBorder *)ptr = border;
+	    }
+	    break;
+
+	case BLT_CONFIG_CAP_STYLE: 
+	    {
+		int cap;
+		Tk_Uid uid;
+		
+		uid = Tk_GetUid(Tcl_GetString(objPtr));
+		if (Tk_GetCapStyle(interp, uid, &cap) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = cap;
+	    }
+	    break;
+
+	case BLT_CONFIG_COLOR: 
+	    {
+		XColor *color;
+		
+		if (objIsEmpty) {
+		    color = NULL;
+		} else {
+		    color = Tk_GetColor(interp, tkwin, 
+			Tk_GetUid(Tcl_GetString(objPtr)));
+		    if (color == NULL) {
+			return TCL_ERROR;
+		    }
+		}
+		if (*(XColor **)ptr != NULL) {
+		    Tk_FreeColor(*(XColor **)ptr);
+		}
+		*(XColor **)ptr = color;
+	    }
+	    break;
+
+	case BLT_CONFIG_CURSOR:
+	case BLT_CONFIG_ACTIVE_CURSOR: 
+	    {
+		Tk_Cursor cursor;
+		
+		if (objIsEmpty) {
+		    cursor = None;
+		} else {
+		    cursor = Tk_AllocCursorFromObj(interp, tkwin, objPtr);
+		    if (cursor == None) {
+			return TCL_ERROR;
+		    }
+		}
+		if (*(Tk_Cursor *)ptr != None) {
+		    Tk_FreeCursor(Tk_Display(tkwin), *(Tk_Cursor *)ptr);
+		}
+		*(Tk_Cursor *)ptr = cursor;
+		if (sp->type == BLT_CONFIG_ACTIVE_CURSOR) {
+		    Tk_DefineCursor(tkwin, cursor);
+		}
+	    }
+	    break;
+
+	case BLT_CONFIG_CUSTOM: 
+	    if ((*sp->customPtr->parseProc)(sp->customPtr->clientData, interp, 
+		tkwin, objPtr, widgRec, sp->offset, sp->specFlags) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+
+	case BLT_CONFIG_DOUBLE: 
+	    {
+		double value;
+		
+		if (Tcl_GetDoubleFromObj(interp, objPtr, &value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(double *)ptr = value;
+	    }
+	    break;
+
+	case BLT_CONFIG_FONT: 
+	    {
+		Blt_Font font;
+		
+		if (objIsEmpty) {
+		    font = NULL;
+		} else {
+		    font = Blt_AllocFontFromObj(interp, tkwin, objPtr);
+		    if (font == NULL) {
+			return TCL_ERROR;
+		    }
+		}
+		if (*(Blt_Font *)ptr != NULL) {
+		    Blt_FreeFont(*(Blt_Font *)ptr);
+		}
+		*(Blt_Font *)ptr = font;
+	    }
+	    break;
+
+	case BLT_CONFIG_TK_FONT: 
+	    {
+		Tk_Font font;
+		
+		if (objIsEmpty) {
+		    font = NULL;
+		} else {
+		    font = Tk_AllocFontFromObj(interp, tkwin, objPtr);
+		    if (font == NULL) {
+			return TCL_ERROR;
+		    }
+		}
+		if (*(Tk_Font *)ptr != NULL) {
+		    Tk_FreeFont(*(Tk_Font *)ptr);
+		}
+		*(Tk_Font *)ptr = font;
+	    }
+	    break;
+
+	case BLT_CONFIG_INT: 
+	    {
+		int value;
+		
+		if (Tcl_GetIntFromObj(interp, objPtr, &value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = value;
+	    }
+	    break;
+
+	case BLT_CONFIG_JOIN_STYLE: 
+	    {
+		int join;
+		Tk_Uid uid;
+
+		uid = Tk_GetUid(Tcl_GetString(objPtr));
+		if (Tk_GetJoinStyle(interp, uid, &join) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = join;
+	    }
+	    break;
+
+	case BLT_CONFIG_JUSTIFY: 
+	    {
+		Tk_Justify justify;
+		
+		if (Tk_GetJustifyFromObj(interp, objPtr, &justify) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(Tk_Justify *)ptr = justify;
+	    }
+	    break;
+
+	case BLT_CONFIG_MM: 
+	    {
+		double value;
+
+		if (Tk_GetMMFromObj(interp, tkwin, objPtr, &value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(double *)ptr = value;
+	    }
+	    break;
+
+
+	case BLT_CONFIG_RELIEF: 
+	    {
+		int relief;
+		
+		if (Tk_GetReliefFromObj(interp, objPtr, &relief) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = relief;
+	    }
+	    break;
+
+	case BLT_CONFIG_STRING: 
+	    {
+		char *value;
+		
+		value = (objIsEmpty) ? NULL : 
+		    Blt_Strdup(Tcl_GetString(objPtr));
+		if (*(char **)ptr != NULL) {
+		    free(*(char **)ptr);
+		    *((char **) ptr) = NULL;
+		}
+		*(char **)ptr = value;
+	    }
+	    break;
+
+	case BLT_CONFIG_WINDOW: 
+	    {
+		Tk_Window tkwin2;
+
+		if (objIsEmpty) {
+		    tkwin2 = None;
+		} else {
+		    const char *path;
+
+		    path = Tcl_GetString(objPtr);
+		    tkwin2 = Tk_NameToWindow(interp, path, tkwin);
+		    if (tkwin2 == NULL) {
+			return TCL_ERROR;
+		    }
+		}
+		*(Tk_Window *)ptr = tkwin2;
+	    }
+	    break;
+
+	case BLT_CONFIG_BITMASK: 
+	    {
+		int bool;
+		unsigned long mask, flags;
+
+		if (Tcl_GetBooleanFromObj(interp, objPtr, &bool) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		mask = (unsigned long)sp->customPtr;
+		flags = *(int *)ptr;
+		flags &= ~mask;
+		if (bool) {
+		    flags |= mask;
+		}
+		*(int *)ptr = flags;
+	    }
+	    break;
+
+	case BLT_CONFIG_BITMASK_INVERT: 
+	    {
+		int bool;
+		unsigned long mask, flags;
+
+		if (Tcl_GetBooleanFromObj(interp, objPtr, &bool) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		mask = (unsigned long)sp->customPtr;
+		flags = *(int *)ptr;
+		flags &= ~mask;
+		if (!bool) {
+		    flags |= mask;
+		}
+		*(int *)ptr = flags;
+	    }
+	    break;
+
+	case BLT_CONFIG_DASHES:
+	    if (Blt_GetDashesFromObj(interp, objPtr, (Blt_Dashes *)ptr) 
+		!= TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+
+
+	case BLT_CONFIG_FILL:
+	    if (Blt_GetFillFromObj(interp, objPtr, (int *)ptr) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+
+	case BLT_CONFIG_FLOAT: 
+	    {
+		double value;
+		
+		if (Tcl_GetDoubleFromObj(interp, objPtr, &value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(float *)ptr = (float)value;
+	    }
+	    break;
+
+	case BLT_CONFIG_INT_NNEG: 
+	    {
+		long value;
+		
+		if (Blt_GetCountFromObj(interp, objPtr, COUNT_NNEG, 
+			&value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = (int)value;
+	    }
+	    break;
+
+
+	case BLT_CONFIG_INT_POS: 
+	    {
+		long value;
+		
+		if (Blt_GetCountFromObj(interp, objPtr, COUNT_POS, &value) 
+		    != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = (int)value;
+	    }
+	    break;
+
+
+	case BLT_CONFIG_LIST: 
+	    {
+		const char **argv;
+		int argc;
+		
+		if (Tcl_SplitList(interp, Tcl_GetString(objPtr), &argc, &argv) 
+		    != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		if (*(char ***)ptr != NULL) {
+		  Tcl_Free((void*)(*(char ***)ptr));
+		    *((char ***) ptr) = NULL;
+		}
+		*(const char ***)ptr = argv;
+	    }
+	    break;
+
+	case BLT_CONFIG_LONG: 
+	    {
+		long value;
+		
+	        if (Tcl_GetLongFromObj(interp, objPtr, &value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(long *)ptr = value;
+	    }
+	    break;
+
+	case BLT_CONFIG_LONG_NNEG: 
+	    {
+		long value;
+		
+		if (Blt_GetCountFromObj(interp, objPtr, COUNT_NNEG, 
+			&value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(long *)ptr = value;
+	    }
+	    break;
+
+
+	case BLT_CONFIG_LONG_POS: 
+	    {
+		long value;
+		
+		if (Blt_GetCountFromObj(interp, objPtr, COUNT_POS, &value) 
+		    != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(long *)ptr = value;
+	    }
+	    break;
+
+	case BLT_CONFIG_OBJ: 
+	    {
+		Tcl_IncrRefCount(objPtr);
+		if (*(Tcl_Obj **)ptr != NULL) {
+		    Tcl_DecrRefCount(*(Tcl_Obj **)ptr);
+		}
+		*(Tcl_Obj **)ptr = objPtr;
+	    }
+	    break;
+
+	case BLT_CONFIG_PAD:
+	    if (Blt_GetPadFromObj(interp, tkwin, objPtr, (Blt_Pad *)ptr) 
+		!= TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+
+	case BLT_CONFIG_PIXELS_NNEG: 
+	    {
+		int value;
+		
+		if (Blt_GetPixelsFromObj(interp, tkwin, objPtr, 
+			PIXELS_NNEG, &value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = value;
+	    }
+	    break;
+
+	case BLT_CONFIG_PIXELS: 
+	    {
+		int value;
+		
+		if (Blt_GetPixelsFromObj(interp, tkwin, objPtr, PIXELS_ANY, 
+			&value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = value;
+	    }
+	    break;
+
+	case BLT_CONFIG_PIXELS_POS: 
+	    {
+		int value;
+		
+		if (Blt_GetPixelsFromObj(interp, tkwin, objPtr, PIXELS_POS,
+			&value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = value;
+	    }
+	    break;
+
+	case BLT_CONFIG_STATE: 
+	    if (Blt_GetStateFromObj(interp, objPtr, (int *)ptr) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+
+	case BLT_CONFIG_SIDE:
+	    if (Blt_GetSideFromObj(interp, objPtr, (int *)ptr) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+
+	case BLT_CONFIG_BACKGROUND: 
+	    {
+		Blt_Background style;
+		
+		if (objIsEmpty) {
+		    style = NULL;
+		} else {
+		    style = Blt_GetBackgroundFromObj(interp, tkwin, objPtr);
+		    if (style == NULL) {
+			return TCL_ERROR;
+		    }
+		}
+		if (*(Blt_Background *)ptr != NULL) {
+		    Blt_FreeBackground(*(Blt_Background *)ptr);
+		}
+		*(Blt_Background *)ptr = style;
+	    }
+	    break;
+
+	default: 
+	    Tcl_AppendResult(interp, "bad config table: unknown type ", 
+			     Blt_Itoa(sp->type), (char *)NULL);
+	    return TCL_ERROR;
+	}
+	sp++;
+    } while ((sp->switchName == NULL) && (sp->type != BLT_CONFIG_END));
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FormatConfigValue --
+ *
+ *	This procedure formats the current value of a configuration
+ *	option.
+ *
+ * Results:
+ *	The return value is the formatted value of the option given
+ *	by specPtr and widgRec.  If the value is static, so that it
+ *	need not be freed, *freeProcPtr will be set to NULL;  otherwise
+ *	*freeProcPtr will be set to the address of a procedure to
+ *	free the result, and the caller must invoke this procedure
+ *	when it is finished with the result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Tcl_Obj *
+FormatConfigValue(
+    Tcl_Interp *interp,		/* Interpreter for use in real conversions. */
+    Tk_Window tkwin,		/* Window corresponding to widget. */
+    Blt_ConfigSpec *sp,		/* Pointer to information describing option.
+				 * Must not point to a synonym option. */
+    char *widgRec)		/* Pointer to record holding current
+				 * values of info for widget. */
+{
+    char *ptr;
+    const char *string;
+
+    ptr = widgRec + sp->offset;
+    string = "";
+    switch (sp->type) {
+    case BLT_CONFIG_ANCHOR:
+	string = Tk_NameOfAnchor(*(Tk_Anchor *)ptr);
+	break;
+
+    case BLT_CONFIG_BITMAP: 
+	if (*(Pixmap *)ptr != None) {
+	    string = Tk_NameOfBitmap(Tk_Display(tkwin), *(Pixmap *)ptr);
+	}
+	break;
+
+    case BLT_CONFIG_BOOLEAN: 
+	return Tcl_NewBooleanObj(*(int *)ptr);
+
+    case BLT_CONFIG_BORDER: 
+	if (*(Tk_3DBorder *)ptr != NULL) {
+	    string = Tk_NameOf3DBorder(*(Tk_3DBorder *)ptr);
+	}
+	break;
+
+    case BLT_CONFIG_CAP_STYLE:
+	string = Tk_NameOfCapStyle(*(int *)ptr);
+	break;
+
+    case BLT_CONFIG_COLOR: 
+	if (*(XColor **)ptr != NULL) {
+	    string = Tk_NameOfColor(*(XColor **)ptr);
+	}
+	break;
+
+    case BLT_CONFIG_CURSOR:
+    case BLT_CONFIG_ACTIVE_CURSOR:
+	if (*(Tk_Cursor *)ptr != None) {
+	    string = Tk_NameOfCursor(Tk_Display(tkwin), *(Tk_Cursor *)ptr);
+	}
+	break;
+
+    case BLT_CONFIG_CUSTOM:
+	return (*sp->customPtr->printProc)
+		(sp->customPtr->clientData, interp, tkwin, widgRec, 
+		sp->offset, sp->specFlags);
+
+    case BLT_CONFIG_DOUBLE: 
+	return Tcl_NewDoubleObj(*(double *)ptr);
+
+    case BLT_CONFIG_FONT: 
+	if (*(Blt_Font *)ptr != NULL) {
+	    string = Blt_NameOfFont(*(Blt_Font *)ptr);
+	}
+	break;
+
+    case BLT_CONFIG_TK_FONT: 
+	if (*(Tk_Font *)ptr != NULL) {
+	    string = Tk_NameOfFont(*(Tk_Font *)ptr);
+	}
+	break;
+
+    case BLT_CONFIG_INT: 
+	return Tcl_NewIntObj(*(int *)ptr);
+
+    case BLT_CONFIG_JOIN_STYLE:
+	string = Tk_NameOfJoinStyle(*(int *)ptr);
+	break;
+
+    case BLT_CONFIG_JUSTIFY:
+	string = Tk_NameOfJustify(*(Tk_Justify *)ptr);
+	break;
+
+    case BLT_CONFIG_MM:
+	return Tcl_NewDoubleObj(*(double *)ptr);
+
+    case BLT_CONFIG_PIXELS: 
+    case BLT_CONFIG_PIXELS_POS: 
+    case BLT_CONFIG_PIXELS_NNEG: 
+	return Tcl_NewIntObj(*(int *)ptr);
+
+    case BLT_CONFIG_RELIEF: 
+	string = Tk_NameOfRelief(*(int *)ptr);
+	break;
+
+    case BLT_CONFIG_STRING: 
+	if (*(char **)ptr != NULL) {
+	    string = *(char **)ptr;
+	}
+	break;
+
+    case BLT_CONFIG_BITMASK:
+	{
+	    unsigned long flag;
+
+	    flag = (*(unsigned long *)ptr) & (unsigned long)sp->customPtr;
+	    return Tcl_NewBooleanObj((flag != 0));
+	}
+
+    case BLT_CONFIG_BITMASK_INVERT:
+	{
+	    unsigned long flag;
+
+	    flag = (*(unsigned long *)ptr) & (unsigned long)sp->customPtr;
+	    return Tcl_NewBooleanObj((flag == 0));
+	}
+
+    case BLT_CONFIG_DASHES: 
+	{
+	    unsigned char *p;
+	    Tcl_Obj *listObjPtr;
+	    Blt_Dashes *dashesPtr = (Blt_Dashes *)ptr;
+	    
+	    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	    for(p = dashesPtr->values; *p != 0; p++) {
+		Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(*p));
+	    }
+	    return listObjPtr;
+	}
+
+    case BLT_CONFIG_INT_NNEG:
+    case BLT_CONFIG_INT_POS:
+	return Tcl_NewIntObj(*(int *)ptr);
+
+    case BLT_CONFIG_FILL: 
+	string = Blt_NameOfFill(*(int *)ptr);
+	break;
+
+    case BLT_CONFIG_FLOAT: 
+	{
+	    double x = *(float *)ptr;
+	    return Tcl_NewDoubleObj(x);
+	}
+
+    case BLT_CONFIG_LIST: 
+	{
+	    Tcl_Obj *objPtr, *listObjPtr;
+	    char *const *p;
+	    
+	    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	    for (p = *(char ***)ptr; *p != NULL; p++) {
+		objPtr = Tcl_NewStringObj(*p, -1);
+		Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	    }
+	    return listObjPtr;
+	}
+
+    case BLT_CONFIG_LONG: 
+	return Tcl_NewLongObj(*(long *)ptr);
+
+    case BLT_CONFIG_LONG_NNEG:
+    case BLT_CONFIG_LONG_POS:
+	return Tcl_NewLongObj(*(long *)ptr);
+
+    case BLT_CONFIG_OBJ:
+	if (*(Tcl_Obj **)ptr != NULL) {
+	    return *(Tcl_Obj **)ptr;
+	}
+	break;
+
+    case BLT_CONFIG_PAD: 
+	{
+	    Blt_Pad *padPtr = (Blt_Pad *)ptr;
+	    Tcl_Obj *objPtr, *listObjPtr;
+	    
+	    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	    objPtr = Tcl_NewIntObj(padPtr->side1);
+	    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	    objPtr = Tcl_NewIntObj(padPtr->side2);
+	    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	    return listObjPtr;
+	}
+
+    case BLT_CONFIG_STATE: 
+	string = Blt_NameOfState(*(int *)ptr);
+	break;
+
+    case BLT_CONFIG_SIDE: 
+	string = Blt_NameOfSide(*(int *)ptr);
+	break;
+
+    case BLT_CONFIG_BACKGROUND: 
+	if (*(Blt_Background *)ptr != NULL) {
+	    string = Blt_NameOfBackground(*(Blt_Background *)ptr);
+	}
+	break;
+
+    default: 
+	string = "?? unknown type ??";
+    }
+    return Tcl_NewStringObj(string, -1);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FormatConfigInfo --
+ *
+ *	Create a valid TCL list holding the configuration information
+ *	for a single configuration option.
+ *
+ * Results:
+ *	A TCL list, dynamically allocated.  The caller is expected to
+ *	arrange for this list to be freed eventually.
+ *
+ * Side effects:
+ *	Memory is allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Tcl_Obj *
+FormatConfigInfo(
+    Tcl_Interp *interp,		/* Interpreter to use for things
+				 * like floating-point precision. */
+    Tk_Window tkwin,		/* Window corresponding to widget. */
+    Blt_ConfigSpec *sp,		/* Pointer to information describing
+				 * option. */
+    char *widgRec)		/* Pointer to record holding current
+				 * values of info for widget. */
+{
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if (sp->switchName != NULL) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj(sp->switchName, -1));
+    }  else {
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1));
+    }
+    if (sp->dbName != NULL) {
+	Tcl_ListObjAppendElement(interp, listObjPtr,  
+		Tcl_NewStringObj(sp->dbName, -1));
+    } else {
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1));
+    }
+    if (sp->type == BLT_CONFIG_SYNONYM) {
+	return listObjPtr;
+    } 
+    if (sp->dbClass != NULL) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj(sp->dbClass, -1));
+    } else {
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1));
+    }
+    if (sp->defValue != NULL) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj(sp->defValue, -1));
+    } else {
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1));
+    }
+    Tcl_ListObjAppendElement(interp, listObjPtr, 
+	FormatConfigValue(interp, tkwin, sp, widgRec));
+    return listObjPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FindConfigSpec --
+ *
+ *	Search through a table of configuration specs, looking for
+ *	one that matches a given switchName.
+ *
+ * Results:
+ *	The return value is a pointer to the matching entry, or NULL
+ *	if nothing matched.  In that case an error message is left
+ *	in the interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_ConfigSpec *
+FindConfigSpec(
+    Tcl_Interp *interp,		/* Used for reporting errors. */
+    Blt_ConfigSpec *specs,	/* Pointer to table of configuration
+				 * specifications for a widget. */
+    Tcl_Obj *objPtr,		/* Name (suitable for use in a "config"
+				 * command) identifying particular option. */
+    int needFlags,		/* Flags that must be present in matching
+				 * entry. */
+    int hateFlags)		/* Flags that must NOT be present in
+				 * matching entry. */
+{
+    Blt_ConfigSpec *matchPtr;	/* Matching spec, or NULL. */
+    Blt_ConfigSpec *sp;
+    const char *string;
+    char c;			/* First character of current argument. */
+    int length;
+
+    string = Tcl_GetStringFromObj(objPtr, &length);
+    c = string[1];
+    matchPtr = NULL;
+    for (sp = specs; sp->type != BLT_CONFIG_END; sp++) {
+	if (sp->switchName == NULL) {
+	    continue;
+	}
+	if ((sp->switchName[1] != c) || 
+	    (strncmp(sp->switchName, string, length) != 0)) {
+	    continue;
+	}
+	if (((sp->specFlags & needFlags) != needFlags) || 
+	    (sp->specFlags & hateFlags)) {
+	    continue;
+	}
+	if (sp->switchName[length] == 0) {
+	    matchPtr = sp;
+	    goto gotMatch;
+	}
+	if (matchPtr != NULL) {
+	    if (interp != NULL) {
+	        Tcl_AppendResult(interp, "ambiguous option \"", string, "\"", 
+			(char *)NULL);
+            }
+	    return (Blt_ConfigSpec *)NULL;
+	}
+	matchPtr = sp;
+    }
+
+    if (matchPtr == NULL) {
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "unknown option \"", string, "\"", 
+		(char *)NULL);
+	}
+	return (Blt_ConfigSpec *)NULL;
+    }
+
+    /*
+     * Found a matching entry.  If it's a synonym, then find the
+     * entry that it's a synonym for.
+     */
+
+ gotMatch:
+    sp = matchPtr;
+    if (sp->type == BLT_CONFIG_SYNONYM) {
+	for (sp = specs; /*empty*/; sp++) {
+	    if (sp->type == BLT_CONFIG_END) {
+		if (interp != NULL) {
+   		    Tcl_AppendResult(interp, 
+			"couldn't find synonym for option \"", string, "\"", 
+			(char *)NULL);
+		}
+		return (Blt_ConfigSpec *) NULL;
+	    }
+	    if ((sp->dbName == matchPtr->dbName) && 
+		(sp->type != BLT_CONFIG_SYNONYM) && 
+		((sp->specFlags & needFlags) == needFlags) && 
+		!(sp->specFlags & hateFlags)) {
+		break;
+	    }
+	}
+    }
+    return sp;
+}
+
+/* Public routines */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ConfigureWidgetFromObj --
+ *
+ *	Process command-line options and database options to
+ *	fill in fields of a widget record with resources and
+ *	other parameters.
+ *
+ * Results:
+ *	A standard TCL return value.  In case of an error,
+ *	the interp's result will hold an error message.
+ *
+ * Side effects:
+ *	The fields of widgRec get filled in with information
+ *	from argc/argv and the option database.  Old information
+ *	in widgRec's fields gets recycled.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_ConfigureWidgetFromObj(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    Tk_Window tkwin,		/* Window containing widget (needed to
+				 * set up X resources). */
+    Blt_ConfigSpec *specs,	/* Describes legal options. */
+    int objc,			/* Number of elements in argv. */
+    Tcl_Obj *const *objv,	/* Command-line options. */
+    char *widgRec,		/* Record whose fields are to be
+				 * modified.  Values must be properly
+				 * initialized. */
+    int flags)			/* Used to specify additional flags
+				 * that must be present in config specs
+				 * for them to be considered.  Also,
+				 * may have BLT_CONFIG_OBJV_ONLY set. */
+{
+    Blt_ConfigSpec *sp;
+    int needFlags;		/* Specs must contain this set of flags
+				 * or else they are not considered. */
+    int hateFlags;		/* If a spec contains any bits here, it's
+				 * not considered. */
+    int result;
+
+    if (tkwin == NULL) {
+	/*
+	 * Either we're not really in Tk, or the main window was destroyed and
+	 * we're on our way out of the application
+	 */
+	Tcl_AppendResult(interp, "NULL main window", (char *)NULL);
+	return TCL_ERROR;
+    }
+
+    needFlags = flags & ~(BLT_CONFIG_USER_BIT - 1);
+    if (Tk_Depth(tkwin) <= 1) {
+	hateFlags = BLT_CONFIG_COLOR_ONLY;
+    } else {
+	hateFlags = BLT_CONFIG_MONO_ONLY;
+    }
+
+    /*
+     * Pass one:  scan through all the option specs, replacing strings
+     * with Tk_Uid structs (if this hasn't been done already) and
+     * clearing the BLT_CONFIG_OPTION_SPECIFIED flags.
+     */
+
+    for (sp = specs; sp->type != BLT_CONFIG_END; sp++) {
+	if (!(sp->specFlags & INIT) && (sp->switchName != NULL)) {
+	    if (sp->dbName != NULL) {
+		sp->dbName = Tk_GetUid(sp->dbName);
+	    }
+	    if (sp->dbClass != NULL) {
+		sp->dbClass = Tk_GetUid(sp->dbClass);
+	    }
+	    if (sp->defValue != NULL) {
+		sp->defValue = Tk_GetUid(sp->defValue);
+	    }
+	}
+	sp->specFlags = (sp->specFlags & ~BLT_CONFIG_OPTION_SPECIFIED) | INIT;
+    }
+
+    /*
+     * Pass two:  scan through all of the arguments, processing those
+     * that match entries in the specs.
+     */
+    while (objc > 0) {
+	sp = FindConfigSpec(interp, specs, objv[0], needFlags, hateFlags);
+	if (sp == NULL) {
+	    return TCL_ERROR;
+	}
+
+	/* Process the entry.  */
+	if (objc < 2) {
+	    Tcl_AppendResult(interp, "value for \"", Tcl_GetString(objv[0]),
+		    "\" missing", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	if (DoConfig(interp, tkwin, sp, objv[1], widgRec) != TCL_OK) {
+	    char msg[100];
+
+	    sprintf_s(msg, 100, "\n    (processing \"%.40s\" option)",
+		    sp->switchName);
+	    Tcl_AddErrorInfo(interp, msg);
+	    return TCL_ERROR;
+	}
+	sp->specFlags |= BLT_CONFIG_OPTION_SPECIFIED;
+	objc -= 2, objv += 2;
+    }
+
+    /*
+     * Pass three:  scan through all of the specs again;  if no
+     * command-line argument matched a spec, then check for info
+     * in the option database.  If there was nothing in the
+     * database, then use the default.
+     */
+
+    if ((flags & BLT_CONFIG_OBJV_ONLY) == 0) {
+	Tcl_Obj *objPtr;
+
+	for (sp = specs; sp->type != BLT_CONFIG_END; sp++) {
+	    if ((sp->specFlags & BLT_CONFIG_OPTION_SPECIFIED) || 
+		(sp->switchName == NULL) || (sp->type == BLT_CONFIG_SYNONYM)) {
+		continue;
+	    }
+	    if (((sp->specFlags & needFlags) != needFlags) || 
+		(sp->specFlags & hateFlags)) {
+		continue;
+	    }
+	    objPtr = NULL;
+	    if (sp->dbName != NULL) {
+		Tk_Uid value;
+
+		/* If a resource name was specified, check if there's
+		 * also a value was associated with it.  This
+		 * overrides the default value. */
+		value = Tk_GetOption(tkwin, sp->dbName, sp->dbClass);
+		if (value != NULL) {
+		    objPtr = Tcl_NewStringObj(value, -1);
+		}
+	    }
+
+	    if (objPtr != NULL) {
+		Tcl_IncrRefCount(objPtr);
+		result = DoConfig(interp, tkwin, sp, objPtr, widgRec);
+		Tcl_DecrRefCount(objPtr);
+		if (result != TCL_OK) {
+		    char msg[200];
+    
+		    sprintf_s(msg, 200, 
+			"\n    (%s \"%.50s\" in widget \"%.50s\")",
+			"database entry for", sp->dbName, Tk_PathName(tkwin));
+		    Tcl_AddErrorInfo(interp, msg);
+		    return TCL_ERROR;
+		}
+	    } else if ((sp->defValue != NULL) && 
+		((sp->specFlags & BLT_CONFIG_DONT_SET_DEFAULT) == 0)) {
+
+		/* No resource value is found, use the default value. */
+		objPtr = Tcl_NewStringObj(sp->defValue, -1);
+		Tcl_IncrRefCount(objPtr);
+		result = DoConfig(interp, tkwin, sp, objPtr, widgRec);
+		Tcl_DecrRefCount(objPtr);
+		if (result != TCL_OK) {
+		    char msg[200];
+		    
+		    sprintf_s(msg, 200, 
+			"\n    (%s \"%.50s\" in widget \"%.50s\")",
+			"default value for", sp->dbName, Tk_PathName(tkwin));
+		    Tcl_AddErrorInfo(interp, msg);
+		    return TCL_ERROR;
+		}
+	    }
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ConfigureInfoFromObj --
+ *
+ *	Return information about the configuration options
+ *	for a window, and their current values.
+ *
+ * Results:
+ *	Always returns TCL_OK.  The interp's result will be modified
+ *	hold a description of either a single configuration option
+ *	available for "widgRec" via "specs", or all the configuration
+ *	options available.  In the "all" case, the result will
+ *	available for "widgRec" via "specs".  The result will
+ *	be a list, each of whose entries describes one option.
+ *	Each entry will itself be a list containing the option's
+ *	name for use on command lines, database name, database
+ *	class, default value, and current value (empty string
+ *	if none).  For options that are synonyms, the list will
+ *	contain only two values:  name and synonym name.  If the
+ *	"name" argument is non-NULL, then the only information
+ *	returned is that for the named argument (i.e. the corresponding
+ *	entry in the overall list is returned).
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Blt_ConfigureInfoFromObj(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    Tk_Window tkwin,		/* Window corresponding to widgRec. */
+    Blt_ConfigSpec *specs,	/* Describes legal options. */
+    char *widgRec,		/* Record whose fields contain current
+				 * values for options. */
+    Tcl_Obj *objPtr,		/* If non-NULL, indicates a single option
+				 * whose info is to be returned.  Otherwise
+				 * info is returned for all options. */
+    int flags)			/* Used to specify additional flags
+				 * that must be present in config specs
+				 * for them to be considered. */
+{
+    Blt_ConfigSpec *sp;
+    Tcl_Obj *listObjPtr, *valueObjPtr;
+    const char *string;
+    int needFlags, hateFlags;
+
+    needFlags = flags & ~(BLT_CONFIG_USER_BIT - 1);
+    if (Tk_Depth(tkwin) <= 1) {
+	hateFlags = BLT_CONFIG_COLOR_ONLY;
+    } else {
+	hateFlags = BLT_CONFIG_MONO_ONLY;
+    }
+
+    /*
+     * If information is only wanted for a single configuration
+     * spec, then handle that one spec specially.
+     */
+
+    Tcl_SetResult(interp, (char *)NULL, TCL_STATIC);
+    if (objPtr != NULL) {
+	sp = FindConfigSpec(interp, specs, objPtr, needFlags, hateFlags);
+	if (sp == NULL) {
+	    return TCL_ERROR;
+	}
+	valueObjPtr =  FormatConfigInfo(interp, tkwin, sp, widgRec);
+	Tcl_SetObjResult(interp, valueObjPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * Loop through all the specs, creating a big list with all
+     * their information.
+     */
+    string = NULL;		/* Suppress compiler warning. */
+    if (objPtr != NULL) {
+	string = Tcl_GetString(objPtr);
+    }
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    for (sp = specs; sp->type != BLT_CONFIG_END; sp++) {
+	if ((objPtr != NULL) && (sp->switchName != string)) {
+	    continue;
+	}
+	if (((sp->specFlags & needFlags) != needFlags) || 
+	    (sp->specFlags & hateFlags)) {
+	    continue;
+	}
+	if (sp->switchName == NULL) {
+	    continue;
+	}
+	valueObjPtr = FormatConfigInfo(interp, tkwin, sp, widgRec);
+	Tcl_ListObjAppendElement(interp, listObjPtr, valueObjPtr);
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ConfigureValueFromObj --
+ *
+ *	This procedure returns the current value of a configuration
+ *	option for a widget.
+ *
+ * Results:
+ *	The return value is a standard TCL completion code (TCL_OK or
+ *	TCL_ERROR).  The interp's result will be set to hold either the value
+ *	of the option given by objPtr (if TCL_OK is returned) or
+ *	an error message (if TCL_ERROR is returned).
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_ConfigureValueFromObj(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    Tk_Window tkwin,		/* Window corresponding to widgRec. */
+    Blt_ConfigSpec *specs,	/* Describes legal options. */
+    char *widgRec,		/* Record whose fields contain current
+				 * values for options. */
+    Tcl_Obj *objPtr,		/* Gives the command-line name for the
+				 * option whose value is to be returned. */
+    int flags)			/* Used to specify additional flags
+				 * that must be present in config specs
+				 * for them to be considered. */
+{
+    Blt_ConfigSpec *sp;
+    int needFlags, hateFlags;
+
+    needFlags = flags & ~(BLT_CONFIG_USER_BIT - 1);
+    if (Tk_Depth(tkwin) <= 1) {
+	hateFlags = BLT_CONFIG_COLOR_ONLY;
+    } else {
+	hateFlags = BLT_CONFIG_MONO_ONLY;
+    }
+    sp = FindConfigSpec(interp, specs, objPtr, needFlags, hateFlags);
+    if (sp == NULL) {
+	return TCL_ERROR;
+    }
+    objPtr = FormatConfigValue(interp, tkwin, sp, widgRec);
+    Tcl_SetObjResult(interp, objPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FreeOptions --
+ *
+ *	Free up all resources associated with configuration options.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Any resource in widgRec that is controlled by a configuration
+ *	option (e.g. a Tk_3DBorder or XColor) is freed in the appropriate
+ *	fashion.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_FreeOptions(
+    Blt_ConfigSpec *specs,	/* Describes legal options. */
+    char *widgRec,		/* Record whose fields contain current
+				 * values for options. */
+    Display *display,		/* X display; needed for freeing some
+				 * resources. */
+    int needFlags)		/* Used to specify additional flags
+				 * that must be present in config specs
+				 * for them to be considered. */
+{
+    Blt_ConfigSpec *sp;
+
+    for (sp = specs; sp->type != BLT_CONFIG_END; sp++) {
+	char *ptr;
+
+	if ((sp->specFlags & needFlags) != needFlags) {
+	    continue;
+	}
+	ptr = widgRec + sp->offset;
+	switch (sp->type) {
+	case BLT_CONFIG_STRING:
+	    if (*((char **) ptr) != NULL) {
+		free(*((char **) ptr));
+		*((char **) ptr) = NULL;
+	    }
+	    break;
+
+	case BLT_CONFIG_COLOR:
+	    if (*((XColor **) ptr) != NULL) {
+		Tk_FreeColor(*((XColor **) ptr));
+		*((XColor **) ptr) = NULL;
+	    }
+	    break;
+
+	case BLT_CONFIG_FONT:
+	    if (*((Blt_Font *) ptr) != None) {
+	        Blt_FreeFont(*((Blt_Font *) ptr));
+  	        *((Blt_Font *) ptr) = NULL;
+            }
+	    break;
+
+	case BLT_CONFIG_TK_FONT:
+	    if (*((Tk_Font *) ptr) != None) {
+	        Tk_FreeFont(*((Tk_Font *) ptr));
+  	        *((Tk_Font *) ptr) = NULL;
+            }
+	    break;
+
+	case BLT_CONFIG_BITMAP:
+	    if (*((Pixmap *) ptr) != None) {
+		Tk_FreeBitmap(display, *((Pixmap *) ptr));
+		*((Pixmap *) ptr) = None;
+	    }
+	    break;
+
+	case BLT_CONFIG_BORDER:
+	    if (*((Tk_3DBorder *) ptr) != NULL) {
+		Tk_Free3DBorder(*((Tk_3DBorder *) ptr));
+		*((Tk_3DBorder *) ptr) = NULL;
+	    }
+	    break;
+
+	case BLT_CONFIG_CURSOR:
+	case BLT_CONFIG_ACTIVE_CURSOR:
+	    if (*((Tk_Cursor *) ptr) != None) {
+		Tk_FreeCursor(display, *((Tk_Cursor *) ptr));
+		*((Tk_Cursor *) ptr) = None;
+	    }
+	    break;
+
+	case BLT_CONFIG_OBJ:
+	    if (*(Tcl_Obj **)ptr != NULL) {
+		Tcl_DecrRefCount(*(Tcl_Obj **)ptr);
+		*(Tcl_Obj **)ptr = NULL;
+	    }
+	    break;
+
+	case BLT_CONFIG_LIST:
+	    if (*((char ***) ptr) != NULL) {
+	      Tcl_Free((void*)(*((char ***) ptr)));
+		*((char ***) ptr) = NULL;
+	    }
+	    break;
+
+	case BLT_CONFIG_BACKGROUND:
+	    if (*((Blt_Background *)ptr) != NULL) {
+		Blt_FreeBackground(*((Blt_Background *)ptr));
+		*((Blt_Background *)ptr) = NULL;
+	    }
+	    break;
+
+	case BLT_CONFIG_CUSTOM:
+	    if ((sp->customPtr->freeProc != NULL) && (*(char **)ptr != NULL)) {
+		(*sp->customPtr->freeProc)(sp->customPtr->clientData,
+			display, widgRec, sp->offset);
+	    }
+	    break;
+
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ConfigModified --
+ *
+ *      Given the configuration specifications and one or more option
+ *	patterns (terminated by a NULL), indicate if any of the matching
+ *	configuration options has been reset.
+ *
+ * Results:
+ *      Returns 1 if one of the options has changed, 0 otherwise.
+ *
+ *---------------------------------------------------------------------------
+ */
+int 
+Blt_ConfigModified TCL_VARARGS_DEF(Blt_ConfigSpec *, arg1)
+{
+    va_list argList;
+    Blt_ConfigSpec *specs;
+    Blt_ConfigSpec *sp;
+    const char *option;
+
+    specs = TCL_VARARGS_START(Blt_ConfigSpec *, arg1, argList);
+    while ((option = va_arg(argList, const char *)) != NULL) {
+	for (sp = specs; sp->type != BLT_CONFIG_END; sp++) {
+	    if ((Tcl_StringMatch(sp->switchName, option)) &&
+		(sp->specFlags & BLT_CONFIG_OPTION_SPECIFIED)) {
+		va_end(argList);
+		return 1;
+	    }
+	}
+    }
+    va_end(argList);
+    return 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ConfigureComponentFromObj --
+ *
+ *	Configures a component of a widget.  This is useful for
+ *	widgets that have multiple components which aren't uniquely
+ *	identified by a Tk_Window. It allows us, for example, set
+ *	resources for axes of the graph widget. The graph really has
+ *	only one window, but its convenient to specify components in a
+ *	hierarchy of options.
+ *
+ *		*graph.x.logScale yes
+ *		*graph.Axis.logScale yes
+ *		*graph.temperature.scaleSymbols yes
+ *		*graph.Element.scaleSymbols yes
+ *
+ *	This is really a hack to work around the limitations of the Tk
+ *	resource database.  It creates a temporary window, needed to
+ *	call Tk_ConfigureWidget, using the name of the component.
+ *
+ * Results:
+ *      A standard TCL result.
+ *
+ * Side Effects:
+ *	A temporary window is created merely to pass to Tk_ConfigureWidget.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_ConfigureComponentFromObj(
+    Tcl_Interp *interp,
+    Tk_Window parent,		/* Window to associate with component */
+    const char *name,		/* Name of component */
+    const char *className,
+    Blt_ConfigSpec *sp,
+    int objc,
+    Tcl_Obj *const *objv,
+    char *widgRec,
+    int flags)
+{
+    Tk_Window tkwin;
+    int result;
+    char *tmpName;
+    int isTemporary = FALSE;
+
+    tmpName = Blt_Strdup(name);
+
+    /* Window name can't start with an upper case letter */
+    tmpName[0] = tolower(name[0]);
+
+    /*
+     * Create component if a child window by the component's name
+     * doesn't already exist.
+     */
+    tkwin = Blt_FindChild(parent, tmpName);
+    if (tkwin == NULL) {
+	tkwin = Tk_CreateWindow(interp, parent, tmpName, (char *)NULL);
+	isTemporary = TRUE;
+    }
+    if (tkwin == NULL) {
+	Tcl_AppendResult(interp, "can't find window in \"", 
+			 Tk_PathName(parent), "\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    assert(Tk_Depth(tkwin) == Tk_Depth(parent));
+    free(tmpName);
+
+    Tk_SetClass(tkwin, className);
+    result = Blt_ConfigureWidgetFromObj(interp, tkwin, sp, objc, objv, widgRec,
+	flags);
+    if (isTemporary) {
+	Tk_DestroyWindow(tkwin);
+    }
+    return result;
+}
diff --git a/tlt3.0/bltConfig.h b/tlt3.0/bltConfig.h
new file mode 100644
index 0000000..aca0e62
--- /dev/null
+++ b/tlt3.0/bltConfig.h
@@ -0,0 +1,326 @@
+/* 
+ * bltConfig.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef BLT_CONFIG_H
+#define BLT_CONFIG_H
+
+#ifndef Blt_Offset
+#ifdef offsetof
+#define Blt_Offset(type, field) ((int) offsetof(type, field))
+#else
+#define Blt_Offset(type, field) ((int) ((char *) &((type *) 0)->field))
+#endif
+#endif /* Blt_Offset */
+
+typedef int (Blt_OptionParseProc)(ClientData clientData, Tcl_Interp *interp, 
+	Tk_Window tkwin, Tcl_Obj *objPtr, char *widgRec, int offset, int flags);
+typedef Tcl_Obj *(Blt_OptionPrintProc)(ClientData clientData, 
+	Tcl_Interp *interp, Tk_Window tkwin, char *widgRec, int offset, 
+	int flags);
+typedef void (Blt_OptionFreeProc)(ClientData clientData, Display *display, 
+	char *widgRec, int offset);
+
+typedef struct Blt_CustomOption {
+    Blt_OptionParseProc *parseProc;	/* Procedure to call to parse
+					 * an option and store it in
+					 * converted form. */
+
+    Blt_OptionPrintProc *printProc;	/* Procedure to return a
+					 * Tcl_Obj representing an
+					 * existing option value. */
+
+    Blt_OptionFreeProc *freeProc;	/* Procedure used to free the
+					 * value. */
+
+    ClientData clientData;		/* Arbitrary one-word value
+					 * used by option parser:
+					 * passed to parseProc and
+					 * printProc. */
+} Blt_CustomOption;
+
+/*
+ * Structure used to specify information for Tk_ConfigureWidget.  Each
+ * structure gives complete information for one option, including
+ * how the option is specified on the command line, where it appears
+ * in the option database, etc.
+ */
+
+typedef struct {
+    int type;			/* Type of option, such as
+				 * BLT_CONFIG_COLOR; see definitions
+				 * below.  Last option in table must
+				 * have type BLT_CONFIG_END. */
+
+    const char *switchName;	/* Switch used to specify option in
+				 * argv.  NULL means this spec is part
+				 * of a group. */
+
+    Tk_Uid dbName;		/* Name for option in option
+				 * database. */
+
+    Tk_Uid dbClass;		/* Class for option in database. */
+
+    Tk_Uid defValue;		/* Default value for option if not
+				 * specified in command line or
+				 * database. */
+
+    int offset;			/* Where in widget record to store
+				 * value; use Blt_Offset macro to
+				 * generate values for this. */
+
+    int specFlags;		/* Any combination of the values
+				 * defined below; other bits are used
+				 * internally by tkConfig.c. */
+
+    Blt_CustomOption *customPtr; /* If type is BLT_CONFIG_CUSTOM then
+				 * this is a pointer to info about how
+				 * to parse and print the option.
+				 * Otherwise it is irrelevant. */
+} Blt_ConfigSpec;
+
+/*
+ * Type values for Blt_ConfigSpec structures.  See the user
+ * documentation for details.
+ */
+typedef enum {
+    BLT_CONFIG_ACTIVE_CURSOR, 
+    BLT_CONFIG_ANCHOR, 
+    BLT_CONFIG_BITMAP,
+    BLT_CONFIG_BOOLEAN, 
+    BLT_CONFIG_BORDER, 
+    BLT_CONFIG_CAP_STYLE, 
+    BLT_CONFIG_COLOR, 
+    BLT_CONFIG_CURSOR, 
+    BLT_CONFIG_CUSTOM, 
+    BLT_CONFIG_DOUBLE, 
+    BLT_CONFIG_FONT, 
+    BLT_CONFIG_INT, 
+    BLT_CONFIG_JOIN_STYLE,
+    BLT_CONFIG_JUSTIFY, 
+    BLT_CONFIG_MM, 
+    BLT_CONFIG_RELIEF, 
+    BLT_CONFIG_STRING,
+    BLT_CONFIG_SYNONYM, 
+    BLT_CONFIG_WINDOW, 
+
+    BLT_CONFIG_BITMASK,
+    BLT_CONFIG_BITMASK_INVERT,
+    BLT_CONFIG_DASHES,
+    BLT_CONFIG_FILL,
+    BLT_CONFIG_FLOAT, 
+    BLT_CONFIG_INT_NNEG,	/* 0..N */
+    BLT_CONFIG_INT_POS,		/* 1..N */
+    BLT_CONFIG_LIST,
+    BLT_CONFIG_LONG, 
+    BLT_CONFIG_LONG_NNEG,	/* 0..N */
+    BLT_CONFIG_LONG_POS,	/* 1..N */
+    BLT_CONFIG_OBJ,
+    BLT_CONFIG_PAD,
+    BLT_CONFIG_PIXELS_NNEG,	/* 1.1c 2m 3.2i excluding negative
+				   values. */
+    BLT_CONFIG_PIXELS_POS,	/* 1.1c 2m 3.2i excluding negative
+				 * values and zero. */
+    BLT_CONFIG_PIXELS,		/* 1.1c 2m 3.2i. */
+    BLT_CONFIG_SIDE,
+    BLT_CONFIG_STATE, 
+    BLT_CONFIG_BACKGROUND,
+
+    BLT_CONFIG_TK_FONT, 
+    BLT_CONFIG_END
+} Blt_ConfigTypes;
+
+/*
+ * Possible values for flags argument to Tk_ConfigureWidget:
+ */
+#define BLT_CONFIG_OBJV_ONLY	1
+
+/*
+ * Possible flag values for Blt_ConfigSpec structures.  Any bits at or
+ * above BLT_CONFIG_USER_BIT may be used by clients for selecting
+ * certain entries.  Before changing any values here, coordinate with
+ * tkOldConfig.c (internal-use-only flags are defined there).
+ */
+/*
+ * Values for "flags" field of Blt_ConfigSpec structures.  Be sure to
+ * coordinate these values with those defined in tk.h
+ * (BLT_CONFIG_COLOR_ONLY, etc.).  There must not be overlap!
+ *
+ * INIT -		Non-zero means (char *) things have been
+ *			converted to Tk_Uid's.
+ */
+#define INIT				(1<<0)
+#define BLT_CONFIG_NULL_OK		(1<<1)
+#define BLT_CONFIG_COLOR_ONLY		(1<<2)
+#define BLT_CONFIG_MONO_ONLY		(1<<3)
+#define BLT_CONFIG_DONT_SET_DEFAULT	(1<<4)
+#define BLT_CONFIG_OPTION_SPECIFIED	(1<<5)
+#define BLT_CONFIG_USER_BIT		(1<<8)
+
+
+#define SIDE_LEFT		(1<<0)
+#define SIDE_TOP		(1<<1)
+#define SIDE_RIGHT		(1<<2)
+#define SIDE_BOTTOM		(1<<3)
+
+#define STATE_NORMAL		(0)
+#define STATE_ACTIVE		(1<<0)
+#define STATE_DISABLED		(1<<1)
+#define STATE_EMPHASIS		(1<<2)
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Pad --
+ *
+ * 	Specifies vertical and horizontal padding.
+ *
+ *	Padding can be specified on a per side basis.  The fields
+ *	side1 and side2 refer to the opposite sides, either
+ *	horizontally or vertically.
+ *
+ *		side1	side2
+ *              -----   -----
+ *          x | left    right
+ *	    y | top     bottom
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    unsigned short int side1, side2;
+} Blt_Pad;
+
+#define padLeft  	xPad.side1
+#define padRight  	xPad.side2
+#define padTop		yPad.side1
+#define padBottom	yPad.side2
+#define PADDING(x)	((x).side1 + (x).side2)
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * The following enumerated values are used as bit flags.
+ *	FILL_NONE		Neither coordinate plane is specified 
+ *	FILL_X			Horizontal plane.
+ *	FILL_Y			Vertical plane.
+ *	FILL_BOTH		Both vertical and horizontal planes.
+ *
+ *---------------------------------------------------------------------------
+ */
+#define FILL_NONE	0
+#define FILL_X		1
+#define FILL_Y		2
+#define FILL_BOTH	3
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Dashes --
+ *
+ * 	List of dash values (maximum 11 based upon PostScript limit).
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    unsigned char values[12];
+    int offset;
+} Blt_Dashes;
+
+#define LineIsDashed(d) ((d).values[0] != 0)
+
+/*
+ * Blt_Limits --
+ *
+ * 	Defines the bounding of a size (width or height) in the paneset.  It may
+ * 	be related to the widget, pane or paneset size.
+ */
+typedef struct {
+    int flags;				/* Flags indicate whether using default
+					 * values for limits or not. See flags
+					 * below. */
+    int max, min;			/* Values for respective limits. */
+    int nom;				/* Nominal starting value. */
+} Blt_Limits;
+
+#define LIMITS_MIN_SET	(1<<0)
+#define LIMITS_MAX_SET	(1<<1)
+#define LIMITS_NOM_SET	(1<<2)
+
+#define LIMITS_MIN	0		/* Default minimum limit  */
+#define LIMITS_MAX	SHRT_MAX	/* Default maximum limit */
+#define LIMITS_NOM	-1000		/* Default nomimal value.  Indicates
+					 * if a pane has received any space
+					 * yet */
+
+extern void Blt_SetDashes (Display *display, GC gc, Blt_Dashes *dashesPtr);
+extern Blt_Dashes *Blt_GetDashes (GC gc);
+
+extern int Blt_GetLimitsFromObj(Tcl_Interp *interp, Tk_Window tkwin, 
+	Tcl_Obj *objPtr, Blt_Limits *limitsPtr);
+
+extern int Blt_ConfigureInfoFromObj(Tcl_Interp *interp, Tk_Window tkwin, 
+	Blt_ConfigSpec *specs, char *widgRec, Tcl_Obj *objPtr, int flags);
+
+extern int Blt_ConfigureValueFromObj(Tcl_Interp *interp, Tk_Window tkwin, 
+	Blt_ConfigSpec *specs, char *widgRec, Tcl_Obj *objPtr, int flags);
+
+extern int Blt_ConfigureWidgetFromObj(Tcl_Interp *interp, Tk_Window tkwin, 
+	Blt_ConfigSpec *specs, int objc, Tcl_Obj *const *objv, char *widgRec, 
+	int flags);
+
+extern int Blt_ConfigureComponentFromObj(Tcl_Interp *interp, 
+	Tk_Window tkwin, const char *name, const char *className, 
+	Blt_ConfigSpec *specs, int objc, Tcl_Obj *const *objv, char *widgRec, 
+	int flags);
+
+extern int Blt_ConfigModified TCL_VARARGS(Blt_ConfigSpec *, specs);
+
+extern const char *Blt_NameOfState(int state);
+extern const char *Blt_NameOfSide(int side);
+
+extern void Blt_FreeOptions(Blt_ConfigSpec *specs, char *widgRec, 
+	Display *display, int needFlags);
+
+extern int Blt_GetSideFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	int *sidePtr);
+
+extern int Blt_GetPixelsFromObj(Tcl_Interp *interp, Tk_Window tkwin, 
+	Tcl_Obj *objPtr, int flags, int *valuePtr);
+
+extern int Blt_GetPadFromObj(Tcl_Interp *interp, Tk_Window tkwin, 
+	Tcl_Obj *objPtr, Blt_Pad *padPtr);
+
+extern int Blt_GetStateFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	int *statePtr);
+
+extern int Blt_GetFillFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	int *fillPtr);
+
+extern int Blt_GetDashesFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	Blt_Dashes *dashesPtr);
+
+#endif /* BLT_CONFIG_H */
diff --git a/tlt3.0/bltDBuffer.c b/tlt3.0/bltDBuffer.c
new file mode 100644
index 0000000..4a64280
--- /dev/null
+++ b/tlt3.0/bltDBuffer.c
@@ -0,0 +1,323 @@
+
+/*
+ * bltDBuffer.c --
+ *
+ * This module implements a dynamic buffer for the BLT toolkit.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "bltInt.h"
+#include "bltDBuffer.h"
+#include "bltBase64.h"
+
+typedef struct _Blt_DBuffer DBuffer;
+
+void
+Blt_DBuffer_Init(DBuffer *srcPtr)
+{
+    srcPtr->bytes = NULL;
+    srcPtr->cursor = srcPtr->count = srcPtr->nBytes = 0;
+    srcPtr->chunk = 64;
+}
+
+void
+Blt_DBuffer_Free(DBuffer *srcPtr)
+{
+    if ((srcPtr->bytes != NULL) && (srcPtr->nBytes > 0)) {
+	free(srcPtr->bytes);
+	srcPtr->bytes=NULL;
+    }
+    Blt_DBuffer_Init(srcPtr);
+}
+
+Blt_DBuffer
+Blt_DBuffer_Create(void)
+{
+    DBuffer *srcPtr;
+
+    srcPtr = malloc(sizeof(DBuffer));
+    Blt_DBuffer_Init(srcPtr);
+    return srcPtr;
+}
+
+void 
+Blt_DBuffer_Destroy(DBuffer *srcPtr) 
+{
+    Blt_DBuffer_Free(srcPtr);
+    free(srcPtr);
+    srcPtr = NULL;
+}
+
+int
+Blt_DBuffer_Resize(DBuffer *srcPtr, size_t nBytes)
+{
+    if (srcPtr->nBytes <= nBytes) {
+	size_t size, wanted;
+	unsigned char *bytes;
+
+	wanted = nBytes + 1;
+	size = srcPtr->chunk; 
+
+	/* 
+	 * Double the buffer size until we have enough room or hit 64K.  After
+	 * 64K, increase by multiples of 64K.
+	 */
+	while ((size <= wanted) && (size < (1<<16))) {
+	    size += size;
+	}    
+	srcPtr->chunk = size;
+	while (size <= wanted) {
+	    size += srcPtr->chunk;
+	}
+	if (srcPtr->bytes == NULL) {
+ 	    bytes = malloc(size);
+ 	} else {
+	    bytes = realloc(srcPtr->bytes, size);
+	}
+	if (bytes == NULL) {
+	    return FALSE;
+ 	}
+	srcPtr->bytes = bytes;
+	srcPtr->nBytes = size;
+    }
+    return TRUE;
+}
+
+unsigned char *
+Blt_DBuffer_Extend(DBuffer *srcPtr, size_t nBytes) 
+{
+    unsigned char *bp;
+
+    if (!Blt_DBuffer_Resize(srcPtr, srcPtr->count + nBytes)) {
+	return NULL;
+    }
+    bp = srcPtr->bytes + srcPtr->count;
+    srcPtr->count += nBytes;
+    return bp;
+}
+
+void
+Blt_DBuffer_AppendByte(DBuffer *destPtr, unsigned char value)
+{
+    if (Blt_DBuffer_Resize(destPtr, destPtr->count + sizeof(value))) {
+	destPtr->bytes[destPtr->count] = value;
+	destPtr->count++;
+    }
+}
+
+void
+Blt_DBuffer_AppendShort(DBuffer *destPtr, unsigned short value)
+{
+    if (Blt_DBuffer_Resize(destPtr, destPtr->count + sizeof(value))) {
+	unsigned char *bp;
+
+	bp = destPtr->bytes + destPtr->count;
+#ifdef WORDS_BIGENDIAN
+	bp[0] = (value >> 8)  & 0xFF;
+	bp[1] = (value)       & 0xFF;
+#else
+	bp[0] = (value)       & 0xFF;
+	bp[1] = (value >> 8)  & 0xFF;
+#endif
+	destPtr->count += 2;
+    }
+}
+
+void
+Blt_DBuffer_AppendLong(DBuffer *destPtr, unsigned int value)
+{
+    if (Blt_DBuffer_Resize(destPtr, destPtr->count + sizeof(value))) {
+	unsigned char *bp;
+
+	bp = destPtr->bytes + destPtr->count;
+#ifdef WORDS_BIGENDIAN
+	bp[0] = (value >> 24) & 0xFF;
+	bp[1] = (value >> 16) & 0xFF;
+	bp[2] = (value >> 8)  & 0xFF;
+	bp[3] = (value)       & 0xFF;
+#else
+	bp[0] = (value)       & 0xFF;
+	bp[1] = (value >> 8)  & 0xFF;
+	bp[2] = (value >> 16) & 0xFF;
+	bp[3] = (value >> 24) & 0xFF;
+#endif
+	destPtr->count += 4;
+    }
+}
+
+Tcl_Obj *
+Blt_DBuffer_ByteArrayObj(DBuffer *srcPtr)
+{
+    return Tcl_NewByteArrayObj(srcPtr->bytes, srcPtr->count);
+}
+
+Tcl_Obj *
+Blt_DBuffer_StringObj(DBuffer *srcPtr)
+{
+    return Tcl_NewStringObj((char *)srcPtr->bytes, srcPtr->count);
+}
+
+int
+Blt_DBuffer_AppendData(DBuffer *srcPtr, const unsigned char *data, 
+		       size_t nBytes)
+{
+    unsigned char *bp;
+
+    bp = Blt_DBuffer_Extend(srcPtr, nBytes);
+    if (bp == NULL) {
+	return FALSE;
+    }
+    memcpy(bp, data, nBytes);
+    return TRUE;
+}
+
+void
+Blt_DBuffer_VarAppend
+TCL_VARARGS_DEF(DBuffer *, arg1)
+{
+    DBuffer *srcPtr;
+    va_list args;
+
+    srcPtr = TCL_VARARGS_START(DBuffer, arg1, args);
+    for (;;) {
+	const unsigned char *string;
+
+	string = va_arg(args, const unsigned char *);
+	if (string == NULL) {
+	    break;
+	}
+	Blt_DBuffer_AppendData(srcPtr, string, strlen((const char *)string));
+    }
+}
+
+void
+Blt_DBuffer_Print
+TCL_VARARGS_DEF(DBuffer *, arg1)
+{
+    DBuffer *srcPtr;
+    char *fmt;
+    char string[BUFSIZ+4];
+    int length;
+    va_list args;
+
+    srcPtr = TCL_VARARGS_START(DBuffer, arg1, args);
+    fmt = va_arg(args, char *);
+    length = vsnprintf(string, BUFSIZ, fmt, args);
+    if (length > BUFSIZ) {
+	strcat(string, "...");
+    }
+    va_end(args);
+    Blt_DBuffer_AppendData(srcPtr, (unsigned char *)string, strlen(string));
+}
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+int
+Blt_DBuffer_LoadFile(
+    Tcl_Interp *interp, 
+    const char *fileName, 
+    Blt_DBuffer dBuffer)
+{
+    int nBytes;
+    Tcl_Channel channel;
+
+    if (fileName[0] == '@') { 
+	int mode;
+
+	/* If the file name starts with a '@', then it represents the name of
+	 * a previously opened channel.  Verify that the channel was opened
+	 * for reading. */
+	fileName++;
+	channel = Tcl_GetChannel(interp, fileName, &mode);
+	if ((mode & TCL_READABLE) == 0) {
+	    Tcl_AppendResult(interp, "can't read from \"", fileName, "\"",
+			     (char *)NULL);
+	    return TCL_ERROR;
+	}
+    } else {
+	channel = Tcl_OpenFileChannel(interp, fileName, "r", 0);
+    }
+    if (channel == NULL) {
+	return TCL_ERROR;
+    }
+    if (Tcl_SetChannelOption(interp, channel, "-encoding", "binary")
+	!= TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_SetChannelOption(interp, channel, "-translation", "binary") 
+	!= TCL_OK) {
+	return TCL_ERROR;
+    }
+    Blt_DBuffer_Init(dBuffer);
+    nBytes = 0;
+    while (!Tcl_Eof(channel)) {
+	int nRead;
+#define BUFFER_SIZE (1<<16)
+	char *bp;
+
+	bp = (char *)Blt_DBuffer_Extend(dBuffer, BUFFER_SIZE);
+	nRead = Tcl_ReadRaw(channel, bp, BUFFER_SIZE);
+	if (nRead == -1) {
+	    Tcl_AppendResult(interp, "error reading ", fileName, ": ",
+			Tcl_PosixError(interp), (char *)NULL);
+	    Blt_DBuffer_Free(dBuffer);
+	    return TCL_ERROR;
+	}
+	nBytes += nRead;
+	Blt_DBuffer_SetLength(dBuffer, nBytes);
+    }
+    Tcl_Close(interp, channel);
+    return TCL_OK;
+}
+
+int
+Blt_DBuffer_DecodeBase64(Tcl_Interp *interp, const char *string, size_t length,
+			 DBuffer *destPtr)
+{
+    unsigned char *bp;
+
+    bp = Blt_Base64_Decode(interp, string, &length);	
+    if (bp == NULL) {
+	return TCL_ERROR;
+    }
+    if (destPtr->bytes != NULL) {
+	free(destPtr->bytes);
+	destPtr->bytes = NULL;
+    }
+    destPtr->bytes = bp;
+    destPtr->nBytes = destPtr->count = length;
+    destPtr->cursor = 0;
+    destPtr->chunk = 64;
+    return TCL_OK;
+}
+
+
+char *
+Blt_DBuffer_EncodeBase64(
+    Tcl_Interp *interp,		/* Interpreter to report errors to. */
+    DBuffer *srcPtr)		/* Input binary buffer. */
+{
+    return Blt_Base64_Encode(interp, srcPtr->bytes, srcPtr->count);
+}
+
diff --git a/tlt3.0/bltDBuffer.h b/tlt3.0/bltDBuffer.h
new file mode 100644
index 0000000..0d08b1d
--- /dev/null
+++ b/tlt3.0/bltDBuffer.h
@@ -0,0 +1,92 @@
+
+/*
+ * bltDBuffer.h --
+ *
+ *	Copyright 2003-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_DBUFFER_H
+#define _BLT_DBUFFER_H
+
+typedef struct _Blt_DBuffer {
+    unsigned char *bytes;	/* Stores output (malloc-ed).*/
+    size_t nBytes;		/* Size of dynamically allocated buffer. */
+
+    size_t count;		/* # of bytes read into the buffer. Marks the
+				 * # current fill point of the buffer. */
+    size_t cursor;		/* Current position in buffer. */
+    size_t chunk;		/* Buffer growth size. */
+
+} *Blt_DBuffer;
+
+extern void Blt_DBuffer_VarAppend TCL_VARARGS(Blt_DBuffer, buffer);
+
+extern void Blt_DBuffer_Print TCL_VARARGS(Blt_DBuffer, buffer);
+
+extern void Blt_DBuffer_Init(Blt_DBuffer buffer);
+extern void Blt_DBuffer_Free(Blt_DBuffer buffer);
+extern unsigned char *Blt_DBuffer_Extend(Blt_DBuffer buffer, size_t extra);
+extern int Blt_DBuffer_AppendData(Blt_DBuffer buffer, 
+	const unsigned char *bytes, size_t extra);
+extern int Blt_DBuffer_Resize(Blt_DBuffer buffer, size_t length);
+extern Blt_DBuffer Blt_DBuffer_Create(void);
+extern void Blt_DBuffer_Destroy(Blt_DBuffer buffer);
+
+extern int Blt_DBuffer_LoadFile(Tcl_Interp *interp, const char *fileName, 
+	Blt_DBuffer buffer); 
+
+extern void Blt_DBuffer_AppendByte(Blt_DBuffer buffer, unsigned char byte);
+extern void Blt_DBuffer_AppendShort(Blt_DBuffer buffer, 
+	unsigned short value);
+extern void Blt_DBuffer_AppendLong(Blt_DBuffer buffer, unsigned int value);
+extern Tcl_Obj *Blt_DBuffer_ByteArrayObj(Blt_DBuffer buffer);
+extern Tcl_Obj *Blt_DBuffer_StringObj(Blt_DBuffer buffer);
+
+#define Blt_DBuffer_Bytes(s)		((s)->bytes)
+#define Blt_DBuffer_Size(s)		((s)->nBytes)
+
+#define Blt_DBuffer_BytesLeft(s)	((s)->count - (s)->cursor)
+#define Blt_DBuffer_NextByte(s)		((s)->bytes[(s)->cursor++])
+#define Blt_DBuffer_Pointer(s)		((s)->bytes + (s)->cursor)
+#define Blt_DBuffer_SetPointer(s,p)	((s)->cursor = (p) - (s)->bytes)
+
+#define Blt_DBuffer_ResetCursor(s)	((s)->cursor = 0)
+#define Blt_DBuffer_Cursor(s)		((s)->cursor)
+#define Blt_DBuffer_SetCursor(s,n)	((s)->cursor = (n))
+#define Blt_DBuffer_IncrCursor(s,i)	((s)->cursor += (i))
+
+#define Blt_DBuffer_End(s)		((s)->bytes + (s)->count)
+#define Blt_DBuffer_Length(s)		((s)->count)
+#define Blt_DBuffer_SetLengthFromPointer(s,p) \
+	((s)->count = ((p) - (s)->bytes))
+#define Blt_DBuffer_SetLength(s,i)    \
+	((s)->count = (i), (s)->bytes[(s)->count] = '\0')
+#define Blt_DBuffer_IncrLength(s,i)	((s)->count += (i))
+
+extern int Blt_DBuffer_DecodeBase64(Tcl_Interp *interp, 
+	const char *string, size_t length, Blt_DBuffer buffer);
+extern char *Blt_DBuffer_EncodeBase64(Tcl_Interp *interp, 
+	Blt_DBuffer buffer);
+
+extern int Blt_IsBase64(const unsigned char *bytes, size_t length);
+
+#endif /*_BLT_DBUFFER_H*/
diff --git a/tlt3.0/bltFont.h b/tlt3.0/bltFont.h
new file mode 100644
index 0000000..272be02
--- /dev/null
+++ b/tlt3.0/bltFont.h
@@ -0,0 +1,137 @@
+
+/*
+ * bltFont.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.v
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_FONT_H
+#define _BLT_FONT_H
+
+#define FONT_ITALIC	(1<<0)
+#define FONT_BOLD	(1<<1)
+
+typedef struct {
+    int ascent;			/* The amount in pixels that the tallest
+				 * letter sticks up above the baseline, plus
+				 * any extra blank space added by the designer
+				 * of the font. */
+    int descent;		/* The largest amount in pixels that any
+				 * letter sticks below the baseline, plus any
+				 * extra blank space added by the designer of
+				 * the font. */
+    int linespace;		/* The sum of the ascent and descent.  How
+				 * far apart two lines of text in the same
+				 * font should be placed so that none of the
+				 * characters in one line overlap any of the
+				 * characters in the other line. */
+    int tabWidth;		/* Width of tabs in this font (pixels). */
+    int	underlinePos;		/* Offset from baseline to origin of
+				 * underline bar (used for drawing underlines
+				 * on a non-underlined font). */
+    int underlineHeight;	/* Height of underline bar (used for drawing
+				 * underlines on a non-underlined font). */
+} Blt_FontMetrics;
+
+
+typedef struct _Blt_Font *Blt_Font;
+typedef struct Blt_FontClass Blt_FontClass;
+
+typedef const char *(Blt_NameOfFontProc)(Blt_Font font);
+typedef void (Blt_GetFontMetricsProc)(Blt_Font font, 
+	Blt_FontMetrics *metricsPtr);
+typedef Font (Blt_FontIdProc)(Blt_Font font);
+typedef int (Blt_TextStringWidthProc)(Blt_Font font, const char *string, 
+	int nBytes);
+typedef void (Blt_FreeFontProc)(Blt_Font font);
+typedef int (Blt_MeasureCharsProc)(Blt_Font font, const char *text, int nBytes, 
+	int maxLength, int flags, int *lengthPtr);
+typedef void (Blt_DrawCharsProc)(Display *display, Drawable drawable, GC gc, 
+	Blt_Font font, int depth, float angle, const char *text, int length, 
+	int x, int y);
+typedef int (Blt_PostscriptFontNameProc)(Blt_Font font, Tcl_DString *resultPtr);
+typedef const char *(Blt_FamilyOfFontProc)(Blt_Font font);
+typedef int (Blt_CanRotateFontProc)(Blt_Font font, float angle);
+typedef void (Blt_UnderlineCharsProc)(Display *display, Drawable drawable, 
+	GC gc, Blt_Font font, const char *text, int textLen, int x, int y, 
+	int first, int last, int xMax);
+
+struct Blt_FontClass {
+    int type;			/* Indicates the type of font used. */
+    Blt_NameOfFontProc *nameOfFont;
+    Blt_FamilyOfFontProc *familyOfFont;
+    Blt_FontIdProc *fontId;
+    Blt_GetFontMetricsProc *getFontMetrics;
+    Blt_MeasureCharsProc *measureChars;
+    Blt_TextStringWidthProc *textWidth;
+    Blt_CanRotateFontProc *canRotateFont;
+    Blt_DrawCharsProc *drawChars;
+    Blt_PostscriptFontNameProc *postscriptFontName;
+    Blt_FreeFontProc  *freeFont;
+    Blt_UnderlineCharsProc  *underlineChars;
+};
+
+struct _Blt_Font {
+    void *clientData;
+    Tcl_Interp *interp;
+    Display *display;
+    Blt_FontClass *classPtr;
+};
+
+#define Blt_NameOfFont(f) (*(f)->classPtr->nameOfFont)(f)
+#define Blt_FontId(f) (*(f)->classPtr->fontId)(f)
+#define Blt_MeasureChars(f,s,l,ml,fl,lp) \
+	(*(f)->classPtr->measureChars)(f,s,l,ml,fl,lp)
+#define Blt_DrawChars(d,w,gc,f,dp,a,t,l,x,y)		\
+	(*(f)->classPtr->drawChars)(d,w,gc,f,dp,a,t,l,x,y)
+#define Blt_PostscriptFontName(f,rp) (*(f)->classPtr->postscriptFontName)(f,rp)
+#define Blt_FamilyOfFont(f) (*(f)->classPtr->familyOfFont)(f)
+#define Blt_CanRotateFont(f,a) (*(f)->classPtr->canRotateFont)(f,a)
+#define Blt_FreeFont(f) (*(f)->classPtr->freeFont)(f)
+#define Blt_UnderlineChars(d,w,g,f,s,l,x,y,a,b,m)		\
+	(*(f)->classPtr->underlineChars)(d,w,g,f,s,l,x,y,a,b,m)
+
+extern Blt_Font Blt_GetFont(Tcl_Interp *interp, Tk_Window tkwin, 
+	const char *string);
+extern Blt_Font Blt_AllocFontFromObj(Tcl_Interp *interp, Tk_Window tkwin, 
+	Tcl_Obj *objPtr);
+
+extern void Blt_DrawCharsWithEllipsis(Tk_Window tkwin, Drawable drawable,
+	GC gc, Blt_Font font, int depth, float angle, const char *string, 
+	int nBytes, int x, int y, int maxLength);
+
+extern Blt_Font Blt_GetFontFromObj(Tcl_Interp *interp, Tk_Window tkwin,
+	Tcl_Obj *objPtr);
+
+extern void Blt_GetFontMetrics(Blt_Font font, Blt_FontMetrics *fmPtr);
+extern int Blt_TextWidth(Blt_Font font, const char *string, int length);
+extern Tcl_Interp *Blt_GetFontInterp(Blt_Font font);
+
+extern const char *Blt_GetFontFileFromObj(Tcl_Interp *interp, 
+	Tcl_Obj *objPtr, double *sizePtr);
+extern const char *Blt_GetFontFile(Tcl_Interp *interp, const char *spec,
+	double *sizePtr);
+
+#endif /* _BLT_FONT_H */
diff --git a/tlt3.0/bltGrAxis.c b/tlt3.0/bltGrAxis.c
new file mode 100644
index 0000000..faa186b
--- /dev/null
+++ b/tlt3.0/bltGrAxis.c
@@ -0,0 +1,5564 @@
+
+/*
+ * bltGrAxis.c --
+ *
+ *	This module implements coordinate axes for the BLT graph widget.
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <X11/Xutil.h>
+
+#include "bltInt.h"
+#include "bltMath.h"
+#include "bltGraph.h"
+#include "bltOp.h"
+#include "bltGrElem.h"
+
+#define MAXTICKS	10001
+
+#define FCLAMP(x)	((((x) < 0.0) ? 0.0 : ((x) > 1.0) ? 1.0 : (x)))
+
+/*
+ * Round x in terms of units
+ */
+#define UROUND(x,u)		(Round((x)/(u))*(u))
+#define UCEIL(x,u)		(ceil((x)/(u))*(u))
+#define UFLOOR(x,u)		(floor((x)/(u))*(u))
+
+#define NUMDIGITS		15	/* Specifies the number of digits of
+					 * accuracy used when outputting axis
+					 * tick labels. */
+enum TickRange {
+    AXIS_TIGHT, AXIS_LOOSE, AXIS_ALWAYS_LOOSE
+};
+
+#define AXIS_PAD_TITLE		2	/* Padding for axis title. */
+
+/* Axis flags: */
+
+#define AXIS_AUTO_MAJOR		(1<<16) /* Auto-generate major ticks. */
+#define AXIS_AUTO_MINOR		(1<<17) /* Auto-generate minor ticks. */
+#define AXIS_USE		(1<<18)	/* Axis is displayed on the screen via
+					 * the "use" operation */
+#define AXIS_GRID		(1<<19)	/* Display grid lines. */
+#define AXIS_GRIDMINOR		(1<<20)	/* Display grid lines for minor
+					 * ticks. */
+#define AXIS_SHOWTICKS		(1<<21)	/* Display axis ticks. */
+#define AXIS_EXTERIOR		(1<<22)	/* Axis is exterior to the plot. */
+#define AXIS_CHECK_LIMITS	(1<<23)	/* Validate user-defined axis limits. */
+
+#define HORIZMARGIN(m)	(!((m)->site & 0x1)) /* Even sites are horizontal */
+
+typedef struct {
+    int axis;				/* Length of the axis.  */
+    int t1;			        /* Length of a major tick (in
+					 * pixels). */
+    int t2;			        /* Length of a minor tick (in
+					 * pixels). */
+    int label;				/* Distance from axis to tick label. */
+} AxisInfo;
+
+typedef struct {
+    const char *name;
+    ClassId classId;
+    int margin, invertMargin;
+} AxisName;
+
+static AxisName axisNames[] = { 
+    { "x",  CID_AXIS_X, MARGIN_BOTTOM, MARGIN_LEFT   },
+    { "y",  CID_AXIS_Y, MARGIN_LEFT,   MARGIN_BOTTOM },
+    { "x2", CID_AXIS_X, MARGIN_TOP,    MARGIN_RIGHT  },
+    { "y2", CID_AXIS_Y, MARGIN_RIGHT,  MARGIN_TOP    }
+} ;
+static int nAxisNames = sizeof(axisNames) / sizeof(AxisName);
+
+static Blt_OptionParseProc ObjToLimitProc;
+static Blt_OptionPrintProc LimitToObjProc;
+static Blt_CustomOption limitOption = {
+    ObjToLimitProc, LimitToObjProc, NULL, (ClientData)0
+};
+
+static Blt_OptionFreeProc  FreeTicksProc;
+static Blt_OptionParseProc ObjToTicksProc;
+static Blt_OptionPrintProc TicksToObjProc;
+static Blt_CustomOption majorTicksOption = {
+    ObjToTicksProc, TicksToObjProc, FreeTicksProc, (ClientData)AXIS_AUTO_MAJOR,
+};
+static Blt_CustomOption minorTicksOption = {
+    ObjToTicksProc, TicksToObjProc, FreeTicksProc, (ClientData)AXIS_AUTO_MINOR,
+};
+static Blt_OptionFreeProc  FreeAxisProc;
+static Blt_OptionPrintProc AxisToObjProc;
+static Blt_OptionParseProc ObjToAxisProc;
+Blt_CustomOption bltXAxisOption = {
+    ObjToAxisProc, AxisToObjProc, FreeAxisProc, (ClientData)CID_AXIS_X
+};
+Blt_CustomOption bltYAxisOption = {
+    ObjToAxisProc, AxisToObjProc, FreeAxisProc, (ClientData)CID_AXIS_Y
+};
+
+static Blt_OptionFreeProc  FreeFormatProc;
+static Blt_OptionParseProc ObjToFormatProc;
+static Blt_OptionPrintProc FormatToObjProc;
+static Blt_CustomOption formatOption = {
+    ObjToFormatProc, FormatToObjProc, FreeFormatProc, (ClientData)0,
+};
+static Blt_OptionParseProc ObjToLooseProc;
+static Blt_OptionPrintProc LooseToObjProc;
+static Blt_CustomOption looseOption = {
+    ObjToLooseProc, LooseToObjProc, NULL, (ClientData)0,
+};
+
+static Blt_OptionParseProc ObjToUseProc;
+static Blt_OptionPrintProc UseToObjProc;
+static Blt_CustomOption useOption = {
+    ObjToUseProc, UseToObjProc, NULL, (ClientData)0
+};
+
+#define DEF_AXIS_ACTIVEBACKGROUND	STD_ACTIVE_BACKGROUND
+#define DEF_AXIS_ACTIVEFOREGROUND	STD_ACTIVE_FOREGROUND
+#define DEF_AXIS_ACTIVERELIEF		"flat"
+#define DEF_AXIS_ANGLE			"0.0"
+#define DEF_AXIS_BACKGROUND		(char *)NULL
+#define DEF_AXIS_BORDERWIDTH		"0"
+#define DEF_AXIS_CHECKLIMITS		"0"
+#define DEF_AXIS_COMMAND		(char *)NULL
+#define DEF_AXIS_DESCENDING		"0"
+#define DEF_AXIS_FOREGROUND		RGB_BLACK
+#define DEF_AXIS_GRID_BARCHART		"1"
+#define DEF_AXIS_GRIDCOLOR		RGB_GREY64
+#define DEF_AXIS_GRIDDASHES		"dot"
+#define DEF_AXIS_GRID_GRAPH		"0"
+#define DEF_AXIS_GRIDLINEWIDTH	"0"
+#define DEF_AXIS_GRIDMINOR		"1"
+#define DEF_AXIS_GRIDMINOR_COLOR	RGB_GREY64
+#define DEF_AXIS_HIDE			"0"
+#define DEF_AXIS_JUSTIFY		"c"
+#define DEF_AXIS_LIMITS_FORMAT	        (char *)NULL
+#define DEF_AXIS_LINEWIDTH		"1"
+#define DEF_AXIS_LOGSCALE		"0"
+#define DEF_AXIS_LOOSE			"0"
+#define DEF_AXIS_RANGE			"0.0"
+#define DEF_AXIS_RELIEF			"flat"
+#define DEF_AXIS_SCROLL_INCREMENT 	"10"
+#define DEF_AXIS_SHIFTBY		"0.0"
+#define DEF_AXIS_SHOWTICKS		"1"
+#define DEF_AXIS_STEP			"0.0"
+#define DEF_AXIS_STEP			"0.0"
+#define DEF_AXIS_SUBDIVISIONS		"2"
+#define DEF_AXIS_TAGS			"all"
+#define DEF_AXIS_EXTERIOR		"1"
+#define DEF_AXIS_TICK_ANCHOR		"c"
+#define DEF_AXIS_LIMITS_FONT		STD_FONT_NUMBERS
+#define DEF_AXIS_TICKFONT_GRAPH		STD_FONT_NUMBERS
+#define DEF_AXIS_TICKFONT_BARCHART	STD_FONT_SMALL
+#define DEF_AXIS_TICKLENGTH		"4"
+#define DEF_AXIS_DIVISIONS		"10"
+#define DEF_AXIS_TITLE_ALTERNATE	"0"
+#define DEF_AXIS_TITLE_FG		RGB_BLACK
+#define DEF_AXIS_TITLE_FONT		"{Sans Serif} 10"
+#define DEF_AXIS_X_STEP_BARCHART	"1.0"
+#define DEF_AXIS_X_SUBDIVISIONS_BARCHART "0"
+
+static Blt_ConfigSpec configSpecs[] =
+{
+    {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", 
+	"ActiveBackground", DEF_AXIS_ACTIVEBACKGROUND, 
+	Blt_Offset(Axis, activeBg), ALL_GRAPHS | BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground",
+	"ActiveForeground", DEF_AXIS_ACTIVEFOREGROUND,
+	Blt_Offset(Axis, activeFgColor), ALL_GRAPHS}, 
+    {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief",
+	DEF_AXIS_ACTIVERELIEF, Blt_Offset(Axis, activeRelief),
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, 
+    {BLT_CONFIG_DOUBLE, "-autorange", "autoRange", "AutoRange",
+	DEF_AXIS_RANGE, Blt_Offset(Axis, windowSize),
+        ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, 
+    {BLT_CONFIG_BACKGROUND, "-background", "background", "Background",
+	DEF_AXIS_BACKGROUND, Blt_Offset(Axis, normalBg),
+	ALL_GRAPHS | BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_AXIS_TAGS, 
+	Blt_Offset(Axis, obj.tags), ALL_GRAPHS | BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 
+	0, ALL_GRAPHS},
+    {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth",
+	DEF_AXIS_BORDERWIDTH, Blt_Offset(Axis, borderWidth),
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMASK, "-checklimits", "checkLimits", "CheckLimits", 
+	DEF_AXIS_CHECKLIMITS, Blt_Offset(Axis, flags), 
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT,
+	(Blt_CustomOption *)AXIS_CHECK_LIMITS},
+    {BLT_CONFIG_COLOR, "-color", "color", "Color",
+	DEF_AXIS_FOREGROUND, Blt_Offset(Axis, tickColor), ALL_GRAPHS},
+    {BLT_CONFIG_STRING, "-command", "command", "Command",
+	DEF_AXIS_COMMAND, Blt_Offset(Axis, formatCmd),
+	BLT_CONFIG_NULL_OK | ALL_GRAPHS},
+    {BLT_CONFIG_BOOLEAN, "-descending", "descending", "Descending",
+	DEF_AXIS_DESCENDING, Blt_Offset(Axis, descending),
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMASK, "-exterior", "exterior", "exterior", DEF_AXIS_EXTERIOR,
+	Blt_Offset(Axis, flags), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT, 
+ 	(Blt_CustomOption *)AXIS_EXTERIOR},
+    {BLT_CONFIG_SYNONYM, "-fg", "color", (char *)NULL, 
+        (char *)NULL, 0, ALL_GRAPHS},
+    {BLT_CONFIG_SYNONYM, "-foreground", "color", (char *)NULL, 
+        (char *)NULL, 0, ALL_GRAPHS},
+    {BLT_CONFIG_BITMASK, "-grid", "grid", "Grid", DEF_AXIS_GRID_BARCHART, 
+	Blt_Offset(Axis, flags), BARCHART, (Blt_CustomOption *)AXIS_GRID},
+    {BLT_CONFIG_BITMASK, "-grid", "grid", "Grid", DEF_AXIS_GRID_GRAPH, 
+	Blt_Offset(Axis, flags), GRAPH | STRIPCHART, 
+	(Blt_CustomOption *)AXIS_GRID},
+    {BLT_CONFIG_COLOR, "-gridcolor", "gridColor", "GridColor", 
+	DEF_AXIS_GRIDCOLOR, Blt_Offset(Axis, major.color), ALL_GRAPHS},
+    {BLT_CONFIG_DASHES, "-griddashes", "gridDashes", "GridDashes", 
+	DEF_AXIS_GRIDDASHES, Blt_Offset(Axis, major.dashes), 
+	BLT_CONFIG_NULL_OK | ALL_GRAPHS},
+    {BLT_CONFIG_PIXELS_NNEG, "-gridlinewidth", "gridLineWidth", 
+	"GridLineWidth", DEF_AXIS_GRIDLINEWIDTH, 
+	Blt_Offset(Axis, major.lineWidth), 
+        BLT_CONFIG_DONT_SET_DEFAULT | ALL_GRAPHS},
+    {BLT_CONFIG_BITMASK, "-gridminor", "gridMinor", "GridMinor", 
+	DEF_AXIS_GRIDMINOR, Blt_Offset(Axis, flags), 
+	BLT_CONFIG_DONT_SET_DEFAULT | ALL_GRAPHS, 
+	(Blt_CustomOption *)AXIS_GRIDMINOR},
+    {BLT_CONFIG_COLOR, "-gridminorcolor", "gridMinorColor", "GridColor", 
+	DEF_AXIS_GRIDMINOR_COLOR, Blt_Offset(Axis, minor.color), ALL_GRAPHS},
+    {BLT_CONFIG_DASHES, "-gridminordashes", "gridMinorDashes", "GridDashes", 
+	DEF_AXIS_GRIDDASHES, Blt_Offset(Axis, minor.dashes), 
+	BLT_CONFIG_NULL_OK | ALL_GRAPHS},
+    {BLT_CONFIG_PIXELS_NNEG, "-gridminorlinewidth", "gridMinorLineWidth", 
+	"GridLineWidth", DEF_AXIS_GRIDLINEWIDTH, 
+	Blt_Offset(Axis, minor.lineWidth), 
+        BLT_CONFIG_DONT_SET_DEFAULT | ALL_GRAPHS},
+    {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_AXIS_HIDE, 
+	Blt_Offset(Axis, flags), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT, 
+        (Blt_CustomOption *)HIDE},
+    {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify",
+	DEF_AXIS_JUSTIFY, Blt_Offset(Axis, titleJustify),
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BOOLEAN, "-labeloffset", "labelOffset", "LabelOffset",
+        (char *)NULL, Blt_Offset(Axis, labelOffset), ALL_GRAPHS}, 
+    {BLT_CONFIG_COLOR, "-limitscolor", "limitsColor", "Color",
+	DEF_AXIS_FOREGROUND, Blt_Offset(Axis, limitsTextStyle.color), 
+	ALL_GRAPHS},
+    {BLT_CONFIG_FONT, "-limitsfont", "limitsFont", "Font", DEF_AXIS_LIMITS_FONT,
+	Blt_Offset(Axis, limitsTextStyle.font), ALL_GRAPHS},
+    {BLT_CONFIG_CUSTOM, "-limitsformat", "limitsFormat", "LimitsFormat",
+        (char *)NULL, Blt_Offset(Axis, limitsFormats),
+	BLT_CONFIG_NULL_OK | ALL_GRAPHS, &formatOption},
+    {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth",
+	DEF_AXIS_LINEWIDTH, Blt_Offset(Axis, lineWidth),
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BOOLEAN, "-logscale", "logScale", "LogScale",
+	DEF_AXIS_LOGSCALE, Blt_Offset(Axis, logScale),
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-loose", "loose", "Loose", DEF_AXIS_LOOSE, 0, 
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT, &looseOption},
+    {BLT_CONFIG_CUSTOM, "-majorticks", "majorTicks", "MajorTicks",
+	(char *)NULL, Blt_Offset(Axis, t1Ptr),
+	BLT_CONFIG_NULL_OK | ALL_GRAPHS, &majorTicksOption},
+    {BLT_CONFIG_CUSTOM, "-max", "max", "Max", (char *)NULL, 
+	Blt_Offset(Axis, reqMax), ALL_GRAPHS, &limitOption},
+    {BLT_CONFIG_CUSTOM, "-min", "min", "Min", (char *)NULL, 
+	Blt_Offset(Axis, reqMin), ALL_GRAPHS, &limitOption},
+    {BLT_CONFIG_CUSTOM, "-minorticks", "minorTicks", "MinorTicks",
+	(char *)NULL, Blt_Offset(Axis, t2Ptr), 
+	BLT_CONFIG_NULL_OK | ALL_GRAPHS, &minorTicksOption},
+    {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief",
+	DEF_AXIS_RELIEF, Blt_Offset(Axis, relief), 
+        ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_FLOAT, "-rotate", "rotate", "Rotate", DEF_AXIS_ANGLE, 
+	Blt_Offset(Axis, tickAngle), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_OBJ, "-scrollcommand", "scrollCommand", "ScrollCommand",
+	(char *)NULL, Blt_Offset(Axis, scrollCmdObjPtr),
+	ALL_GRAPHS | BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_PIXELS_POS, "-scrollincrement", "scrollIncrement", 
+	"ScrollIncrement", DEF_AXIS_SCROLL_INCREMENT, 
+	Blt_Offset(Axis, scrollUnits), ALL_GRAPHS|BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-scrollmax", "scrollMax", "ScrollMax", (char *)NULL, 
+	Blt_Offset(Axis, reqScrollMax),  ALL_GRAPHS, &limitOption},
+    {BLT_CONFIG_CUSTOM, "-scrollmin", "scrollMin", "ScrollMin", (char *)NULL, 
+	Blt_Offset(Axis, reqScrollMin), ALL_GRAPHS, &limitOption},
+    {BLT_CONFIG_DOUBLE, "-shiftby", "shiftBy", "ShiftBy",
+	DEF_AXIS_SHIFTBY, Blt_Offset(Axis, shiftBy),
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMASK, "-showticks", "showTicks", "ShowTicks",
+	DEF_AXIS_SHOWTICKS, Blt_Offset(Axis, flags), 
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT,
+	(Blt_CustomOption *)AXIS_SHOWTICKS},
+    {BLT_CONFIG_DOUBLE, "-stepsize", "stepSize", "StepSize",
+	DEF_AXIS_STEP, Blt_Offset(Axis, reqStep),
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_INT, "-subdivisions", "subdivisions", "Subdivisions",
+	DEF_AXIS_SUBDIVISIONS, Blt_Offset(Axis, reqNumMinorTicks), ALL_GRAPHS},
+    {BLT_CONFIG_ANCHOR, "-tickanchor", "tickAnchor", "Anchor",
+	DEF_AXIS_TICK_ANCHOR, Blt_Offset(Axis, reqTickAnchor), ALL_GRAPHS},
+    {BLT_CONFIG_FONT, "-tickfont", "tickFont", "Font",
+	DEF_AXIS_TICKFONT_GRAPH, Blt_Offset(Axis, tickFont), 
+	GRAPH | STRIPCHART},
+    {BLT_CONFIG_FONT, "-tickfont", "tickFont", "Font",
+	DEF_AXIS_TICKFONT_BARCHART, Blt_Offset(Axis, tickFont), BARCHART},
+    {BLT_CONFIG_PIXELS_NNEG, "-ticklength", "tickLength", "TickLength",
+	DEF_AXIS_TICKLENGTH, Blt_Offset(Axis, tickLength), 
+        ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_INT, "-tickdefault", "tickDefault", "TickDefault",
+	DEF_AXIS_DIVISIONS, Blt_Offset(Axis, reqNumMajorTicks),
+	ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-title", "title", "Title",
+	(char *)NULL, Blt_Offset(Axis, title),
+	BLT_CONFIG_DONT_SET_DEFAULT | BLT_CONFIG_NULL_OK | ALL_GRAPHS},
+    {BLT_CONFIG_BOOLEAN, "-titlealternate", "titleAlternate", "TitleAlternate",
+	DEF_AXIS_TITLE_ALTERNATE, Blt_Offset(Axis, titleAlternate),
+	BLT_CONFIG_DONT_SET_DEFAULT | ALL_GRAPHS},
+    {BLT_CONFIG_COLOR, "-titlecolor", "titleColor", "Color", 
+	DEF_AXIS_FOREGROUND, Blt_Offset(Axis, titleColor), 	
+	ALL_GRAPHS},
+    {BLT_CONFIG_FONT, "-titlefont", "titleFont", "Font", DEF_AXIS_TITLE_FONT, 
+	Blt_Offset(Axis, titleFont), ALL_GRAPHS},
+    {BLT_CONFIG_CUSTOM, "-use", "use", "Use", (char *)NULL, 0, ALL_GRAPHS, 
+	&useOption},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+/* Forward declarations */
+static void DestroyAxis(Axis *axisPtr);
+static Tcl_FreeProc FreeAxis;
+static int GetAxisByClass(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
+	ClassId classId, Axis **axisPtrPtr);
+static void TimeScaleAxis(Axis *axisPtr, double min, double max);
+
+static int lastMargin;
+typedef int (GraphAxisProc)(Tcl_Interp *interp, Axis *axisPtr, int objc, 
+	Tcl_Obj *const *objv);
+typedef int (GraphVirtualAxisProc)(Tcl_Interp *interp, Graph *graphPtr, 
+	int objc, Tcl_Obj *const *objv);
+
+INLINE static double
+Clamp(double x) 
+{
+    return (x < 0.0) ? 0.0 : (x > 1.0) ? 1.0 : x;
+}
+
+INLINE static int
+Round(double x)
+{
+    return (int) (x + ((x < 0.0) ? -0.5 : 0.5));
+}
+
+static void
+SetAxisRange(AxisRange *rangePtr, double min, double max)
+{
+    rangePtr->min = min;
+    rangePtr->max = max;
+    rangePtr->range = max - min;
+    if (fabs(rangePtr->range) < DBL_EPSILON) {
+	rangePtr->range = 1.0;
+    }
+    rangePtr->scale = 1.0 / rangePtr->range;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * InRange --
+ *
+ *	Determines if a value lies within a given range.
+ *
+ *	The value is normalized and compared against the interval [0..1],
+ *	where 0.0 is the minimum and 1.0 is the maximum.  DBL_EPSILON is the
+ *	smallest number that can be represented on the host machine, such that
+ *	(1.0 + epsilon) != 1.0.
+ *
+ *	Please note, *max* can't equal *min*.
+ *
+ * Results:
+ *	If the value is within the interval [min..max], 1 is returned; 0
+ *	otherwise.
+ *
+ *---------------------------------------------------------------------------
+ */
+INLINE static int
+InRange(double x, AxisRange *rangePtr)
+{
+    if (rangePtr->range < DBL_EPSILON) {
+	return (fabs(rangePtr->max - x) >= DBL_EPSILON);
+    } else {
+	double norm;
+
+	norm = (x - rangePtr->min) * rangePtr->scale;
+	return ((norm >= -DBL_EPSILON) && ((norm - 1.0) < DBL_EPSILON));
+    }
+}
+
+INLINE static int
+AxisIsHorizontal(Axis *axisPtr)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+
+    return ((axisPtr->obj.classId == CID_AXIS_Y) == graphPtr->inverted);
+}
+
+
+static void
+ReleaseAxis(Axis *axisPtr)
+{
+    if (axisPtr != NULL) {
+	axisPtr->refCount--;
+	assert(axisPtr->refCount >= 0);
+	if (axisPtr->refCount == 0) {
+	    axisPtr->flags |= DELETE_PENDING;
+	    Tcl_EventuallyFree(axisPtr, FreeAxis);
+	}
+    }
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Custom option parse and print procedures
+ *-----------------------------------------------------------------------------
+ */
+
+/*ARGSUSED*/
+static void
+FreeAxisProc(
+    ClientData clientData,		/* Not used. */
+    Display *display,			/* Not used. */
+    char *widgRec,
+    int offset)
+{
+    Axis **axisPtrPtr = (Axis **)(widgRec + offset);
+
+    if (*axisPtrPtr != NULL) {
+	ReleaseAxis(*axisPtrPtr);
+	*axisPtrPtr = NULL;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToAxisProc --
+ *
+ *	Converts the name of an axis to a pointer to its axis structure.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The axis flags are written
+ *	into the widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToAxisProc(
+    ClientData clientData,		/* Class identifier of the type of
+					 * axis we are looking for. */
+    Tcl_Interp *interp,			/* Interpreter to report results. */
+    Tk_Window tkwin,			/* Used to look up pointer to graph. */
+    Tcl_Obj *objPtr,			/* String representing new value. */
+    char *widgRec,			/* Pointer to structure record. */
+    int offset,				/* Offset to field in structure */
+    int flags)	
+{
+    ClassId classId = (ClassId)clientData;
+    Axis **axisPtrPtr = (Axis **)(widgRec + offset);
+    Axis *axisPtr;
+    Graph *graphPtr;
+
+    if (flags & BLT_CONFIG_NULL_OK) {
+	const char *string;
+
+	string  = Tcl_GetString(objPtr);
+	if (string[0] == '\0') {
+	    ReleaseAxis(*axisPtrPtr);
+	    *axisPtrPtr = NULL;
+	    return TCL_OK;
+	}
+    }
+    graphPtr = Blt_GetGraphFromWindowData(tkwin);
+    assert(graphPtr);
+    if (GetAxisByClass(interp, graphPtr, objPtr, classId, &axisPtr) 
+	!= TCL_OK) {
+	return TCL_ERROR;
+    }
+    ReleaseAxis(*axisPtrPtr);
+    *axisPtrPtr = axisPtr;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisToObjProc --
+ *
+ *	Convert the window coordinates into a string.
+ *
+ * Results:
+ *	The string representing the coordinate position is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+AxisToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Not used. */
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* Pointer to structure record .*/
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    Axis *axisPtr = *(Axis **)(widgRec + offset);
+    const char *name;
+
+    name = (axisPtr == NULL) ? "" : axisPtr->obj.name;
+    return Tcl_NewStringObj(name, -1);
+}
+
+/*ARGSUSED*/
+static void
+FreeFormatProc(
+    ClientData clientData,		/* Not used. */
+    Display *display,			/* Not used. */
+    char *widgRec,
+    int offset)				/* Not used. */
+{
+    Axis *axisPtr = (Axis *)(widgRec);
+
+    if (axisPtr->limitsFormats != NULL) {
+	free(axisPtr->limitsFormats);
+	axisPtr->limitsFormats = NULL;
+    }
+    axisPtr->nFormats = 0;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToFormatProc --
+ *
+ *	Convert the name of virtual axis to an pointer.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The axis flags are written
+ *	into the widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToFormatProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Interpreter to report results. */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* String representing new value. */
+    char *widgRec,			/* Pointer to structure record. */
+    int offset,				/* Not used. */
+    int flags)				/* Not used. */
+{
+    Axis *axisPtr = (Axis *)(widgRec);
+    const char **argv;
+    int argc;
+
+    if (Tcl_SplitList(interp, Tcl_GetString(objPtr), &argc, &argv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (argc > 2) {
+	Tcl_AppendResult(interp, "too many elements in limits format list \"",
+		Tcl_GetString(objPtr), "\"", (char *)NULL);
+	free(argv);
+	return TCL_ERROR;
+    }
+    if (axisPtr->limitsFormats != NULL) {
+	free(axisPtr->limitsFormats);
+    }
+    axisPtr->limitsFormats = argv;
+    axisPtr->nFormats = argc;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FormatToObjProc --
+ *
+ *	Convert the window coordinates into a string.
+ *
+ * Results:
+ *	The string representing the coordinate position is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+FormatToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Not used. */
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* Widget record */
+    int offset,				/* Not used. */
+    int flags)				/* Not used. */
+{
+    Axis *axisPtr = (Axis *)(widgRec);
+    Tcl_Obj *objPtr;
+
+    if (axisPtr->nFormats == 0) {
+	objPtr = Tcl_NewStringObj("", -1);
+    } else {
+	char *string;
+
+	string = Tcl_Merge(axisPtr->nFormats, axisPtr->limitsFormats); 
+	objPtr = Tcl_NewStringObj(string, -1);
+	free(string);
+    }
+    return objPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToLimitProc --
+ *
+ *	Convert the string representation of an axis limit into its numeric
+ *	form.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The symbol type is written
+ *	into the widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToLimitProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Interpreter to send results back
+					 * to */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* String representing new value. */
+    char *widgRec,			/* Pointer to structure record. */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    double *limitPtr = (double *)(widgRec + offset);
+    const char *string;
+
+    string = Tcl_GetString(objPtr);
+    if (string[0] == '\0') {
+      *limitPtr = NAN;
+    } else if (Blt_ExprDoubleFromObj(interp, objPtr, limitPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LimitToObjProc --
+ *
+ *	Convert the floating point axis limits into a string.
+ *
+ * Results:
+ *	The string representation of the limits is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+LimitToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Not used. */
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    double limit = *(double *)(widgRec + offset);
+    Tcl_Obj *objPtr;
+
+    if (isnormal(limit)) {
+	objPtr = Tcl_NewDoubleObj(limit);
+    } else {
+	objPtr = Tcl_NewStringObj("", -1);
+    }
+    return objPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToUseProc --
+ *
+ *	Convert the string representation of the margin to use into its 
+ *	numeric form.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The use type is written
+ *	into the widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToUseProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,		        /* Interpreter to send results. */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* String representing new value. */
+    char *widgRec,			/* Pointer to structure record. */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    Axis *axisPtr = (Axis *)(widgRec);
+    AxisName *p, *pend;
+    Blt_Chain chain;
+    Graph *graphPtr;
+    const char *string;
+    int margin;
+
+    graphPtr = axisPtr->obj.graphPtr;
+    if (axisPtr->refCount == 0) {
+	/* Clear the axis class if it's not currently used by an element.*/
+	Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE);
+    }
+    /* Remove the axis from the margin's use list and clear its use flag. */
+    if (axisPtr->link != NULL) {
+	Blt_Chain_UnlinkLink(axisPtr->chain, axisPtr->link);
+    }
+    axisPtr->flags &= ~AXIS_USE;
+    string = Tcl_GetString(objPtr);
+    if ((string == NULL) || (string[0] == '\0')) {
+	goto done;
+    }
+    for (p = axisNames, pend = axisNames + nAxisNames; p < pend; p++) {
+	if (strcmp(p->name, string) == 0) {
+	    break;			/* Found the axis name. */
+	}
+    }
+    if (p == pend) {
+	Tcl_AppendResult(interp, "unknown axis type \"", string, "\": "
+			 "should be x, y, x1, y2, or \"\".", (char *)NULL);
+	return TCL_ERROR;
+    }
+    /* Check the axis class. Can't use the axis if it's already being used as
+     * another type.  */
+    if (axisPtr->obj.classId == CID_NONE) {
+	Blt_GraphSetObjectClass(&axisPtr->obj, p->classId);
+    } else if (axisPtr->obj.classId != p->classId) {
+	Tcl_AppendResult(interp, "wrong type for axis \"", 
+		axisPtr->obj.name, "\": can't use ", 
+		axisPtr->obj.className, " type axis.", (char *)NULL); 
+	return TCL_ERROR;
+    }
+    margin = (graphPtr->inverted) ? p->invertMargin : p->margin;
+    chain = graphPtr->margins[margin].axes;
+    if (axisPtr->link != NULL) {
+	/* Move the axis from the old margin's "use" list to the new. */
+	Blt_Chain_AppendLink(chain, axisPtr->link);
+    } else {
+	axisPtr->link = Blt_Chain_Append(chain, axisPtr);
+    }
+    axisPtr->chain = chain;
+    axisPtr->flags |= AXIS_USE;
+    axisPtr->margin = margin;
+ done:
+    graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES);
+    /* When any axis changes, we need to layout the entire graph.  */
+    graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD);
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * UseToObjProc --
+ *
+ *	Convert the floating point axis limits into a string.
+ *
+ * Results:
+ *	The string representation of the limits is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+UseToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Not used. */
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    Axis *axisPtr = (Axis *)(widgRec);
+    
+    if (axisPtr->margin == MARGIN_NONE) {
+	return Tcl_NewStringObj("", -1);
+    }
+    return Tcl_NewStringObj(axisNames[axisPtr->margin].name, -1);
+}
+
+/*ARGSUSED*/
+static void
+FreeTicksProc(
+    ClientData clientData,		/* Either AXIS_AUTO_MAJOR or
+					 * AXIS_AUTO_MINOR. */
+    Display *display,			/* Not used. */
+    char *widgRec,
+    int offset)
+{
+    Axis *axisPtr = (Axis *)widgRec;
+    Ticks **ticksPtrPtr = (Ticks **) (widgRec + offset);
+    unsigned long mask = (unsigned long)clientData;
+
+    axisPtr->flags |= mask;
+    if (*ticksPtrPtr != NULL) {
+	free(*ticksPtrPtr);
+    }
+    *ticksPtrPtr = NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToTicksProc --
+ *
+ *
+ * Results:
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToTicksProc(
+    ClientData clientData,		/* Either AXIS_AUTO_MAJOR or
+					 * AXIS_AUTO_MINOR. */
+    Tcl_Interp *interp,		        /* Interpreter to send results. */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* String representing new value. */
+    char *widgRec,			/* Pointer to structure record. */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    Axis *axisPtr = (Axis *)widgRec;
+    Tcl_Obj **objv;
+    Ticks **ticksPtrPtr = (Ticks **) (widgRec + offset);
+    Ticks *ticksPtr;
+    int objc;
+    unsigned long mask = (unsigned long)clientData;
+
+    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    axisPtr->flags |= mask;
+    ticksPtr = NULL;
+    if (objc > 0) {
+	int i;
+
+	ticksPtr = malloc(sizeof(Ticks) + (objc*sizeof(double)));
+	for (i = 0; i < objc; i++) {
+	    double value;
+
+	    if (Blt_ExprDoubleFromObj(interp, objv[i], &value) != TCL_OK) {
+		free(ticksPtr);
+		return TCL_ERROR;
+	    }
+	    ticksPtr->values[i] = value;
+	}
+	ticksPtr->nTicks = objc;
+	axisPtr->flags &= ~mask;
+    }
+    FreeTicksProc(clientData, Tk_Display(tkwin), widgRec, offset);
+    *ticksPtrPtr = ticksPtr;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TicksToObjProc --
+ *
+ *	Convert array of tick coordinates to a list.
+ *
+ * Results:
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+TicksToObjProc(
+    ClientData clientData,		/* Either AXIS_AUTO_MAJOR or
+					 * AXIS_AUTO_MINOR. */
+    Tcl_Interp *interp,
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    Axis *axisPtr;
+    Tcl_Obj *listObjPtr;
+    Ticks *ticksPtr;
+    unsigned long mask;
+
+    axisPtr = (Axis *)widgRec;
+    ticksPtr = *(Ticks **) (widgRec + offset);
+    mask = (unsigned long)clientData;
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if ((ticksPtr != NULL) && ((axisPtr->flags & mask) == 0)) {
+	unsigned int i;
+
+	for (i = 0; i < ticksPtr->nTicks; i++) {
+	    Tcl_Obj *objPtr;
+
+	    objPtr = Tcl_NewDoubleObj(ticksPtr->values[i]);
+	    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	}
+    }
+    return listObjPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToLooseProc --
+ *
+ *	Convert a string to one of three values.
+ *		0 - false, no, off
+ *		1 - true, yes, on
+ *		2 - always
+ * Results:
+ *	If the string is successfully converted, TCL_OK is returned.
+ *	Otherwise, TCL_ERROR is returned and an error message is left in
+ *	interpreter's result field.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToLooseProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,		        /* Interpreter to send results. */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* String representing new value. */
+    char *widgRec,			/* Pointer to structure record. */
+    int offset,				/* Not used. */
+    int flags)				/* Not used. */
+{
+    Axis *axisPtr = (Axis *)(widgRec);
+    Tcl_Obj **objv;
+    int i;
+    int objc;
+    int values[2];
+
+    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if ((objc < 1) || (objc > 2)) {
+	Tcl_AppendResult(interp, "wrong # elements in loose value \"",
+	    Tcl_GetString(objPtr), "\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    for (i = 0; i < objc; i++) {
+	const char *string;
+
+	string = Tcl_GetString(objv[i]);
+	if ((string[0] == 'a') && (strcmp(string, "always") == 0)) {
+	    values[i] = AXIS_ALWAYS_LOOSE;
+	} else {
+	    int bool;
+
+	    if (Tcl_GetBooleanFromObj(interp, objv[i], &bool) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    values[i] = bool;
+	}
+    }
+    axisPtr->looseMin = axisPtr->looseMax = values[0];
+    if (objc > 1) {
+	axisPtr->looseMax = values[1];
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LooseToObjProc --
+ *
+ * Results:
+ *	The string representation of the auto boolean is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+LooseToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* Widget record */
+    int offset,				/* Not used. */
+    int flags)				/* Not used. */
+{
+    Axis *axisPtr = (Axis *)widgRec;
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if (axisPtr->looseMin == AXIS_TIGHT) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewBooleanObj(FALSE));
+    } else if (axisPtr->looseMin == AXIS_LOOSE) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewBooleanObj(TRUE));
+    } else if (axisPtr->looseMin == AXIS_ALWAYS_LOOSE) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj("always", 6));
+    }
+    if (axisPtr->looseMin != axisPtr->looseMax) {
+	if (axisPtr->looseMax == AXIS_TIGHT) {
+	    Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewBooleanObj(FALSE));
+	} else if (axisPtr->looseMax == AXIS_LOOSE) {
+	    Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewBooleanObj(TRUE));
+	} else if (axisPtr->looseMax == AXIS_ALWAYS_LOOSE) {
+	    Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj("always", 6));
+	}
+    }
+    return listObjPtr;
+}
+
+static void
+FreeTickLabels(Blt_Chain chain)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_FirstLink(chain); link != NULL; 
+	 link = Blt_Chain_NextLink(link)) {
+	TickLabel *labelPtr;
+
+	labelPtr = Blt_Chain_GetValue(link);
+	free(labelPtr);
+    }
+    Blt_Chain_Reset(chain);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MakeLabel --
+ *
+ *	Converts a floating point tick value to a string to be used as its
+ *	label.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Returns a new label in the string character buffer.  The formatted
+ *	tick label will be displayed on the graph.
+ *
+ * -------------------------------------------------------------------------- 
+ */
+static TickLabel *
+MakeLabel(Axis *axisPtr, double value)
+{
+#define TICK_LABEL_SIZE		200
+    char string[TICK_LABEL_SIZE + 1];
+    TickLabel *labelPtr;
+
+    /* Generate a default tick label based upon the tick value.  */
+    if (axisPtr->logScale) {
+	sprintf_s(string, TICK_LABEL_SIZE, "1E%d", ROUND(value));
+    } else {
+	sprintf_s(string, TICK_LABEL_SIZE, "%.*G", NUMDIGITS, value);
+    }
+
+    if (axisPtr->formatCmd != NULL) {
+	Graph *graphPtr;
+	Tcl_Interp *interp;
+	Tk_Window tkwin;
+	
+	graphPtr = axisPtr->obj.graphPtr;
+	interp = graphPtr->interp;
+	tkwin = graphPtr->tkwin;
+	/*
+	 * A TCL proc was designated to format tick labels. Append the path
+	 * name of the widget and the default tick label as arguments when
+	 * invoking it. Copy and save the new label from interp->result.
+	 */
+	Tcl_ResetResult(interp);
+	if (Tcl_VarEval(interp, axisPtr->formatCmd, " ", Tk_PathName(tkwin),
+		" ", string, (char *)NULL) != TCL_OK) {
+	    Tcl_BackgroundError(interp);
+	} else {
+	    /* 
+	     * The proc could return a string of any length, so arbitrarily
+	     * limit it to what will fit in the return string.
+	     */
+	    strncpy(string, Tcl_GetStringResult(interp), TICK_LABEL_SIZE);
+	    string[TICK_LABEL_SIZE] = '\0';
+	    
+	    Tcl_ResetResult(interp); /* Clear the interpreter's result. */
+	}
+    }
+    labelPtr = malloc(sizeof(TickLabel) + strlen(string));
+    strcpy(labelPtr->string, string);
+    labelPtr->anchorPos.x = labelPtr->anchorPos.y = DBL_MAX;
+    return labelPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_InvHMap --
+ *
+ *	Maps the given screen coordinate back to a graph coordinate.  Called
+ *	by the graph locater routine.
+ *
+ * Results:
+ *	Returns the graph coordinate value at the given window
+ *	y-coordinate.
+ *
+ *---------------------------------------------------------------------------
+ */
+double
+Blt_InvHMap(Axis *axisPtr, double x)
+{
+    double value;
+
+    x = (double)(x - axisPtr->screenMin) * axisPtr->screenScale;
+    if (axisPtr->descending) {
+	x = 1.0 - x;
+    }
+    value = (x * axisPtr->axisRange.range) + axisPtr->axisRange.min;
+    if (axisPtr->logScale) {
+	value = EXP10(value);
+    }
+    return value;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_InvVMap --
+ *
+ *	Maps the given screen y-coordinate back to the graph coordinate
+ *	value. Called by the graph locater routine.
+ *
+ * Results:
+ *	Returns the graph coordinate value for the given screen
+ *	coordinate.
+ *
+ *---------------------------------------------------------------------------
+ */
+double
+Blt_InvVMap(Axis *axisPtr, double y) /* Screen coordinate */
+{
+    double value;
+
+    y = (double)(y - axisPtr->screenMin) * axisPtr->screenScale;
+    if (axisPtr->descending) {
+	y = 1.0 - y;
+    }
+    value = ((1.0 - y) * axisPtr->axisRange.range) + axisPtr->axisRange.min;
+    if (axisPtr->logScale) {
+	value = EXP10(value);
+    }
+    return value;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_HMap --
+ *
+ *	Map the given graph coordinate value to its axis, returning a window
+ *	position.
+ *
+ * Results:
+ *	Returns a double precision number representing the window coordinate
+ *	position on the given axis.
+ *
+ *---------------------------------------------------------------------------
+ */
+double
+Blt_HMap(Axis *axisPtr, double x)
+{
+    if ((axisPtr->logScale) && (x != 0.0)) {
+	x = log10(fabs(x));
+    }
+    /* Map graph coordinate to normalized coordinates [0..1] */
+    x = (x - axisPtr->axisRange.min) * axisPtr->axisRange.scale;
+    if (axisPtr->descending) {
+	x = 1.0 - x;
+    }
+    return (x * axisPtr->screenRange + axisPtr->screenMin);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_VMap --
+ *
+ *	Map the given graph coordinate value to its axis, returning a window
+ *	position.
+ *
+ * Results:
+ *	Returns a double precision number representing the window coordinate
+ *	position on the given axis.
+ *
+ *---------------------------------------------------------------------------
+ */
+double
+Blt_VMap(Axis *axisPtr, double y)
+{
+    if ((axisPtr->logScale) && (y != 0.0)) {
+	y = log10(fabs(y));
+    }
+    /* Map graph coordinate to normalized coordinates [0..1] */
+    y = (y - axisPtr->axisRange.min) * axisPtr->axisRange.scale;
+    if (axisPtr->descending) {
+	y = 1.0 - y;
+    }
+    return ((1.0 - y) * axisPtr->screenRange + axisPtr->screenMin);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Map2D --
+ *
+ *	Maps the given graph x,y coordinate values to a window position.
+ *
+ * Results:
+ *	Returns a XPoint structure containing the window coordinates of
+ *	the given graph x,y coordinate.
+ *
+ *---------------------------------------------------------------------------
+ */
+Point2d
+Blt_Map2D(
+    Graph *graphPtr,
+    double x, double y,			/* Graph x and y coordinates */
+    Axis2d *axesPtr)			/* Specifies which axes to use */
+{
+    Point2d point;
+
+    if (graphPtr->inverted) {
+	point.x = Blt_HMap(axesPtr->y, y);
+	point.y = Blt_VMap(axesPtr->x, x);
+    } else {
+	point.x = Blt_HMap(axesPtr->x, x);
+	point.y = Blt_VMap(axesPtr->y, y);
+    }
+    return point;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_InvMap2D --
+ *
+ *	Maps the given window x,y coordinates to graph values.
+ *
+ * Results:
+ *	Returns a structure containing the graph coordinates of the given
+ *	window x,y coordinate.
+ *
+ *---------------------------------------------------------------------------
+ */
+Point2d
+Blt_InvMap2D(
+    Graph *graphPtr,
+    double x, double y,			/* Window x and y coordinates */
+    Axis2d *axesPtr)			/* Specifies which axes to use */
+{
+    Point2d point;
+
+    if (graphPtr->inverted) {
+	point.x = Blt_InvVMap(axesPtr->x, y);
+	point.y = Blt_InvHMap(axesPtr->y, x);
+    } else {
+	point.x = Blt_InvHMap(axesPtr->x, x);
+	point.y = Blt_InvVMap(axesPtr->y, y);
+    }
+    return point;
+}
+
+
+static void
+GetDataLimits(Axis *axisPtr, double min, double max)
+{
+    if (axisPtr->valueRange.min > min) {
+	axisPtr->valueRange.min = min;
+    }
+    if (axisPtr->valueRange.max < max) {
+	axisPtr->valueRange.max = max;
+    }
+}
+
+static void
+FixAxisRange(Axis *axisPtr)
+{
+    double min, max;
+
+    /*
+     * When auto-scaling, the axis limits are the bounds of the element data.
+     * If no data exists, set arbitrary limits (wrt to log/linear scale).
+     */
+    min = axisPtr->valueRange.min;
+    max = axisPtr->valueRange.max;
+
+    /* Check the requested axis limits. Can't allow -min to be greater
+     * than -max, or have undefined log scale limits.  */
+    if (((isnormal(axisPtr->reqMin)) && (isnormal(axisPtr->reqMax))) &&
+	(axisPtr->reqMin >= axisPtr->reqMax)) {
+      axisPtr->reqMin = axisPtr->reqMax = NAN;
+    }
+    if (axisPtr->logScale) {
+	if ((isnormal(axisPtr->reqMin)) && (axisPtr->reqMin <= 0.0)) {
+	  axisPtr->reqMin = NAN;
+	}
+	if ((isnormal(axisPtr->reqMax)) && (axisPtr->reqMax <= 0.0)) {
+	  axisPtr->reqMax = NAN;
+	}
+    }
+
+    if (min == DBL_MAX) {
+	if (isnormal(axisPtr->reqMin)) {
+	    min = axisPtr->reqMin;
+	} else {
+	    min = (axisPtr->logScale) ? 0.001 : 0.0;
+	}
+    }
+    if (max == -DBL_MAX) {
+	if (isnormal(axisPtr->reqMax)) {
+	    max = axisPtr->reqMax;
+	} else {
+	    max = 1.0;
+	}
+    }
+    if (min >= max) {
+	/*
+	 * There is no range of data (i.e. min is not less than max), so
+	 * manufacture one.
+	 */
+	if (min == 0.0) {
+	    min = 0.0, max = 1.0;
+	} else {
+	    max = min + (fabs(min) * 0.1);
+	}
+    }
+    SetAxisRange(&axisPtr->valueRange, min, max);
+
+    /*   
+     * The axis limits are either the current data range or overridden by the
+     * values selected by the user with the -min or -max options.
+     */
+    axisPtr->min = min;
+    axisPtr->max = max;
+    if (isnormal(axisPtr->reqMin)) {
+	axisPtr->min = axisPtr->reqMin;
+    }
+    if (isnormal(axisPtr->reqMax)) { 
+	axisPtr->max = axisPtr->reqMax;
+    }
+    if (axisPtr->max < axisPtr->min) {
+	/*   
+	 * If the limits still don't make sense, it's because one limit
+	 * configuration option (-min or -max) was set and the other default
+	 * (based upon the data) is too small or large.  Remedy this by making
+	 * up a new min or max from the user-defined limit.
+	 */
+	if (!isnormal(axisPtr->reqMin)) {
+	    axisPtr->min = axisPtr->max - (fabs(axisPtr->max) * 0.1);
+	}
+	if (!isnormal(axisPtr->reqMax)) {
+	    axisPtr->max = axisPtr->min + (fabs(axisPtr->max) * 0.1);
+	}
+    }
+    /* 
+     * If a window size is defined, handle auto ranging by shifting the axis
+     * limits.
+     */
+    if ((axisPtr->windowSize > 0.0) && 
+	(!isnormal(axisPtr->reqMin)) && (!isnormal(axisPtr->reqMax))) {
+	if (axisPtr->shiftBy < 0.0) {
+	    axisPtr->shiftBy = 0.0;
+	}
+	max = axisPtr->min + axisPtr->windowSize;
+	if (axisPtr->max >= max) {
+	    if (axisPtr->shiftBy > 0.0) {
+		max = UCEIL(axisPtr->max, axisPtr->shiftBy);
+	    }
+	    axisPtr->min = max - axisPtr->windowSize;
+	}
+	axisPtr->max = max;
+    }
+    if ((axisPtr->max != axisPtr->prevMax) || 
+	(axisPtr->min != axisPtr->prevMin)) {
+	/* Indicate if the axis limits have changed */
+	axisPtr->flags |= DIRTY;
+	/* and save the previous minimum and maximum values */
+	axisPtr->prevMin = axisPtr->min;
+	axisPtr->prevMax = axisPtr->max;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NiceNum --
+ *
+ *	Reference: Paul Heckbert, "Nice Numbers for Graph Labels",
+ *		   Graphics Gems, pp 61-63.  
+ *
+ *	Finds a "nice" number approximately equal to x.
+ *
+ *---------------------------------------------------------------------------
+ */
+static double
+NiceNum(double x, int round)		/* If non-zero, round. Otherwise take
+					 * ceiling of value. */
+{
+    double expt;			/* Exponent of x */
+    double frac;			/* Fractional part of x */
+    double nice;			/* Nice, rounded fraction */
+
+    expt = floor(log10(x));
+    frac = x / EXP10(expt);		/* between 1 and 10 */
+    if (round) {
+	if (frac < 1.5) {
+	    nice = 1.0;
+	} else if (frac < 3.0) {
+	    nice = 2.0;
+	} else if (frac < 7.0) {
+	    nice = 5.0;
+	} else {
+	    nice = 10.0;
+	}
+    } else {
+	if (frac <= 1.0) {
+	    nice = 1.0;
+	} else if (frac <= 2.0) {
+	    nice = 2.0;
+	} else if (frac <= 5.0) {
+	    nice = 5.0;
+	} else {
+	    nice = 10.0;
+	}
+    }
+    return nice * EXP10(expt);
+}
+
+static Ticks *
+GenerateTicks(TickSweep *sweepPtr)
+{
+    Ticks *ticksPtr;
+
+    ticksPtr = malloc(sizeof(Ticks) + 
+	(sweepPtr->nSteps * sizeof(double)));
+    ticksPtr->nTicks = 0;
+
+    if (sweepPtr->step == 0.0) { 
+	/* Hack: A zero step indicates to use log values. */
+	int i;
+	/* Precomputed log10 values [1..10] */
+	static double logTable[] = {
+	    0.0, 
+	    0.301029995663981, 
+	    0.477121254719662, 
+	    0.602059991327962, 
+	    0.698970004336019, 
+	    0.778151250383644, 
+	    0.845098040014257,
+	    0.903089986991944, 
+	    0.954242509439325, 
+	    1.0
+	};
+	for (i = 0; i < sweepPtr->nSteps; i++) {
+	    ticksPtr->values[i] = logTable[i];
+	}
+    } else {
+	double value;
+	int i;
+    
+	value = sweepPtr->initial;	/* Start from smallest axis tick */
+	for (i = 0; i < sweepPtr->nSteps; i++) {
+	    value = UROUND(value, sweepPtr->step);
+	    ticksPtr->values[i] = value;
+	    value += sweepPtr->step;
+	}
+    }
+    ticksPtr->nTicks = sweepPtr->nSteps;
+    return ticksPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LogScaleAxis --
+ *
+ * 	Determine the range and units of a log scaled axis.
+ *
+ * 	Unless the axis limits are specified, the axis is scaled
+ * 	automatically, where the smallest and largest major ticks encompass
+ * 	the range of actual data values.  When an axis limit is specified,
+ * 	that value represents the smallest(min)/largest(max) value in the
+ * 	displayed range of values.
+ *
+ * 	Both manual and automatic scaling are affected by the step used.  By
+ * 	default, the step is the largest power of ten to divide the range in
+ * 	more than one piece.
+ *
+ *	Automatic scaling:
+ *	Find the smallest number of units which contain the range of values.
+ *	The minimum and maximum major tick values will be represent the
+ *	range of values for the axis. This greatest number of major ticks
+ *	possible is 10.
+ *
+ * 	Manual scaling:
+ *   	Make the minimum and maximum data values the represent the range of
+ *   	the values for the axis.  The minimum and maximum major ticks will be
+ *   	inclusive of this range.  This provides the largest area for plotting
+ *   	and the expected results when the axis min and max values have be set
+ *   	by the user (.e.g zooming).  The maximum number of major ticks is 20.
+ *
+ *   	For log scale, there's the possibility that the minimum and
+ *   	maximum data values are the same magnitude.  To represent the
+ *   	points properly, at least one full decade should be shown.
+ *   	However, if you zoom a log scale plot, the results should be
+ *   	predictable. Therefore, in that case, show only minor ticks.
+ *   	Lastly, there should be an appropriate way to handle numbers
+ *   	<=0.
+ *
+ *          maxY
+ *            |    units = magnitude (of least significant digit)
+ *            |    high  = largest unit tick < max axis value
+ *      high _|    low   = smallest unit tick > min axis value
+ *            |
+ *            |    range = high - low
+ *            |    # ticks = greatest factor of range/units
+ *           _|
+ *        U   |
+ *        n   |
+ *        i   |
+ *        t  _|
+ *            |
+ *            |
+ *            |
+ *       low _|
+ *            |
+ *            |_minX________________maxX__
+ *            |   |       |      |       |
+ *     minY  low                        high
+ *           minY
+ *
+ *
+ * 	numTicks = Number of ticks
+ * 	min = Minimum value of axis
+ * 	max = Maximum value of axis
+ * 	range    = Range of values (max - min)
+ *
+ * 	If the number of decades is greater than ten, it is assumed
+ *	that the full set of log-style ticks can't be drawn properly.
+ *
+ * Results:
+ *	None
+ *
+ * -------------------------------------------------------------------------- */
+static void
+LogScaleAxis(Axis *axisPtr, double min, double max)
+{
+    double range;
+    double tickMin, tickMax;
+    double majorStep, minorStep;
+    int nMajor, nMinor;
+
+    nMajor = nMinor = 0;
+    /* Suppress compiler warnings. */
+    majorStep = minorStep = 0.0;
+    tickMin = tickMax = NAN;
+    if (min < max) {
+	min = (min != 0.0) ? log10(fabs(min)) : 0.0;
+	max = (max != 0.0) ? log10(fabs(max)) : 1.0;
+
+	tickMin = floor(min);
+	tickMax = ceil(max);
+	range = tickMax - tickMin;
+	
+	if (range > 10) {
+	    /* There are too many decades to display a major tick at every
+	     * decade.  Instead, treat the axis as a linear scale.  */
+	    range = NiceNum(range, 0);
+	    majorStep = NiceNum(range / axisPtr->reqNumMajorTicks, 1);
+	    tickMin = UFLOOR(tickMin, majorStep);
+	    tickMax = UCEIL(tickMax, majorStep);
+	    nMajor = (int)((tickMax - tickMin) / majorStep) + 1;
+	    minorStep = EXP10(floor(log10(majorStep)));
+	    if (minorStep == majorStep) {
+		nMinor = 4, minorStep = 0.2;
+	    } else {
+		nMinor = Round(majorStep / minorStep) - 1;
+	    }
+	} else {
+	    if (tickMin == tickMax) {
+		tickMax++;
+	    }
+	    majorStep = 1.0;
+	    nMajor = (int)(tickMax - tickMin + 1); /* FIXME: Check this. */
+	    
+	    minorStep = 0.0;		/* This is a special hack to pass
+					 * information to the GenerateTicks
+					 * routine. An interval of 0.0 tells 1)
+					 * this is a minor sweep and 2) the axis
+					 * is log scale. */
+	    nMinor = 10;
+	}
+	if ((axisPtr->looseMin == AXIS_TIGHT) || 
+	    ((axisPtr->looseMin == AXIS_LOOSE) && 
+	     (isnormal(axisPtr->reqMin)))) {
+	    tickMin = min;
+	    nMajor++;
+	}
+	if ((axisPtr->looseMax == AXIS_TIGHT) || 
+	    ((axisPtr->looseMax == AXIS_LOOSE) &&
+	     (isnormal(axisPtr->reqMax)))) {
+	    tickMax = max;
+	}
+    }
+    axisPtr->majorSweep.step = majorStep;
+    axisPtr->majorSweep.initial = floor(tickMin);
+    axisPtr->majorSweep.nSteps = nMajor;
+    axisPtr->minorSweep.initial = axisPtr->minorSweep.step = minorStep;
+    axisPtr->minorSweep.nSteps = nMinor;
+
+    SetAxisRange(&axisPtr->axisRange, tickMin, tickMax);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LinearScaleAxis --
+ *
+ * 	Determine the units of a linear scaled axis.
+ *
+ *	The axis limits are either the range of the data values mapped
+ *	to the axis (autoscaled), or the values specified by the -min
+ *	and -max options (manual).
+ *
+ *	If autoscaled, the smallest and largest major ticks will
+ *	encompass the range of data values.  If the -loose option is
+ *	selected, the next outer ticks are choosen.  If tight, the
+ *	ticks are at or inside of the data limits are used.
+ *
+ * 	If manually set, the ticks are at or inside the data limits
+ * 	are used.  This makes sense for zooming.  You want the
+ * 	selected range to represent the next limit, not something a
+ * 	bit bigger.
+ *
+ *	Note: I added an "always" value to the -loose option to force
+ *	      the manually selected axes to be loose. It's probably
+ *	      not a good idea.
+ *
+ *          maxY
+ *            |    units = magnitude (of least significant digit)
+ *            |    high  = largest unit tick < max axis value
+ *      high _|    low   = smallest unit tick > min axis value
+ *            |
+ *            |    range = high - low
+ *            |    # ticks = greatest factor of range/units
+ *           _|
+ *        U   |
+ *        n   |
+ *        i   |
+ *        t  _|
+ *            |
+ *            |
+ *            |
+ *       low _|
+ *            |
+ *            |_minX________________maxX__
+ *            |   |       |      |       |
+ *     minY  low                        high
+ *           minY
+ *
+ * 	numTicks = Number of ticks
+ * 	min = Minimum value of axis
+ * 	max = Maximum value of axis
+ * 	range    = Range of values (max - min)
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	The axis tick information is set.  The actual tick values will
+ *	be generated later.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+LinearScaleAxis(Axis *axisPtr, double min, double max)
+{
+    double step;
+    double tickMin, tickMax;
+    double axisMin, axisMax;
+    unsigned int nTicks;
+
+    nTicks = 0;
+    step = 1.0;
+    /* Suppress compiler warning. */
+    axisMin = axisMax = tickMin = tickMax = NAN;
+    if (min < max) {
+	double range;
+
+	range = max - min;
+	/* Calculate the major tick stepping. */
+	if (axisPtr->reqStep > 0.0) {
+	    /* An interval was designated by the user.  Keep scaling it until
+	     * it fits comfortably within the current range of the axis.  */
+	    step = axisPtr->reqStep;
+	    while ((2 * step) >= range) {
+		step *= 0.5;
+	    }
+	} else {
+	    range = NiceNum(range, 0);
+	    step = NiceNum(range / axisPtr->reqNumMajorTicks, 1);
+	}
+	
+	/* Find the outer tick values. Add 0.0 to prevent getting -0.0. */
+	axisMin = tickMin = floor(min / step) * step + 0.0;
+	axisMax = tickMax = ceil(max / step) * step + 0.0;
+	
+	nTicks = Round((tickMax - tickMin) / step) + 1;
+    } 
+    axisPtr->majorSweep.step = step;
+    axisPtr->majorSweep.initial = tickMin;
+    axisPtr->majorSweep.nSteps = nTicks;
+
+    /*
+     * The limits of the axis are either the range of the data ("tight") or at
+     * the next outer tick interval ("loose").  The looseness or tightness has
+     * to do with how the axis fits the range of data values.  This option is
+     * overridden when the user sets an axis limit (by either -min or -max
+     * option).  The axis limit is always at the selected limit (otherwise we
+     * assume that user would have picked a different number).
+     */
+    if ((axisPtr->looseMin == AXIS_TIGHT) || 
+	((axisPtr->looseMin == AXIS_LOOSE) &&
+	 (isnormal(axisPtr->reqMin)))) {
+	axisMin = min;
+    }
+    if ((axisPtr->looseMax == AXIS_TIGHT) || 
+	((axisPtr->looseMax == AXIS_LOOSE) &&
+	 (isnormal(axisPtr->reqMax)))) {
+	axisMax = max;
+    }
+    SetAxisRange(&axisPtr->axisRange, axisMin, axisMax);
+
+    /* Now calculate the minor tick step and number. */
+
+    if ((axisPtr->reqNumMinorTicks > 0) && (axisPtr->flags & AXIS_AUTO_MAJOR)) {
+	nTicks = axisPtr->reqNumMinorTicks - 1;
+	step = 1.0 / (nTicks + 1);
+    } else {
+	nTicks = 0;			/* No minor ticks. */
+	step = 0.5;			/* Don't set the minor tick interval to
+					 * 0.0. It makes the GenerateTicks
+					 * routine * create minor log-scale tick
+					 * marks.  */
+    }
+    axisPtr->minorSweep.initial = axisPtr->minorSweep.step = step;
+    axisPtr->minorSweep.nSteps = nTicks;
+}
+
+
+static void
+SweepTicks(Axis *axisPtr)
+{
+    if (axisPtr->flags & AXIS_AUTO_MAJOR) {
+	if (axisPtr->t1Ptr != NULL) {
+	    free(axisPtr->t1Ptr);
+	}
+	axisPtr->t1Ptr = GenerateTicks(&axisPtr->majorSweep);
+    }
+    if (axisPtr->flags & AXIS_AUTO_MINOR) {
+	if (axisPtr->t2Ptr != NULL) {
+	    free(axisPtr->t2Ptr);
+	}
+	axisPtr->t2Ptr = GenerateTicks(&axisPtr->minorSweep);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ResetAxes --
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_ResetAxes(Graph *graphPtr)
+{
+    Blt_ChainLink link;
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch cursor;
+
+    /* FIXME: This should be called whenever the display list of
+     *	      elements change. Maybe yet another flag INIT_STACKS to
+     *	      indicate that the element display list has changed.
+     *	      Needs to be done before the axis limits are set.
+     */
+    Blt_InitBarSetTable(graphPtr);
+    if ((graphPtr->mode == BARS_STACKED) && (graphPtr->nBarGroups > 0)) {
+	Blt_ComputeBarStacks(graphPtr);
+    }
+    /*
+     * Step 1:  Reset all axes. Initialize the data limits of the axis to
+     *		impossible values.
+     */
+    for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor);
+	hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	Axis *axisPtr;
+
+	axisPtr = Blt_GetHashValue(hPtr);
+	axisPtr->min = axisPtr->valueRange.min = DBL_MAX;
+	axisPtr->max = axisPtr->valueRange.max = -DBL_MAX;
+    }
+
+    /*
+     * Step 2:  For each element that's to be displayed, get the smallest
+     *		and largest data values mapped to each X and Y-axis.  This
+     *		will be the axis limits if the user doesn't override them 
+     *		with -min and -max options.
+     */
+    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+	 link != NULL; link = Blt_Chain_NextLink(link)) {
+	Element *elemPtr;
+	Region2d exts;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if ((graphPtr->flags & UNMAP_HIDDEN) && (elemPtr->flags & HIDE)) {
+	    continue;
+	}
+	(*elemPtr->procsPtr->extentsProc) (elemPtr, &exts);
+	GetDataLimits(elemPtr->axes.x, exts.left, exts.right);
+	GetDataLimits(elemPtr->axes.y, exts.top, exts.bottom);
+    }
+    /*
+     * Step 3:  Now that we know the range of data values for each axis,
+     *		set axis limits and compute a sweep to generate tick values.
+     */
+    for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor);
+	 hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	Axis *axisPtr;
+	double min, max;
+
+	axisPtr = Blt_GetHashValue(hPtr);
+	FixAxisRange(axisPtr);
+
+	/* Calculate min/max tick (major/minor) layouts */
+	min = axisPtr->min;
+	max = axisPtr->max;
+	if ((isnormal(axisPtr->scrollMin)) && (min < axisPtr->scrollMin)) {
+	    min = axisPtr->scrollMin;
+	}
+	if ((isnormal(axisPtr->scrollMax)) && (max > axisPtr->scrollMax)) {
+	    max = axisPtr->scrollMax;
+	}
+	if (axisPtr->logScale) {
+	    LogScaleAxis(axisPtr, min, max);
+	} else if (axisPtr->timeScale) {
+	    TimeScaleAxis(axisPtr, min, max);
+	} else {
+	    LinearScaleAxis(axisPtr, min, max);
+	}
+
+	if ((axisPtr->flags & (DIRTY|AXIS_USE)) == (DIRTY|AXIS_USE)) {
+	    graphPtr->flags |= CACHE_DIRTY;
+	}
+    }
+
+    graphPtr->flags &= ~RESET_AXES;
+
+    /*
+     * When any axis changes, we need to layout the entire graph.
+     */
+    graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | MAP_ALL | 
+			REDRAW_WORLD);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ResetTextStyles --
+ *
+ *	Configures axis attributes (font, line width, label, etc) and
+ *	allocates a new (possibly shared) graphics context.  Line cap style is
+ *	projecting.  This is for the problem of when a tick sits directly at
+ *	the end point of the axis.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ * Side Effects:
+ *	Axis resources are allocated (GC, font). Axis layout is deferred until
+ *	the height and width of the window are known.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+ResetTextStyles(Axis *axisPtr)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+    GC newGC;
+    XGCValues gcValues;
+    unsigned long gcMask;
+
+    Blt_Ts_ResetStyle(graphPtr->tkwin, &axisPtr->limitsTextStyle);
+
+    gcMask = (GCForeground | GCLineWidth | GCCapStyle);
+    gcValues.foreground = axisPtr->tickColor->pixel;
+    gcValues.font = Blt_FontId(axisPtr->tickFont);
+    gcValues.line_width = LineWidth(axisPtr->lineWidth);
+    gcValues.cap_style = CapProjecting;
+
+    newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (axisPtr->tickGC != NULL) {
+	Tk_FreeGC(graphPtr->display, axisPtr->tickGC);
+    }
+    axisPtr->tickGC = newGC;
+
+    /* Assuming settings from above GC */
+    gcValues.foreground = axisPtr->activeFgColor->pixel;
+    newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (axisPtr->activeTickGC != NULL) {
+	Tk_FreeGC(graphPtr->display, axisPtr->activeTickGC);
+    }
+    axisPtr->activeTickGC = newGC;
+
+    gcValues.background = gcValues.foreground = axisPtr->major.color->pixel;
+    gcValues.line_width = LineWidth(axisPtr->major.lineWidth);
+    gcMask = (GCForeground | GCBackground | GCLineWidth);
+    if (LineIsDashed(axisPtr->major.dashes)) {
+	gcValues.line_style = LineOnOffDash;
+	gcMask |= GCLineStyle;
+    }
+    newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (LineIsDashed(axisPtr->major.dashes)) {
+	Blt_SetDashes(graphPtr->display, newGC, &axisPtr->major.dashes);
+    }
+    if (axisPtr->major.gc != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, axisPtr->major.gc);
+    }
+    axisPtr->major.gc = newGC;
+
+    gcValues.background = gcValues.foreground = axisPtr->minor.color->pixel;
+    gcValues.line_width = LineWidth(axisPtr->minor.lineWidth);
+    gcMask = (GCForeground | GCBackground | GCLineWidth);
+    if (LineIsDashed(axisPtr->minor.dashes)) {
+	gcValues.line_style = LineOnOffDash;
+	gcMask |= GCLineStyle;
+    }
+    newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (LineIsDashed(axisPtr->minor.dashes)) {
+	Blt_SetDashes(graphPtr->display, newGC, &axisPtr->minor.dashes);
+    }
+    if (axisPtr->minor.gc != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, axisPtr->minor.gc);
+    }
+    axisPtr->minor.gc = newGC;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DestroyAxis --
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Resources (font, color, gc, labels, etc.) associated with the axis are
+ *	deallocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DestroyAxis(Axis *axisPtr)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+    int flags;
+
+    flags = Blt_GraphType(graphPtr);
+    Blt_FreeOptions(configSpecs, (char *)axisPtr, graphPtr->display, flags);
+    if (graphPtr->bindTable != NULL) {
+	Blt_DeleteBindings(graphPtr->bindTable, axisPtr);
+    }
+    if (axisPtr->link != NULL) {
+	Blt_Chain_DeleteLink(axisPtr->chain, axisPtr->link);
+    }
+    if (axisPtr->obj.name != NULL) {
+      free((void*)(axisPtr->obj.name));
+    }
+    if (axisPtr->hashPtr != NULL) {
+	Blt_DeleteHashEntry(&graphPtr->axes.table, axisPtr->hashPtr);
+    }
+    Blt_Ts_FreeStyle(graphPtr->display, &axisPtr->limitsTextStyle);
+
+    if (axisPtr->tickGC != NULL) {
+	Tk_FreeGC(graphPtr->display, axisPtr->tickGC);
+    }
+    if (axisPtr->activeTickGC != NULL) {
+	Tk_FreeGC(graphPtr->display, axisPtr->activeTickGC);
+    }
+    if (axisPtr->major.gc != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, axisPtr->major.gc);
+    }
+    if (axisPtr->minor.gc != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, axisPtr->minor.gc);
+    }
+    FreeTickLabels(axisPtr->tickLabels);
+    Blt_Chain_Destroy(axisPtr->tickLabels);
+    if (axisPtr->segments != NULL) {
+	free(axisPtr->segments);
+    }
+    free(axisPtr);
+    axisPtr = NULL;
+}
+
+static void FreeAxis(char* data)
+{
+    Axis *axisPtr = (Axis *)data;
+    DestroyAxis(axisPtr);
+}
+
+static float titleAngle[4] =		/* Rotation for each axis title */
+{
+    0.0, 90.0, 0.0, 270.0
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisOffsets --
+ *
+ *	Determines the sites of the axis, major and minor ticks, and title of
+ *	the axis.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+AxisOffsets(
+    Axis *axisPtr,
+    int margin,
+    int offset,
+    AxisInfo *infoPtr)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+    Margin *marginPtr;
+    int pad;				/* Offset of axis from interior
+					 * region. This includes a possible
+					 * border and the axis line width. */
+    int axisLine;
+    int t1, t2, labelOffset;
+    int tickLabel, axisPad;
+    int inset, mark;
+    int x, y;
+    float fangle;
+
+    axisPtr->titleAngle = titleAngle[margin];
+    marginPtr = graphPtr->margins + margin;
+
+    tickLabel = axisLine = t1 = t2 = 0;
+    labelOffset = AXIS_PAD_TITLE;
+    if (axisPtr->lineWidth > 0) {
+	if (axisPtr->flags & AXIS_SHOWTICKS) {
+	    t1 = axisPtr->tickLength;
+	    t2 = (t1 * 10) / 15;
+	}
+	labelOffset = t1 + AXIS_PAD_TITLE;
+	if (axisPtr->flags & AXIS_EXTERIOR) {
+	    labelOffset += axisPtr->lineWidth;
+	}
+    }
+    axisPad = 0;
+    if (graphPtr->plotRelief != TK_RELIEF_SOLID) {
+	axisPad = 0;
+    }
+    /* Adjust offset for the interior border width and the line width */
+    pad = 1;
+    if (graphPtr->plotBW > 0) {
+	pad += graphPtr->plotBW + 1;
+    }
+    pad = 0;				/* FIXME: test */
+    /*
+     * Pre-calculate the x-coordinate positions of the axis, tick labels, and
+     * the individual major and minor ticks.
+     */
+    inset = pad + axisPtr->lineWidth / 2;
+    switch (margin) {
+    case MARGIN_TOP:
+	axisLine = graphPtr->top;
+	if (axisPtr->flags & AXIS_EXTERIOR) {
+	    axisLine -= graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2;
+	    tickLabel = axisLine - 2;
+	    if (axisPtr->lineWidth > 0) {
+		tickLabel -= axisPtr->tickLength;
+	    }
+	} else {
+	    if (graphPtr->plotRelief == TK_RELIEF_SOLID) {
+		axisLine--;
+	    } 
+	    axisLine -= axisPad + axisPtr->lineWidth / 2;
+	    tickLabel = graphPtr->top -  graphPtr->plotBW - 2;
+	}
+	mark = graphPtr->top - offset - pad;
+	axisPtr->tickAnchor = TK_ANCHOR_S;
+	axisPtr->left = axisPtr->screenMin - inset - 2;
+	axisPtr->right = axisPtr->screenMin + axisPtr->screenRange + inset - 1;
+	if (graphPtr->stackAxes) {
+	    axisPtr->top = mark - marginPtr->axesOffset;
+	} else {
+	    axisPtr->top = mark - axisPtr->height;
+	}
+	axisPtr->bottom = mark;
+	if (axisPtr->titleAlternate) {
+	    x = graphPtr->right + AXIS_PAD_TITLE;
+	    y = mark - (axisPtr->height  / 2);
+	    axisPtr->titleAnchor = TK_ANCHOR_W;
+	} else {
+	    x = (axisPtr->right + axisPtr->left) / 2;
+	    if (graphPtr->stackAxes) {
+		y = mark - marginPtr->axesOffset + AXIS_PAD_TITLE;
+	    } else {
+		y = mark - axisPtr->height + AXIS_PAD_TITLE;
+	    }
+	    axisPtr->titleAnchor = TK_ANCHOR_N;
+	}
+	axisPtr->titlePos.x = x;
+	axisPtr->titlePos.y = y;
+	break;
+
+    case MARGIN_BOTTOM:
+	/*
+	 *  ----------- bottom + plot borderwidth
+	 *      mark --------------------------------------------
+	 *          ===================== axisLine (linewidth)
+	 *                   tick
+	 *		    title
+	 *
+	 *          ===================== axisLine (linewidth)
+	 *  ----------- bottom + plot borderwidth
+	 *      mark --------------------------------------------
+	 *                   tick
+	 *		    title
+	 */
+	axisLine = graphPtr->bottom;
+	if (graphPtr->plotRelief == TK_RELIEF_SOLID) {
+	    axisLine++;
+	} 
+	if (axisPtr->flags & AXIS_EXTERIOR) {
+	    axisLine += graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2;
+	    tickLabel = axisLine + 2;
+	    if (axisPtr->lineWidth > 0) {
+		tickLabel += axisPtr->tickLength;
+	    }
+	} else {
+	    axisLine -= axisPad + axisPtr->lineWidth / 2;
+	    tickLabel = graphPtr->bottom +  graphPtr->plotBW + 2;
+	}
+	mark = graphPtr->bottom + offset;
+	fangle = fmod(axisPtr->tickAngle, 90.0);
+	if (fangle == 0.0) {
+	    axisPtr->tickAnchor = TK_ANCHOR_N;
+	} else {
+	    int quadrant;
+
+	    quadrant = (int)(axisPtr->tickAngle / 90.0);
+	    if ((quadrant == 0) || (quadrant == 2)) {
+		axisPtr->tickAnchor = TK_ANCHOR_NE;
+	    } else {
+		axisPtr->tickAnchor = TK_ANCHOR_NW;
+	    }
+	}
+	axisPtr->left = axisPtr->screenMin - inset - 2;
+	axisPtr->right = axisPtr->screenMin + axisPtr->screenRange + inset - 1;
+	axisPtr->top = graphPtr->bottom + labelOffset - t1;
+	if (graphPtr->stackAxes) {
+	    axisPtr->bottom = mark + marginPtr->axesOffset - 1;
+	} else {
+	    axisPtr->bottom = mark + axisPtr->height - 1;
+	}
+	if (axisPtr->titleAlternate) {
+	    x = graphPtr->right + AXIS_PAD_TITLE;
+	    y = mark + (axisPtr->height / 2);
+	    axisPtr->titleAnchor = TK_ANCHOR_W; 
+	} else {
+	    x = (axisPtr->right + axisPtr->left) / 2;
+	    if (graphPtr->stackAxes) {
+		y = mark + marginPtr->axesOffset - AXIS_PAD_TITLE;
+	    } else {
+		y = mark + axisPtr->height - AXIS_PAD_TITLE;
+	    }
+	    axisPtr->titleAnchor = TK_ANCHOR_S; 
+	}
+	axisPtr->titlePos.x = x;
+	axisPtr->titlePos.y = y;
+	break;
+
+    case MARGIN_LEFT:
+	/*
+	 *                    mark
+	 *                  |  : 
+	 *                  |  :      
+	 *                  |  : 
+	 *                  |  :
+	 *                  |  : 
+	 *     axisLine
+	 */
+	/* 
+	 * Exterior axis 
+	 *     + plotarea right
+	 *     |A|B|C|D|E|F|G|H
+	 *           |right
+	 * A = plot pad 
+	 * B = plot border width
+	 * C = axis pad
+	 * D = axis line
+	 * E = tick length
+	 * F = tick label 
+	 * G = graph border width
+	 * H = highlight thickness
+	 */
+	/* 
+	 * Interior axis 
+	 *     + plotarea right
+	 *     |A|B|C|D|E|F|G|H
+	 *           |right
+	 * A = plot pad 
+	 * B = tick length
+	 * C = axis line width
+	 * D = axis pad
+	 * E = plot border width
+	 * F = tick label 
+	 * G = graph border width
+	 * H = highlight thickness
+	 */
+	axisLine = graphPtr->left;
+	if (axisPtr->flags & AXIS_EXTERIOR) {
+	    axisLine -= graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2;
+	    tickLabel = axisLine - 2;
+	    if (axisPtr->lineWidth > 0) {
+		tickLabel -= axisPtr->tickLength;
+	    }
+	} else {
+	    if (graphPtr->plotRelief == TK_RELIEF_SOLID) {
+		axisLine--;
+	    } 
+	    axisLine += axisPad + axisPtr->lineWidth / 2;
+	    tickLabel = graphPtr->left - graphPtr->plotBW - 2;
+	}
+	mark = graphPtr->left - offset;
+	axisPtr->tickAnchor = TK_ANCHOR_E;
+	if (graphPtr->stackAxes) {
+	    axisPtr->left = mark - marginPtr->axesOffset;
+	} else {
+	    axisPtr->left = mark - axisPtr->width;
+	}
+	axisPtr->right = mark - 3;
+	axisPtr->top = axisPtr->screenMin - inset - 2;
+	axisPtr->bottom = axisPtr->screenMin + axisPtr->screenRange + inset - 1;
+	if (axisPtr->titleAlternate) {
+	    x = mark - (axisPtr->width / 2);
+	    y = graphPtr->top - AXIS_PAD_TITLE;
+	    axisPtr->titleAnchor = TK_ANCHOR_SW; 
+	} else {
+	    if (graphPtr->stackAxes) {
+		x = mark - marginPtr->axesOffset;
+	    } else {
+		x = mark - axisPtr->width + AXIS_PAD_TITLE;
+	    }
+	    y = (axisPtr->bottom + axisPtr->top) / 2;
+	    axisPtr->titleAnchor = TK_ANCHOR_W; 
+	} 
+	axisPtr->titlePos.x = x;
+	axisPtr->titlePos.y = y;
+	break;
+
+    case MARGIN_RIGHT:
+	axisLine = graphPtr->right;
+	if (graphPtr->plotRelief == TK_RELIEF_SOLID) {
+	    axisLine++;			/* Draw axis line within solid plot
+					 * border. */
+	} 
+	if (axisPtr->flags & AXIS_EXTERIOR) {
+	    axisLine += graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2;
+	    tickLabel = axisLine + 2;
+	    if (axisPtr->lineWidth > 0) {
+		tickLabel += axisPtr->tickLength;
+	    }
+	} else {
+	    axisLine -= axisPad + axisPtr->lineWidth / 2;
+	    tickLabel = graphPtr->right + graphPtr->plotBW + 2;
+	}
+	mark = graphPtr->right + offset + pad;
+	axisPtr->tickAnchor = TK_ANCHOR_W;
+	axisPtr->left = mark;
+	if (graphPtr->stackAxes) {
+	    axisPtr->right = mark + marginPtr->axesOffset - 1;
+	} else {
+	    axisPtr->right = mark + axisPtr->width - 1;
+	}
+	axisPtr->top = axisPtr->screenMin - inset - 2;
+	axisPtr->bottom = axisPtr->screenMin + axisPtr->screenRange + inset -1;
+	if (axisPtr->titleAlternate) {
+	    x = mark + (axisPtr->width / 2);
+	    y = graphPtr->top - AXIS_PAD_TITLE;
+	    axisPtr->titleAnchor = TK_ANCHOR_SE; 
+	} else {
+	    if (graphPtr->stackAxes) {
+		x = mark + marginPtr->axesOffset - AXIS_PAD_TITLE;
+	    } else {
+		x = mark + axisPtr->width - AXIS_PAD_TITLE;
+	    }
+	    y = (axisPtr->bottom + axisPtr->top) / 2;
+	    axisPtr->titleAnchor = TK_ANCHOR_E;
+	}
+	axisPtr->titlePos.x = x;
+	axisPtr->titlePos.y = y;
+	break;
+
+    case MARGIN_NONE:
+	axisLine = 0;
+	break;
+    }
+    if ((margin == MARGIN_LEFT) || (margin == MARGIN_TOP)) {
+	t1 = -t1, t2 = -t2;
+	labelOffset = -labelOffset;
+    }
+    infoPtr->axis = axisLine;
+    infoPtr->t1 = axisLine + t1;
+    infoPtr->t2 = axisLine + t2;
+    if (tickLabel > 0) {
+	infoPtr->label = tickLabel;
+    } else {
+	infoPtr->label = axisLine + labelOffset;
+    }
+    if ((axisPtr->flags & AXIS_EXTERIOR) == 0) {
+	/*infoPtr->label = axisLine + labelOffset - t1; */
+	infoPtr->t1 = axisLine - t1;
+	infoPtr->t2 = axisLine - t2;
+    } 
+}
+
+static void
+MakeAxisLine(Axis *axisPtr, int line, Segment2d *sp)
+{
+    double min, max;
+
+    min = axisPtr->axisRange.min;
+    max = axisPtr->axisRange.max;
+    if (axisPtr->logScale) {
+	min = EXP10(min);
+	max = EXP10(max);
+    }
+    if (AxisIsHorizontal(axisPtr)) {
+	sp->p.x = Blt_HMap(axisPtr, min);
+	sp->q.x = Blt_HMap(axisPtr, max);
+	sp->p.y = sp->q.y = line;
+    } else {
+	sp->q.x = sp->p.x = line;
+	sp->p.y = Blt_VMap(axisPtr, min);
+	sp->q.y = Blt_VMap(axisPtr, max);
+    }
+}
+
+
+static void
+MakeTick(Axis *axisPtr, double value, int tick, int line, Segment2d *sp)
+{
+    if (axisPtr->logScale) {
+	value = EXP10(value);
+    }
+    if (AxisIsHorizontal(axisPtr)) {
+	sp->p.x = sp->q.x = Blt_HMap(axisPtr, value);
+	sp->p.y = line;
+	sp->q.y = tick;
+    } else {
+	sp->p.x = line;
+	sp->p.y = sp->q.y = Blt_VMap(axisPtr, value);
+	sp->q.x = tick;
+    }
+}
+
+static void
+MakeSegments(Axis *axisPtr, AxisInfo *infoPtr)
+{
+    int arraySize;
+    int nMajorTicks, nMinorTicks;
+    Segment2d *segments;
+    Segment2d *sp;
+
+    if (axisPtr->segments != NULL) {
+	free(axisPtr->segments);
+	axisPtr->segments = NULL;	
+    }
+    nMajorTicks = nMinorTicks = 0;
+    if (axisPtr->t1Ptr != NULL) {
+	nMajorTicks = axisPtr->t1Ptr->nTicks;
+    }
+    if (axisPtr->t2Ptr != NULL) {
+	nMinorTicks = axisPtr->t2Ptr->nTicks;
+    }
+    arraySize = 1 + (nMajorTicks * (nMinorTicks + 1));
+    segments = malloc(arraySize * sizeof(Segment2d));
+    sp = segments;
+    if (axisPtr->lineWidth > 0) {
+	/* Axis baseline */
+	MakeAxisLine(axisPtr, infoPtr->axis, sp);
+	sp++;
+    }
+    if (axisPtr->flags & AXIS_SHOWTICKS) {
+	Blt_ChainLink link;
+	double labelPos;
+	int i;
+	int isHoriz;
+
+	isHoriz = AxisIsHorizontal(axisPtr);
+	for (i = 0; i < nMajorTicks; i++) {
+	    double t1, t2;
+	    int j;
+
+	    t1 = axisPtr->t1Ptr->values[i];
+	    /* Minor ticks */
+	    for (j = 0; j < nMinorTicks; j++) {
+		t2 = t1 + (axisPtr->majorSweep.step * 
+			   axisPtr->t2Ptr->values[j]);
+		if (InRange(t2, &axisPtr->axisRange)) {
+		    MakeTick(axisPtr, t2, infoPtr->t2, infoPtr->axis, sp);
+		    sp++;
+		}
+	    }
+	    if (!InRange(t1, &axisPtr->axisRange)) {
+		continue;
+	    }
+	    /* Major tick */
+	    MakeTick(axisPtr, t1, infoPtr->t1, infoPtr->axis, sp);
+	    sp++;
+	}
+
+	link = Blt_Chain_FirstLink(axisPtr->tickLabels);
+	labelPos = (double)infoPtr->label;
+
+	for (i = 0; i < nMajorTicks; i++) {
+	    double t1;
+	    TickLabel *labelPtr;
+	    Segment2d seg;
+
+	    t1 = axisPtr->t1Ptr->values[i];
+	    if (axisPtr->labelOffset) {
+		t1 += axisPtr->majorSweep.step * 0.5;
+	    }
+	    if (!InRange(t1, &axisPtr->axisRange)) {
+		continue;
+	    }
+	    labelPtr = Blt_Chain_GetValue(link);
+	    link = Blt_Chain_NextLink(link);
+	    MakeTick(axisPtr, t1, infoPtr->t1, infoPtr->axis, &seg);
+	    /* Save tick label X-Y position. */
+	    if (isHoriz) {
+		labelPtr->anchorPos.x = seg.p.x;
+		labelPtr->anchorPos.y = labelPos;
+	    } else {
+		labelPtr->anchorPos.x = labelPos;
+		labelPtr->anchorPos.y = seg.p.y;
+	    }
+	}
+    }
+    axisPtr->segments = segments;
+    axisPtr->nSegments = sp - segments;
+    assert(axisPtr->nSegments <= arraySize);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapAxis --
+ *
+ *	Pre-calculates positions of the axis, ticks, and labels (to be used
+ *	later when displaying the axis).  Calculates the values for each major
+ *	and minor tick and checks to see if they are in range (the outer ticks
+ *	may be outside of the range of plotted values).
+ *
+ *	Line segments for the minor and major ticks are saved into one
+ *	XSegment array so that they can be drawn by a single XDrawSegments
+ *	call. The positions of the tick labels are also computed and saved.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Line segments and tick labels are saved and used later to draw the
+ *	axis.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapAxis(Axis *axisPtr, int offset, int margin)
+{
+    AxisInfo info;
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+
+    if (AxisIsHorizontal(axisPtr)) {
+	axisPtr->screenMin = graphPtr->hOffset;
+	axisPtr->width = graphPtr->right - graphPtr->left;
+	axisPtr->screenRange = graphPtr->hRange;
+    } else {
+	axisPtr->screenMin = graphPtr->vOffset;
+	axisPtr->height = graphPtr->bottom - graphPtr->top;
+	axisPtr->screenRange = graphPtr->vRange;
+    }
+    axisPtr->screenScale = 1.0 / axisPtr->screenRange;
+    AxisOffsets(axisPtr, margin, offset, &info);
+    MakeSegments(axisPtr, &info);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapStackedAxis --
+ *
+ *	Pre-calculates positions of the axis, ticks, and labels (to be used
+ *	later when displaying the axis).  Calculates the values for each major
+ *	and minor tick and checks to see if they are in range (the outer ticks
+ *	may be outside of the range of plotted values).
+ *
+ *	Line segments for the minor and major ticks are saved into one XSegment
+ *	array so that they can be drawn by a single XDrawSegments call. The
+ *	positions of the tick labels are also computed and saved.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Line segments and tick labels are saved and used later to draw the
+ *	axis.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapStackedAxis(Axis *axisPtr, int count, int margin)
+{
+    AxisInfo info;
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+    unsigned int slice, w, h;
+
+    if ((graphPtr->margins[axisPtr->margin].axes->nLinks > 1) ||
+	(axisPtr->reqNumMajorTicks <= 0)) {
+	axisPtr->reqNumMajorTicks = 4;
+    }
+    if (AxisIsHorizontal(axisPtr)) {
+	slice = graphPtr->hRange / graphPtr->margins[margin].axes->nLinks;
+	axisPtr->screenMin = graphPtr->hOffset;
+	axisPtr->width = slice;
+    } else {
+	slice = graphPtr->vRange / graphPtr->margins[margin].axes->nLinks;
+	axisPtr->screenMin = graphPtr->vOffset;
+	axisPtr->height = slice;
+    }
+#define AXIS_PAD 2
+    Blt_GetTextExtents(axisPtr->tickFont, 0, "0", 1, &w, &h);
+    axisPtr->screenMin += (slice * count) + AXIS_PAD + h / 2;
+    axisPtr->screenRange = slice - 2 * AXIS_PAD - h;
+    axisPtr->screenScale = 1.0f / axisPtr->screenRange;
+    AxisOffsets(axisPtr, margin, 0, &info);
+    MakeSegments(axisPtr, &info);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AdjustViewport --
+ *
+ *	Adjusts the offsets of the viewport according to the scroll mode.  This
+ *	is to accommodate both "listbox" and "canvas" style scrolling.
+ *
+ *	"canvas"	The viewport scrolls within the range of world
+ *			coordinates.  This way the viewport always displays
+ *			a full page of the world.  If the world is smaller
+ *			than the viewport, then (bizarrely) the world and
+ *			viewport are inverted so that the world moves up
+ *			and down within the viewport.
+ *
+ *	"listbox"	The viewport can scroll beyond the range of world
+ *			coordinates.  Every entry can be displayed at the
+ *			top of the viewport.  This also means that the
+ *			scrollbar thumb weirdly shrinks as the last entry
+ *			is scrolled upward.
+ *
+ * Results:
+ *	The corrected offset is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+static double
+AdjustViewport(double offset, double windowSize)
+{
+    /*
+     * Canvas-style scrolling allows the world to be scrolled within the window.
+     */
+    if (windowSize > 1.0) {
+	if (windowSize < (1.0 - offset)) {
+	    offset = 1.0 - windowSize;
+	}
+	if (offset > 0.0) {
+	    offset = 0.0;
+	}
+    } else {
+	if ((offset + windowSize) > 1.0) {
+	    offset = 1.0 - windowSize;
+	}
+	if (offset < 0.0) {
+	    offset = 0.0;
+	}
+    }
+    return offset;
+}
+
+static int
+GetAxisScrollInfo(
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv,
+    double *offsetPtr,
+    double windowSize,
+    double scrollUnits,
+    double scale)
+{
+    const char *string;
+    char c;
+    double offset;
+    int length;
+
+    offset = *offsetPtr;
+    string = Tcl_GetStringFromObj(objv[0], &length);
+    c = string[0];
+    scrollUnits *= scale;
+    if ((c == 's') && (strncmp(string, "scroll", length) == 0)) {
+	int count;
+	double fract;
+
+	assert(objc == 3);
+	/* Scroll number unit/page */
+	if (Tcl_GetIntFromObj(interp, objv[1], &count) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	string = Tcl_GetStringFromObj(objv[2], &length);
+	c = string[0];
+	if ((c == 'u') && (strncmp(string, "units", length) == 0)) {
+	    fract = count * scrollUnits;
+	} else if ((c == 'p') && (strncmp(string, "pages", length) == 0)) {
+	    /* A page is 90% of the view-able window. */
+	    fract = (int)(count * windowSize * 0.9 + 0.5);
+	} else if ((c == 'p') && (strncmp(string, "pixels", length) == 0)) {
+	    fract = count * scale;
+	} else {
+	    Tcl_AppendResult(interp, "unknown \"scroll\" units \"", string,
+		"\"", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	offset += fract;
+    } else if ((c == 'm') && (strncmp(string, "moveto", length) == 0)) {
+	double fract;
+
+	assert(objc == 2);
+	/* moveto fraction */
+	if (Blt_GetDoubleFromObj(interp, objv[1], &fract) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	offset = fract;
+    } else {
+	int count;
+	double fract;
+
+	/* Treat like "scroll units" */
+	if (Tcl_GetIntFromObj(interp, objv[0], &count) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	fract = (double)count * scrollUnits;
+	offset += fract;
+	/* CHECK THIS: return TCL_OK; */
+    }
+    *offsetPtr = AdjustViewport(offset, windowSize);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawAxis --
+ *
+ *	Draws the axis, ticks, and labels onto the canvas.
+ *
+ *	Initializes and passes text attribute information through TextStyle
+ *	structure.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Axis gets drawn on window.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawAxis(Axis *axisPtr, Drawable drawable)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+
+    if (axisPtr->normalBg != NULL) {
+	Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, 
+		axisPtr->normalBg, 
+		axisPtr->left, axisPtr->top, 
+		axisPtr->right - axisPtr->left, 
+		axisPtr->bottom - axisPtr->top, axisPtr->borderWidth, 
+		axisPtr->relief);
+    }
+    if (axisPtr->title != NULL) {
+	TextStyle ts;
+
+	Blt_Ts_InitStyle(ts);
+	Blt_Ts_SetAngle(ts, axisPtr->titleAngle);
+	Blt_Ts_SetFont(ts, axisPtr->titleFont);
+	Blt_Ts_SetPadding(ts, 1, 2, 0, 0);
+	Blt_Ts_SetAnchor(ts, axisPtr->titleAnchor);
+	Blt_Ts_SetJustify(ts, axisPtr->titleJustify);
+	if (axisPtr->flags & ACTIVE) {
+	    Blt_Ts_SetForeground(ts, axisPtr->activeFgColor);
+	} else {
+	    Blt_Ts_SetForeground(ts, axisPtr->titleColor);
+	}
+	Blt_Ts_SetForeground(ts, axisPtr->titleColor);
+	if ((axisPtr->titleAngle == 90.0) || (axisPtr->titleAngle == 270.0)) {
+	    Blt_Ts_SetMaxLength(ts, axisPtr->height);
+	} else {
+	    Blt_Ts_SetMaxLength(ts, axisPtr->width);
+	}
+	Blt_Ts_DrawText(graphPtr->tkwin, drawable, axisPtr->title, -1, &ts, 
+		(int)axisPtr->titlePos.x, (int)axisPtr->titlePos.y);
+    }
+    if (axisPtr->scrollCmdObjPtr != NULL) {
+	double viewWidth, viewMin, viewMax;
+	double worldWidth, worldMin, worldMax;
+	double fract;
+	int isHoriz;
+
+	worldMin = axisPtr->valueRange.min;
+	worldMax = axisPtr->valueRange.max;
+	if (isnormal(axisPtr->scrollMin)) {
+	    worldMin = axisPtr->scrollMin;
+	}
+	if (isnormal(axisPtr->scrollMax)) {
+	    worldMax = axisPtr->scrollMax;
+	}
+	viewMin = axisPtr->min;
+	viewMax = axisPtr->max;
+	if (viewMin < worldMin) {
+	    viewMin = worldMin;
+	}
+	if (viewMax > worldMax) {
+	    viewMax = worldMax;
+	}
+	if (axisPtr->logScale) {
+	    worldMin = log10(worldMin);
+	    worldMax = log10(worldMax);
+	    viewMin = log10(viewMin);
+	    viewMax = log10(viewMax);
+	}
+	worldWidth = worldMax - worldMin;	
+	viewWidth = viewMax - viewMin;
+	isHoriz = AxisIsHorizontal(axisPtr);
+
+	if (isHoriz != axisPtr->descending) {
+	    fract = (viewMin - worldMin) / worldWidth;
+	} else {
+	    fract = (worldMax - viewMax) / worldWidth;
+	}
+	fract = AdjustViewport(fract, viewWidth / worldWidth);
+
+	if (isHoriz != axisPtr->descending) {
+	    viewMin = (fract * worldWidth);
+	    axisPtr->min = viewMin + worldMin;
+	    axisPtr->max = axisPtr->min + viewWidth;
+	    viewMax = viewMin + viewWidth;
+	    if (axisPtr->logScale) {
+		axisPtr->min = EXP10(axisPtr->min);
+		axisPtr->max = EXP10(axisPtr->max);
+	    }
+	    Blt_UpdateScrollbar(graphPtr->interp, axisPtr->scrollCmdObjPtr,
+		viewMin, viewMax, worldWidth);
+	} else {
+	    viewMax = (fract * worldWidth);
+	    axisPtr->max = worldMax - viewMax;
+	    axisPtr->min = axisPtr->max - viewWidth;
+	    viewMin = viewMax + viewWidth;
+	    if (axisPtr->logScale) {
+		axisPtr->min = EXP10(axisPtr->min);
+		axisPtr->max = EXP10(axisPtr->max);
+	    }
+	    Blt_UpdateScrollbar(graphPtr->interp, axisPtr->scrollCmdObjPtr,
+		viewMax, viewMin, worldWidth);
+	}
+    }
+    if (axisPtr->flags & AXIS_SHOWTICKS) {
+	Blt_ChainLink link;
+	TextStyle ts;
+
+	Blt_Ts_InitStyle(ts);
+	Blt_Ts_SetAngle(ts, axisPtr->tickAngle);
+	Blt_Ts_SetFont(ts, axisPtr->tickFont);
+	Blt_Ts_SetPadding(ts, 2, 0, 0, 0);
+	Blt_Ts_SetAnchor(ts, axisPtr->tickAnchor);
+	if (axisPtr->flags & ACTIVE) {
+	    Blt_Ts_SetForeground(ts, axisPtr->activeFgColor);
+	} else {
+	    Blt_Ts_SetForeground(ts, axisPtr->tickColor);
+	}
+	for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL;
+	    link = Blt_Chain_NextLink(link)) {	
+	    TickLabel *labelPtr;
+
+	    labelPtr = Blt_Chain_GetValue(link);
+	    /* Draw major tick labels */
+	    Blt_DrawText(graphPtr->tkwin, drawable, labelPtr->string, &ts, 
+		(int)labelPtr->anchorPos.x, (int)labelPtr->anchorPos.y);
+	}
+    }
+    if ((axisPtr->nSegments > 0) && (axisPtr->lineWidth > 0)) {	
+	GC gc;
+
+	if (axisPtr->flags & ACTIVE) {
+	    gc = axisPtr->activeTickGC;
+	} else {
+	    gc = axisPtr->tickGC;
+	}
+	/* Draw the tick marks and axis line. */
+	Blt_Draw2DSegments(graphPtr->display, drawable, gc, axisPtr->segments, 
+		axisPtr->nSegments);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisToPostScript --
+ *
+ *	Generates PostScript output to draw the axis, ticks, and labels.
+ *
+ *	Initializes and passes text attribute information through TextStyle
+ *	structure.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	PostScript output is left in graphPtr->interp->result;
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static void
+AxisToPostScript(Blt_Ps ps, Axis *axisPtr)
+{
+    Blt_Ps_Format(ps, "%% Axis \"%s\"\n", axisPtr->obj.name);
+    if (axisPtr->normalBg != NULL) {
+	Tk_3DBorder border;
+
+	border = Blt_BackgroundBorder(axisPtr->normalBg);
+	Blt_Ps_Fill3DRectangle(ps, border, 
+		(double)axisPtr->left, (double)axisPtr->top, 
+		axisPtr->right - axisPtr->left, axisPtr->bottom - axisPtr->top, 
+		axisPtr->borderWidth, axisPtr->relief);
+    }
+    if (axisPtr->title != NULL) {
+	TextStyle ts;
+
+	Blt_Ts_InitStyle(ts);
+	Blt_Ts_SetAngle(ts, axisPtr->titleAngle);
+	Blt_Ts_SetFont(ts, axisPtr->titleFont);
+	Blt_Ts_SetPadding(ts, 1, 2, 0, 0);
+	Blt_Ts_SetAnchor(ts, axisPtr->titleAnchor);
+	Blt_Ts_SetJustify(ts, axisPtr->titleJustify);
+	Blt_Ts_SetForeground(ts, axisPtr->titleColor);
+	Blt_Ps_DrawText(ps, axisPtr->title, &ts, axisPtr->titlePos.x, 
+		axisPtr->titlePos.y);
+    }
+    if (axisPtr->flags & AXIS_SHOWTICKS) {
+	Blt_ChainLink link;
+	TextStyle ts;
+
+	Blt_Ts_InitStyle(ts);
+	Blt_Ts_SetAngle(ts, axisPtr->tickAngle);
+	Blt_Ts_SetFont(ts, axisPtr->tickFont);
+	Blt_Ts_SetPadding(ts, 2, 0, 0, 0);
+	Blt_Ts_SetAnchor(ts, axisPtr->tickAnchor);
+	Blt_Ts_SetForeground(ts, axisPtr->tickColor);
+
+	for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; 
+	     link = Blt_Chain_NextLink(link)) {
+	    TickLabel *labelPtr;
+
+	    labelPtr = Blt_Chain_GetValue(link);
+	    Blt_Ps_DrawText(ps, labelPtr->string, &ts, labelPtr->anchorPos.x, 
+		labelPtr->anchorPos.y);
+	}
+    }
+    if ((axisPtr->nSegments > 0) && (axisPtr->lineWidth > 0)) {
+	Blt_Ps_XSetLineAttributes(ps, axisPtr->tickColor, axisPtr->lineWidth, 
+		(Blt_Dashes *)NULL, CapButt, JoinMiter);
+	Blt_Ps_Draw2DSegments(ps, axisPtr->segments, axisPtr->nSegments);
+    }
+}
+
+static void
+MakeGridLine(Axis *axisPtr, double value, Segment2d *sp)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+
+    if (axisPtr->logScale) {
+	value = EXP10(value);
+    }
+    /* Grid lines run orthogonally to the axis */
+    if (AxisIsHorizontal(axisPtr)) {
+	sp->p.y = graphPtr->top;
+	sp->q.y = graphPtr->bottom;
+	sp->p.x = sp->q.x = Blt_HMap(axisPtr, value);
+    } else {
+	sp->p.x = graphPtr->left;
+	sp->q.x = graphPtr->right;
+	sp->p.y = sp->q.y = Blt_VMap(axisPtr, value);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapGridlines --
+ *
+ *	Assembles the grid lines associated with an axis. Generates tick
+ *	positions if necessary (this happens when the axis is not a logical axis
+ *	too).
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapGridlines(Axis *axisPtr)
+{
+    Segment2d *s1, *s2;
+    Ticks *t1Ptr, *t2Ptr;
+    int needed;
+    int i;
+
+    if (axisPtr == NULL) {
+	return;
+    }
+    t1Ptr = axisPtr->t1Ptr;
+    if (t1Ptr == NULL) {
+	t1Ptr = GenerateTicks(&axisPtr->majorSweep);
+    }
+    t2Ptr = axisPtr->t2Ptr;
+    if (t2Ptr == NULL) {
+	t2Ptr = GenerateTicks(&axisPtr->minorSweep);
+    }
+    needed = t1Ptr->nTicks;
+    if (axisPtr->flags & AXIS_GRIDMINOR) {
+	needed += (t1Ptr->nTicks * t2Ptr->nTicks);
+    }
+    if (needed == 0) {
+	return;			
+    }
+    needed = t1Ptr->nTicks;
+    if (needed != axisPtr->major.nAllocated) {
+	if (axisPtr->major.segments != NULL) {
+	  free(axisPtr->major.segments);
+	  axisPtr->major.segments = NULL;
+	}
+	axisPtr->major.segments = malloc(sizeof(Segment2d) * needed);
+	axisPtr->major.nAllocated = needed;
+    }
+    needed = (t1Ptr->nTicks * t2Ptr->nTicks);
+    if (needed != axisPtr->minor.nAllocated) {
+	if (axisPtr->minor.segments != NULL) {
+	  free(axisPtr->minor.segments);
+	  axisPtr->minor.segments = NULL;
+	}
+	axisPtr->minor.segments = malloc(sizeof(Segment2d) * needed);
+	axisPtr->minor.nAllocated = needed;
+    }
+    s1 = axisPtr->major.segments, s2 = axisPtr->minor.segments;
+    for (i = 0; i < t1Ptr->nTicks; i++) {
+	double value;
+
+	value = t1Ptr->values[i];
+	if (axisPtr->flags & AXIS_GRIDMINOR) {
+	    int j;
+
+	    for (j = 0; j < t2Ptr->nTicks; j++) {
+		double subValue;
+
+		subValue = value + (axisPtr->majorSweep.step * 
+				    t2Ptr->values[j]);
+		if (InRange(subValue, &axisPtr->axisRange)) {
+		    MakeGridLine(axisPtr, subValue, s2);
+		    s2++;
+		}
+	    }
+	}
+	if (InRange(value, &axisPtr->axisRange)) {
+	    MakeGridLine(axisPtr, value, s1);
+	    s1++;
+	}
+    }
+    if (t1Ptr != axisPtr->t1Ptr) {
+	free(t1Ptr);		/* Free generated ticks. */
+    }
+    if (t2Ptr != axisPtr->t2Ptr) {
+	free(t2Ptr);		/* Free generated ticks. */
+    }
+    axisPtr->major.nUsed = s1 - axisPtr->major.segments;
+    axisPtr->minor.nUsed = s2 - axisPtr->minor.segments;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetAxisGeometry --
+ *
+ * Results:
+ *	None.
+ *
+ * Exterior axis:
+ *                    l       r
+ *  |a|b|c|d|e|f|g|h|i|   j   |i|h|g|f|e|d|c|d|a|
+ *
+ * Interior axis: 
+ *                  l           r
+ *  |a|b|c|d|h|g|f|e|     j     |e|f|g|h|d|c|b|a|
+ *               i..             ..i 
+ * a = highlight thickness
+ * b = graph borderwidth
+ * c = axis title
+ * d = tick label 
+ * e = tick 
+ * f = axis line
+ * g = 1 pixel pad
+ * h = plot borderwidth
+ * i = plot pad
+ * j = plot area 
+ *---------------------------------------------------------------------------
+ */
+static void
+GetAxisGeometry(Graph *graphPtr, Axis *axisPtr)
+{
+    unsigned int y;
+
+    FreeTickLabels(axisPtr->tickLabels);
+    y = 0;
+
+    if ((axisPtr->flags & AXIS_EXTERIOR) && 
+	(graphPtr->plotRelief != TK_RELIEF_SOLID)) {
+	/* Leave room for axis baseline and padding */
+	y += axisPtr->lineWidth + 2;
+    }
+
+    axisPtr->maxTickHeight = axisPtr->maxTickWidth = 0;
+    if (axisPtr->flags & AXIS_SHOWTICKS) {
+	unsigned int pad;
+	unsigned int i, nLabels, nTicks;
+
+	SweepTicks(axisPtr);
+	
+	nTicks = 0;
+	if (axisPtr->t1Ptr != NULL) {
+	    nTicks = axisPtr->t1Ptr->nTicks;
+	}
+	assert(nTicks <= MAXTICKS);
+	
+	nLabels = 0;
+	for (i = 0; i < nTicks; i++) {
+	    TickLabel *labelPtr;
+	    double x, x2;
+	    unsigned int lw, lh;	/* Label width and height. */
+
+	    x2 = x = axisPtr->t1Ptr->values[i];
+	    if (axisPtr->labelOffset) {
+		x2 += axisPtr->majorSweep.step * 0.5;
+	    }
+	    if (!InRange(x2, &axisPtr->axisRange)) {
+		continue;
+	    }
+	    labelPtr = MakeLabel(axisPtr, x);
+	    Blt_Chain_Append(axisPtr->tickLabels, labelPtr);
+	    nLabels++;
+	    /* 
+	     * Get the dimensions of each tick label.  Remember tick labels
+	     * can be multi-lined and/or rotated.
+	     */
+	    Blt_GetTextExtents(axisPtr->tickFont, 0, labelPtr->string, -1, 
+		&lw, &lh);
+	    labelPtr->width  = lw;
+	    labelPtr->height = lh;
+
+	    if (axisPtr->tickAngle != 0.0f) {
+		double rlw, rlh;	/* Rotated label width and height. */
+		Blt_GetBoundingBox(lw, lh, axisPtr->tickAngle, &rlw, &rlh,NULL);
+		lw = ROUND(rlw), lh = ROUND(rlh);
+	    }
+	    if (axisPtr->maxTickWidth < lw) {
+		axisPtr->maxTickWidth = lw;
+	    }
+	    if (axisPtr->maxTickHeight < lh) {
+		axisPtr->maxTickHeight = lh;
+	    }
+	}
+	assert(nLabels <= nTicks);
+	
+	pad = 0;
+	if (axisPtr->flags & AXIS_EXTERIOR) {
+	    /* Because the axis cap style is "CapProjecting", we need to
+	     * account for an extra 1.5 linewidth at the end of each line.  */
+	    pad = ((axisPtr->lineWidth * 12) / 8);
+	}
+	if (AxisIsHorizontal(axisPtr)) {
+	    y += axisPtr->maxTickHeight + pad;
+	} else {
+	    y += axisPtr->maxTickWidth + pad;
+	    if (axisPtr->maxTickWidth > 0) {
+		y += 5;			/* Pad either size of label. */
+	    }  
+	}
+	y += 2 * AXIS_PAD_TITLE;
+	if ((axisPtr->lineWidth > 0) && (axisPtr->flags & AXIS_EXTERIOR)) {
+	    /* Distance from axis line to tick label. */
+	    y += axisPtr->tickLength;
+	}
+    }
+
+    if (axisPtr->title != NULL) {
+	if (axisPtr->titleAlternate) {
+	    if (y < axisPtr->titleHeight) {
+		y = axisPtr->titleHeight;
+	    }
+	} else {
+	    y += axisPtr->titleHeight + AXIS_PAD_TITLE;
+	}
+    }
+
+    /* Correct for orientation of the axis. */
+    if (AxisIsHorizontal(axisPtr)) {
+	axisPtr->height = y;
+    } else {
+	axisPtr->width = y;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetMarginGeometry --
+ *
+ *	Examines all the axes in the given margin and determines the area
+ *	required to display them.
+ *
+ *	Note: For multiple axes, the titles are displayed in another
+ *	      margin. So we must keep track of the widest title.
+ *	
+ * Results:
+ *	Returns the width or height of the margin, depending if it runs
+ *	horizontally along the graph or vertically.
+ *
+ * Side Effects:
+ *	The area width and height set in the margin.  Note again that this may
+ *	be corrected later (mulitple axes) to adjust for the longest title in
+ *	another margin.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+GetMarginGeometry(Graph *graphPtr, Margin *marginPtr)
+{
+    Blt_ChainLink link;
+    unsigned int l, w, h;		/* Length, width, and height. */
+    int isHoriz;
+    unsigned int nVisible;
+
+    isHoriz = HORIZMARGIN(marginPtr);
+
+    /* Count the visible axes. */
+    nVisible = 0;
+    l = w = h = 0;
+    marginPtr->maxTickWidth = marginPtr->maxTickHeight = 0;
+    if (graphPtr->stackAxes) {
+	for (link = Blt_Chain_FirstLink(marginPtr->axes); link != NULL;
+	     link = Blt_Chain_NextLink(link)) {
+	    Axis *axisPtr;
+	    
+	    axisPtr = Blt_Chain_GetValue(link);
+	    if ((axisPtr->flags & (HIDE|AXIS_USE)) == AXIS_USE) {
+		nVisible++;
+		if (graphPtr->flags & GET_AXIS_GEOMETRY) {
+		    GetAxisGeometry(graphPtr, axisPtr);
+		}
+		if (isHoriz) {
+		    if (h < axisPtr->height) {
+			h = axisPtr->height;
+		    }
+		} else {
+		    if (w < axisPtr->width) {
+			w = axisPtr->width;
+		    }
+		}
+		if (axisPtr->maxTickWidth > marginPtr->maxTickWidth) {
+		    marginPtr->maxTickWidth = axisPtr->maxTickWidth;
+		}
+		if (axisPtr->maxTickHeight > marginPtr->maxTickHeight) {
+		    marginPtr->maxTickHeight = axisPtr->maxTickHeight;
+		}
+	    }
+	}
+    } else {
+	for (link = Blt_Chain_FirstLink(marginPtr->axes); link != NULL;
+	     link = Blt_Chain_NextLink(link)) {
+	    Axis *axisPtr;
+	    
+	    axisPtr = Blt_Chain_GetValue(link);
+	    if ((axisPtr->flags & (HIDE|AXIS_USE)) == AXIS_USE) {
+		nVisible++;
+		if (graphPtr->flags & GET_AXIS_GEOMETRY) {
+		    GetAxisGeometry(graphPtr, axisPtr);
+		}
+		if ((axisPtr->titleAlternate) && (l < axisPtr->titleWidth)) {
+		    l = axisPtr->titleWidth;
+		}
+		if (isHoriz) {
+		    h += axisPtr->height;
+		} else {
+		    w += axisPtr->width;
+		}
+		if (axisPtr->maxTickWidth > marginPtr->maxTickWidth) {
+		    marginPtr->maxTickWidth = axisPtr->maxTickWidth;
+		}
+		if (axisPtr->maxTickHeight > marginPtr->maxTickHeight) {
+		    marginPtr->maxTickHeight = axisPtr->maxTickHeight;
+		}
+	    }
+	}
+    }
+    /* Enforce a minimum size for margins. */
+    if (w < 3) {
+	w = 3;
+    }
+    if (h < 3) {
+	h = 3;
+    }
+    marginPtr->nAxes = nVisible;
+    marginPtr->axesTitleLength = l;
+    marginPtr->width = w;
+    marginPtr->height = h;
+    marginPtr->axesOffset = (isHoriz) ? h : w;
+    return marginPtr->axesOffset;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_LayoutGraph --
+ *
+ *	Calculate the layout of the graph.  Based upon the data, axis limits,
+ *	X and Y titles, and title height, determine the cavity left which is
+ *	the plotting surface.  The first step get the data and axis limits for
+ *	calculating the space needed for the top, bottom, left, and right
+ *	margins.
+ *
+ * 	1) The LEFT margin is the area from the left border to the Y axis 
+ *	   (not including ticks). It composes the border width, the width an 
+ *	   optional Y axis label and its padding, and the tick numeric labels. 
+ *	   The Y axis label is rotated 90 degrees so that the width is the 
+ *	   font height.
+ *
+ * 	2) The RIGHT margin is the area from the end of the graph
+ *	   to the right window border. It composes the border width,
+ *	   some padding, the font height (this may be dubious. It
+ *	   appears to provide a more even border), the max of the
+ *	   legend width and 1/2 max X tick number. This last part is
+ *	   so that the last tick label is not clipped.
+ *
+ *           Window Width
+ *      ___________________________________________________________
+ *      |          |                               |               |
+ *      |          |   TOP  height of title        |               |
+ *      |          |                               |               |
+ *      |          |           x2 title            |               |
+ *      |          |                               |               |
+ *      |          |        height of x2-axis      |               |
+ *      |__________|_______________________________|_______________|  W
+ *      |          | -plotpady                     |               |  i
+ *      |__________|_______________________________|_______________|  n
+ *      |          | top                   right   |               |  d
+ *      |          |                               |               |  o
+ *      |   LEFT   |                               |     RIGHT     |  w
+ *      |          |                               |               |
+ *      | y        |     Free area = 104%          |      y2       |  H
+ *      |          |     Plotting surface = 100%   |               |  e
+ *      | t        |     Tick length = 2 + 2%      |      t        |  i
+ *      | i        |                               |      i        |  g
+ *      | t        |                               |      t  legend|  h
+ *      | l        |                               |      l   width|  t
+ *      | e        |                               |      e        |
+ *      |    height|                               |height         |
+ *      |       of |                               | of            |
+ *      |    y-axis|                               |y2-axis        |
+ *      |          |                               |               |
+ *      |          |origin 0,0                     |               |
+ *      |__________|_left_________________bottom___|_______________|
+ *      |          |-plotpady                      |               |
+ *      |__________|_______________________________|_______________|
+ *      |          | (xoffset, yoffset)            |               |
+ *      |          |                               |               |
+ *      |          |       height of x-axis        |               |
+ *      |          |                               |               |
+ *      |          |   BOTTOM   x title            |               |
+ *      |__________|_______________________________|_______________|
+ *
+ * 3) The TOP margin is the area from the top window border to the top
+ *    of the graph. It composes the border width, twice the height of
+ *    the title font (if one is given) and some padding between the
+ *    title.
+ *
+ * 4) The BOTTOM margin is area from the bottom window border to the
+ *    X axis (not including ticks). It composes the border width, the height
+ *    an optional X axis label and its padding, the height of the font
+ *    of the tick labels.
+ *
+ * The plotting area is between the margins which includes the X and Y axes
+ * including the ticks but not the tick numeric labels. The length of the
+ * ticks and its padding is 5% of the entire plotting area.  Hence the entire
+ * plotting area is scaled as 105% of the width and height of the area.
+ *
+ * The axis labels, ticks labels, title, and legend may or may not be
+ * displayed which must be taken into account.
+ *
+ * if reqWidth > 0 : set outer size
+ * if reqPlotWidth > 0 : set plot size
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_LayoutGraph(Graph *graphPtr)
+{
+    unsigned int titleY;
+    unsigned int left, right, top, bottom;
+    unsigned int plotWidth, plotHeight;
+    unsigned int inset, inset2;
+    int width, height;
+    int pad;
+
+    width = graphPtr->width;
+    height = graphPtr->height;
+
+    /* 
+     * Step 1:  Compute the amount of space needed to display the axes
+     *		associated with each margin.  They can be overridden by 
+     *		-leftmargin, -rightmargin, -bottommargin, and -topmargin
+     *		graph options, respectively.
+     */
+    left   = GetMarginGeometry(graphPtr, &graphPtr->leftMargin);
+    right  = GetMarginGeometry(graphPtr, &graphPtr->rightMargin);
+    top    = GetMarginGeometry(graphPtr, &graphPtr->topMargin);
+    bottom = GetMarginGeometry(graphPtr, &graphPtr->bottomMargin);
+
+    pad = graphPtr->bottomMargin.maxTickWidth;
+    if (pad < graphPtr->topMargin.maxTickWidth) {
+	pad = graphPtr->topMargin.maxTickWidth;
+    }
+    pad = pad / 2 + 3;
+    if (right < pad) {
+	right = pad;
+    }
+    if (left < pad) {
+	left = pad;
+    }
+    pad = graphPtr->leftMargin.maxTickHeight;
+    if (pad < graphPtr->rightMargin.maxTickHeight) {
+	pad = graphPtr->rightMargin.maxTickHeight;
+    }
+    pad = pad / 2;
+    if (top < pad) {
+	top = pad;
+    }
+    if (bottom < pad) {
+	bottom = pad;
+    }
+
+    if (graphPtr->leftMargin.reqSize > 0) {
+	left = graphPtr->leftMargin.reqSize;
+    }
+    if (graphPtr->rightMargin.reqSize > 0) {
+	right = graphPtr->rightMargin.reqSize;
+    }
+    if (graphPtr->topMargin.reqSize > 0) {
+	top = graphPtr->topMargin.reqSize;
+    }
+    if (graphPtr->bottomMargin.reqSize > 0) {
+	bottom = graphPtr->bottomMargin.reqSize;
+    }
+
+    /* 
+     * Step 2:  Add the graph title height to the top margin. 
+     */
+    if (graphPtr->title != NULL) {
+	top += graphPtr->titleHeight + 6;
+    }
+    inset = (graphPtr->inset + graphPtr->plotBW);
+    inset2 = 2 * inset;
+
+    /* 
+     * Step 3: Estimate the size of the plot area from the remaining
+     *	       space.  This may be overridden by the -plotwidth and
+     *	       -plotheight graph options.  We use this to compute the
+     *	       size of the legend. 
+     */
+    if (width == 0) {
+	width = 400;
+    }
+    if (height == 0) {
+	height = 400;
+    }
+    plotWidth  = (graphPtr->reqPlotWidth > 0) ? graphPtr->reqPlotWidth :
+	width - (inset2 + left + right); /* Plot width. */
+    plotHeight = (graphPtr->reqPlotHeight > 0) ? graphPtr->reqPlotHeight : 
+	height - (inset2 + top + bottom); /* Plot height. */
+    Blt_MapLegend(graphPtr, plotWidth, plotHeight);
+
+    /* 
+     * Step 2:  Add the legend to the appropiate margin. 
+     */
+    if (!Blt_Legend_IsHidden(graphPtr)) {
+	switch (Blt_Legend_Site(graphPtr)) {
+	case LEGEND_RIGHT:
+	    right += Blt_Legend_Width(graphPtr) + 2;
+	    break;
+	case LEGEND_LEFT:
+	    left += Blt_Legend_Width(graphPtr) + 2;
+	    break;
+	case LEGEND_TOP:
+	    top += Blt_Legend_Height(graphPtr) + 2;
+	    break;
+	case LEGEND_BOTTOM:
+	    bottom += Blt_Legend_Height(graphPtr) + 2;
+	    break;
+	case LEGEND_XY:
+	case LEGEND_PLOT:
+	case LEGEND_WINDOW:
+	    /* Do nothing. */
+	    break;
+	}
+    }
+
+    /* 
+     * Recompute the plotarea or graph size, now accounting for the legend. 
+     */
+    if (graphPtr->reqPlotWidth == 0) {
+	plotWidth = width  - (inset2 + left + right);
+	if (plotWidth < 1) {
+	    plotWidth = 1;
+	}
+    }
+    if (graphPtr->reqPlotHeight == 0) {
+	plotHeight = height - (inset2 + top + bottom);
+	if (plotHeight < 1) {
+	    plotHeight = 1;
+	}
+    }
+
+    /*
+     * Step 5: If necessary, correct for the requested plot area aspect
+     *	       ratio.
+     */
+    if ((graphPtr->reqPlotWidth == 0) && (graphPtr->reqPlotHeight == 0) && 
+	(graphPtr->aspect > 0.0f)) {
+	float ratio;
+
+	/* 
+	 * Shrink one dimension of the plotarea to fit the requested
+	 * width/height aspect ratio.
+	 */
+	ratio = (float)plotWidth / (float)plotHeight;
+	if (ratio > graphPtr->aspect) {
+	    int scaledWidth;
+
+	    /* Shrink the width. */
+	    scaledWidth = (int)(plotHeight * graphPtr->aspect);
+	    if (scaledWidth < 1) {
+		scaledWidth = 1;
+	    }
+	    /* Add the difference to the right margin. */
+	    /* CHECK THIS: w = scaledWidth; */
+	    right += (plotWidth - scaledWidth);
+	} else {
+	    int scaledHeight;
+
+	    /* Shrink the height. */
+	    scaledHeight = (int)(plotWidth / graphPtr->aspect);
+	    if (scaledHeight < 1) {
+		scaledHeight = 1;
+	    }
+	    /* Add the difference to the top margin. */
+	    /* CHECK THIS: h = scaledHeight; */
+	    top += (plotHeight - scaledHeight); 
+	}
+    }
+
+    /* 
+     * Step 6: If there's multiple axes in a margin, the axis titles will be
+     *	       displayed in the adjoining margins.  Make sure there's room 
+     *	       for the longest axis titles.
+     */
+
+    if (top < graphPtr->leftMargin.axesTitleLength) {
+	top = graphPtr->leftMargin.axesTitleLength;
+    }
+    if (right < graphPtr->bottomMargin.axesTitleLength) {
+	right = graphPtr->bottomMargin.axesTitleLength;
+    }
+    if (top < graphPtr->rightMargin.axesTitleLength) {
+	top = graphPtr->rightMargin.axesTitleLength;
+    }
+    if (right < graphPtr->topMargin.axesTitleLength) {
+	right = graphPtr->topMargin.axesTitleLength;
+    }
+
+    /* 
+     * Step 7: Override calculated values with requested margin sizes.
+     */
+    if (graphPtr->leftMargin.reqSize > 0) {
+	left = graphPtr->leftMargin.reqSize;
+    }
+    if (graphPtr->rightMargin.reqSize > 0) {
+	right = graphPtr->rightMargin.reqSize;
+    }
+    if (graphPtr->topMargin.reqSize > 0) {
+	top = graphPtr->topMargin.reqSize;
+    }
+    if (graphPtr->bottomMargin.reqSize > 0) {
+	bottom = graphPtr->bottomMargin.reqSize;
+    }
+    if (graphPtr->reqPlotWidth > 0) {	
+	int w;
+
+	/* 
+	 * Width of plotarea is constained.  If there's extra space, add it to
+	 * th left and/or right margins.  If there's too little, grow the
+	 * graph width to accomodate it.
+	 */
+	w = plotWidth + inset2 + left + right;
+	if (width > w) {		/* Extra space in window. */
+	    int extra;
+
+	    extra = (width - w) / 2;
+	    if (graphPtr->leftMargin.reqSize == 0) { 
+		left += extra;
+		if (graphPtr->rightMargin.reqSize == 0) { 
+		    right += extra;
+		} else {
+		    left += extra;
+		}
+	    } else if (graphPtr->rightMargin.reqSize == 0) {
+		right += extra + extra;
+	    }
+	} else if (width < w) {
+	    width = w;
+	}
+    } 
+    if (graphPtr->reqPlotHeight > 0) {	/* Constrain the plotarea height. */
+	int h;
+
+	/* 
+	 * Height of plotarea is constained.  If there's extra space, 
+	 * add it to th top and/or bottom margins.  If there's too little,
+	 * grow the graph height to accomodate it.
+	 */
+	h = plotHeight + inset2 + top + bottom;
+	if (height > h) {		/* Extra space in window. */
+	    int extra;
+
+	    extra = (height - h) / 2;
+	    if (graphPtr->topMargin.reqSize == 0) { 
+		top += extra;
+		if (graphPtr->bottomMargin.reqSize == 0) { 
+		    bottom += extra;
+		} else {
+		    top += extra;
+		}
+	    } else if (graphPtr->bottomMargin.reqSize == 0) {
+		bottom += extra + extra;
+	    }
+	} else if (height < h) {
+	    height = h;
+	}
+    }	
+    graphPtr->width  = width;
+    graphPtr->height = height;
+    graphPtr->left   = left + inset;
+    graphPtr->top    = top + inset;
+    graphPtr->right  = width - right - inset;
+    graphPtr->bottom = height - bottom - inset;
+
+    graphPtr->leftMargin.width    = left   + graphPtr->inset;
+    graphPtr->rightMargin.width   = right  + graphPtr->inset;
+    graphPtr->topMargin.height    = top    + graphPtr->inset;
+    graphPtr->bottomMargin.height = bottom + graphPtr->inset;
+	    
+    graphPtr->vOffset = graphPtr->top + graphPtr->padTop;
+    graphPtr->vRange  = plotHeight - PADDING(graphPtr->yPad);
+    graphPtr->hOffset = graphPtr->left + graphPtr->padLeft;
+    graphPtr->hRange  = plotWidth  - PADDING(graphPtr->xPad);
+
+    if (graphPtr->vRange < 1) {
+	graphPtr->vRange = 1;
+    }
+    if (graphPtr->hRange < 1) {
+	graphPtr->hRange = 1;
+    }
+    graphPtr->hScale = 1.0f / (float)graphPtr->hRange;
+    graphPtr->vScale = 1.0f / (float)graphPtr->vRange;
+
+    /*
+     * Calculate the placement of the graph title so it is centered within the
+     * space provided for it in the top margin
+     */
+    titleY = graphPtr->titleHeight;
+    graphPtr->titleY = 3 + graphPtr->inset;
+    graphPtr->titleX = (graphPtr->right + graphPtr->left) / 2;
+
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureAxis --
+ *
+ *	Configures axis attributes (font, line width, label, etc).
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ * Side Effects:
+ *	Axis layout is deferred until the height and width of the window are
+ *	known.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ConfigureAxis(Axis *axisPtr)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+    float angle;
+
+    /* Check the requested axis limits. Can't allow -min to be greater than
+     * -max.  Do this regardless of -checklimits option. We want to always 
+     * detect when the user has zoomed in beyond the precision of the data.*/
+    if (((isnormal(axisPtr->reqMin)) && (isnormal(axisPtr->reqMax))) &&
+	(axisPtr->reqMin >= axisPtr->reqMax)) {
+	char msg[200];
+	sprintf_s(msg, 200, 
+		  "impossible axis limits (-min %g >= -max %g) for \"%s\"",
+		  axisPtr->reqMin, axisPtr->reqMax, axisPtr->obj.name);
+	Tcl_AppendResult(graphPtr->interp, msg, (char *)NULL);
+	return TCL_ERROR;
+    }
+    axisPtr->scrollMin = axisPtr->reqScrollMin;
+    axisPtr->scrollMax = axisPtr->reqScrollMax;
+    if (axisPtr->logScale) {
+	if (axisPtr->flags & AXIS_CHECK_LIMITS) {
+	    /* Check that the logscale limits are positive.  */
+	    if ((isnormal(axisPtr->reqMin)) && (axisPtr->reqMin <= 0.0)) {
+		Tcl_AppendResult(graphPtr->interp,"bad logscale -min limit \"", 
+			Blt_Dtoa(graphPtr->interp, axisPtr->reqMin), 
+			"\" for axis \"", axisPtr->obj.name, "\"", 
+			(char *)NULL);
+		return TCL_ERROR;
+	    }
+	}
+	if ((isnormal(axisPtr->scrollMin)) && (axisPtr->scrollMin <= 0.0)) {
+	  axisPtr->scrollMin = NAN;
+	}
+	if ((isnormal(axisPtr->scrollMax)) && (axisPtr->scrollMax <= 0.0)) {
+	  axisPtr->scrollMax = NAN;
+	}
+    }
+    angle = fmod(axisPtr->tickAngle, 360.0);
+    if (angle < 0.0f) {
+	angle += 360.0f;
+    }
+    if (axisPtr->normalBg != NULL) {
+	Blt_SetBackgroundChangedProc(axisPtr->normalBg, Blt_UpdateGraph, 
+		graphPtr);
+    }
+    if (axisPtr->activeBg != NULL) {
+	Blt_SetBackgroundChangedProc(axisPtr->activeBg, Blt_UpdateGraph, 
+		graphPtr);
+    }
+    axisPtr->tickAngle = angle;
+    ResetTextStyles(axisPtr);
+
+    axisPtr->titleWidth = axisPtr->titleHeight = 0;
+    if (axisPtr->title != NULL) {
+	unsigned int w, h;
+
+	Blt_GetTextExtents(axisPtr->titleFont, 0, axisPtr->title, -1, &w, &h);
+	axisPtr->titleWidth = (unsigned short int)w;
+	axisPtr->titleHeight = (unsigned short int)h;
+    }
+
+    /* 
+     * Don't bother to check what configuration options have changed.  Almost
+     * every option changes the size of the plotting area (except for -color
+     * and -titlecolor), requiring the graph and its contents to be completely
+     * redrawn.
+     *
+     * Recompute the scale and offset of the axis in case -min, -max options
+     * have changed.
+     */
+    graphPtr->flags |= REDRAW_WORLD;
+    graphPtr->flags |= MAP_WORLD | RESET_AXES | CACHE_DIRTY;
+    axisPtr->flags |= DIRTY;
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NewAxis --
+ *
+ *	Create and initialize a structure containing information to display
+ *	a graph axis.
+ *
+ * Results:
+ *	The return value is a pointer to an Axis structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Axis *
+NewAxis(Graph *graphPtr, const char *name, int margin)
+{
+    Axis *axisPtr;
+    Blt_HashEntry *hPtr;
+    int isNew;
+
+    if (name[0] == '-') {
+	Tcl_AppendResult(graphPtr->interp, "name of axis \"", name, 
+			 "\" can't start with a '-'", (char *)NULL);
+	return NULL;
+    }
+    hPtr = Blt_CreateHashEntry(&graphPtr->axes.table, name, &isNew);
+    if (!isNew) {
+	axisPtr = Blt_GetHashValue(hPtr);
+	if ((axisPtr->flags & DELETE_PENDING) == 0) {
+	    Tcl_AppendResult(graphPtr->interp, "axis \"", name,
+		"\" already exists in \"", Tk_PathName(graphPtr->tkwin), "\"",
+		(char *)NULL);
+	    return NULL;
+	}
+	axisPtr->flags &= ~DELETE_PENDING;
+    } else {
+	axisPtr = calloc(1, sizeof(Axis));
+	if (axisPtr == NULL) {
+	    Tcl_AppendResult(graphPtr->interp, 
+		"can't allocate memory for axis \"", name, "\"", (char *)NULL);
+	    return NULL;
+	}
+	axisPtr->obj.name = Blt_Strdup(name);
+	axisPtr->hashPtr = hPtr;
+	Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE);
+	axisPtr->obj.graphPtr = graphPtr;
+	axisPtr->looseMin = axisPtr->looseMax = AXIS_TIGHT;
+	axisPtr->reqNumMinorTicks = 2;
+	axisPtr->reqNumMajorTicks = 4 /*10*/;
+	axisPtr->margin = MARGIN_NONE;
+	axisPtr->tickLength = 8;
+	axisPtr->scrollUnits = 10;
+	axisPtr->reqMin = axisPtr->reqMax = NAN;
+	axisPtr->reqScrollMin = axisPtr->reqScrollMax = NAN;
+	axisPtr->flags = (AXIS_SHOWTICKS|AXIS_GRIDMINOR|AXIS_AUTO_MAJOR|
+			  AXIS_AUTO_MINOR | AXIS_EXTERIOR);
+	if (graphPtr->classId == CID_ELEM_BAR) {
+	    axisPtr->flags |= AXIS_GRID;
+	}
+	if ((graphPtr->classId == CID_ELEM_BAR) && 
+	    ((margin == MARGIN_TOP) || (margin == MARGIN_BOTTOM))) {
+	    axisPtr->reqStep = 1.0;
+	    axisPtr->reqNumMinorTicks = 0;
+	} 
+	if ((margin == MARGIN_RIGHT) || (margin == MARGIN_TOP)) {
+	    axisPtr->flags |= HIDE;
+	}
+	Blt_Ts_InitStyle(axisPtr->limitsTextStyle);
+	axisPtr->tickLabels = Blt_Chain_Create();
+	axisPtr->lineWidth = 1;
+	Blt_SetHashValue(hPtr, axisPtr);
+    }
+    return axisPtr;
+}
+
+static int
+GetAxisFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, 
+	       Axis **axisPtrPtr)
+{
+    Blt_HashEntry *hPtr;
+    const char *name;
+
+    *axisPtrPtr = NULL;
+    name = Tcl_GetString(objPtr);
+    hPtr = Blt_FindHashEntry(&graphPtr->axes.table, name);
+    if (hPtr != NULL) {
+	Axis *axisPtr;
+
+	axisPtr = Blt_GetHashValue(hPtr);
+	if ((axisPtr->flags & DELETE_PENDING) == 0) {
+	    *axisPtrPtr = axisPtr;
+	    return TCL_OK;
+	}
+    }
+    if (interp != NULL) {
+	Tcl_AppendResult(interp, "can't find axis \"", name, "\" in \"", 
+		Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
+    }
+    return TCL_ERROR;
+}
+
+static int
+GetAxisByClass(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
+	       ClassId classId, Axis **axisPtrPtr)
+{
+    Axis *axisPtr;
+
+    if (GetAxisFromObj(interp, graphPtr, objPtr, &axisPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (classId != CID_NONE) {
+	if ((axisPtr->refCount == 0) || (axisPtr->obj.classId == CID_NONE)) {
+	    /* Set the axis type on the first use of it. */
+	    Blt_GraphSetObjectClass(&axisPtr->obj, classId);
+	} else if (axisPtr->obj.classId != classId) {
+	    if (interp != NULL) {
+  	        Tcl_AppendResult(interp, "axis \"", Tcl_GetString(objPtr),
+		    "\" is already in use on an opposite ", 
+			axisPtr->obj.className, "-axis", 
+			(char *)NULL);
+	    }
+	    return TCL_ERROR;
+	}
+	axisPtr->refCount++;
+    }
+    *axisPtrPtr = axisPtr;
+    return TCL_OK;
+}
+
+void
+Blt_DestroyAxes(Graph *graphPtr)
+{
+    {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch cursor;
+
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	    Axis *axisPtr;
+	    
+	    axisPtr = Blt_GetHashValue(hPtr);
+	    axisPtr->hashPtr = NULL;
+	    DestroyAxis(axisPtr);
+	}
+    }
+    Blt_DeleteHashTable(&graphPtr->axes.table);
+    {
+	int i;
+	
+	for (i = 0; i < 4; i++) {
+	    Blt_Chain_Destroy(graphPtr->axisChain[i]);
+	}
+    }
+    Blt_DeleteHashTable(&graphPtr->axes.tagTable);
+    Blt_Chain_Destroy(graphPtr->axes.displayList);
+}
+
+void
+Blt_ConfigureAxes(Graph *graphPtr)
+{
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch cursor;
+    
+    for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor);
+	 hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	Axis *axisPtr;
+	
+	axisPtr = Blt_GetHashValue(hPtr);
+	ConfigureAxis(axisPtr);
+    }
+}
+
+int
+Blt_DefaultAxes(Graph *graphPtr)
+{
+    int i;
+    int flags;
+
+    flags = Blt_GraphType(graphPtr);
+    for (i = 0; i < 4; i++) {
+	Blt_Chain chain;
+	Axis *axisPtr;
+
+	chain = Blt_Chain_Create();
+	graphPtr->axisChain[i] = chain;
+
+	/* Create a default axis for each chain. */
+	axisPtr = NewAxis(graphPtr, axisNames[i].name, i);
+	if (axisPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	axisPtr->refCount = 1;	/* Default axes are assumed in use. */
+	axisPtr->margin = i;
+	axisPtr->flags |= AXIS_USE;
+	Blt_GraphSetObjectClass(&axisPtr->obj, axisNames[i].classId);
+	/*
+	 * Blt_ConfigureComponentFromObj creates a temporary child window 
+	 * by the name of the axis.  It's used so that the Tk routines
+	 * that access the X resource database can describe a single 
+	 * component and not the entire graph.
+	 */
+ 	if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin,
+		axisPtr->obj.name, "Axis", configSpecs, 0, (Tcl_Obj **)NULL,
+		(char *)axisPtr, flags) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (ConfigureAxis(axisPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	axisPtr->link = Blt_Chain_Append(chain, axisPtr);
+	axisPtr->chain = chain;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ActivateOp --
+ *
+ * 	Activates the axis, drawing the axis with its -activeforeground,
+ *	-activebackgound, -activerelief attributes.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new axis attributes.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ActivateOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+    const char *string;
+
+    string = Tcl_GetString(objv[2]);
+    if (string[0] == 'a') {
+	axisPtr->flags |= ACTIVE;
+    } else {
+	axisPtr->flags &= ~ACTIVE;
+    }
+    if ((axisPtr->flags & (AXIS_USE|HIDE)) == AXIS_USE) {
+	graphPtr->flags |= DRAW_MARGINS | CACHE_DIRTY;
+	Blt_EventuallyRedrawGraph(graphPtr);
+    }
+    return TCL_OK;
+}
+
+/*-------------------------------------------------------------------------------
+ *
+ * BindOp --
+ *
+ *    .g axis bind axisName sequence command
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+BindOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+
+    return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable,
+          Blt_MakeAxisTag(graphPtr, axisPtr->obj.name), objc, objv);
+}
+          
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CgetOp --
+ *
+ *	Queries axis attributes (font, line width, label, etc).
+ *
+ * Results:
+ *	Return value is a standard TCL result.  If querying configuration
+ *	values, interp->result will contain the results.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static int
+CgetOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+
+    return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs,
+	(char *)axisPtr, objv[0], Blt_GraphType(graphPtr));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureOp --
+ *
+ *	Queries or resets axis attributes (font, line width, label, etc).
+ *
+ * Results:
+ *	Return value is a standard TCL result.  If querying configuration
+ *	values, interp->result will contain the results.
+ *
+ * Side Effects:
+ *	Axis resources are possibly allocated (GC, font). Axis layout is
+ *	deferred until the height and width of the window are known.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ConfigureOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+    int flags;
+
+    flags = BLT_CONFIG_OBJV_ONLY | Blt_GraphType(graphPtr);
+    if (objc == 0) {
+	return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs,
+	    (char *)axisPtr, (Tcl_Obj *)NULL, flags);
+    } else if (objc == 1) {
+	return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs,
+	    (char *)axisPtr, objv[0], flags);
+    }
+    if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, 
+	objc, objv, (char *)axisPtr, flags) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (ConfigureAxis(axisPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (axisPtr->flags & AXIS_USE) {
+	if (!Blt_ConfigModified(configSpecs, "-*color", "-background", "-bg",
+				(char *)NULL)) {
+	    graphPtr->flags |= CACHE_DIRTY;
+	}
+	Blt_EventuallyRedrawGraph(graphPtr);
+    }
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LimitsOp --
+ *
+ *	This procedure returns a string representing the axis limits
+ *	of the graph.  The format of the string is { left top right bottom}.
+ *
+ * Results:
+ *	Always returns TCL_OK.  The interp->result field is
+ *	a list of the graph axis limits.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+LimitsOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+    Tcl_Obj *listObjPtr;
+    double min, max;
+
+    if (graphPtr->flags & RESET_AXES) {
+	Blt_ResetAxes(graphPtr);
+    }
+    if (axisPtr->logScale) {
+	min = EXP10(axisPtr->axisRange.min);
+	max = EXP10(axisPtr->axisRange.max);
+    } else {
+	min = axisPtr->axisRange.min;
+	max = axisPtr->axisRange.max;
+    }
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(min));
+    Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(max));
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * InvTransformOp --
+ *
+ *	Maps the given window coordinate into an axis-value.
+ *
+ * Results:
+ *	Returns a standard TCL result.  interp->result contains
+ *	the axis value. If an error occurred, TCL_ERROR is returned
+ *	and interp->result will contain an error message.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+InvTransformOp(Tcl_Interp *interp, Axis *axisPtr, int objc, 
+	       Tcl_Obj *const *objv)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+    double y;				/* Real graph coordinate */
+    int sy;				/* Integer window coordinate*/
+
+    if (graphPtr->flags & RESET_AXES) {
+	Blt_ResetAxes(graphPtr);
+    }
+    if (Tcl_GetIntFromObj(interp, objv[0], &sy) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    /*
+     * Is the axis vertical or horizontal?
+     *
+     * Check the site where the axis was positioned.  If the axis is
+     * virtual, all we have to go on is how it was mapped to an
+     * element (using either -mapx or -mapy options).  
+     */
+    if (AxisIsHorizontal(axisPtr)) {
+	y = Blt_InvHMap(axisPtr, (double)sy);
+    } else {
+	y = Blt_InvVMap(axisPtr, (double)sy);
+    }
+    Tcl_SetDoubleObj(Tcl_GetObjResult(interp), y);
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MarginOp --
+ *
+ *	This procedure returns a string representing the margin the axis
+ *	resides.  The format of the string is { left top right bottom}.
+ *
+ * Results:
+ *	Always returns TCL_OK.  The interp->result field is
+ *	a list of the graph axis limits.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+MarginOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv)
+{
+    const char *marginName;
+
+    marginName = "";
+    if (axisPtr->flags & AXIS_USE) {
+	marginName = axisNames[axisPtr->margin].name;
+    }
+    Tcl_SetStringObj(Tcl_GetObjResult(interp), marginName, -1);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TransformOp --
+ *
+ *	Maps the given axis-value to a window coordinate.
+ *
+ * Results:
+ *	Returns a standard TCL result.  interp->result contains
+ *	the window coordinate. If an error occurred, TCL_ERROR
+ *	is returned and interp->result will contain an error
+ *	message.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+TransformOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv)
+{
+    Graph *graphPtr = axisPtr->obj.graphPtr;
+    double x;
+
+    if (graphPtr->flags & RESET_AXES) {
+	Blt_ResetAxes(graphPtr);
+    }
+    if (Blt_ExprDoubleFromObj(interp, objv[0], &x) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (AxisIsHorizontal(axisPtr)) {
+	x = Blt_HMap(axisPtr, x);
+    } else {
+	x = Blt_VMap(axisPtr, x);
+    }
+    Tcl_SetIntObj(Tcl_GetObjResult(interp), (int)x);
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TypeOp --
+ *
+ *	This procedure returns a string representing the margin the axis
+ *	resides.  The format of the string is "x", "y", or "".
+ *
+ * Results:
+ *	Always returns TCL_OK.  The interp->result field is the type of 
+ *	axis.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+TypeOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv)
+{
+    const char *typeName;
+
+    typeName = "";
+    if (axisPtr->flags & AXIS_USE) {
+	if (axisNames[axisPtr->margin].classId == CID_AXIS_X) {
+	    typeName = "x";
+	} else if (axisNames[axisPtr->margin].classId == CID_AXIS_Y) {
+	    typeName = "y";
+	}
+    }
+    Tcl_SetStringObj(Tcl_GetObjResult(interp), typeName, -1);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * UseOp --
+ *
+ *	Sets the default axis for a margin.
+ *
+ * Results:
+ *	A standard TCL result.  If the named axis doesn't exist
+ *	an error message is put in interp->result.
+ *
+ * .g xaxis use "abc def gah"
+ * .g xaxis use [lappend abc [.g axis use]]
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+UseOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv)
+{
+    Graph *graphPtr = (Graph *)axisPtr;
+    Blt_Chain chain;
+    Blt_ChainLink link;
+    Tcl_Obj **axisObjv;
+    ClassId classId;
+    int axisObjc;
+    int i;
+
+    chain = graphPtr->margins[lastMargin].axes;
+    if (objc == 0) {
+	Tcl_Obj *listObjPtr;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	for (link = Blt_Chain_FirstLink(chain); link != NULL;
+	     link = Blt_Chain_NextLink(link)) {
+	    Axis *axisPtr;
+
+	    axisPtr = Blt_Chain_GetValue(link);
+	    Tcl_ListObjAppendElement(interp, listObjPtr,
+		Tcl_NewStringObj(axisPtr->obj.name, -1));
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+	return TCL_OK;
+    }
+    if ((lastMargin == MARGIN_BOTTOM) || (lastMargin == MARGIN_TOP)) {
+	classId = (graphPtr->inverted) ? CID_AXIS_Y : CID_AXIS_X;
+    } else {
+	classId = (graphPtr->inverted) ? CID_AXIS_X : CID_AXIS_Y;
+    }
+    if (Tcl_ListObjGetElements(interp, objv[0], &axisObjc, &axisObjv) 
+	!= TCL_OK) {
+	return TCL_ERROR;
+    }
+    for (link = Blt_Chain_FirstLink(chain); link!= NULL; 
+	 link = Blt_Chain_NextLink(link)) {
+	Axis *axisPtr;
+
+	axisPtr = Blt_Chain_GetValue(link);
+	axisPtr->link = NULL;
+	axisPtr->flags &= ~AXIS_USE;
+	/* Clear the axis type if it's not currently used.*/
+	if (axisPtr->refCount == 0) {
+	    Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE);
+	}
+    }
+    Blt_Chain_Reset(chain);
+    for (i = 0; i < axisObjc; i++) {
+	Axis *axisPtr;
+
+	if (GetAxisFromObj(interp, graphPtr, axisObjv[i], &axisPtr) != TCL_OK){
+	    return TCL_ERROR;
+	}
+	if (axisPtr->obj.classId == CID_NONE) {
+	    Blt_GraphSetObjectClass(&axisPtr->obj, classId);
+	} else if (axisPtr->obj.classId != classId) {
+	    Tcl_AppendResult(interp, "wrong type axis \"", 
+		axisPtr->obj.name, "\": can't use ", 
+		axisPtr->obj.className, " type axis.", (char *)NULL); 
+	    return TCL_ERROR;
+	}
+	if (axisPtr->link != NULL) {
+	    /* Move the axis from the old margin's "use" list to the new. */
+	    Blt_Chain_UnlinkLink(axisPtr->chain, axisPtr->link);
+	    Blt_Chain_AppendLink(chain, axisPtr->link);
+	} else {
+	    axisPtr->link = Blt_Chain_Append(chain, axisPtr);
+	}
+	axisPtr->chain = chain;
+	axisPtr->flags |= AXIS_USE;
+    }
+    graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES);
+    /* When any axis changes, we need to layout the entire graph.  */
+    graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD);
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+static int
+ViewOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv)
+{
+    Graph *graphPtr;
+    double axisOffset, axisScale;
+    double fract;
+    double viewMin, viewMax, worldMin, worldMax;
+    double viewWidth, worldWidth;
+
+    graphPtr = axisPtr->obj.graphPtr;
+    worldMin = axisPtr->valueRange.min;
+    worldMax = axisPtr->valueRange.max;
+    /* Override data dimensions with user-selected limits. */
+    if (isnormal(axisPtr->scrollMin)) {
+	worldMin = axisPtr->scrollMin;
+    }
+    if (isnormal(axisPtr->scrollMax)) {
+	worldMax = axisPtr->scrollMax;
+    }
+    viewMin = axisPtr->min;
+    viewMax = axisPtr->max;
+    /* Bound the view within scroll region. */ 
+    if (viewMin < worldMin) {
+	viewMin = worldMin;
+    } 
+    if (viewMax > worldMax) {
+	viewMax = worldMax;
+    }
+    if (axisPtr->logScale) {
+	worldMin = log10(worldMin);
+	worldMax = log10(worldMax);
+	viewMin  = log10(viewMin);
+	viewMax  = log10(viewMax);
+    }
+    worldWidth = worldMax - worldMin;
+    viewWidth  = viewMax - viewMin;
+
+    /* Unlike horizontal axes, vertical axis values run opposite of the
+     * scrollbar first/last values.  So instead of pushing the axis minimum
+     * around, we move the maximum instead. */
+    if (AxisIsHorizontal(axisPtr) != axisPtr->descending) {
+	axisOffset  = viewMin - worldMin;
+	axisScale = graphPtr->hScale;
+    } else {
+	axisOffset  = worldMax - viewMax;
+	axisScale = graphPtr->vScale;
+    }
+    if (objc == 4) {
+	Tcl_Obj *listObjPtr;
+	double first, last;
+
+	first = Clamp(axisOffset / worldWidth);
+	last = Clamp((axisOffset + viewWidth) / worldWidth);
+	listObjPtr = Tcl_NewListObj(0, NULL);
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(first));
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(last));
+	Tcl_SetObjResult(interp, listObjPtr);
+	return TCL_OK;
+    }
+    fract = axisOffset / worldWidth;
+    if (GetAxisScrollInfo(interp, objc, objv, &fract, 
+	viewWidth / worldWidth, axisPtr->scrollUnits, axisScale) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (AxisIsHorizontal(axisPtr) != axisPtr->descending) {
+	axisPtr->reqMin = (fract * worldWidth) + worldMin;
+	axisPtr->reqMax = axisPtr->reqMin + viewWidth;
+    } else {
+	axisPtr->reqMax = worldMax - (fract * worldWidth);
+	axisPtr->reqMin = axisPtr->reqMax - viewWidth;
+    }
+    if (axisPtr->logScale) {
+	axisPtr->reqMin = EXP10(axisPtr->reqMin);
+	axisPtr->reqMax = EXP10(axisPtr->reqMax);
+    }
+    graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES);
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisCreateOp --
+ *
+ *	Creates a new axis.
+ *
+ * Results:
+ *	Returns a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+AxisCreateOp(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+	     Tcl_Obj *const *objv)
+{
+    Axis *axisPtr;
+    int flags;
+
+    axisPtr = NewAxis(graphPtr, Tcl_GetString(objv[3]), MARGIN_NONE);
+    if (axisPtr == NULL) {
+	return TCL_ERROR;
+    }
+    flags = Blt_GraphType(graphPtr);
+    if ((Blt_ConfigureComponentFromObj(interp, graphPtr->tkwin, 
+	axisPtr->obj.name, "Axis", configSpecs, objc - 4, objv + 4, 
+	(char *)axisPtr, flags) != TCL_OK) || 
+	(ConfigureAxis(axisPtr) != TCL_OK)) {
+	DestroyAxis(axisPtr);
+	return TCL_ERROR;
+    }
+    Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->obj.name, -1);
+    return TCL_OK;
+}
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisActivateOp --
+ *
+ * 	Activates the axis, drawing the axis with its -activeforeground,
+ *	-activebackgound, -activerelief attributes.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new axis attributes.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+AxisActivateOp(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+	       Tcl_Obj *const *objv)
+{
+    Axis *axisPtr;
+
+    if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return ActivateOp(interp, axisPtr, objc, objv);
+}
+
+
+/*-------------------------------------------------------------------------------
+ *
+ * AxisBindOp --
+ *
+ *    .g axis bind axisName sequence command
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+AxisBindOp(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+	      Tcl_Obj *const *objv)
+{
+    if (objc == 3) {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch cursor;
+	Tcl_Obj *listObjPtr;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.tagTable, &cursor);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	    const char *tagName;
+	    Tcl_Obj *objPtr;
+
+	    tagName = Blt_GetHashKey(&graphPtr->axes.tagTable, hPtr);
+	    objPtr = Tcl_NewStringObj(tagName, -1);
+	    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+	return TCL_OK;
+    }
+    return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, 
+	Blt_MakeAxisTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4);
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisCgetOp --
+ *
+ *	Queries axis attributes (font, line width, label, etc).
+ *
+ * Results:
+ *	Return value is a standard TCL result.  If querying configuration
+ *	values, interp->result will contain the results.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static int
+AxisCgetOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    Axis *axisPtr;
+
+    if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return CgetOp(interp, axisPtr, objc - 4, objv + 4);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisConfigureOp --
+ *
+ *	Queries or resets axis attributes (font, line width, label, etc).
+ *
+ * Results:
+ *	Return value is a standard TCL result.  If querying configuration
+ *	values, interp->result will contain the results.
+ *
+ * Side Effects:
+ *	Axis resources are possibly allocated (GC, font). Axis layout is
+ *	deferred until the height and width of the window are known.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+AxisConfigureOp(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+		Tcl_Obj *const *objv)
+{
+    Tcl_Obj *const *options;
+    int i;
+    int nNames, nOpts;
+
+    /* Figure out where the option value pairs begin */
+    objc -= 3;
+    objv += 3;
+    for (i = 0; i < objc; i++) {
+	Axis *axisPtr;
+	const char *string;
+
+	string = Tcl_GetString(objv[i]);
+	if (string[0] == '-') {
+	    break;
+	}
+	if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    nNames = i;				/* Number of pen names specified */
+    nOpts = objc - i;			/* Number of options specified */
+    options = objv + i;			/* Start of options in objv  */
+
+    for (i = 0; i < nNames; i++) {
+	Axis *axisPtr;
+
+	if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (ConfigureOp(interp, axisPtr, nOpts, options) != TCL_OK) {
+	    break;
+	}
+    }
+    if (i < nNames) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisDeleteOp --
+ *
+ *	Deletes one or more axes.  The actual removal may be deferred until the
+ *	axis is no longer used by any element. The axis can't be referenced by
+ *	its name any longer and it may be recreated.
+ *
+ * Results:
+ *	Returns a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+AxisDeleteOp(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+	     Tcl_Obj *const *objv)
+{
+    int i;
+
+    for (i = 3; i < objc; i++) {
+	Axis *axisPtr;
+
+	if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	axisPtr->flags |= DELETE_PENDING;
+	if (axisPtr->refCount == 0) {
+	    Tcl_EventuallyFree(axisPtr, FreeAxis);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisFocusOp --
+ *
+ * 	Activates the axis, drawing the axis with its -activeforeground,
+ *	-activebackgound, -activerelief attributes.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new axis attributes.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+AxisFocusOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    if (objc > 3) {
+	Axis *axisPtr;
+	const char *string;
+
+	axisPtr = NULL;
+	string = Tcl_GetString(objv[3]);
+	if ((string[0] != '\0') && 
+	    (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK)) {
+	    return TCL_ERROR;
+	}
+	graphPtr->focusPtr = NULL;
+	if ((axisPtr != NULL) && 
+	    ((axisPtr->flags & (AXIS_USE|HIDE)) == AXIS_USE)) {
+	    graphPtr->focusPtr = axisPtr;
+	}
+	Blt_SetFocusItem(graphPtr->bindTable, graphPtr->focusPtr, NULL);
+    }
+    /* Return the name of the axis that has focus. */
+    if (graphPtr->focusPtr != NULL) {
+	Tcl_SetStringObj(Tcl_GetObjResult(interp), 
+		graphPtr->focusPtr->obj.name, -1);
+    }
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisGetOp --
+ *
+ *    Returns the name of the picked axis (using the axis bind operation).
+ *    Right now, the only name accepted is "current".
+ *
+ * Results:
+ *    A standard TCL result.  The interpreter result will contain the name of
+ *    the axis.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+AxisGetOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    Axis *axisPtr;
+
+    axisPtr = Blt_GetCurrentItem(graphPtr->bindTable);
+    /* Report only on axes. */
+    if ((axisPtr != NULL) && 
+	((axisPtr->obj.classId == CID_AXIS_X) || 
+	 (axisPtr->obj.classId == CID_AXIS_Y) || 
+	 (axisPtr->obj.classId == CID_NONE))) {
+	char c;
+	char  *string;
+
+	string = Tcl_GetString(objv[3]);
+	c = string[0];
+	if ((c == 'c') && (strcmp(string, "current") == 0)) {
+	    Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->obj.name,-1);
+	} else if ((c == 'd') && (strcmp(string, "detail") == 0)) {
+	    Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->detail, -1);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisInvTransformOp --
+ *
+ *	Maps the given window coordinate into an axis-value.
+ *
+ * Results:
+ *	Returns a standard TCL result.  interp->result contains
+ *	the axis value. If an error occurred, TCL_ERROR is returned
+ *	and interp->result will contain an error message.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+AxisInvTransformOp(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+		   Tcl_Obj *const *objv)
+{
+    Axis *axisPtr;
+
+    if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return InvTransformOp(interp, axisPtr, objc - 4, objv + 4);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisLimitsOp --
+ *
+ *	This procedure returns a string representing the axis limits of the
+ *	graph.  The format of the string is { left top right bottom}.
+ *
+ * Results:
+ *	Always returns TCL_OK.  The interp->result field is
+ *	a list of the graph axis limits.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+AxisLimitsOp(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+	     Tcl_Obj *const *objv)
+{
+    Axis *axisPtr;
+
+    if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return LimitsOp(interp, axisPtr, objc - 4, objv + 4);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisMarginOp --
+ *
+ *	This procedure returns a string representing the axis limits of the
+ *	graph.  The format of the string is { left top right bottom}.
+ *
+ * Results:
+ *	Always returns TCL_OK.  The interp->result field is
+ *	a list of the graph axis limits.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+AxisMarginOp(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+	     Tcl_Obj *const *objv)
+{
+    Axis *axisPtr;
+
+    if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return MarginOp(interp, axisPtr, objc - 4, objv + 4);
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisNamesOp --
+ *
+ *	Return a list of the names of all the axes.
+ *
+ * Results:
+ *	Returns a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+/*ARGSUSED*/
+static int
+AxisNamesOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if (objc == 3) {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch cursor;
+
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	    Axis *axisPtr;
+
+	    axisPtr = Blt_GetHashValue(hPtr);
+	    if (axisPtr->flags & DELETE_PENDING) {
+		continue;
+	    }
+	    Tcl_ListObjAppendElement(interp, listObjPtr, 
+		     Tcl_NewStringObj(axisPtr->obj.name, -1));
+	}
+    } else {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch cursor;
+
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	    Axis *axisPtr;
+	    int i;
+
+	    axisPtr = Blt_GetHashValue(hPtr);
+	    for (i = 3; i < objc; i++) {
+		const char *pattern;
+
+		pattern = Tcl_GetString(objv[i]);
+		if (Tcl_StringMatch(axisPtr->obj.name, pattern)) {
+		    Tcl_ListObjAppendElement(interp, listObjPtr, 
+			Tcl_NewStringObj(axisPtr->obj.name, -1));
+		    break;
+		}
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisTransformOp --
+ *
+ *	Maps the given axis-value to a window coordinate.
+ *
+ * Results:
+ *	Returns the window coordinate via interp->result.  If an error occurred,
+ *	TCL_ERROR is returned and interp->result will contain an error message.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+AxisTransformOp(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+		Tcl_Obj *const *objv)
+{
+    Axis *axisPtr;
+
+    if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TransformOp(interp, axisPtr, objc - 4, objv + 4);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisMarginOp --
+ *
+ *	This procedure returns a string representing the axis limits of the
+ *	graph.  The format of the string is { left top right bottom}.
+ *
+ * Results:
+ *	Always returns TCL_OK.  The interp->result field is
+ *	a list of the graph axis limits.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+AxisTypeOp(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+	     Tcl_Obj *const *objv)
+{
+    Axis *axisPtr;
+
+    if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TypeOp(interp, axisPtr, objc - 4, objv + 4);
+}
+
+
+static int
+AxisViewOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    Axis *axisPtr;
+
+    if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return ViewOp(interp, axisPtr, objc - 4, objv + 4);
+}
+
+static Blt_OpSpec virtAxisOps[] = {
+    {"activate",     1, AxisActivateOp,     4, 4, "axisName"},
+    {"bind",         1, AxisBindOp,         3, 6, "axisName sequence command"},
+    {"cget",         2, AxisCgetOp,         5, 5, "axisName option"},
+    {"configure",    2, AxisConfigureOp,    4, 0, "axisName ?axisName?... "
+	"?option value?..."},
+    {"create",       2, AxisCreateOp,       4, 0, "axisName ?option value?..."},
+    {"deactivate",   3, AxisActivateOp,     4, 4, "axisName"},
+    {"delete",       3, AxisDeleteOp,       3, 0, "?axisName?..."},
+    {"focus",        1, AxisFocusOp,        3, 4, "?axisName?"},
+    {"get",          1, AxisGetOp,          4, 4, "name"},
+    {"invtransform", 1, AxisInvTransformOp, 5, 5, "axisName value"},
+    {"limits",       1, AxisLimitsOp,       4, 4, "axisName"},
+    {"margin",       1, AxisMarginOp,       4, 4, "axisName"},
+    {"names",        1, AxisNamesOp,        3, 0, "?pattern?..."},
+    {"transform",    2, AxisTransformOp,    5, 5, "axisName value"},
+    {"type",         2, AxisTypeOp,       4, 4, "axisName"},
+    {"view",         1, AxisViewOp,         4, 7, "axisName ?moveto fract? "
+	"?scroll number what?"},
+};
+static int nVirtAxisOps = sizeof(virtAxisOps) / sizeof(Blt_OpSpec);
+
+int
+Blt_VirtualAxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+		  Tcl_Obj *const *objv)
+{
+    GraphVirtualAxisProc *proc;
+    int result;
+
+    proc = Blt_GetOpFromObj(interp, nVirtAxisOps, virtAxisOps, BLT_OP_ARG2, 
+	objc, objv, 0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    result = (*proc) (interp, graphPtr, objc, objv);
+    return result;
+}
+
+static Blt_OpSpec axisOps[] = {
+    {"activate",     1, ActivateOp,     3, 3, "",},
+    {"bind",         1, BindOp,         2, 5, "sequence command",},
+    {"cget",         2, CgetOp,         4, 4, "option",},
+    {"configure",    2, ConfigureOp,    3, 0, "?option value?...",},
+    {"deactivate",   1, ActivateOp,     3, 3, "",},
+    {"invtransform", 1, InvTransformOp, 4, 4, "value",},
+    {"limits",       1, LimitsOp,       3, 3, "",},
+    {"transform",    1, TransformOp,    4, 4, "value",},
+    {"use",          1, UseOp,          3, 4, "?axisName?",},
+    {"view",         1, ViewOp,         3, 6, "?moveto fract? ",},
+};
+
+static int nAxisOps = sizeof(axisOps) / sizeof(Blt_OpSpec);
+
+int
+Blt_AxisOp(Tcl_Interp *interp, Graph *graphPtr, int margin, int objc,
+	   Tcl_Obj *const *objv)
+{
+    int result;
+    GraphAxisProc *proc;
+
+    proc = Blt_GetOpFromObj(interp, nAxisOps, axisOps, BLT_OP_ARG2, 
+	objc, objv, 0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    if (proc == UseOp) {
+	lastMargin = margin;		/* Set global variable to the margin
+					 * in the argument list. Needed only
+					 * for UseOp. */
+	result = (*proc)(interp, (Axis *)graphPtr, objc - 3, objv + 3);
+    } else {
+	Axis *axisPtr;
+
+	axisPtr = Blt_GetFirstAxis(graphPtr->margins[margin].axes);
+	if (axisPtr == NULL) {
+	    return TCL_OK;
+	}
+	result = (*proc)(interp, axisPtr, objc - 3, objv + 3);
+    }
+    return result;
+}
+
+void
+Blt_MapAxes(Graph *graphPtr)
+{
+    int margin;
+    
+    for (margin = 0; margin < 4; margin++) {
+	Blt_Chain chain;
+	Blt_ChainLink link;
+	int count, offset;
+
+	chain = graphPtr->margins[margin].axes;
+	count = offset = 0;
+	for (link = Blt_Chain_FirstLink(chain); link != NULL; 
+	     link = Blt_Chain_NextLink(link)) {
+	    Axis *axisPtr;
+
+	    axisPtr = Blt_Chain_GetValue(link);
+	    if ((axisPtr->flags & (AXIS_USE|DELETE_PENDING)) != AXIS_USE) {
+		continue;
+	    }
+	    if (graphPtr->stackAxes) {
+		if (axisPtr->reqNumMajorTicks <= 0) {
+		    axisPtr->reqNumMajorTicks = 4;
+		}
+		MapStackedAxis(axisPtr, count, margin);
+	    } else {
+		if (axisPtr->reqNumMajorTicks <= 0) {
+		    axisPtr->reqNumMajorTicks = 4;
+		}
+		MapAxis(axisPtr, offset, margin);
+	    }
+	    if (axisPtr->flags & AXIS_GRID) {
+		MapGridlines(axisPtr);
+	    }
+	    offset += (AxisIsHorizontal(axisPtr)) 
+		? axisPtr->height : axisPtr->width;
+	    count++;
+	}
+    }
+}
+
+void
+Blt_DrawAxes(Graph *graphPtr, Drawable drawable)
+{
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	Blt_ChainLink link;
+
+	for (link = Blt_Chain_LastLink(graphPtr->margins[i].axes); 
+	     link != NULL; link = Blt_Chain_PrevLink(link)) {
+	    Axis *axisPtr;
+
+	    axisPtr = Blt_Chain_GetValue(link);
+	    if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) == AXIS_USE) {
+		DrawAxis(axisPtr, drawable);
+	    }
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DrawGrids --
+ *
+ *	Draws the grid lines associated with each axis.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DrawGrids(Graph *graphPtr, Drawable drawable) 
+{
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	Blt_ChainLink link;
+
+	for (link = Blt_Chain_FirstLink(graphPtr->margins[i].axes); link != NULL;
+	     link = Blt_Chain_NextLink(link)) {
+	    Axis *axisPtr;
+
+	    axisPtr = Blt_Chain_GetValue(link);
+	    if (axisPtr->flags & (DELETE_PENDING|HIDE)) {
+		continue;
+	    }
+	    if ((axisPtr->flags & AXIS_USE) && (axisPtr->flags & AXIS_GRID)) {
+		Blt_Draw2DSegments(graphPtr->display, drawable, 
+				   axisPtr->major.gc, axisPtr->major.segments, 
+				   axisPtr->major.nUsed);
+		if (axisPtr->flags & AXIS_GRIDMINOR) {
+		    Blt_Draw2DSegments(graphPtr->display, drawable, 
+			axisPtr->minor.gc, axisPtr->minor.segments, 
+			axisPtr->minor.nUsed);
+		}
+	    }
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GridsToPostScript --
+ *
+ *	Draws the grid lines associated with each axis.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_GridsToPostScript(Graph *graphPtr, Blt_Ps ps) 
+{
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	Blt_ChainLink link;
+
+	for (link = Blt_Chain_FirstLink(graphPtr->margins[i].axes); link != NULL;
+	     link = Blt_Chain_NextLink(link)) {
+	    Axis *axisPtr;
+
+	    axisPtr = Blt_Chain_GetValue(link);
+	    if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE|AXIS_GRID)) !=
+		(AXIS_GRID|AXIS_USE)) {
+		continue;
+	    }
+	    Blt_Ps_Format(ps, "%% Axis %s: grid line attributes\n",
+		axisPtr->obj.name);
+	    Blt_Ps_XSetLineAttributes(ps, axisPtr->major.color, 
+		axisPtr->major.lineWidth, &axisPtr->major.dashes, CapButt, 
+		JoinMiter);
+	    Blt_Ps_Format(ps, "%% Axis %s: major grid line segments\n",
+		axisPtr->obj.name);
+	    Blt_Ps_Draw2DSegments(ps, axisPtr->major.segments, 
+				  axisPtr->major.nUsed);
+	    if (axisPtr->flags & AXIS_GRIDMINOR) {
+		Blt_Ps_XSetLineAttributes(ps, axisPtr->minor.color, 
+		    axisPtr->minor.lineWidth, &axisPtr->minor.dashes, CapButt, 
+		    JoinMiter);
+		Blt_Ps_Format(ps, "%% Axis %s: minor grid line segments\n",
+			axisPtr->obj.name);
+		Blt_Ps_Draw2DSegments(ps, axisPtr->minor.segments, 
+			axisPtr->minor.nUsed);
+	    }
+	}
+    }
+}
+
+void
+Blt_AxesToPostScript(Graph *graphPtr, Blt_Ps ps) 
+{
+    Margin *mp, *mend;
+
+    for (mp = graphPtr->margins, mend = mp + 4; mp < mend; mp++) {
+	Blt_ChainLink link;
+
+	for (link = Blt_Chain_FirstLink(mp->axes); link != NULL; 
+	     link = Blt_Chain_NextLink(link)) {
+	    Axis *axisPtr;
+
+	    axisPtr = Blt_Chain_GetValue(link);
+	    if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) == AXIS_USE) {
+		AxisToPostScript(ps, axisPtr);
+	    }
+	}
+    }
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DrawAxisLimits --
+ *
+ *	Draws the min/max values of the axis in the plotting area.  The text
+ *	strings are formatted according to the "sprintf" format descriptors in
+ *	the limitsFormats array.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Draws the numeric values of the axis limits into the outer regions of
+ *	the plotting area.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DrawAxisLimits(Graph *graphPtr, Drawable drawable)
+{
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch cursor;
+    char minString[200], maxString[200];
+    int vMin, hMin, vMax, hMax;
+
+#define SPACING 8
+    vMin = vMax = graphPtr->left + graphPtr->padLeft + 2;
+    hMin = hMax = graphPtr->bottom - graphPtr->padBottom - 2;	/* Offsets */
+
+    for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor);
+	hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	Axis *axisPtr;
+	Dim2D textDim;
+	const char *minFmt, *maxFmt;
+	char *minPtr, *maxPtr;
+	int isHoriz;
+
+	axisPtr = Blt_GetHashValue(hPtr);
+	if (axisPtr->flags & DELETE_PENDING) {
+	    continue;
+	} 
+	if (axisPtr->nFormats == 0) {
+	    continue;
+	}
+	isHoriz = AxisIsHorizontal(axisPtr);
+	minPtr = maxPtr = NULL;
+	minFmt = maxFmt = axisPtr->limitsFormats[0];
+	if (axisPtr->nFormats > 1) {
+	    maxFmt = axisPtr->limitsFormats[1];
+	}
+	if (minFmt[0] != '\0') {
+	    minPtr = minString;
+	    sprintf_s(minString, 200, minFmt, axisPtr->axisRange.min);
+	}
+	if (maxFmt[0] != '\0') {
+	    maxPtr = maxString;
+	    sprintf_s(maxString, 200, maxFmt, axisPtr->axisRange.max);
+	}
+	if (axisPtr->descending) {
+	    char *tmp;
+
+	    tmp = minPtr, minPtr = maxPtr, maxPtr = tmp;
+	}
+	if (maxPtr != NULL) {
+	    if (isHoriz) {
+		Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0);
+		Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SE);
+		Blt_DrawText2(graphPtr->tkwin, drawable, maxPtr,
+		    &axisPtr->limitsTextStyle, graphPtr->right, hMax, &textDim);
+		hMax -= (textDim.height + SPACING);
+	    } else {
+		Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0);
+		Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_NW);
+		Blt_DrawText2(graphPtr->tkwin, drawable, maxPtr,
+		    &axisPtr->limitsTextStyle, vMax, graphPtr->top, &textDim);
+		vMax += (textDim.width + SPACING);
+	    }
+	}
+	if (minPtr != NULL) {
+	    Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SW);
+	    if (isHoriz) {
+		Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0);
+		Blt_DrawText2(graphPtr->tkwin, drawable, minPtr,
+		    &axisPtr->limitsTextStyle, graphPtr->left, hMin, &textDim);
+		hMin -= (textDim.height + SPACING);
+	    } else {
+		Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0);
+		Blt_DrawText2(graphPtr->tkwin, drawable, minPtr,
+		    &axisPtr->limitsTextStyle, vMin, graphPtr->bottom, &textDim);
+		vMin += (textDim.width + SPACING);
+	    }
+	}
+    } /* Loop on axes */
+}
+
+void
+Blt_AxisLimitsToPostScript(Graph *graphPtr, Blt_Ps ps)
+{
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch cursor;
+    double vMin, hMin, vMax, hMax;
+    char string[200];
+
+#define SPACING 8
+    vMin = vMax = graphPtr->left + graphPtr->padLeft + 2;
+    hMin = hMax = graphPtr->bottom - graphPtr->padBottom - 2;	/* Offsets */
+    for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor);
+	 hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	Axis *axisPtr;
+	const char *minFmt, *maxFmt;
+	unsigned int textWidth, textHeight;
+
+	axisPtr = Blt_GetHashValue(hPtr);
+	if (axisPtr->flags & DELETE_PENDING) {
+	    continue;
+	} 
+	if (axisPtr->nFormats == 0) {
+	    continue;
+	}
+	minFmt = maxFmt = axisPtr->limitsFormats[0];
+	if (axisPtr->nFormats > 1) {
+	    maxFmt = axisPtr->limitsFormats[1];
+	}
+	if (*maxFmt != '\0') {
+	    sprintf_s(string, 200, maxFmt, axisPtr->axisRange.max);
+	    Blt_GetTextExtents(axisPtr->tickFont, 0, string, -1, &textWidth,
+		&textHeight);
+	    if ((textWidth > 0) && (textHeight > 0)) {
+		if (axisPtr->obj.classId == CID_AXIS_X) {
+		    Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0);
+		    Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SE);
+		    Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, 
+			(double)graphPtr->right, hMax);
+		    hMax -= (textWidth + SPACING);
+		} else {
+		    Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0);
+		    Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_NW);
+		    Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle,
+			vMax, (double)graphPtr->top);
+		    vMax += (textWidth + SPACING);
+		}
+	    }
+	}
+	if (*minFmt != '\0') {
+	    sprintf_s(string, 200, minFmt, axisPtr->axisRange.min);
+	    Blt_GetTextExtents(axisPtr->tickFont, 0, string, -1, &textWidth,
+		&textHeight);
+	    if ((textWidth > 0) && (textHeight > 0)) {
+		Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SW);
+		if (axisPtr->obj.classId == CID_AXIS_X) {
+		    Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0);
+		    Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, 
+			(double)graphPtr->left, hMin);
+		    hMin -= (textWidth + SPACING);
+		} else {
+		    Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0);
+		    Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, 
+			vMin, (double)graphPtr->bottom);
+		    vMin += (textWidth + SPACING);
+		}
+	    }
+	}
+    }
+}
+
+Axis *
+Blt_GetFirstAxis(Blt_Chain chain)
+{
+    Blt_ChainLink link;
+
+    link = Blt_Chain_FirstLink(chain);
+    if (link == NULL) {
+	return NULL;
+    }
+    return Blt_Chain_GetValue(link);
+}
+
+Axis *
+Blt_NearestAxis(Graph *graphPtr, int x, int y)
+{
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch cursor;
+    
+    for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor); 
+	 hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	Axis *axisPtr;
+
+	axisPtr = Blt_GetHashValue(hPtr);
+	if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) != AXIS_USE) {
+	    continue;
+	}
+	if (axisPtr->flags & AXIS_SHOWTICKS) {
+	    Blt_ChainLink link;
+
+	    for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; 
+		 link = Blt_Chain_NextLink(link)) {	
+		TickLabel *labelPtr;
+		Point2d t;
+		double rw, rh;
+		Point2d bbox[5];
+
+		labelPtr = Blt_Chain_GetValue(link);
+		Blt_GetBoundingBox(labelPtr->width, labelPtr->height, 
+			axisPtr->tickAngle, &rw, &rh, bbox);
+		t = Blt_AnchorPoint(labelPtr->anchorPos.x, 
+			labelPtr->anchorPos.y, rw, rh, axisPtr->tickAnchor);
+		t.x = x - t.x - (rw * 0.5);
+		t.y = y - t.y - (rh * 0.5);
+
+		bbox[4] = bbox[0];
+		if (Blt_PointInPolygon(&t, bbox, 5)) {
+		    axisPtr->detail = "label";
+		    return axisPtr;
+		}
+	    }
+	}
+	if (axisPtr->title != NULL) {	/* and then the title string. */
+	    Point2d bbox[5];
+	    Point2d t;
+	    double rw, rh;
+	    unsigned int w, h;
+
+	    Blt_GetTextExtents(axisPtr->titleFont, 0, axisPtr->title,-1,&w,&h);
+	    Blt_GetBoundingBox(w, h, axisPtr->titleAngle, &rw, &rh, bbox);
+	    t = Blt_AnchorPoint(axisPtr->titlePos.x, axisPtr->titlePos.y, 
+		rw, rh, axisPtr->titleAnchor);
+	    /* Translate the point so that the 0,0 is the upper left 
+	     * corner of the bounding box.  */
+	    t.x = x - t.x - (rw * 0.5);
+	    t.y = y - t.y - (rh * 0.5);
+	    
+	    bbox[4] = bbox[0];
+	    if (Blt_PointInPolygon(&t, bbox, 5)) {
+		axisPtr->detail = "title";
+		return axisPtr;
+	    }
+	}
+	if (axisPtr->lineWidth > 0) {	/* Check for the axis region */
+	    if ((x <= axisPtr->right) && (x >= axisPtr->left) && 
+		(y <= axisPtr->bottom) && (y >= axisPtr->top)) {
+		axisPtr->detail = "line";
+		return axisPtr;
+	    }
+	}
+    }
+    return NULL;
+}
+ 
+ClientData
+Blt_MakeAxisTag(Graph *graphPtr, const char *tagName)
+{
+    Blt_HashEntry *hPtr;
+    int isNew;
+
+    hPtr = Blt_CreateHashEntry(&graphPtr->axes.tagTable, tagName, &isNew);
+    return Blt_GetHashKey(&graphPtr->axes.tagTable, hPtr);
+}
+
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TimeScaleAxis --
+ *
+ * 	Determine the units of a linear scaled axis.
+ *
+ *	The axis limits are either the range of the data values mapped
+ *	to the axis (autoscaled), or the values specified by the -min
+ *	and -max options (manual).
+ *
+ *	If autoscaled, the smallest and largest major ticks will
+ *	encompass the range of data values.  If the -loose option is
+ *	selected, the next outer ticks are choosen.  If tight, the
+ *	ticks are at or inside of the data limits are used.
+ *
+ * 	If manually set, the ticks are at or inside the data limits
+ * 	are used.  This makes sense for zooming.  You want the
+ * 	selected range to represent the next limit, not something a
+ * 	bit bigger.
+ *
+ *	Note: I added an "always" value to the -loose option to force
+ *	      the manually selected axes to be loose. It's probably
+ *	      not a good idea.
+ *
+ *          maxY
+ *            |    units = magnitude (of least significant digit)
+ *            |    high  = largest unit tick < max axis value
+ *      high _|    low   = smallest unit tick > min axis value
+ *            |
+ *            |    range = high - low
+ *            |    # ticks = greatest factor of range/units
+ *           _|
+ *        U   |
+ *        n   |
+ *        i   |
+ *        t  _|
+ *            |
+ *            |
+ *            |
+ *       low _|
+ *            |
+ *            |_minX________________maxX__
+ *            |   |       |      |       |
+ *     minY  low                        high
+ *           minY
+ *
+ * 	numTicks = Number of ticks
+ * 	min = Minimum value of axis
+ * 	max = Maximum value of axis
+ * 	range    = Range of values (max - min)
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	The axis tick information is set.  The actual tick values will
+ *	be generated later.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+TimeScaleAxis(Axis *axisPtr, double min, double max)
+{
+}
+
+
diff --git a/tlt3.0/bltGrAxis.h b/tlt3.0/bltGrAxis.h
new file mode 100644
index 0000000..a009aec
--- /dev/null
+++ b/tlt3.0/bltGrAxis.h
@@ -0,0 +1,332 @@
+
+/*
+ * bltGrAxis.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_GR_AXIS_H
+#define _BLT_GR_AXIS_H
+
+#include "bltList.h"
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Grid --
+ *
+ *	Contains attributes of describing how to draw grids (at major ticks)
+ *	in the graph.  Grids may be mapped to either/both X and Y axis.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    Blt_Dashes dashes;		/* Dash style of the grid. This represents an
+				 * array of alternatingly drawn pixel
+				 * values. */
+    int lineWidth;		/* Width of the grid lines */
+    XColor *color;		/* Color of the grid lines */
+    GC gc;			/* Graphics context for the grid. */
+
+    Segment2d *segments;	/* Array of line segments representing the
+				 * grid lines */
+    int nUsed;			/* # of axis segments in use. */
+    int nAllocated;		/* # of axis segments allocated. */
+} Grid;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AxisRange --
+ *
+ *	Designates a range of values by a minimum and maximum limit.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    double min, max, range, scale;
+} AxisRange;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TickLabel --
+ *
+ * 	Structure containing the X-Y screen coordinates of the tick
+ * 	label (anchored at its center).
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    Point2d anchorPos;
+    unsigned int width, height;
+    char string[1];
+} TickLabel;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Ticks --
+ *
+ * 	Structure containing information where the ticks (major or
+ *	minor) will be displayed on the graph.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    unsigned int nTicks;	/* # of ticks on axis */
+    double values[1];		/* Array of tick values (malloc-ed). */
+} Ticks;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TickSweep --
+ *
+ * 	Structure containing information where the ticks (major or
+ *	minor) will be displayed on the graph.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    double initial;		/* Initial value */
+    double step;		/* Size of interval */
+    unsigned int nSteps;	/* Number of intervals. */
+} TickSweep;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Axis --
+ *
+ * 	Structure contains options controlling how the axis will be
+ * 	displayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    GraphObj obj;			/* Must be first field in axis. */
+
+    unsigned int flags;		
+
+    Blt_HashEntry *hashPtr;
+
+    /* Fields specific to axes. */
+
+    const char *detail;
+
+    int refCount;			/* Number of elements referencing this
+					 * axis. */
+    int logScale;			/* If non-zero, generate log scale
+					 * ticks for the axis. */
+    int timeScale;			/* If non-zero, generate time scale
+					 * ticks for the axis. This option is
+					 * overridden by -logscale. */
+    int descending;			/* If non-zero, display the range of
+					 * values on the axis in descending
+					 * order, from high to low. */
+
+    int looseMin, looseMax;		/* If non-zero, axis range extends to
+					 * the outer major ticks, otherwise at
+					 * the limits of the data values. This
+					 * is overriddened by setting the -min
+					 * and -max options.  */
+
+    const char *title;			/* Title of the axis. */
+
+    int titleAlternate;			/* Indicates whether to position the
+					 * title above/left of the axis. */
+
+    Point2d titlePos;			/* Position of the title */
+
+    unsigned short int titleWidth, titleHeight;	
+
+
+    int lineWidth;			/* Width of lines representing axis
+					 * (including ticks).  If zero, then
+					 * no axis lines or ticks are
+					 * drawn. */
+
+    const char **limitsFormats;		/* One or two strings of sprintf-like
+					 * formats describing how to display
+					 * virtual axis limits. If NULL,
+					 * display no limits. */
+    int nFormats;
+
+    TextStyle limitsTextStyle;		/* Text attributes (color, font,
+					 * rotation, etc.)  of the limits. */
+
+    double windowSize;			/* Size of a sliding window of values
+					 * used to scale the axis
+					 * automatically as new data values
+					 * are added. The axis will always
+					 * display the latest values in this
+					 * range. */
+
+    double shiftBy;			/* Shift maximum by this interval. */
+
+    int tickLength;			/* Length of major ticks in pixels */
+
+    const char *formatCmd;		/* Specifies a TCL command, to be
+					 * invoked by the axis whenever it has
+					 * to generate tick labels. */
+
+    Tcl_Obj *scrollCmdObjPtr;
+    int scrollUnits;
+
+    double min, max;			/* The actual axis range. */
+
+    double reqMin, reqMax;		/* Requested axis bounds. Consult the
+					 * axisPtr->flags field for
+					 * AXIS_CONFIG_MIN and AXIS_CONFIG_MAX
+					 * to see if the requested bound have
+					 * been set.  They override the
+					 * computed range of the axis
+					 * (determined by auto-scaling). */
+
+    double reqScrollMin, reqScrollMax;
+
+    double scrollMin, scrollMax;	/* Defines the scrolling reqion of the
+					 * axis.  Normally the region is
+					 * determined from the data limits. If
+					 * specified, these values override
+					 * the data-range. */
+
+    AxisRange valueRange;		/* Range of data values of elements
+					 * mapped to this axis. This is used
+					 * to auto-scale the axis in "tight"
+					 * mode. */
+    AxisRange axisRange;		/* Smallest and largest major tick
+					 * values for the axis.  The tick
+					 * values lie outside the range of
+					 * data values.  This is used to
+					 * auto-scale the axis in "loose"
+					 * mode. */
+
+    double prevMin, prevMax;
+
+    double reqStep;		/* If > 0.0, overrides the computed major 
+				 * tick interval.  Otherwise a stepsize 
+				 * is automatically calculated, based 
+				 * upon the range of elements mapped to the 
+				 * axis. The default value is 0.0. */
+
+    Ticks *t1Ptr;		/* Array of major tick positions. May be
+				 * set by the user or generated from the 
+				 * major sweep below. */
+
+    Ticks *t2Ptr;		/* Array of minor tick positions. May be
+				 * set by the user or generated from the
+				 * minor sweep below. */
+
+    TickSweep minorSweep, majorSweep;
+
+    int reqNumMajorTicks;	/* Default number of ticks to be displayed. */
+    int reqNumMinorTicks;	/* If non-zero, represents the
+				 * requested the number of minor ticks
+				 * to be uniformally displayed along
+				 * each major tick. */
+
+
+    int labelOffset;		/* If non-zero, indicates that the tick
+				 * label should be offset to sit in the
+				 * middle of the next interval. */
+
+    /* The following fields are specific to logical axes */
+
+    int margin;				/* Margin that contains this axis. */
+    Blt_ChainLink link;			/* Axis link in margin list. */
+    Blt_Chain chain;
+    Segment2d *segments;		/* Array of line segments representing
+					 * the major and minor ticks, but also
+					 * the * axis line itself. The segment
+					 * coordinates * are relative to the
+					 * axis. */
+    int nSegments;			/* Number of segments in the above
+					 * array. */
+    Blt_Chain tickLabels;		/* Contains major tick label strings
+					 * and their offsets along the
+					 * axis. */
+    short int left, right, top, bottom;	/* Region occupied by the of axis. */
+    short int width, height;		/* Extents of axis */
+    short int maxTickWidth, maxTickHeight;
+    Blt_Background normalBg;
+    Blt_Background activeBg;
+    XColor *activeFgColor;
+
+    int relief;
+    int borderWidth;
+    int activeRelief;
+
+    float tickAngle;	
+    Blt_Font tickFont;
+    Tk_Anchor tickAnchor;
+    Tk_Anchor reqTickAnchor;
+    XColor *tickColor;
+    GC tickGC;				/* Graphics context for axis and tick
+					 * labels */
+    GC activeTickGC;
+
+    double titleAngle;	
+    Blt_Font titleFont;
+    Tk_Anchor titleAnchor;
+    Tk_Justify titleJustify;
+    XColor *titleColor;
+    
+    Grid major, minor;			/* Axis grid information. */
+
+    double screenScale;
+    int screenMin, screenRange;
+
+} Axis;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Axis2d --
+ *
+ *	The pair of axes mapping a point onto the graph.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    Axis *x, *y;
+} Axis2d;
+
+/* Axis flags: */
+
+#define AXIS_AUTO_MAJOR		(1<<16) /* Auto-generate major ticks. */
+#define AXIS_AUTO_MINOR		(1<<17) /* Auto-generate minor ticks. */
+#define AXIS_ONSCREEN		(1<<18)	/* Axis is displayed on the screen via
+					 * the "use" operation */
+#define AXIS_GRID		(1<<19)
+#define AXIS_GRID_MINOR		(1<<20)
+#define AXIS_TICKS		(1<<21)
+#define AXIS_TICKS_INTERIOR	(1<<22)
+#define AXIS_CHECK_LIMITS	(1<<23)
+#define AXIS_LOGSCALE		(1<<24)
+#define AXIS_DECREASING		(1<<25)
+
+#endif /* _BLT_GR_AXIS_H */
diff --git a/tlt3.0/bltGrBar.c b/tlt3.0/bltGrBar.c
new file mode 100644
index 0000000..0caf5ba
--- /dev/null
+++ b/tlt3.0/bltGrBar.c
@@ -0,0 +1,2539 @@
+
+/*
+ * bltGrBar.c --
+ *
+ * This module implements barchart elements for the BLT graph widget.
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <X11/Xutil.h>
+
+#include "bltInt.h"
+#include "bltMath.h"
+#include "bltGraph.h"
+#include "bltGrElem.h"
+
+#define CLAMP(x,l,h)	((x) = (((x)<(l))? (l) : ((x)>(h)) ? (h) : (x)))
+
+typedef struct {
+    float x1, y1, x2, y2;
+} BarRegion;
+
+typedef struct {
+    Point2f ul, lr;
+    Segment2d segments[4];  
+    int nSegments;
+} Bar;
+
+typedef struct {
+    const char *name;			/* Pen style identifier.  If NULL, pen
+					 * was statically allocated. */
+    ClassId classId;			/* Type of pen */
+    const char *typeId;			/* String token identifying the type of
+					 * pen */
+    unsigned int flags;			/* Indicates if the pen element is
+					 * active or normal */
+    int refCount;			/* Reference count for elements using
+					 * this pen. */
+    Blt_HashEntry *hashPtr;
+    Blt_ConfigSpec *configSpecs;	/* Configuration specifications */
+    PenConfigureProc *configProc;
+    PenDestroyProc *destroyProc;
+    Graph *graphPtr;			/* Graph that the pen is associated
+					 * with. */
+    /* Barchart specific pen fields start here. */
+    XColor *outlineColor;		/* Outline (foreground) color of bar */
+    Blt_Background fill;		/* 3D border and fill (background)
+					 * color */
+    int borderWidth;			/* 3D border width of bar */
+    int relief;				/* Relief of the bar */
+    Pixmap stipple;			/* Stipple */
+    GC fillGC;				/* Graphics context */
+    GC outlineGC;			/* GC for outline of bar. */
+
+    /* Error bar attributes. */
+    int errorBarShow;			/* Describes which error bars to
+					 * display: none, x, y, or * both. */
+
+    int errorBarLineWidth;		/* Width of the error bar segments. */
+
+    int errorBarCapWidth;
+    XColor *errorBarColor;		/* Color of the error bar. */
+
+    GC errorBarGC;			/* Error bar graphics context. */
+
+    /* Show value attributes. */
+    int valueShow;			/* Indicates whether to display data
+					 * value.  Values are x, y, or none. */
+
+    const char *valueFormat;		/* A printf format string. */
+    TextStyle valueStyle;		/* Text attributes (color, font,
+					 * rotation, etc.) of the value. */
+    
+} BarPen;
+
+typedef struct {
+    Weight weight;			/* Weight range where this pen is
+					 * valid. */
+    BarPen *penPtr;			/* Pen to use. */
+
+    XRectangle *bars;			/* Indicates starting location in bar
+					 * array for this pen. */
+    int nBars;				/* # of bar segments for this pen. */
+
+    GraphSegments xeb, yeb;		/* X and Y error bars. */
+
+    int symbolSize;			/* Size of the pen's symbol scaled to
+					 * the current graph size. */
+    int errorBarCapWidth;		/* Length of the cap ends on each error
+					 * bar. */
+
+} BarStyle;
+
+typedef struct {
+    GraphObj obj;			/* Must be first field in element. */
+    unsigned int flags;		
+    Blt_HashEntry *hashPtr;
+
+    /* Fields specific to elements. */
+    const char *label;			/* Label displayed in legend */
+    unsigned short row, col;		/* Position of the entry in the
+					 * legend. */
+    int legendRelief;			/* Relief of label in legend. */
+    Axis2d axes;			/* X-axis and Y-axis mapping the
+					 * element */
+    ElemValues x, y, w;			/* Contains array of floating point
+					 * graph coordinate values. Also holds
+					 * min/max and the number of
+					 * coordinates */
+    int *activeIndices;			/* Array of indices (malloc-ed) which
+					 * indicate which data points are active
+					 * (drawn * with "active" colors). */
+    int nActiveIndices;			/* Number of active data points.
+					 * Special case: if nActiveIndices < 0
+					 * and the active bit is set in "flags",
+					 * then all data * points are drawn
+					 * active. */
+    ElementProcs *procsPtr;
+    Blt_ConfigSpec *configSpecs;	/* Configuration specifications. */
+    BarPen *activePenPtr;		/* Standard Pens */
+    BarPen *normalPenPtr;
+    BarPen *builtinPenPtr;
+    Blt_Chain stylePalette;		/* Palette of pens. */
+
+    /* Symbol scaling */
+    int scaleSymbols;			/* If non-zero, the symbols will scale
+					 * in size as the graph is zoomed
+					 * in/out.  */
+    double xRange, yRange;		/* Initial X-axis and Y-axis ranges:
+					 * used to scale the size of element's
+					 * symbol. */
+    int state;
+    Blt_ChainLink link;
+
+    /* Fields specific to the barchart element */
+
+    float barWidth;
+    const char *groupName;
+
+    int *barToData;
+    XRectangle *bars;		       /* Array of rectangles comprising the bar
+					* segments of the element. */
+    int *activeToData;
+    XRectangle *activeRects;
+
+    int nBars;				/* # of visible bar segments for
+					 * element */
+    int nActive;
+
+    int xPad;				/* Spacing on either side of bar */
+
+    ElemValues xError;			/* Relative/symmetric X error values. */
+    ElemValues yError;			/* Relative/symmetric Y error values. */
+    ElemValues xHigh, xLow;		/* Absolute/asymmetric X-coordinate
+					 * high/low error values. */
+    ElemValues yHigh, yLow;		/* Absolute/asymmetric Y-coordinate
+					 * high/low error values. */
+    BarPen builtinPen;
+
+    GraphSegments xeb, yeb;
+
+    int errorBarCapWidth;		/* Length of cap on error bars */
+} BarElement;
+
+extern Blt_CustomOption bltBarPenOption;
+extern Blt_CustomOption bltValuesOption;
+extern Blt_CustomOption bltValuePairsOption;
+extern Blt_CustomOption bltXAxisOption;
+extern Blt_CustomOption bltYAxisOption;
+extern Blt_CustomOption bltColorOption;
+extern Blt_CustomOption bltBarStylesOption;
+
+static Blt_OptionParseProc ObjToBarMode;
+static Blt_OptionPrintProc BarModeToObj;
+Blt_CustomOption bltBarModeOption =
+{
+    ObjToBarMode, BarModeToObj, NULL, (ClientData)0
+};
+
+#define DEF_BAR_ACTIVE_PEN		"activeBar"
+#define DEF_BAR_AXIS_X			"x"
+#define DEF_BAR_AXIS_Y			"y"
+#define DEF_BAR_BACKGROUND		"navyblue"
+#define DEF_BAR_BORDERWIDTH		"2"
+#define DEF_BAR_ERRORBAR_COLOR		"defcolor"
+#define DEF_BAR_ERRORBAR_LINE_WIDTH	"1"
+#define DEF_BAR_ERRORBAR_CAP_WIDTH	"1"
+#define DEF_BAR_FOREGROUND		"blue"
+#define DEF_BAR_HIDE			"no"
+#define DEF_BAR_LABEL_RELIEF		"flat"
+#define DEF_BAR_NORMAL_STIPPLE		""
+#define DEF_BAR_RELIEF			"raised"
+#define DEF_BAR_SHOW_ERRORBARS		"both"
+#define DEF_BAR_STATE			"normal"
+#define DEF_BAR_STACK			(char *)NULL
+#define DEF_BAR_STYLES			""
+#define DEF_BAR_TAGS			"all"
+#define DEF_BAR_WIDTH			"0.0"
+
+#define DEF_PEN_ACTIVE_BACKGROUND	"red"
+#define DEF_PEN_ACTIVE_FOREGROUND     	"pink"
+#define DEF_PEN_BORDERWIDTH		"2"
+#define DEF_PEN_NORMAL_BACKGROUND	"navyblue"
+#define DEF_PEN_NORMAL_FOREGROUND	"blue"
+#define DEF_PEN_RELIEF			"raised"
+#define DEF_PEN_STIPPLE			""
+#define DEF_PEN_TYPE			"bar"
+#define	DEF_PEN_VALUE_ANCHOR		"s"
+#define	DEF_PEN_VALUE_COLOR		RGB_BLACK
+#define	DEF_PEN_VALUE_FONT		STD_FONT_SMALL
+#define	DEF_PEN_VALUE_FORMAT		"%g"
+#define DEF_PEN_SHOW_VALUES		"no"
+
+static Blt_ConfigSpec barPenConfigSpecs[] =
+{
+    {BLT_CONFIG_BACKGROUND, "-background", "background", "Background",
+	DEF_PEN_ACTIVE_BACKGROUND, Blt_Offset(BarPen, fill),
+	BLT_CONFIG_NULL_OK | ACTIVE_PEN},
+    {BLT_CONFIG_BACKGROUND, "-background", "background", "Background",
+	DEF_PEN_NORMAL_BACKGROUND, Blt_Offset(BarPen, fill),
+	BLT_CONFIG_NULL_OK | NORMAL_PEN},
+    {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL,
+	(char *)NULL, 0, ALL_PENS},
+    {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL,
+	(char *)NULL, 0, ALL_PENS},
+    {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth",
+	DEF_PEN_BORDERWIDTH, Blt_Offset(BarPen, borderWidth), ALL_PENS},
+    {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor",
+	DEF_BAR_ERRORBAR_COLOR, Blt_Offset(BarPen, errorBarColor), ALL_PENS, 
+	&bltColorOption},
+    {BLT_CONFIG_PIXELS_NNEG, "-errorbarwidth", "errorBarWidth","ErrorBarWidth",
+	DEF_BAR_ERRORBAR_LINE_WIDTH, Blt_Offset(BarPen, errorBarLineWidth),
+        ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-errorbarcap", "errorBarCap", "ErrorBarCap", 
+	DEF_BAR_ERRORBAR_CAP_WIDTH, Blt_Offset(BarPen, errorBarCapWidth),
+        ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL,
+	(char *)NULL, 0, ALL_PENS},
+    {BLT_CONFIG_SYNONYM, "-fill", "background", (char *)NULL,
+	(char *)NULL, 0, ALL_PENS},
+    {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
+	DEF_PEN_ACTIVE_FOREGROUND, Blt_Offset(BarPen, outlineColor),
+	ACTIVE_PEN | BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
+	DEF_PEN_NORMAL_FOREGROUND, Blt_Offset(BarPen, outlineColor),
+	NORMAL_PEN |  BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char *)NULL,
+	(char *)NULL, 0, ALL_PENS},
+    {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief",
+	DEF_PEN_RELIEF, Blt_Offset(BarPen, relief), ALL_PENS},
+    {BLT_CONFIG_FILL, "-showerrorbars", "showErrorBars", "ShowErrorBars",
+	DEF_BAR_SHOW_ERRORBARS, Blt_Offset(BarPen, errorBarShow),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues",
+	DEF_PEN_SHOW_VALUES, Blt_Offset(BarPen, valueShow),
+        ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple", DEF_PEN_STIPPLE, 
+	Blt_Offset(BarPen, stipple), ALL_PENS | BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_STRING, "-type", (char *)NULL, (char *)NULL, DEF_PEN_TYPE, 
+	Blt_Offset(BarPen, typeId), ALL_PENS | BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor",
+	DEF_PEN_VALUE_ANCHOR, Blt_Offset(BarPen, valueStyle.anchor), 
+	ALL_PENS},
+    {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor",
+	DEF_PEN_VALUE_COLOR, Blt_Offset(BarPen, valueStyle.color), 
+	ALL_PENS},
+    {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont",
+	DEF_PEN_VALUE_FONT, Blt_Offset(BarPen, valueStyle.font), 
+	ALL_PENS},
+    {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat",
+	DEF_PEN_VALUE_FORMAT, Blt_Offset(BarPen, valueFormat),
+	ALL_PENS | BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate",
+	(char *)NULL, Blt_Offset(BarPen, valueStyle.angle), ALL_PENS},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+
+static Blt_ConfigSpec barElemConfigSpecs[] = {
+    {BLT_CONFIG_CUSTOM, "-activepen", "activePen", "ActivePen",
+	DEF_BAR_ACTIVE_PEN, Blt_Offset(BarElement, activePenPtr), 
+	BLT_CONFIG_NULL_OK, &bltBarPenOption},
+    {BLT_CONFIG_BACKGROUND, "-background", "background", "Background",
+	DEF_BAR_BACKGROUND, Blt_Offset(BarElement, builtinPen.fill),
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_FLOAT, "-barwidth", "barWidth", "BarWidth",
+	DEF_BAR_WIDTH, Blt_Offset(BarElement, barWidth),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL,
+	(char *)NULL, 0, 0},
+    {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL,
+	(char *)NULL, 0, 0},
+    {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_BAR_TAGS, 
+	Blt_Offset(BarElement, obj.tags), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth",
+	DEF_BAR_BORDERWIDTH, Blt_Offset(BarElement, builtinPen.borderWidth), 0},
+    {BLT_CONFIG_SYNONYM, "-color", "background", (char *)NULL,
+	(char *)NULL, 0, 0},
+    {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor",
+	DEF_BAR_ERRORBAR_COLOR, 
+	Blt_Offset(BarElement, builtinPen.errorBarColor), 0, &bltColorOption},
+    {BLT_CONFIG_PIXELS_NNEG,"-errorbarwidth", "errorBarWidth", "ErrorBarWidth",
+	DEF_BAR_ERRORBAR_LINE_WIDTH, 
+	Blt_Offset(BarElement, builtinPen.errorBarLineWidth), 
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-errorbarcap", "errorBarCap", "ErrorBarCap", 
+	DEF_BAR_ERRORBAR_CAP_WIDTH, 
+	Blt_Offset(BarElement, builtinPen.errorBarCapWidth),
+        BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_CUSTOM, "-data", "data", "Data", (char *)NULL, 0, 0, 
+	&bltValuePairsOption},
+    {BLT_CONFIG_SYNONYM, "-fill", "background", (char *)NULL,
+	(char *)NULL, 0, 0},
+    {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
+	DEF_BAR_FOREGROUND, Blt_Offset(BarElement, builtinPen.outlineColor), 
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_STRING, "-label", "label", "Label", (char *)NULL, 
+	Blt_Offset(BarElement, label), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_RELIEF, "-legendrelief", "legendRelief", "LegendRelief",
+	DEF_BAR_LABEL_RELIEF, Blt_Offset(BarElement, legendRelief),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_BAR_HIDE, 
+         Blt_Offset(BarElement, flags), BLT_CONFIG_DONT_SET_DEFAULT,
+        (Blt_CustomOption *)HIDE},
+    {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_BAR_AXIS_X, 
+	Blt_Offset(BarElement, axes.x), 0, &bltXAxisOption},
+    {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_BAR_AXIS_Y, 
+	Blt_Offset(BarElement, axes.y), 0, &bltYAxisOption},
+    {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char *)NULL,
+	(char *)NULL, 0, 0},
+    {BLT_CONFIG_CUSTOM, "-pen", "pen", "Pen", (char *)NULL, 
+	Blt_Offset(BarElement, normalPenPtr), BLT_CONFIG_NULL_OK, 
+	&bltBarPenOption},
+    {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief",
+	DEF_BAR_RELIEF, Blt_Offset(BarElement, builtinPen.relief), 0},
+    {BLT_CONFIG_FILL, "-showerrorbars", "showErrorBars", "ShowErrorBars",
+	DEF_BAR_SHOW_ERRORBARS, Blt_Offset(BarElement, builtinPen.errorBarShow),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues",
+	DEF_PEN_SHOW_VALUES, Blt_Offset(BarElement, builtinPen.valueShow),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-stack", "stack", "Stack", DEF_BAR_STACK, 
+	Blt_Offset(BarElement, groupName), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_STATE, "-state", "state", "State", DEF_BAR_STATE, 
+	Blt_Offset(BarElement, state), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple",
+	DEF_BAR_NORMAL_STIPPLE, Blt_Offset(BarElement, builtinPen.stipple),
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_CUSTOM, "-styles", "styles", "Styles", DEF_BAR_STYLES, 
+	Blt_Offset(BarElement, stylePalette), 0, &bltBarStylesOption},
+    {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor",
+	DEF_PEN_VALUE_ANCHOR, 
+	Blt_Offset(BarElement, builtinPen.valueStyle.anchor), 0},
+    {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor",
+	DEF_PEN_VALUE_COLOR, 
+	Blt_Offset(BarElement, builtinPen.valueStyle.color), 0},
+    {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont",
+	DEF_PEN_VALUE_FONT, 
+	Blt_Offset(BarElement, builtinPen.valueStyle.font), 0},
+    {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat",
+	DEF_PEN_VALUE_FORMAT, Blt_Offset(BarElement, builtinPen.valueFormat),
+        BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate",
+	(char *)NULL, Blt_Offset(BarElement, builtinPen.valueStyle.angle), 0},
+    {BLT_CONFIG_CUSTOM, "-weights", "weights", "Weights", (char *)NULL, 
+	Blt_Offset(BarElement, w), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-x", "xdata", "Xdata", (char *)NULL, 
+	Blt_Offset(BarElement, x), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-y", "ydata", "Ydata", (char *)NULL, 
+	Blt_Offset(BarElement, y), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-xdata", "xdata", "Xdata", (char *)NULL, 
+	Blt_Offset(BarElement, x), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-ydata", "ydata", "Ydata", (char *)NULL, 
+	Blt_Offset(BarElement, y), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-xerror", "xError", "XError", (char *)NULL, 
+	Blt_Offset(BarElement, xError), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-xhigh", "xHigh", "XHigh", (char *)NULL, 
+	Blt_Offset(BarElement, xHigh), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-xlow", "xLow", "XLow", (char *)NULL, 
+	Blt_Offset(BarElement, xLow), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-yerror", "yError", "YError", (char *)NULL, 
+	Blt_Offset(BarElement, yError), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-yhigh", "yHigh", "YHigh", (char *)NULL, 
+	Blt_Offset(BarElement, yHigh), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-ylow", "yLow", "YLow", (char *)NULL, 
+	Blt_Offset(BarElement, yLow), 0, &bltValuesOption},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+/* Forward declarations */
+static PenConfigureProc ConfigureBarPenProc;
+static PenDestroyProc DestroyBarPenProc;
+static ElementClosestProc ClosestBarProc;
+static ElementConfigProc ConfigureBarProc;
+static ElementDestroyProc DestroyBarProc;
+static ElementDrawProc DrawActiveBarProc;
+static ElementDrawProc DrawNormalBarProc;
+static ElementDrawSymbolProc DrawSymbolProc;
+static ElementExtentsProc GetBarExtentsProc;
+static ElementToPostScriptProc ActiveBarToPostScriptProc;
+static ElementToPostScriptProc NormalBarToPostScriptProc;
+static ElementSymbolToPostScriptProc SymbolToPostScriptProc;
+static ElementMapProc MapBarProc;
+
+/*
+ *---------------------------------------------------------------------------
+ * Custom option parse and print procedures
+ *---------------------------------------------------------------------------
+ */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NameOfBarMode --
+ *
+ *	Converts the integer representing the mode style into a string.
+ *
+ *---------------------------------------------------------------------------
+ */
+static const char *
+NameOfBarMode(BarMode mode)
+{
+    switch (mode) {
+    case BARS_INFRONT:
+	return "infront";
+    case BARS_OVERLAP:
+	return "overlap";
+    case BARS_STACKED:
+	return "stacked";
+    case BARS_ALIGNED:
+	return "aligned";
+    default:
+	return "unknown mode value";
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToMode --
+ *
+ *	Converts the mode string into its numeric representation.
+ *
+ *	Valid mode strings are:
+ *
+ *      "infront"   Draw a full bar at each point in the element.
+ *
+ * 	"stacked"   Stack bar segments vertically. Each stack is defined
+ *		    by each ordinate at a particular abscissa. The height
+ *		    of each segment is represented by the sum the previous
+ *		    ordinates.
+ *
+ *	"aligned"   Align bar segments as smaller slices one next to
+ *		    the other.  Like "stacks", aligned segments are
+ *		    defined by each ordinate at a particular abscissa.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToBarMode(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Interpreter to send results back
+					 * to */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* Mode style string */
+    char *widgRec,			/* Cubicle structure record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    BarMode *modePtr = (BarMode *)(widgRec + offset);
+    int length;
+    char c;
+    char *string;
+    
+    string = Tcl_GetStringFromObj(objPtr, &length);
+    c = string[0];
+    if ((c == 'n') && (strncmp(string, "normal", length) == 0)) {
+	*modePtr = BARS_INFRONT;
+    } else if ((c == 'i') && (strncmp(string, "infront", length) == 0)) {
+	*modePtr = BARS_INFRONT;
+    } else if ((c == 's') && (strncmp(string, "stacked", length) == 0)) {
+	*modePtr = BARS_STACKED;
+    } else if ((c == 'a') && (strncmp(string, "aligned", length) == 0)) {
+	*modePtr = BARS_ALIGNED;
+    } else if ((c == 'o') && (strncmp(string, "overlap", length) == 0)) {
+	*modePtr = BARS_OVERLAP;
+    } else {
+	Tcl_AppendResult(interp, "bad mode argument \"", string, "\": should"
+		"be \"infront\", \"stacked\", \"overlap\", or \"aligned\"",
+		(char *)NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BarModeToObj --
+ *
+ *	Returns the mode style string based upon the mode flags.
+ *
+ * Results:
+ *	The mode style string is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+BarModeToObj(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Not used. */
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* Row/column structure record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    BarMode mode = *(BarMode *)(widgRec + offset);
+
+    return Tcl_NewStringObj(NameOfBarMode(mode), -1);
+}
+
+
+/* 
+ * Zero out the style's number of bars and errorbars. 
+ */
+static void
+ResetStylePalette(Blt_Chain stylePalette)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_FirstLink(stylePalette); link != NULL; 
+	 link = Blt_Chain_NextLink(link)) {
+	BarStyle *stylePtr;
+
+	stylePtr = Blt_Chain_GetValue(link);
+	stylePtr->xeb.length = stylePtr->yeb.length = 0;
+	stylePtr->nBars = 0;
+    }
+}
+
+static int
+ConfigureBarPen(Graph *graphPtr, BarPen *penPtr)
+{
+    XGCValues gcValues;
+    unsigned long gcMask;
+    GC newGC;
+    long defColor;
+    int screenNum;
+
+    screenNum = Tk_ScreenNumber(graphPtr->tkwin);
+    gcMask = GCForeground | GCLineWidth;
+    gcValues.line_width = LineWidth(penPtr->errorBarLineWidth);
+
+    if (penPtr->outlineColor != NULL) {
+	defColor = penPtr->outlineColor->pixel;
+	gcValues.foreground = penPtr->outlineColor->pixel;
+    } else if (penPtr->fill != NULL) {
+	defColor = Blt_BackgroundBorderColor(penPtr->fill)->pixel;
+	gcValues.foreground = defColor;
+    } else {
+	defColor = BlackPixel(graphPtr->display, screenNum);
+    }
+    newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (penPtr->outlineGC != NULL) {
+	Tk_FreeGC(graphPtr->display, penPtr->outlineGC);
+    }
+    penPtr->outlineGC = newGC;
+
+    newGC = NULL;
+    if (penPtr->stipple != None) {
+	/* Handle old-style -stipple specially. */
+	gcMask = GCForeground | GCBackground | GCFillStyle | GCStipple;
+	gcValues.foreground = BlackPixel(graphPtr->display, screenNum);
+	gcValues.background = WhitePixel(graphPtr->display, screenNum);
+	if (penPtr->fill != NULL) {
+	    gcValues.foreground =
+		Blt_BackgroundBorderColor(penPtr->fill)->pixel;
+	} else if (penPtr->outlineColor != NULL) {
+	    gcValues.foreground = penPtr->outlineColor->pixel;
+	}
+	gcValues.stipple = penPtr->stipple;
+	gcValues.fill_style = FillStippled;
+	newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    }
+    if (penPtr->fillGC != NULL) {
+	Tk_FreeGC(graphPtr->display, penPtr->fillGC);
+    }
+    penPtr->fillGC = newGC;
+
+    gcMask = GCForeground | GCLineWidth;
+    if (penPtr->errorBarColor == COLOR_DEFAULT) {
+	gcValues.foreground = defColor;
+    } else {
+	gcValues.foreground = penPtr->errorBarColor->pixel;
+    }
+    gcValues.line_width = LineWidth(penPtr->errorBarLineWidth);
+    newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (penPtr->errorBarGC != NULL) {
+	Tk_FreeGC(graphPtr->display, penPtr->errorBarGC);
+    }
+    penPtr->errorBarGC = newGC;
+    return TCL_OK;
+}
+
+static void
+DestroyBarPen(Graph *graphPtr, BarPen *penPtr)
+{
+    Blt_Ts_FreeStyle(graphPtr->display, &penPtr->valueStyle);
+    if (penPtr->outlineGC != NULL) {
+	Tk_FreeGC(graphPtr->display, penPtr->outlineGC);
+    }
+    if (penPtr->fillGC != NULL) {
+	Tk_FreeGC(graphPtr->display, penPtr->fillGC);
+    }
+    if (penPtr->errorBarGC != NULL) {
+	Tk_FreeGC(graphPtr->display, penPtr->errorBarGC);
+    }
+}
+
+static int
+ConfigureBarPenProc(Graph *graphPtr, Pen *basePtr)
+{
+    return ConfigureBarPen(graphPtr, (BarPen *)basePtr);
+}
+
+static void
+DestroyBarPenProc(Graph *graphPtr, Pen *basePtr)
+{
+    DestroyBarPen(graphPtr, (BarPen *)basePtr);
+}
+
+
+static void
+InitializeBarPen(BarPen *penPtr)
+{
+    /* Generic fields common to all pen types. */
+    penPtr->configProc = ConfigureBarPenProc;
+    penPtr->destroyProc = DestroyBarPenProc;
+    penPtr->flags = NORMAL_PEN;
+    penPtr->configSpecs = barPenConfigSpecs;
+
+    /* Initialize fields specific to bar pens. */
+    Blt_Ts_InitStyle(penPtr->valueStyle);
+    penPtr->relief = TK_RELIEF_RAISED;
+    penPtr->valueShow = SHOW_NONE;
+    penPtr->borderWidth = 2;
+    penPtr->errorBarShow = SHOW_BOTH;
+}
+
+Pen *
+Blt_BarPen(const char *penName)
+{
+    BarPen *penPtr;
+
+    penPtr = calloc(1, sizeof(BarPen));
+    InitializeBarPen(penPtr);
+    penPtr->name = Blt_Strdup(penName);
+    if (strcmp(penName, "activeBar") == 0) {
+	penPtr->flags = ACTIVE_PEN;
+    }
+    return (Pen *)penPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CheckBarStacks --
+ *
+ *	Check that the data limits are not superseded by the heights of
+ *	stacked bar segments.  The heights are calculated by
+ *	Blt_ComputeStacks.
+ *
+ * Results:
+ *	If the y-axis limits need to be adjusted for stacked segments,
+ *	*minPtr* or *maxPtr* are updated.
+ *
+ * Side effects:
+ *	Autoscaling of the y-axis is affected.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+CheckBarStacks(Graph *graphPtr, Axis2d *pairPtr, double *minPtr, double *maxPtr)
+{
+    BarGroup *gp, *gend;
+
+    if ((graphPtr->mode != BARS_STACKED) || (graphPtr->nBarGroups == 0)) {
+	return;
+    }
+    for (gp = graphPtr->barGroups, gend = gp + graphPtr->nBarGroups; gp < gend;
+	 gp++) {
+	if ((gp->axes.x == pairPtr->x) && (gp->axes.y == pairPtr->y)) {
+	    /*
+	     * Check if any of the y-values (because of stacking) are greater
+	     * than the current limits of the graph.
+	     */
+	    if (gp->sum < 0.0f) {
+		if (*minPtr > gp->sum) {
+		    *minPtr = gp->sum;
+		}
+	    } else {
+		if (*maxPtr < gp->sum) {
+		    *maxPtr = gp->sum;
+		}
+	    }
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureBarProc --
+ *
+ *	Sets up the appropriate configuration parameters in the GC.  It is
+ *	assumed the parameters have been previously set by a call to
+ *	Blt_ConfigureWidget.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  If TCL_ERROR is returned,
+ *	then interp->result contains an error message.
+ *
+ * Side effects:
+ *	Configuration information such as bar foreground/background color and
+ *	stipple etc. get set in a new GC.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ConfigureBarProc(Graph *graphPtr, Element *basePtr)
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+    Blt_ChainLink link;
+    BarStyle *stylePtr;
+
+    if (ConfigureBarPen(graphPtr, elemPtr->builtinPenPtr)!= TCL_OK) {
+	return TCL_ERROR;
+    }
+    /*
+     * Point to the static normal pen if no external pens have been selected.
+     */
+    link = Blt_Chain_FirstLink(elemPtr->stylePalette);
+    if (link == NULL) {
+	link = Blt_Chain_AllocLink(sizeof(BarStyle));
+	Blt_Chain_LinkAfter(elemPtr->stylePalette, link, NULL);
+    }
+    stylePtr = Blt_Chain_GetValue(link);
+    stylePtr->penPtr = NORMALPEN(elemPtr);
+
+    if (Blt_ConfigModified(elemPtr->configSpecs, "-barwidth", "-*data",
+	    "-map*", "-label", "-hide", "-x", "-y", (char *)NULL)) {
+	elemPtr->flags |= MAP_ITEM;
+    }
+    return TCL_OK;
+}
+
+static void
+GetBarExtentsProc(Element *basePtr, Region2d *regPtr)
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+    Graph *graphPtr;
+    double middle, barWidth;
+    int nPoints;
+
+    graphPtr = elemPtr->obj.graphPtr;
+    regPtr->top = regPtr->left = DBL_MAX;
+    regPtr->bottom = regPtr->right = -DBL_MAX;
+
+    nPoints = NUMBEROFPOINTS(elemPtr);
+    if (nPoints < 1) {
+	return;				/* No data points */
+    }
+    barWidth = graphPtr->barWidth;
+    if (elemPtr->barWidth > 0.0f) {
+	barWidth = elemPtr->barWidth;
+    }
+    middle = 0.5;
+    regPtr->left = elemPtr->x.min - middle;
+    regPtr->right = elemPtr->x.max + middle;
+
+    regPtr->top = elemPtr->y.min;
+    regPtr->bottom = elemPtr->y.max;
+    if (regPtr->bottom < graphPtr->baseline) {
+	regPtr->bottom = graphPtr->baseline;
+    }
+    /*
+     * Handle stacked bar elements specially.
+     *
+     * If element is stacked, the sum of its ordinates may be outside the
+     * minimum/maximum limits of the element's data points.
+     */
+    if ((graphPtr->mode == BARS_STACKED) && (graphPtr->nBarGroups > 0)) {
+	CheckBarStacks(graphPtr, &elemPtr->axes, &regPtr->top, &regPtr->bottom);
+    }
+    /* Warning: You get what you deserve if the x-axis is logScale */
+    if (elemPtr->axes.x->logScale) {
+	regPtr->left = Blt_FindElemValuesMinimum(&elemPtr->x, DBL_MIN) + 
+	    middle;
+    }
+    /* Fix y-min limits for barchart */
+    if (elemPtr->axes.y->logScale) {
+ 	if ((regPtr->top <= 0.0) || (regPtr->top > 1.0)) {
+	    regPtr->top = 1.0;
+	}
+    } else {
+	if (regPtr->top > 0.0) {
+	    regPtr->top = 0.0;
+	}
+    }
+    /* Correct the extents for error bars if they exist. */
+    if (elemPtr->xError.nValues > 0) {
+	int i;
+	
+	/* Correct the data limits for error bars */
+	nPoints = MIN(elemPtr->xError.nValues, nPoints);
+	for (i = 0; i < nPoints; i++) {
+	    double x;
+
+	    x = elemPtr->x.values[i] + elemPtr->xError.values[i];
+	    if (x > regPtr->right) {
+		regPtr->right = x;
+	    }
+	    x = elemPtr->x.values[i] - elemPtr->xError.values[i];
+	    if (elemPtr->axes.x->logScale) {
+		if (x < 0.0) {
+		    x = -x;		/* Mirror negative values, instead of
+					 * ignoring them. */
+		}
+		if ((x > DBL_MIN) && (x < regPtr->left)) {
+		    regPtr->left = x;
+		}
+	    } else if (x < regPtr->left) {
+		regPtr->left = x;
+	    }
+	}		     
+    } else {
+	if ((elemPtr->xHigh.nValues > 0) && 
+	    (elemPtr->xHigh.max > regPtr->right)) {
+	    regPtr->right = elemPtr->xHigh.max;
+	}
+	if (elemPtr->xLow.nValues > 0) {
+	    double left;
+	    
+	    if ((elemPtr->xLow.min <= 0.0) && 
+		(elemPtr->axes.x->logScale)) {
+		left = Blt_FindElemValuesMinimum(&elemPtr->xLow, DBL_MIN);
+	    } else {
+		left = elemPtr->xLow.min;
+	    }
+	    if (left < regPtr->left) {
+		regPtr->left = left;
+	    }
+	}
+    }
+    if (elemPtr->yError.nValues > 0) {
+	int i;
+	
+	nPoints = MIN(elemPtr->yError.nValues, nPoints);
+	for (i = 0; i < nPoints; i++) {
+	    double y;
+
+	    y = elemPtr->y.values[i] + elemPtr->yError.values[i];
+	    if (y > regPtr->bottom) {
+		regPtr->bottom = y;
+	    }
+	    y = elemPtr->y.values[i] - elemPtr->yError.values[i];
+	    if (elemPtr->axes.y->logScale) {
+		if (y < 0.0) {
+		    y = -y;		/* Mirror negative values, instead of
+					 * ignoring them. */
+		}
+		if ((y > DBL_MIN) && (y < regPtr->left)) {
+		    regPtr->top = y;
+		}
+	    } else if (y < regPtr->top) {
+		regPtr->top = y;
+	    }
+	}		     
+    } else {
+	if ((elemPtr->yHigh.nValues > 0) && 
+	    (elemPtr->yHigh.max > regPtr->bottom)) {
+	    regPtr->bottom = elemPtr->yHigh.max;
+	}
+	if (elemPtr->yLow.nValues > 0) {
+	    double top;
+	    
+	    if ((elemPtr->yLow.min <= 0.0) && 
+		(elemPtr->axes.y->logScale)) {
+		top = Blt_FindElemValuesMinimum(&elemPtr->yLow, DBL_MIN);
+	    } else {
+		top = elemPtr->yLow.min;
+	    }
+	    if (top < regPtr->top) {
+		regPtr->top = top;
+	    }
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ClosestBar --
+ *
+ *	Find the bar segment closest to the window coordinates point
+ *	specified.
+ *
+ *	Note:  This does not return the height of the stacked segment
+ *	       (in graph coordinates) properly.
+ *
+ * Results:
+ *	Returns 1 if the point is width any bar segment, otherwise 0.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static void
+ClosestBarProc(
+    Graph *graphPtr,			/* Not used. */
+    Element *basePtr,			/* Bar element */
+    ClosestSearch *searchPtr)		/* Information about closest point in
+					 * element */
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+    XRectangle *bp;
+    double minDist;
+    int imin;
+    int i;
+
+    minDist = searchPtr->dist;
+    imin = 0;
+    
+    for (bp = elemPtr->bars, i = 0; i < elemPtr->nBars; i++, bp++) {
+	Point2d *pp, *pend;
+	Point2d outline[5];
+	double left, right, top, bottom;
+
+	if (PointInRectangle(bp, searchPtr->x, searchPtr->y)) {
+	    imin = elemPtr->barToData[i];
+	    minDist = 0.0;
+	    break;
+	}
+	left = bp->x, top = bp->y;
+	right = (double)(bp->x + bp->width);
+	bottom = (double)(bp->y + bp->height);
+	outline[4].x = outline[3].x = outline[0].x = left;
+	outline[4].y = outline[1].y = outline[0].y = top;
+	outline[2].x = outline[1].x = right;
+	outline[3].y = outline[2].y = bottom;
+
+	for (pp = outline, pend = outline + 4; pp < pend; pp++) {
+	    Point2d t;
+	    double dist;
+
+	    t = Blt_GetProjection(searchPtr->x, searchPtr->y, pp, pp + 1);
+	    if (t.x > right) {
+		t.x = right;
+	    } else if (t.x < left) {
+		t.x = left;
+	    }
+	    if (t.y > bottom) {
+		t.y = bottom;
+	    } else if (t.y < top) {
+		t.y = top;
+	    }
+	    dist = hypot((t.x - searchPtr->x), (t.y - searchPtr->y));
+	    if (dist < minDist) {
+		minDist = dist;
+		imin = elemPtr->barToData[i];
+	    }
+	}
+    }
+    if (minDist < searchPtr->dist) {
+	searchPtr->elemPtr = (Element *)elemPtr;
+	searchPtr->dist = minDist;
+	searchPtr->index = imin;
+	searchPtr->point.x = (double)elemPtr->x.values[imin];
+	searchPtr->point.y = (double)elemPtr->y.values[imin];
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MergePens --
+ *
+ *	Reorders the both arrays of points and errorbars to merge pens.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The old arrays are freed and new ones allocated containing
+ *	the reordered points and errorbars.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MergePens(BarElement *elemPtr, BarStyle **dataToStyle)
+{
+    if (Blt_Chain_GetLength(elemPtr->stylePalette) < 2) {
+	Blt_ChainLink link;
+	BarStyle *stylePtr;
+
+	link = Blt_Chain_FirstLink(elemPtr->stylePalette);
+
+	stylePtr = Blt_Chain_GetValue(link);
+	stylePtr->nBars = elemPtr->nBars;
+	stylePtr->bars = elemPtr->bars;
+	stylePtr->symbolSize = elemPtr->bars->width / 2;
+	stylePtr->xeb.length = elemPtr->xeb.length;
+	stylePtr->xeb.segments = elemPtr->xeb.segments;
+	stylePtr->yeb.length = elemPtr->yeb.length;
+	stylePtr->yeb.segments = elemPtr->yeb.segments;
+	return;
+    }
+    /* We have more than one style. Group bar segments of like pen styles
+     * together.  */
+
+    if (elemPtr->nBars > 0) {
+	Blt_ChainLink link;
+	XRectangle *bars, *bp;
+	int *ip, *barToData;
+
+	bars = malloc(elemPtr->nBars * sizeof(XRectangle));
+	barToData = malloc(elemPtr->nBars * sizeof(int));
+	bp = bars, ip = barToData;
+	for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; 
+	     link = Blt_Chain_NextLink(link)) {
+	    BarStyle *stylePtr;
+	    int i;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    stylePtr->symbolSize = bp->width / 2;
+	    stylePtr->bars = bp;
+	    for (i = 0; i < elemPtr->nBars; i++) {
+		int iData;
+
+		iData = elemPtr->barToData[i];
+		if (dataToStyle[iData] == stylePtr) {
+		    *bp++ = elemPtr->bars[i];
+		    *ip++ = iData;
+		}
+	    }
+	    stylePtr->nBars = bp - stylePtr->bars;
+	}
+	free(elemPtr->bars);
+	free(elemPtr->barToData);
+	elemPtr->bars = bars;
+	elemPtr->barToData = barToData;
+    }
+
+    if (elemPtr->xeb.length > 0) {
+	Blt_ChainLink link;
+	Segment2d *bars, *sp;
+	int *map, *ip;
+
+	bars = malloc(elemPtr->xeb.length * sizeof(Segment2d));
+	map = malloc(elemPtr->xeb.length * sizeof(int));
+	sp = bars, ip = map;
+	for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    BarStyle *stylePtr;
+	    int i;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    stylePtr->xeb.segments = sp;
+	    for (i = 0; i < elemPtr->xeb.length; i++) {
+		int iData;
+
+		iData = elemPtr->xeb.map[i];
+		if (dataToStyle[iData] == stylePtr) {
+		    *sp++ = elemPtr->xeb.segments[i];
+		    *ip++ = iData;
+		}
+	    }
+	    stylePtr->xeb.length = sp - stylePtr->xeb.segments;
+	}
+	free(elemPtr->xeb.segments);
+	elemPtr->xeb.segments = bars;
+	free(elemPtr->xeb.map);
+	elemPtr->xeb.map = map;
+    }
+    if (elemPtr->yeb.length > 0) {
+	Blt_ChainLink link;
+	Segment2d *bars, *sp;
+	int *map, *ip;
+
+	bars = malloc(elemPtr->yeb.length * sizeof(Segment2d));
+	map = malloc(elemPtr->yeb.length * sizeof(int));
+	sp = bars, ip = map;
+	for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; 
+	     link = Blt_Chain_NextLink(link)) {
+	    BarStyle *stylePtr;
+	    int i;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    stylePtr->yeb.segments = sp;
+	    for (i = 0; i < elemPtr->yeb.length; i++) {
+		int iData;
+
+		iData = elemPtr->yeb.map[i];
+		if (dataToStyle[iData] == stylePtr) {
+		    *sp++ = elemPtr->yeb.segments[i];
+		    *ip++ = iData;
+		}
+	    }
+	    stylePtr->yeb.length = sp - stylePtr->yeb.segments;
+	}
+	free(elemPtr->yeb.segments);
+	elemPtr->yeb.segments = bars;
+	free(elemPtr->yeb.map);
+	elemPtr->yeb.map = map;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapActiveBars --
+ *
+ *	Creates an array of points of the active graph coordinates.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is freed and allocated for the active point array.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapActiveBars(BarElement *elemPtr)
+{
+    if (elemPtr->activeRects != NULL) {
+	free(elemPtr->activeRects);
+	elemPtr->activeRects = NULL;
+    }
+    if (elemPtr->activeToData != NULL) {
+	free(elemPtr->activeToData);
+	elemPtr->activeToData = NULL;
+    }
+    elemPtr->nActive = 0;
+
+    if (elemPtr->nActiveIndices > 0) {
+	XRectangle *activeRects;
+	int *activeToData;
+	int i;
+	int count;
+
+	activeRects = malloc(sizeof(XRectangle) * 
+				       elemPtr->nActiveIndices);
+	activeToData = malloc(sizeof(int) * 
+					elemPtr->nActiveIndices);
+	count = 0;
+	for (i = 0; i < elemPtr->nBars; i++) {
+	    int *ip, *iend;
+
+	    for (ip = elemPtr->activeIndices, 
+		     iend = ip + elemPtr->nActiveIndices; ip < iend; ip++) {
+		if (elemPtr->barToData[i] == *ip) {
+		    activeRects[count] = elemPtr->bars[i];
+		    activeToData[count] = i;
+		    count++;
+		}
+	    }
+	}
+	elemPtr->nActive = count;
+	elemPtr->activeRects = activeRects;
+	elemPtr->activeToData = activeToData;
+    }
+    elemPtr->flags &= ~ACTIVE_PENDING;
+}
+
+static void
+ResetBar(BarElement *elemPtr)
+{
+    /* Release any storage associated with the display of the bar */
+    ResetStylePalette(elemPtr->stylePalette);
+    if (elemPtr->activeRects != NULL) {
+	free(elemPtr->activeRects);
+    }
+    if (elemPtr->activeToData != NULL) {
+	free(elemPtr->activeToData);
+    }
+    if (elemPtr->xeb.segments != NULL) {
+	free(elemPtr->xeb.segments);
+    }
+    if (elemPtr->xeb.map != NULL) {
+	free(elemPtr->xeb.map);
+    }
+    if (elemPtr->yeb.segments != NULL) {
+	free(elemPtr->yeb.segments);
+    }
+    if (elemPtr->yeb.map != NULL) {
+	free(elemPtr->yeb.map);
+    }
+    if (elemPtr->bars != NULL) {
+	free(elemPtr->bars);
+    }
+    if (elemPtr->barToData != NULL) {
+	free(elemPtr->barToData);
+    }
+    elemPtr->activeToData = elemPtr->xeb.map = elemPtr->yeb.map = 
+	elemPtr->barToData = NULL;
+    elemPtr->activeRects = elemPtr->bars = NULL;
+    elemPtr->xeb.segments = elemPtr->yeb.segments = NULL;
+    elemPtr->nActive = elemPtr->xeb.length = elemPtr->yeb.length = 
+	elemPtr->nBars = 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_MapErrorBars --
+ *
+ *	Creates two arrays of points and pen indices, filled with the screen
+ *	coordinates of the visible
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is freed and allocated for the index array.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapErrorBars(Graph *graphPtr, BarElement *elemPtr, BarStyle **dataToStyle)
+{
+    int n, nPoints;
+    Region2d reg;
+
+    Blt_GraphExtents(graphPtr, &reg);
+    nPoints = NUMBEROFPOINTS(elemPtr);
+    if (elemPtr->xError.nValues > 0) {
+	n = MIN(elemPtr->xError.nValues, nPoints);
+    } else {
+	n = MIN3(elemPtr->xHigh.nValues, elemPtr->xLow.nValues, nPoints);
+    }
+    if (n > 0) {
+	Segment2d *bars;
+	Segment2d *segPtr;
+	int *map;
+	int *indexPtr;
+	int i;
+		
+	segPtr = bars = malloc(n * 3 * sizeof(Segment2d));
+	indexPtr = map = malloc(n * 3 * sizeof(int));
+	for (i = 0; i < n; i++) {
+	    double x, y;
+	    double high, low;
+	    BarStyle *stylePtr;
+
+	    x = elemPtr->x.values[i];
+	    y = elemPtr->y.values[i];
+	    stylePtr = dataToStyle[i];
+	    if ((isfinite(x)) && (isfinite(y))) {
+		if (elemPtr->xError.nValues > 0) {
+		    high = x + elemPtr->xError.values[i];
+		    low = x - elemPtr->xError.values[i];
+		} else {
+		    high = elemPtr->xHigh.values[i];
+		    low = elemPtr->xLow.values[i];
+		}
+		if ((isfinite(high)) && (isfinite(low)))  {
+		    Point2d p, q;
+
+		    p = Blt_Map2D(graphPtr, high, y, &elemPtr->axes);
+		    q = Blt_Map2D(graphPtr, low, y, &elemPtr->axes);
+		    segPtr->p = p;
+		    segPtr->q = q;
+		    if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		    /* Left cap */
+		    segPtr->p.x = segPtr->q.x = p.x;
+		    segPtr->p.y = p.y - stylePtr->errorBarCapWidth;
+		    segPtr->q.y = p.y + stylePtr->errorBarCapWidth;
+		    if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		    /* Right cap */
+		    segPtr->p.x = segPtr->q.x = q.x;
+		    segPtr->p.y = q.y - stylePtr->errorBarCapWidth;
+		    segPtr->q.y = q.y + stylePtr->errorBarCapWidth;
+		    if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		}
+	    }
+	}
+	elemPtr->xeb.segments = bars;
+	elemPtr->xeb.length = segPtr - bars;
+	elemPtr->xeb.map = map;
+    }
+    if (elemPtr->yError.nValues > 0) {
+	n = MIN(elemPtr->yError.nValues, nPoints);
+    } else {
+	n = MIN3(elemPtr->yHigh.nValues, elemPtr->yLow.nValues, nPoints);
+    }
+    if (n > 0) {
+	Segment2d *bars;
+	Segment2d *segPtr;
+	int *map;
+	int *indexPtr;
+	int i;
+		
+	segPtr = bars = malloc(n * 3 * sizeof(Segment2d));
+	indexPtr = map = malloc(n * 3 * sizeof(int));
+	for (i = 0; i < n; i++) {
+	    double x, y;
+	    double high, low;
+	    BarStyle *stylePtr;
+
+	    x = elemPtr->x.values[i];
+	    y = elemPtr->y.values[i];
+	    stylePtr = dataToStyle[i];
+	    if ((isfinite(x)) && (isfinite(y))) {
+		if (elemPtr->yError.nValues > 0) {
+		    high = y + elemPtr->yError.values[i];
+		    low = y - elemPtr->yError.values[i];
+		} else {
+		    high = elemPtr->yHigh.values[i];
+		    low = elemPtr->yLow.values[i];
+		}
+		if ((isfinite(high)) && (isfinite(low)))  {
+		    Point2d p, q;
+		    
+		    p = Blt_Map2D(graphPtr, x, high, &elemPtr->axes);
+		    q = Blt_Map2D(graphPtr, x, low, &elemPtr->axes);
+		    segPtr->p = p;
+		    segPtr->q = q;
+		    if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		    /* Top cap. */
+		    segPtr->p.y = segPtr->q.y = p.y;
+		    segPtr->p.x = p.x - stylePtr->errorBarCapWidth;
+		    segPtr->q.x = p.x + stylePtr->errorBarCapWidth;
+		    if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		    /* Bottom cap. */
+		    segPtr->p.y = segPtr->q.y = q.y;
+		    segPtr->p.x = q.x - stylePtr->errorBarCapWidth;
+		    segPtr->q.x = q.x + stylePtr->errorBarCapWidth;
+		    if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		}
+	    }
+	}
+	elemPtr->yeb.segments = bars;
+	elemPtr->yeb.length = segPtr - bars;
+	elemPtr->yeb.map = map;
+    }
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapBarProc --
+ *
+ *	Calculates the actual window coordinates of the bar element.  The
+ *	window coordinates are saved in the bar element structure.
+ *
+ * Results:
+ *	None.
+ *
+ * Notes:
+ *	A bar can have multiple segments (more than one x,y pairs).  In this
+ *	case, the bar can be represented as either a set of non-contiguous
+ *	bars or a single multi-segmented (stacked) bar.
+ *
+ *	The x-axis layout for a barchart may be presented in one of two ways.
+ *	If abscissas are used, the bars are placed at those coordinates.
+ *	Otherwise, the range will represent the number of values.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapBarProc(Graph *graphPtr, Element *basePtr)
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+    BarStyle **dataToStyle;
+    double *x, *y;
+    double barWidth, barOffset;
+    double baseline, ybot;
+    int *barToData;			/* Maps bars to data point indices */
+    int invertBar;
+    int nPoints, count;
+    XRectangle *rp, *bars;
+    int i;
+    int size;
+
+    ResetBar(elemPtr);
+    nPoints = NUMBEROFPOINTS(elemPtr);
+    if (nPoints < 1) {
+	return;				/* No data points */
+    }
+    barWidth = graphPtr->barWidth;
+    barWidth = (elemPtr->barWidth > 0.0f) 
+	? elemPtr->barWidth : graphPtr->barWidth;
+    baseline = (elemPtr->axes.y->logScale) ? 0.0 : graphPtr->baseline;
+    barOffset = barWidth * 0.5;
+
+    /*
+     * Create an array of bars representing the screen coordinates of all the
+     * segments in the bar.
+     */
+    bars = calloc(nPoints, sizeof(XRectangle));
+    barToData = calloc(nPoints, sizeof(int));
+
+    x = elemPtr->x.values, y = elemPtr->y.values;
+    count = 0;
+    for (rp = bars, i = 0; i < nPoints; i++) {
+	Point2d c1, c2;			/* Two opposite corners of the rectangle
+					 * in graph coordinates. */
+	double dx, dy;
+	int height;
+	double right, left, top, bottom;
+
+	if (((x[i] - barWidth) > elemPtr->axes.x->axisRange.max) ||
+	    ((x[i] + barWidth) < elemPtr->axes.x->axisRange.min)) {
+	    continue;			/* Abscissa is out of range of the
+					 * x-axis */
+	}
+	c1.x = x[i] - barOffset;
+	c1.y = y[i];
+	c2.x = c1.x + barWidth;
+	c2.y = baseline;
+
+	/*
+	 * If the mode is "aligned" or "stacked" we need to adjust the x or y
+	 * coordinates of the two corners.
+	 */
+
+	if ((graphPtr->nBarGroups > 0) && (graphPtr->mode != BARS_INFRONT) && 
+	    (!graphPtr->stackAxes)) {
+	    Blt_HashEntry *hPtr;
+	    BarSetKey key;
+
+	    key.value = (float)x[i];
+	    key.axes = elemPtr->axes;
+	    key.axes.y = NULL;
+	    hPtr = Blt_FindHashEntry(&graphPtr->setTable, (char *)&key);
+	    if (hPtr != NULL) {
+		Blt_HashTable *tablePtr;
+		const char *name;
+
+		tablePtr = Blt_GetHashValue(hPtr);
+		name = (elemPtr->groupName != NULL) ? elemPtr->groupName : 
+		    elemPtr->axes.y->obj.name;
+ 		hPtr = Blt_FindHashEntry(tablePtr, name);
+		if (hPtr != NULL) {
+		    BarGroup *groupPtr;
+		    double slice, width, offset;
+		    
+		    groupPtr = Blt_GetHashValue(hPtr);
+		    slice = barWidth / (double)graphPtr->maxBarSetSize;
+		    offset = (slice * groupPtr->index);
+		    if (graphPtr->maxBarSetSize > 1) {
+			offset += slice * 0.05;
+			slice *= 0.90;
+		    }
+		    switch (graphPtr->mode) {
+		    case BARS_STACKED:
+			groupPtr->count++;
+			c2.y = groupPtr->lastY;
+			c1.y += c2.y;
+			groupPtr->lastY = c1.y;
+			c1.x += offset;
+			c2.x = c1.x + slice;
+			break;
+			
+		    case BARS_ALIGNED:
+			slice /= groupPtr->nSegments;
+			c1.x += offset + (slice * groupPtr->count);
+			c2.x = c1.x + slice;
+			groupPtr->count++;
+			break;
+			
+		    case BARS_OVERLAP:
+			slice /= (groupPtr->nSegments + 1);
+			width = slice + slice;
+			groupPtr->count++;
+			c1.x += offset + 
+			    (slice * (groupPtr->nSegments - groupPtr->count));
+			c2.x = c1.x + width;
+			break;
+			
+		    case BARS_INFRONT:
+			break;
+		    }
+		}
+	    }
+	}
+	invertBar = FALSE;
+	if (c1.y < c2.y) {
+	    double temp;
+
+	    /* Handle negative bar values by swapping ordinates */
+	    temp = c1.y, c1.y = c2.y, c2.y = temp;
+	    invertBar = TRUE;
+	}
+	/*
+	 * Get the two corners of the bar segment and compute the rectangle
+	 */
+	ybot = c2.y;
+	c1 = Blt_Map2D(graphPtr, c1.x, c1.y, &elemPtr->axes);
+	c2 = Blt_Map2D(graphPtr, c2.x, c2.y, &elemPtr->axes);
+	if ((ybot == 0.0) && (elemPtr->axes.y->logScale)) {
+	    c2.y = graphPtr->bottom;
+	}
+	    
+	if (c2.y < c1.y) {
+	    double t;
+	    t = c1.y, c1.y = c2.y, c2.y = t;
+	}
+	if (c2.x < c1.x) {
+	    double t;
+	    t = c1.x, c1.x = c2.x, c2.x = t;
+	}
+	if ((c1.x > graphPtr->right) || (c2.x < graphPtr->left) || 
+	    (c1.y > graphPtr->bottom) || (c2.y < graphPtr->top)) {
+	    continue;
+	}
+	/* Bound the bars horizontally by the width of the graph window */
+	/* Bound the bars vertically by the position of the axis. */
+	if (graphPtr->stackAxes) {
+	    top = elemPtr->axes.y->screenMin;
+	    bottom = elemPtr->axes.y->screenMin + elemPtr->axes.y->screenRange;
+	    left = graphPtr->left;
+	    right = graphPtr->right;
+	} else {
+	    left = top = 0;
+	    bottom = right = 10000;
+	    /* Shouldn't really have a call to Tk_Width or Tk_Height in
+	     * mapping routine.  We only want to clamp the bar segment to the
+	     * size of the window if we're actually mapped onscreen. */
+	    if (Tk_Height(graphPtr->tkwin) > 1) {
+		bottom = Tk_Height(graphPtr->tkwin);
+	    }
+	    if (Tk_Width(graphPtr->tkwin) > 1) {
+		right = Tk_Width(graphPtr->tkwin);
+	    }
+	}
+	CLAMP(c1.y, top, bottom);
+	CLAMP(c2.y, top, bottom);
+	CLAMP(c1.x, left, right);
+	CLAMP(c2.x, left, right);
+	dx = fabs(c1.x - c2.x);
+	dy = fabs(c1.y - c2.y);
+	if ((dx == 0) || (dy == 0)) {
+	    continue;
+	}
+	height = (int)dy;
+	if (invertBar) {
+	    rp->y = (short int)MIN(c1.y, c2.y);
+	} else {
+	    rp->y = (short int)(MAX(c1.y, c2.y)) - height;
+	}
+	rp->x = (short int)MIN(c1.x, c2.x);
+	rp->width = (short int)dx + 1;
+	rp->width |= 0x1;
+	if (rp->width < 1) {
+	    rp->width = 1;
+	}
+	rp->height = height + 1;
+	if (rp->height < 1) {
+	    rp->height = 1;
+	}
+	barToData[count] = i;		/* Save the data index corresponding to
+					 * the rectangle */
+	count++;
+	rp++;
+    }
+    elemPtr->nBars = count;
+    elemPtr->bars = bars;
+    elemPtr->barToData = barToData;
+    if (elemPtr->nActiveIndices > 0) {
+	MapActiveBars(elemPtr);
+    }
+	
+    size = 20;
+    if (count > 0) {
+	size = bars->width;
+    }
+    {
+	Blt_ChainLink link;
+
+	/* Set the symbol size of all the pen styles. */
+	for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL;
+	     link = Blt_Chain_NextLink(link)) {
+	    BarStyle *stylePtr;
+	    
+	    stylePtr = Blt_Chain_GetValue(link);
+	    stylePtr->symbolSize = size;
+	    stylePtr->errorBarCapWidth = 
+		(stylePtr->penPtr->errorBarCapWidth > 0) 
+		? stylePtr->penPtr->errorBarCapWidth : (size * 66666) / 100000;
+	    stylePtr->errorBarCapWidth /= 2;
+	}
+    }
+    dataToStyle = (BarStyle **)Blt_StyleMap((Element *)elemPtr);
+    if (((elemPtr->yHigh.nValues > 0) && (elemPtr->yLow.nValues > 0)) ||
+	((elemPtr->xHigh.nValues > 0) && (elemPtr->xLow.nValues > 0)) ||
+	(elemPtr->xError.nValues > 0) || (elemPtr->yError.nValues > 0)) {
+	MapErrorBars(graphPtr, elemPtr, dataToStyle);
+    }
+    MergePens(elemPtr, dataToStyle);
+    free(dataToStyle);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawSymbolProc --
+ *
+ * 	Draw a symbol centered at the given x,y window coordinate based upon
+ * 	the element symbol type and size.
+ *
+ * Results:
+ *	None.
+ *
+ * Problems:
+ *	Most notable is the round-off errors generated when calculating the
+ *	centered position of the symbol.  
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static void
+DrawSymbolProc(Graph *graphPtr, Drawable drawable, Element *basePtr, 
+	       int x, int y, int size)
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+    BarPen *penPtr;
+    int radius;
+
+    penPtr = NORMALPEN(elemPtr);
+    if ((penPtr->fill == NULL) && (penPtr->outlineColor == NULL)) {
+	return;
+    }
+    radius = (size / 2);
+    size--;
+
+    x -= radius;
+    y -= radius;
+    if (penPtr->fillGC != NULL) {
+	XSetTSOrigin(graphPtr->display, penPtr->fillGC, x, y);
+    }
+    if (penPtr->stipple != None) {
+	XFillRectangle(graphPtr->display, drawable, penPtr->fillGC, x, y, 
+		       size, size);
+    } else {
+	Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, penPtr->fill, 
+		x, y, size, size, penPtr->borderWidth, penPtr->relief);
+    }
+    XDrawRectangle(graphPtr->display, drawable, penPtr->outlineGC, x, y, 
+		   size, size);
+    if (penPtr->fillGC != NULL) {
+	XSetTSOrigin(graphPtr->display, penPtr->fillGC, 0, 0);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawBarSegments --
+ *
+ * 	Draws each of the rectangular segments for the element.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawBarSegments(Graph *graphPtr, Drawable drawable, BarPen *penPtr,
+		XRectangle *bars, int nBars)
+{
+    TkRegion rgn;
+
+    {
+	XRectangle clip;
+	clip.x = graphPtr->left;
+	clip.y = graphPtr->top;
+	clip.width  = graphPtr->right - graphPtr->left + 1;
+	clip.height = graphPtr->bottom - graphPtr->top + 1;
+	rgn = TkCreateRegion();
+	TkUnionRectWithRegion(&clip, rgn, rgn);
+    }
+    if (penPtr->fill != NULL) {
+	XRectangle *rp, *rend;
+	int hasOutline;
+	int relief;
+
+	relief = (penPtr->relief == TK_RELIEF_SOLID) 
+	    ? TK_RELIEF_FLAT: penPtr->relief;
+	hasOutline = ((relief == TK_RELIEF_FLAT) && 
+		      (penPtr->outlineColor != NULL));
+	if (penPtr->stipple != None) {
+	    TkSetRegion(graphPtr->display, penPtr->fillGC, rgn);
+	}
+	Blt_SetBackgroundClipRegion(graphPtr->tkwin, penPtr->fill, rgn);
+	if (hasOutline) {
+	    TkSetRegion(graphPtr->display, penPtr->outlineGC, rgn);
+	}
+	for (rp = bars, rend = rp + nBars; rp < rend; rp++) {
+	    if (penPtr->stipple != None) {
+		XFillRectangle(graphPtr->display, drawable, penPtr->fillGC, 
+			       rp->x, rp->y, rp->width, rp->height);
+	    } else {
+		Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, 
+			penPtr->fill, rp->x, rp->y, rp->width, rp->height, 
+			penPtr->borderWidth, relief);
+	    }
+	    if (hasOutline) {
+		XDrawRectangle(graphPtr->display, drawable, penPtr->outlineGC, 
+			       rp->x, rp->y, rp->width, rp->height);
+	    }
+	}
+	Blt_UnsetBackgroundClipRegion(graphPtr->tkwin, penPtr->fill);
+	if (hasOutline) {
+	    XSetClipMask(graphPtr->display, penPtr->outlineGC, None);
+	}
+	if (penPtr->stipple != None) {
+	    XSetClipMask(graphPtr->display, penPtr->fillGC, None);
+	}
+    } else if (penPtr->outlineColor != NULL) {
+	TkSetRegion(graphPtr->display, penPtr->outlineGC, rgn);
+	XDrawRectangles(graphPtr->display, drawable, penPtr->outlineGC, bars, 
+			nBars);
+	XSetClipMask(graphPtr->display, penPtr->outlineGC, None);
+    }
+    TkDestroyRegion(rgn);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawBarValues --
+ *
+ * 	Draws the numeric value of the bar.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawBarValues(Graph *graphPtr, Drawable drawable, BarElement *elemPtr,
+	      BarPen *penPtr, XRectangle *bars, int nBars, int *barToData)
+{
+    XRectangle *rp, *rend;
+    int count;
+    const char *fmt;
+    
+    fmt = penPtr->valueFormat;
+    if (fmt == NULL) {
+	fmt = "%g";
+    }
+    count = 0;
+    for (rp = bars, rend = rp + nBars; rp < rend; rp++) {
+	Point2d anchorPos;
+	double x, y;
+	char string[TCL_DOUBLE_SPACE * 2 + 2];
+
+	x = elemPtr->x.values[barToData[count]];
+	y = elemPtr->y.values[barToData[count]];
+
+	count++;
+	if (penPtr->valueShow == SHOW_X) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); 
+	} else if (penPtr->valueShow == SHOW_Y) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y); 
+	} else if (penPtr->valueShow == SHOW_BOTH) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x);
+	    strcat(string, ",");
+	    sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y);
+	}
+	if (graphPtr->inverted) {
+	    anchorPos.y = rp->y + rp->height * 0.5;
+	    anchorPos.x = rp->x + rp->width;
+	    if (x < graphPtr->baseline) {
+		anchorPos.x -= rp->width;
+	    } 
+	} else {
+	    anchorPos.x = rp->x + rp->width * 0.5;
+	    anchorPos.y = rp->y;
+	    if (y < graphPtr->baseline) {			
+		anchorPos.y += rp->height;
+	    }
+	}
+	Blt_DrawText(graphPtr->tkwin, drawable, string, &penPtr->valueStyle, 
+		     (int)anchorPos.x, (int)anchorPos.y);
+    }
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawNormalBar --
+ *
+ *	Draws the rectangle representing the bar element.  If the relief
+ *	option is set to "raised" or "sunken" and the bar borderwidth is set
+ *	(borderwidth > 0), a 3D border is drawn around the bar.
+ *
+ *	Don't draw bars that aren't visible (i.e. within the limits of the
+ *	axis).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	X drawing commands are output.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawNormalBarProc(Graph *graphPtr, Drawable drawable, Element *basePtr)
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+    int count;
+    Blt_ChainLink link;
+
+    count = 0;
+    for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL;
+	 link = Blt_Chain_NextLink(link)) {
+	BarStyle *stylePtr;
+	BarPen *penPtr;
+
+	stylePtr = Blt_Chain_GetValue(link);
+	penPtr = stylePtr->penPtr;
+	if (stylePtr->nBars > 0) {
+	    DrawBarSegments(graphPtr, drawable, penPtr, stylePtr->bars,
+		stylePtr->nBars);
+	}
+	if ((stylePtr->xeb.length > 0) && (penPtr->errorBarShow & SHOW_X)) {
+	    Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC, 
+		       stylePtr->xeb.segments, stylePtr->xeb.length);
+	}
+	if ((stylePtr->yeb.length > 0) && (penPtr->errorBarShow & SHOW_Y)) {
+	    Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC, 
+		       stylePtr->yeb.segments, stylePtr->yeb.length);
+	}
+	if (penPtr->valueShow != SHOW_NONE) {
+	    DrawBarValues(graphPtr, drawable, elemPtr, penPtr, 
+			stylePtr->bars, stylePtr->nBars, 
+			elemPtr->barToData + count);
+	}
+	count += stylePtr->nBars;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawActiveBar --
+ *
+ *	Draws bars representing the active segments of the bar element.  If
+ *	the -relief option is set (other than "flat") and the borderwidth is
+ *	greater than 0, a 3D border is drawn around the each bar segment.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	X drawing commands are output.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawActiveBarProc(Graph *graphPtr, Drawable drawable, Element *basePtr)
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+
+    if (elemPtr->activePenPtr != NULL) {
+	BarPen *penPtr = elemPtr->activePenPtr;
+
+	if (elemPtr->nActiveIndices > 0) {
+	    if (elemPtr->flags & ACTIVE_PENDING) {
+		MapActiveBars(elemPtr);
+	    }
+	    DrawBarSegments(graphPtr, drawable, penPtr, elemPtr->activeRects, 
+			 elemPtr->nActive);
+	    if (penPtr->valueShow != SHOW_NONE) {
+		DrawBarValues(graphPtr, drawable, elemPtr, penPtr, 
+			elemPtr->activeRects, elemPtr->nActive, 
+			elemPtr->activeToData);
+	    }
+	} else if (elemPtr->nActiveIndices < 0) {
+	    DrawBarSegments(graphPtr, drawable, penPtr, elemPtr->bars, 
+			 elemPtr->nBars);
+	    if (penPtr->valueShow != SHOW_NONE) {
+		DrawBarValues(graphPtr, drawable, elemPtr, penPtr, 
+			elemPtr->bars, elemPtr->nBars, elemPtr->barToData);
+	    }
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SymbolToPostScript --
+ *
+ * 	Draw a symbol centered at the given x,y window coordinate based upon
+ * 	the element symbol type and size.
+ *
+ * Results:
+ *	None.
+ *
+ * Problems:
+ *	Most notable is the round-off errors generated when calculating the
+ *	centered position of the symbol.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static void
+SymbolToPostScriptProc(
+    Graph *graphPtr,
+    Blt_Ps ps,
+    Element *basePtr,
+    double x, double y,
+    int size)
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+    BarPen *penPtr;
+
+    penPtr = NORMALPEN(elemPtr);
+    if ((penPtr->fill == NULL) && (penPtr->outlineColor == NULL)) {
+	return;
+    }
+    /*
+     * Build a PostScript procedure to draw the fill and outline of the symbol
+     * after the path of the symbol shape has been formed
+     */
+    Blt_Ps_Append(ps, "\n"
+		  "/DrawSymbolProc {\n"
+		  "gsave\n    ");
+    if (penPtr->stipple != None) {
+	if (penPtr->fill != NULL) {
+	    Blt_Ps_XSetBackground(ps, Blt_BackgroundBorderColor(penPtr->fill));
+	    Blt_Ps_Append(ps, "    gsave fill grestore\n    ");
+	}
+	if (penPtr->outlineColor != NULL) {
+	    Blt_Ps_XSetForeground(ps, penPtr->outlineColor);
+	} else {
+	    Blt_Ps_XSetForeground(ps, Blt_BackgroundBorderColor(penPtr->fill));
+	}
+	Blt_Ps_XSetStipple(ps, graphPtr->display, penPtr->stipple);
+    } else if (penPtr->outlineColor != NULL) {
+	Blt_Ps_XSetForeground(ps, penPtr->outlineColor);
+	Blt_Ps_Append(ps, "    fill\n");
+    }
+    Blt_Ps_Append(ps, "  grestore\n");
+    Blt_Ps_Append(ps, "} def\n\n");
+    Blt_Ps_Format(ps, "%g %g %d Sq\n", x, y, size);
+}
+
+static void
+SegmentsToPostScript(Graph *graphPtr, Blt_Ps ps, BarPen *penPtr, 
+		     XRectangle *bars, int nBars)
+{
+    XRectangle *rp, *rend;
+
+    if ((penPtr->fill == NULL) && (penPtr->outlineColor == NULL)) {
+	return;
+    }
+    for (rp = bars, rend = rp + nBars; rp < rend; rp++) {
+	if ((rp->width < 1) || (rp->height < 1)) {
+	    continue;
+	}
+	if (penPtr->stipple != None) {
+	    Blt_Ps_Rectangle(ps, rp->x, rp->y, rp->width - 1, rp->height - 1);
+	    if (penPtr->fill != NULL) {
+		Blt_Ps_XSetBackground(ps,Blt_BackgroundBorderColor(penPtr->fill));
+		Blt_Ps_Append(ps, "gsave fill grestore\n");
+	    }
+	    if (penPtr->outlineColor != NULL) {
+		Blt_Ps_XSetForeground(ps, penPtr->outlineColor);
+	    } else {
+		Blt_Ps_XSetForeground(ps,Blt_BackgroundBorderColor(penPtr->fill));
+	    }
+	    Blt_Ps_XSetStipple(ps, graphPtr->display, penPtr->stipple);
+	} else if (penPtr->outlineColor != NULL) {
+	    Blt_Ps_XSetForeground(ps, penPtr->outlineColor);
+	    Blt_Ps_XFillRectangle(ps, (double)rp->x, (double)rp->y, 
+		(int)rp->width - 1, (int)rp->height - 1);
+	}
+	if ((penPtr->fill != NULL) && (penPtr->borderWidth > 0) && 
+	    (penPtr->relief != TK_RELIEF_FLAT)) {
+	    Blt_Ps_Draw3DRectangle(ps, Blt_BackgroundBorder(penPtr->fill), 
+		(double)rp->x, (double)rp->y, (int)rp->width, (int)rp->height,
+		penPtr->borderWidth, penPtr->relief);
+	}
+    }
+}
+
+static void
+BarValuesToPostScript(Graph *graphPtr, Blt_Ps ps, BarElement *elemPtr,
+		      BarPen *penPtr, XRectangle *bars, int nBars, 
+		      int *barToData)
+{
+    XRectangle *rp, *rend;
+    int count;
+    const char *fmt;
+    char string[TCL_DOUBLE_SPACE * 2 + 2];
+    double x, y;
+    Point2d anchorPos;
+    
+    count = 0;
+    fmt = penPtr->valueFormat;
+    if (fmt == NULL) {
+	fmt = "%g";
+    }
+    for (rp = bars, rend = rp + nBars; rp < rend; rp++) {
+	x = elemPtr->x.values[barToData[count]];
+	y = elemPtr->y.values[barToData[count]];
+	count++;
+	if (penPtr->valueShow == SHOW_X) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); 
+	} else if (penPtr->valueShow == SHOW_Y) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y); 
+	} else if (penPtr->valueShow == SHOW_BOTH) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x);
+	    strcat(string, ",");
+	    sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y);
+	}
+	if (graphPtr->inverted) {
+	    anchorPos.y = rp->y + rp->height * 0.5;
+	    anchorPos.x = rp->x + rp->width;
+	    if (x < graphPtr->baseline) {
+		anchorPos.x -= rp->width;
+	    } 
+	} else {
+	    anchorPos.x = rp->x + rp->width * 0.5;
+	    anchorPos.y = rp->y;
+	    if (y < graphPtr->baseline) {			
+		anchorPos.y += rp->height;
+	    }
+	}
+	Blt_Ps_DrawText(ps, string, &penPtr->valueStyle, anchorPos.x, 
+		anchorPos.y);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ActiveBarToPostScript --
+ *
+ *	Similar to the NormalBarToPostScript procedure, generates PostScript
+ *	commands to display the bars representing the active bar segments of
+ *	the element.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	PostScript pen width, dashes, and color settings are changed.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static void
+ActiveBarToPostScriptProc(Graph *graphPtr, Blt_Ps ps, Element *basePtr)
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+
+    if (elemPtr->activePenPtr != NULL) {
+	BarPen *penPtr = elemPtr->activePenPtr;
+	
+	if (elemPtr->nActiveIndices > 0) {
+	    if (elemPtr->flags & ACTIVE_PENDING) {
+		MapActiveBars(elemPtr);
+	    }
+	    SegmentsToPostScript(graphPtr, ps, penPtr, elemPtr->activeRects,
+		elemPtr->nActive);
+	    if (penPtr->valueShow != SHOW_NONE) {
+		BarValuesToPostScript(graphPtr, ps, elemPtr, penPtr, 
+		   elemPtr->activeRects, elemPtr->nActive, elemPtr->activeToData);
+	    }
+	} else if (elemPtr->nActiveIndices < 0) {
+	    SegmentsToPostScript(graphPtr, ps, penPtr, elemPtr->bars, 
+		elemPtr->nBars);
+	    if (penPtr->valueShow != SHOW_NONE) {
+		BarValuesToPostScript(graphPtr, ps, elemPtr, penPtr, 
+		   elemPtr->bars, elemPtr->nBars, elemPtr->barToData);
+	    }
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NormalBarToPostScript --
+ *
+ *	Generates PostScript commands to form the bars representing the
+ *	segments of the bar element.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	PostScript pen width, dashes, and color settings are changed.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static void
+NormalBarToPostScriptProc(Graph *graphPtr, Blt_Ps ps, Element *basePtr)
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+    Blt_ChainLink link;
+    int count;
+
+    count = 0;
+    for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL;
+	 link = Blt_Chain_NextLink(link)) {
+	BarStyle *stylePtr;
+	BarPen *penPtr;
+	XColor *colorPtr;
+
+	stylePtr = Blt_Chain_GetValue(link);
+	penPtr = stylePtr->penPtr;
+	if (stylePtr->nBars > 0) {
+	    SegmentsToPostScript(graphPtr, ps, penPtr, stylePtr->bars, 
+		stylePtr->nBars);
+	}
+	colorPtr = penPtr->errorBarColor;
+	if (colorPtr == COLOR_DEFAULT) {
+	    colorPtr = penPtr->outlineColor;
+	}
+	if ((stylePtr->xeb.length > 0) && (penPtr->errorBarShow & SHOW_X)) {
+	    Blt_Ps_XSetLineAttributes(ps, colorPtr, penPtr->errorBarLineWidth, 
+		NULL, CapButt, JoinMiter);
+	    Blt_Ps_Draw2DSegments(ps, stylePtr->xeb.segments,
+		stylePtr->xeb.length);
+	}
+	if ((stylePtr->yeb.length > 0) && (penPtr->errorBarShow & SHOW_Y)) {
+	    Blt_Ps_XSetLineAttributes(ps, colorPtr, penPtr->errorBarLineWidth, 
+		NULL, CapButt, JoinMiter);
+	    Blt_Ps_Draw2DSegments(ps, stylePtr->yeb.segments, 
+		stylePtr->yeb.length);
+	}
+	if (penPtr->valueShow != SHOW_NONE) {
+	    BarValuesToPostScript(graphPtr, ps, elemPtr, penPtr, 
+		stylePtr->bars, stylePtr->nBars, elemPtr->barToData + count);
+	}
+	count += stylePtr->nBars;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DestroyBar --
+ *
+ *	Release memory and resources allocated for the bar element.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Everything associated with the bar element is freed up.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+DestroyBarProc(Graph *graphPtr, Element *basePtr)
+{
+    BarElement *elemPtr = (BarElement *)basePtr;
+
+    DestroyBarPen(graphPtr, elemPtr->builtinPenPtr);
+    if (elemPtr->activePenPtr != NULL) {
+	Blt_FreePen((Pen *)elemPtr->activePenPtr);
+    }
+    ResetBar(elemPtr);
+    if (elemPtr->stylePalette != NULL) {
+	Blt_FreeStylePalette(elemPtr->stylePalette);
+	Blt_Chain_Destroy(elemPtr->stylePalette);
+    }
+    if (elemPtr->activeIndices != NULL) {
+	free(elemPtr->activeIndices);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_BarElement --
+ *
+ *	Allocate memory and initialize methods for the new bar element.
+ *
+ * Results:
+ *	The pointer to the newly allocated element structure is returned.
+ *
+ * Side effects:
+ *	Memory is allocated for the bar element structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static ElementProcs barProcs = {
+    ClosestBarProc,
+    ConfigureBarProc,
+    DestroyBarProc,
+    DrawActiveBarProc,
+    DrawNormalBarProc,
+    DrawSymbolProc,
+    GetBarExtentsProc,
+    ActiveBarToPostScriptProc,
+    NormalBarToPostScriptProc,
+    SymbolToPostScriptProc,
+    MapBarProc,
+};
+
+
+Element *
+Blt_BarElement(Graph *graphPtr, const char *name, ClassId classId)
+{
+    BarElement *elemPtr;
+
+    elemPtr = calloc(1, sizeof(BarElement));
+    elemPtr->procsPtr = &barProcs;
+    elemPtr->configSpecs = barElemConfigSpecs;
+    elemPtr->legendRelief = TK_RELIEF_FLAT;
+    Blt_GraphSetObjectClass(&elemPtr->obj, classId);
+    elemPtr->obj.name = Blt_Strdup(name);
+    elemPtr->obj.graphPtr = graphPtr;
+    /* By default, an element's name and label are the same. */
+    elemPtr->label = Blt_Strdup(name);
+    elemPtr->builtinPenPtr = &elemPtr->builtinPen;
+    InitializeBarPen(elemPtr->builtinPenPtr);
+    elemPtr->stylePalette = Blt_Chain_Create();
+    bltBarStylesOption.clientData = (ClientData)sizeof(BarStyle);
+    return (Element *)elemPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_InitBarSetTable --
+ *
+ *	Generate a table of abscissa frequencies.  Duplicate x-coordinates
+ *	(depending upon the bar drawing mode) indicate that something special
+ *	should be done with each bar segment mapped to the same abscissa
+ *	(i.e. it should be stacked, aligned, or overlay-ed with other segments)
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is allocated for the bar element structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_InitBarSetTable(Graph *graphPtr)
+{
+    Blt_ChainLink link;
+    int nStacks, nSegs;
+    Blt_HashTable setTable;
+    int sum, max;
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch iter;
+
+    /*
+     * Free resources associated with a previous frequency table. This includes
+     * the array of frequency information and the table itself
+     */
+    Blt_DestroyBarSets(graphPtr);
+    if (graphPtr->mode == BARS_INFRONT) {
+	return;				/* No set table is needed for
+					 * "infront" mode */
+    }
+    Blt_InitHashTable(&graphPtr->setTable, sizeof(BarSetKey) / sizeof(int));
+
+    /*
+     * Initialize a hash table and fill it with unique abscissas.  Keep track
+     * of the frequency of each x-coordinate and how many abscissas have
+     * duplicate mappings.
+     */
+    Blt_InitHashTable(&setTable, sizeof(BarSetKey) / sizeof(int));
+    nSegs = nStacks = 0;
+    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+	link != NULL; link = Blt_Chain_NextLink(link)) {
+	BarElement *elemPtr;
+	double *x, *xend;
+	int nPoints;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if ((elemPtr->flags & HIDE) || (elemPtr->obj.classId != CID_ELEM_BAR)) {
+	    continue;
+	}
+	nSegs++;
+	nPoints = NUMBEROFPOINTS(elemPtr);
+	for (x = elemPtr->x.values, xend = x + nPoints; x < xend; x++) {
+	    Blt_HashEntry *hPtr;
+	    Blt_HashTable *tablePtr;
+	    BarSetKey key;
+	    int isNew;
+	    size_t count;
+	    const char *name;
+
+	    key.value = *x;
+	    key.axes = elemPtr->axes;
+	    key.axes.y = NULL;
+	    hPtr = Blt_CreateHashEntry(&setTable, (char *)&key, &isNew);
+	    if (isNew) {
+		tablePtr = malloc(sizeof(Blt_HashTable));
+		Blt_InitHashTable(tablePtr, BLT_STRING_KEYS);
+		Blt_SetHashValue(hPtr, tablePtr);
+	    } else {
+		tablePtr = Blt_GetHashValue(hPtr);
+	    }
+	    name = (elemPtr->groupName != NULL) ? elemPtr->groupName : 
+		elemPtr->axes.y->obj.name;
+	    hPtr = Blt_CreateHashEntry(tablePtr, name, &isNew);
+	    if (isNew) {
+		count = 1;
+	    } else {
+		count = (size_t)Blt_GetHashValue(hPtr);
+ 		count++;
+	    }		
+	    Blt_SetHashValue(hPtr, (ClientData)count);
+	}
+    }
+    if (setTable.numEntries == 0) {
+	return;				/* No bar elements to be displayed */
+    }
+    sum = max = 0;
+    for (hPtr = Blt_FirstHashEntry(&setTable, &iter); hPtr != NULL;
+	 hPtr = Blt_NextHashEntry(&iter)) {
+	Blt_HashTable *tablePtr;
+	Blt_HashEntry *hPtr2;
+	BarSetKey *keyPtr;
+	int isNew;
+
+	keyPtr = (BarSetKey *)Blt_GetHashKey(&setTable, hPtr);
+	hPtr2 = Blt_CreateHashEntry(&graphPtr->setTable, (char *)keyPtr,&isNew);
+	tablePtr = Blt_GetHashValue(hPtr);
+	Blt_SetHashValue(hPtr2, tablePtr);
+	if (max < tablePtr->numEntries) {
+	    max = tablePtr->numEntries;	/* # of stacks in group. */
+	}
+	sum += tablePtr->numEntries;
+    }
+    Blt_DeleteHashTable(&setTable);
+    if (sum > 0) {
+	BarGroup *groupPtr;
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch iter;
+
+	graphPtr->barGroups = calloc(sum, sizeof(BarGroup));
+	groupPtr = graphPtr->barGroups;
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->setTable, &iter); 
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	    BarSetKey *keyPtr;
+	    Blt_HashTable *tablePtr;
+	    Blt_HashEntry *hPtr2;
+	    Blt_HashSearch iter2;
+	    size_t xcount;
+
+	    tablePtr = Blt_GetHashValue(hPtr);
+	    keyPtr = (BarSetKey *)Blt_GetHashKey(&setTable, hPtr);
+	    xcount = 0;
+	    for (hPtr2 = Blt_FirstHashEntry(tablePtr, &iter2); hPtr2!=NULL;
+		 hPtr2 = Blt_NextHashEntry(&iter2)) {
+		size_t count;
+
+		count = (size_t)Blt_GetHashValue(hPtr2);
+		groupPtr->nSegments = count;
+		groupPtr->axes = keyPtr->axes;
+		Blt_SetHashValue(hPtr2, groupPtr);
+		groupPtr->index = xcount++;
+		groupPtr++;
+	    }
+	}
+    }
+    graphPtr->maxBarSetSize = max;
+    graphPtr->nBarGroups = sum;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ComputeStacks --
+ *
+ *	Determine the height of each stack of bar segments.  A stack is created
+ *	by designating two or more points with the same abscissa.  Each ordinate
+ *	defines the height of a segment in the stack.  This procedure simply
+ *	looks at all the data points summing the heights of each stacked
+ *	segment. The sum is saved in the frequency information table.  This
+ *	value will be used to calculate the y-axis limits (data limits aren't
+ *	sufficient).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The heights of each stack is computed. CheckBarGroups will use this
+ *	information to adjust the y-axis limits if necessary.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_ComputeBarStacks(Graph *graphPtr)
+{
+    Blt_ChainLink link;
+
+    if ((graphPtr->mode != BARS_STACKED) || (graphPtr->nBarGroups == 0)) {
+	return;
+    }
+
+    /* Initialize the stack sums to zero. */
+    {
+	BarGroup *gp, *gend;
+
+	for (gp = graphPtr->barGroups, gend = gp + graphPtr->nBarGroups; 
+	     gp < gend; gp++) {
+	    gp->sum = 0.0;
+	}
+    }
+
+    /* Consider each bar x-y coordinate. Add the ordinates of duplicate
+     * abscissas. */
+
+    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); 
+	 link != NULL; link = Blt_Chain_NextLink(link)) {
+	BarElement *elemPtr;
+	double *x, *y, *xend;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if ((elemPtr->flags & HIDE) || (elemPtr->obj.classId != CID_ELEM_BAR)) {
+	    continue;
+	}
+	for (x = elemPtr->x.values, y = elemPtr->y.values, 
+		 xend = x + NUMBEROFPOINTS(elemPtr); x < xend; x++, y++) {
+	    BarSetKey key;
+	    BarGroup *groupPtr;
+	    Blt_HashEntry *hPtr;
+	    Blt_HashTable *tablePtr;
+	    const char *name;
+
+	    key.value = *x;
+	    key.axes = elemPtr->axes;
+	    key.axes.y = NULL;
+	    hPtr = Blt_FindHashEntry(&graphPtr->setTable, (char *)&key);
+	    if (hPtr == NULL) {
+		continue;
+	    }
+	    tablePtr = Blt_GetHashValue(hPtr);
+	    name = (elemPtr->groupName != NULL) ? elemPtr->groupName : 
+		elemPtr->axes.y->obj.name;
+	    hPtr = Blt_FindHashEntry(tablePtr, name);
+	    if (hPtr == NULL) {
+		continue;
+	    }
+	    groupPtr = Blt_GetHashValue(hPtr);
+	    groupPtr->sum += *y;
+	}
+    }
+}
+
+void
+Blt_ResetBarGroups(Graph *graphPtr)
+{
+    BarGroup *gp, *gend;
+
+    for (gp = graphPtr->barGroups, gend = gp + graphPtr->nBarGroups; gp < gend; 
+	 gp++) {
+	gp->lastY = 0.0;
+	gp->count = 0;
+    }
+}
+
+void
+Blt_DestroyBarSets(Graph *graphPtr)
+{
+    Blt_HashSearch iter;
+    Blt_HashEntry *hPtr;
+
+    if (graphPtr->barGroups != NULL) {
+	free(graphPtr->barGroups);
+	graphPtr->barGroups = NULL;
+    }
+    graphPtr->nBarGroups = 0;
+    for (hPtr = Blt_FirstHashEntry(&graphPtr->setTable, &iter); 
+	 hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	Blt_HashTable *tablePtr;
+	
+	tablePtr = Blt_GetHashValue(hPtr);
+	Blt_DeleteHashTable(tablePtr);
+	free(tablePtr);
+    }
+    Blt_DeleteHashTable(&graphPtr->setTable);
+    Blt_InitHashTable(&graphPtr->setTable, sizeof(BarSetKey) / sizeof(int));
+}
diff --git a/tlt3.0/bltGrElem.c b/tlt3.0/bltGrElem.c
new file mode 100644
index 0000000..9abdc6e
--- /dev/null
+++ b/tlt3.0/bltGrElem.c
@@ -0,0 +1,2214 @@
+
+/*
+ * bltGrElem.c --
+ *
+ * This module implements generic elements for the BLT graph widget.
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <math.h>
+#include <X11/Xutil.h>
+
+#include "bltInt.h"
+#include "bltGraph.h"
+#include "bltOp.h"
+
+#define GRAPH_KEY		"BLT Graph Data"
+
+/* Ignore elements that aren't in the display list or have been deleted. */
+#define IGNORE_ELEMENT(e) (((e)->link == NULL) || ((e)->flags & DELETE_PENDING))
+
+static Blt_OptionParseProc ObjToAlong;
+static Blt_OptionPrintProc AlongToObj;
+static Blt_CustomOption alongOption =
+{
+    ObjToAlong, AlongToObj, NULL, (ClientData)0
+};
+static Blt_OptionFreeProc FreeValues;
+static Blt_OptionParseProc ObjToValues;
+static Blt_OptionPrintProc ValuesToObj;
+Blt_CustomOption bltValuesOption =
+{
+    ObjToValues, ValuesToObj, FreeValues, (ClientData)0
+};
+static Blt_OptionFreeProc FreeValuePairs;
+static Blt_OptionParseProc ObjToValuePairs;
+static Blt_OptionPrintProc ValuePairsToObj;
+Blt_CustomOption bltValuePairsOption =
+{
+    ObjToValuePairs, ValuePairsToObj, FreeValuePairs, (ClientData)0
+};
+
+static Blt_OptionFreeProc  FreeStyles;
+static Blt_OptionParseProc ObjToStyles;
+static Blt_OptionPrintProc StylesToObj;
+Blt_CustomOption bltLineStylesOption =
+{
+    ObjToStyles, StylesToObj, FreeStyles, (ClientData)0,
+};
+
+Blt_CustomOption bltBarStylesOption =
+{
+    ObjToStyles, StylesToObj, FreeStyles, (ClientData)0,
+};
+
+#include "bltGrElem.h"
+
+static Blt_VectorChangedProc VectorChangedProc;
+
+static void FindRange(ElemValues *valuesPtr);
+static void FreeDataValues(ElemValues *valuesPtr);
+static Tcl_FreeProc FreeElement;
+
+typedef int (GraphElementProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+/*
+ *---------------------------------------------------------------------------
+ * Custom option parse and print procedures
+ *---------------------------------------------------------------------------
+ */
+static int
+GetPenStyleFromObj(
+    Tcl_Interp *interp,
+    Graph *graphPtr,
+    Tcl_Obj *objPtr,
+    ClassId classId,
+    PenStyle *stylePtr)
+{
+    Pen *penPtr;
+    Tcl_Obj **objv;
+    int objc;
+
+    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if ((objc != 1) && (objc != 3)) {
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "bad style entry \"", 
+			Tcl_GetString(objPtr), 
+			"\": should be \"penName\" or \"penName min max\"", 
+			(char *)NULL);
+	}
+	return TCL_ERROR;
+    }
+    if (Blt_GetPenFromObj(interp, graphPtr, objv[0], classId, &penPtr) 
+	!= TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (objc == 3) {
+	double min, max;
+
+	if ((Tcl_GetDoubleFromObj(interp, objv[1], &min) != TCL_OK) ||
+	    (Tcl_GetDoubleFromObj(interp, objv[2], &max) != TCL_OK)) {
+	    return TCL_ERROR;
+	}
+	SetWeight(stylePtr->weight, min, max);
+    }
+    stylePtr->penPtr = penPtr;
+    return TCL_OK;
+}
+
+static void
+FreeVectorSource(ElemValues *valuesPtr)
+{
+    if (valuesPtr->vectorSource.vector != NULL) { 
+	Blt_SetVectorChangedProc(valuesPtr->vectorSource.vector, NULL, NULL);
+	Blt_FreeVectorId(valuesPtr->vectorSource.vector); 
+	valuesPtr->vectorSource.vector = NULL;
+    }
+}
+
+static int
+FetchVectorValues(Tcl_Interp *interp, ElemValues *valuesPtr, Blt_Vector *vector)
+{
+    double *array;
+    
+    if (valuesPtr->values == NULL) {
+	array = malloc(Blt_VecLength(vector) * sizeof(double));
+    } else {
+	array = realloc(valuesPtr->values, 
+			    Blt_VecLength(vector) * sizeof(double));
+    }
+    if (array == NULL) {
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL);
+	}
+	return TCL_ERROR;
+    }
+    memcpy(array, Blt_VecData(vector), sizeof(double) * Blt_VecLength(vector));
+    valuesPtr->min = Blt_VecMin(vector);
+    valuesPtr->max = Blt_VecMax(vector);
+    valuesPtr->values = array;
+    valuesPtr->nValues = Blt_VecLength(vector);
+    /* FindRange(valuesPtr); */
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VectorChangedProc --
+ *
+ * Results:
+ *     	None.
+ *
+ * Side Effects:
+ *	Graph is redrawn.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+VectorChangedProc(
+    Tcl_Interp *interp, 
+    ClientData clientData, 
+    Blt_VectorNotify notify)
+{
+    ElemValues *valuesPtr = clientData;
+
+    if (notify == BLT_VECTOR_NOTIFY_DESTROY) {
+	FreeDataValues(valuesPtr);
+    } else {
+	Blt_Vector *vector;
+	
+	Blt_GetVectorById(interp, valuesPtr->vectorSource.vector, &vector);
+	if (FetchVectorValues(NULL, valuesPtr, vector) != TCL_OK) {
+	    return;
+	}
+    }
+    {
+	Element *elemPtr = valuesPtr->elemPtr;
+	Graph *graphPtr;
+	
+	graphPtr = elemPtr->obj.graphPtr;
+	graphPtr->flags |= RESET_AXES;
+	elemPtr->flags |= MAP_ITEM;
+	if (!IGNORE_ELEMENT(elemPtr)) {
+	    graphPtr->flags |= CACHE_DIRTY;
+	    Blt_EventuallyRedrawGraph(graphPtr);
+	}
+    }
+}
+
+static int 
+GetVectorData(Tcl_Interp *interp, ElemValues *valuesPtr, const char *vecName)
+{
+    Blt_Vector *vecPtr;
+    VectorDataSource *srcPtr;
+
+    srcPtr = &valuesPtr->vectorSource;
+    srcPtr->vector = Blt_AllocVectorId(interp, vecName);
+    if (Blt_GetVectorById(interp, srcPtr->vector, &vecPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (FetchVectorValues(interp, valuesPtr, vecPtr) != TCL_OK) {
+	FreeVectorSource(valuesPtr);
+	return TCL_ERROR;
+    }
+    Blt_SetVectorChangedProc(srcPtr->vector, VectorChangedProc, valuesPtr);
+    valuesPtr->type = ELEM_SOURCE_VECTOR;
+    return TCL_OK;
+}
+
+static int
+ParseValues(Tcl_Interp *interp, Tcl_Obj *objPtr, int *nValuesPtr,
+	    double **arrayPtr)
+{
+    int objc;
+    Tcl_Obj **objv;
+
+    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    *arrayPtr = NULL;
+    *nValuesPtr = 0;
+    if (objc > 0) {
+	double *array;
+	double *p;
+	int i;
+
+	array = malloc(sizeof(double) * objc);
+	if (array == NULL) {
+	    Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	for (p = array, i = 0; i < objc; i++, p++) {
+	    if (Blt_ExprDoubleFromObj(interp, objv[i], p) != TCL_OK) {
+		free(array);
+		return TCL_ERROR;
+	    }
+	}
+	*arrayPtr = array;
+	*nValuesPtr = objc;
+    }
+    return TCL_OK;
+}
+
+static void
+FreeDataValues(ElemValues *valuesPtr)
+{
+    switch (valuesPtr->type) {
+    case ELEM_SOURCE_VECTOR: 
+	FreeVectorSource(valuesPtr);	break;
+    case ELEM_SOURCE_VALUES:
+					break;
+    }
+    if (valuesPtr->values != NULL) {
+	free(valuesPtr->values);
+    }
+    valuesPtr->values = NULL;
+    valuesPtr->nValues = 0;
+    valuesPtr->type = ELEM_SOURCE_VALUES;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FindRange --
+ *
+ *	Find the minimum, positive minimum, and maximum values in a given
+ *	vector and store the results in the vector structure.
+ *
+ * Results:
+ *     	None.
+ *
+ * Side Effects:
+ *	Minimum, positive minimum, and maximum values are stored in the
+ *	vector.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+FindRange(ElemValues *valuesPtr)
+{
+    int i;
+    double *x;
+    double min, max;
+
+    if ((valuesPtr->nValues < 1) || (valuesPtr->values == NULL)) {
+	return;			/* This shouldn't ever happen. */
+    }
+    x = valuesPtr->values;
+
+    min = DBL_MAX, max = -DBL_MAX;
+    for(i = 0; i < valuesPtr->nValues; i++) {
+	if (isfinite(x[i])) {
+	    min = max = x[i];
+	    break;
+	}
+    }
+    /*  Initialize values to track the vector range */
+    for (/* empty */; i < valuesPtr->nValues; i++) {
+	if (isfinite(x[i])) {
+	    if (x[i] < min) {
+		min = x[i];
+	    } else if (x[i] > max) {
+		max = x[i];
+	    }
+	}
+    }
+    valuesPtr->min = min, valuesPtr->max = max;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FindElemValuesMinimum --
+ *
+ *	Find the minimum, positive minimum, and maximum values in a given
+ *	vector and store the results in the vector structure.
+ *
+ * Results:
+ *     	None.
+ *
+ * Side Effects:
+ *	Minimum, positive minimum, and maximum values are stored in the
+ *	vector.
+ *
+ *---------------------------------------------------------------------------
+ */
+double
+Blt_FindElemValuesMinimum(ElemValues *valuesPtr, double minLimit)
+{
+    int i;
+    double min;
+
+    min = DBL_MAX;
+    for (i = 0; i < valuesPtr->nValues; i++) {
+	double x;
+
+	x = valuesPtr->values[i];
+	if (x < 0.0) {
+	    /* What do you do about negative values when using log
+	     * scale values seems like a grey area.  Mirror. */
+	    x = -x;
+	}
+	if ((x > minLimit) && (min > x)) {
+	    min = x;
+	}
+    }
+    if (min == DBL_MAX) {
+	min = minLimit;
+    }
+    return min;
+}
+
+/*ARGSUSED*/
+static void
+FreeValues(
+    ClientData clientData,	/* Not used. */
+    Display *display,		/* Not used. */
+    char *widgRec,
+    int offset)
+{
+    ElemValues *valuesPtr = (ElemValues *)(widgRec + offset);
+
+    FreeDataValues(valuesPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToValues --
+ *
+ *	Given a TCL list of numeric expression representing the element
+ *	values, convert into an array of double precision values. In addition,
+ *	the minimum and maximum values are saved.  Since elastic values are
+ *	allow (values which translate to the min/max of the graph), we must
+ *	try to get the non-elastic minimum and maximum.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The vector is passed
+ *	back via the valuesPtr.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToValues(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tk_Window tkwin,		/* Not used. */
+    Tcl_Obj *objPtr,		/* TCL list of expressions */
+    char *widgRec,		/* Element record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    ElemValues *valuesPtr = (ElemValues *)(widgRec + offset);
+    Element *elemPtr = (Element *)widgRec;
+    Tcl_Obj **objv;
+    int objc;
+    int result;
+    const char *string;
+
+    valuesPtr->elemPtr = elemPtr;
+    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    elemPtr->flags |= MAP_ITEM;
+
+    /* Release the current data sources. */
+    FreeDataValues(valuesPtr);
+    if (objc == 0) {
+	return TCL_OK;			/* Empty list of values. */
+    }
+    string = Tcl_GetString(objv[0]);
+    if ((objc == 1) && (Blt_VectorExists2(interp, string))) {
+	result = GetVectorData(interp, valuesPtr, string);
+    } else {
+	double *values;
+	int nValues;
+
+	result = ParseValues(interp, objPtr, &nValues, &values);
+	if (result != TCL_OK) {
+	    return TCL_ERROR;		/* Can't parse the values as numbers. */
+	}
+	FreeDataValues(valuesPtr);
+	if (nValues > 0) {
+	    valuesPtr->values = values;
+	}
+	valuesPtr->nValues = nValues;
+	FindRange(valuesPtr);
+	valuesPtr->type = ELEM_SOURCE_VALUES;
+    }
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ValuesToObj --
+ *
+ *	Convert the vector of floating point values into a TCL list.
+ *
+ * Results:
+ *	The string representation of the vector is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+ValuesToObj(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,
+    Tk_Window tkwin,		/* Not used. */
+    char *widgRec,		/* Element record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    ElemValues *valuesPtr = (ElemValues *)(widgRec + offset);
+
+    switch (valuesPtr->type) {
+    case ELEM_SOURCE_VECTOR:
+	{
+	    const char *vecName;
+	    
+	    vecName = Blt_NameOfVectorId(valuesPtr->vectorSource.vector);
+	    return Tcl_NewStringObj(vecName, -1);
+	}
+    case ELEM_SOURCE_VALUES:
+	{
+	    Tcl_Obj *listObjPtr;
+	    double *vp, *vend; 
+	    
+	    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	    for (vp = valuesPtr->values, vend = vp + valuesPtr->nValues; 
+		 vp < vend; vp++) {
+		Tcl_ListObjAppendElement(interp, listObjPtr, 
+					 Tcl_NewDoubleObj(*vp));
+	    }
+	    return listObjPtr;
+	}
+    default:
+	abort();
+    }
+    return Tcl_NewStringObj("", 0);
+}
+
+/*ARGSUSED*/
+static void
+FreeValuePairs(
+    ClientData clientData,	/* Not used. */
+    Display *display,		/* Not used. */
+    char *widgRec,
+    int offset)			/* Not used. */
+{
+    Element *elemPtr = (Element *)widgRec;
+
+    FreeDataValues(&elemPtr->x);
+    FreeDataValues(&elemPtr->y);
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToValuePairs --
+ *
+ *	This procedure is like ObjToValues except that it interprets
+ *	the list of numeric expressions as X Y coordinate pairs.  The
+ *	minimum and maximum for both the X and Y vectors are
+ *	determined.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The vectors are
+ *	passed back via the widget record (elemPtr).
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToValuePairs(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tk_Window tkwin,		/* Not used. */
+    Tcl_Obj *objPtr,		/* TCL list of numeric expressions */
+    char *widgRec,		/* Element record */
+    int offset,			/* Not used. */
+    int flags)			/* Not used. */
+{
+    Element *elemPtr = (Element *)widgRec;
+    double *values;
+    int nValues;
+    size_t newSize;
+
+    if (ParseValues(interp, objPtr, &nValues, &values) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (nValues & 1) {
+	Tcl_AppendResult(interp, "odd number of data points", (char *)NULL);
+	free(values);
+	return TCL_ERROR;
+    }
+    nValues /= 2;
+    newSize = nValues * sizeof(double);
+    FreeDataValues(&elemPtr->x);	/* Release the current data sources. */
+    FreeDataValues(&elemPtr->y);
+    if (newSize > 0) {
+	double *p;
+	int i;
+
+	elemPtr->x.values = malloc(newSize);
+	elemPtr->y.values = malloc(newSize);
+	elemPtr->x.nValues = elemPtr->y.nValues = nValues;
+	for (p = values, i = 0; i < nValues; i++) {
+	    elemPtr->x.values[i] = *p++;
+	    elemPtr->y.values[i] = *p++;
+	}
+	free(values);
+	FindRange(&elemPtr->x);
+	FindRange(&elemPtr->y);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ValuePairsToObj --
+ *
+ *	Convert pairs of floating point values in the X and Y arrays
+ *	into a TCL list.
+ *
+ * Results:
+ *	The return value is a string (Tcl list).
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+ValuePairsToObj(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,
+    Tk_Window tkwin,		/* Not used. */
+    char *widgRec,		/* Element information record */
+    int offset,			/* Not used. */
+    int flags)			/* Not used. */
+{
+    Element *elemPtr = (Element *)widgRec;
+    Tcl_Obj *listObjPtr;
+    int i;
+    int length;
+
+    length = NUMBEROFPOINTS(elemPtr);
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    for (i = 0; i < length; i++) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+				 Tcl_NewDoubleObj(elemPtr->x.values[i]));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+				 Tcl_NewDoubleObj(elemPtr->y.values[i]));
+    }
+    return listObjPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToAlong --
+ *
+ *	Given a TCL list of numeric expression representing the element
+ *	values, convert into an array of double precision values. In
+ *	addition, the minimum and maximum values are saved.  Since
+ *	elastic values are allow (values which translate to the
+ *	min/max of the graph), we must try to get the non-elastic
+ *	minimum and maximum.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The vector is passed
+ *	back via the valuesPtr.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToAlong(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tk_Window tkwin,		/* Not used. */
+    Tcl_Obj *objPtr,		/* String representation of value. */
+    char *widgRec,		/* Widget record. */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    int *intPtr = (int *)(widgRec + offset);
+    char *string;
+
+    string = Tcl_GetString(objPtr);
+    if ((string[0] == 'x') && (string[1] == '\0')) {
+	*intPtr = SEARCH_X;
+    } else if ((string[0] == 'y') && (string[1] == '\0')) { 
+	*intPtr = SEARCH_Y;
+    } else if ((string[0] == 'b') && (strcmp(string, "both") == 0)) {
+	*intPtr = SEARCH_BOTH;
+    } else {
+	Tcl_AppendResult(interp, "bad along value \"", string, "\"",
+			 (char *)NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AlongToObj --
+ *
+ *	Convert the vector of floating point values into a TCL list.
+ *
+ * Results:
+ *	The string representation of the vector is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+AlongToObj(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Not used. */
+    Tk_Window tkwin,		/* Not used. */
+    char *widgRec,		/* Widget record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    int along = *(int *)(widgRec + offset);
+    Tcl_Obj *objPtr;
+
+    switch (along) {
+    case SEARCH_X:
+	objPtr = Tcl_NewStringObj("x", 1);
+	break;
+    case SEARCH_Y:
+	objPtr = Tcl_NewStringObj("y", 1);
+	break;
+    case SEARCH_BOTH:
+	objPtr = Tcl_NewStringObj("both", 4);
+	break;
+    default:
+	objPtr = Tcl_NewStringObj("unknown along value", 4);
+	break;
+    }
+    return objPtr;
+}
+
+void
+Blt_FreeStylePalette(Blt_Chain stylePalette)
+{
+    Blt_ChainLink link;
+
+    /* Skip the first slot. It contains the built-in "normal" pen of
+     * the element.  */
+    link = Blt_Chain_FirstLink(stylePalette);
+    if (link != NULL) {
+	Blt_ChainLink next;
+
+	for (link = Blt_Chain_NextLink(link); link != NULL; link = next) {
+	    PenStyle *stylePtr;
+
+	    next = Blt_Chain_NextLink(link);
+	    stylePtr = Blt_Chain_GetValue(link);
+	    Blt_FreePen(stylePtr->penPtr);
+	    Blt_Chain_DeleteLink(stylePalette, link);
+	}
+    }
+}
+
+/*ARGSUSED*/
+static void
+FreeStyles(
+    ClientData clientData,	/* Not used. */
+    Display *display,		/* Not used. */
+    char *widgRec,
+    int offset)
+{
+    Blt_Chain stylePalette = *(Blt_Chain *)(widgRec + offset);
+
+    Blt_FreeStylePalette(stylePalette);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ObjToStyles --
+ *
+ *	Parse the list of style names.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToStyles(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tk_Window tkwin,		/* Not used. */
+    Tcl_Obj *objPtr,		/* String representing style list */
+    char *widgRec,		/* Element information record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    Blt_Chain stylePalette = *(Blt_Chain *)(widgRec + offset);
+    Blt_ChainLink link;
+    Element *elemPtr = (Element *)(widgRec);
+    PenStyle *stylePtr;
+    Tcl_Obj **objv;
+    int objc;
+    int i;
+    size_t size = (size_t)clientData;
+
+
+    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    /* Reserve the first entry for the "normal" pen. We'll set the
+     * style later */
+    Blt_FreeStylePalette(stylePalette);
+    link = Blt_Chain_FirstLink(stylePalette);
+    if (link == NULL) {
+	link = Blt_Chain_AllocLink(size);
+	Blt_Chain_LinkAfter(stylePalette, link, NULL);
+    }
+    stylePtr = Blt_Chain_GetValue(link);
+    stylePtr->penPtr = elemPtr->normalPenPtr;
+    for (i = 0; i < objc; i++) {
+	link = Blt_Chain_AllocLink(size);
+	stylePtr = Blt_Chain_GetValue(link);
+	stylePtr->weight.min = (double)i;
+	stylePtr->weight.max = (double)i + 1.0;
+	stylePtr->weight.range = 1.0;
+	if (GetPenStyleFromObj(interp, elemPtr->obj.graphPtr, objv[i], 
+		elemPtr->obj.classId, (PenStyle *)stylePtr) != TCL_OK) {
+	    Blt_FreeStylePalette(stylePalette);
+	    return TCL_ERROR;
+	}
+	Blt_Chain_LinkAfter(stylePalette, link, NULL);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * StylesToObj --
+ *
+ *	Convert the style information into a Tcl_Obj.
+ *
+ * Results:
+ *	The string representing the style information is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+StylesToObj(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,
+    Tk_Window tkwin,		/* Not used. */
+    char *widgRec,		/* Element information record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    Blt_Chain stylePalette = *(Blt_Chain *)(widgRec + offset);
+    Blt_ChainLink link;
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    link = Blt_Chain_FirstLink(stylePalette);
+    if (link != NULL) {
+	/* Skip the first style (it's the default) */
+	for (link = Blt_Chain_NextLink(link); link != NULL; 
+	     link = Blt_Chain_NextLink(link)) {
+	    PenStyle *stylePtr;
+	    Tcl_Obj *subListObjPtr;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    subListObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	    Tcl_ListObjAppendElement(interp, subListObjPtr, 
+		Tcl_NewStringObj(stylePtr->penPtr->name, -1));
+	    Tcl_ListObjAppendElement(interp, subListObjPtr, 
+				     Tcl_NewDoubleObj(stylePtr->weight.min));
+	    Tcl_ListObjAppendElement(interp, subListObjPtr, 
+				     Tcl_NewDoubleObj(stylePtr->weight.max));
+	    Tcl_ListObjAppendElement(interp, listObjPtr, subListObjPtr);
+	}
+    }
+    return listObjPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_StyleMap --
+ *
+ *	Creates an array of style indices and fills it based on the weight
+ *	of each data point.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is freed and allocated for the index array.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+PenStyle **
+Blt_StyleMap(Element *elemPtr)
+{
+    int i;
+    int nWeights;		/* Number of weights to be examined.
+				 * If there are more data points than
+				 * weights, they will default to the
+				 * normal pen. */
+
+    PenStyle **dataToStyle;	/* Directory of styles.  Each array
+				 * element represents the style for
+				 * the data point at that index */
+    Blt_ChainLink link;
+    PenStyle *stylePtr;
+    double *w;			/* Weight vector */
+    int nPoints;
+
+    nPoints = NUMBEROFPOINTS(elemPtr);
+    nWeights = MIN(elemPtr->w.nValues, nPoints);
+    w = elemPtr->w.values;
+    link = Blt_Chain_FirstLink(elemPtr->stylePalette);
+    stylePtr = Blt_Chain_GetValue(link);
+
+    /* 
+     * Create a style mapping array (data point index to style), 
+     * initialized to the default style.
+     */
+    dataToStyle = malloc(nPoints * sizeof(PenStyle *));
+    for (i = 0; i < nPoints; i++) {
+	dataToStyle[i] = stylePtr;
+    }
+
+    for (i = 0; i < nWeights; i++) {
+	for (link = Blt_Chain_LastLink(elemPtr->stylePalette); link != NULL; 
+	     link = Blt_Chain_PrevLink(link)) {
+	    stylePtr = Blt_Chain_GetValue(link);
+
+	    if (stylePtr->weight.range > 0.0) {
+		double norm;
+
+		norm = (w[i] - stylePtr->weight.min) / stylePtr->weight.range;
+		if (((norm - 1.0) <= DBL_EPSILON) && 
+		    (((1.0 - norm) - 1.0) <= DBL_EPSILON)) {
+		    dataToStyle[i] = stylePtr;
+		    break;		/* Done: found range that matches. */
+		}
+	    }
+	}
+    }
+    return dataToStyle;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetIndex --
+ *
+ *	Given a string representing the index of a pair of x,y
+ *	coordinates, return the numeric index.
+ *
+ * Results:
+ *     	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+GetIndex(Tcl_Interp *interp, Element *elemPtr, Tcl_Obj *objPtr, int *indexPtr)
+{
+    char *string;
+
+    string = Tcl_GetString(objPtr);
+    if ((*string == 'e') && (strcmp("end", string) == 0)) {
+	*indexPtr = NUMBEROFPOINTS(elemPtr) - 1;
+    } else if (Blt_ExprIntFromObj(interp, objPtr, indexPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetElement --
+ *
+ *	Find the element represented the given name, returning a pointer to
+ *	its data structure via elemPtrPtr.
+ *
+ * Results:
+ *     	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_GetElement(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, 
+	       Element **elemPtrPtr)
+{
+    Blt_HashEntry *hPtr;
+    char *name;
+
+    name = Tcl_GetString(objPtr);
+    hPtr = Blt_FindHashEntry(&graphPtr->elements.table, name);
+    if (hPtr == NULL) {
+	if (interp != NULL) {
+ 	    Tcl_AppendResult(interp, "can't find element \"", name,
+		"\" in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
+	}
+	return TCL_ERROR;
+    }
+    *elemPtrPtr = Blt_GetHashValue(hPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DestroyElement --
+ *
+ *	Add a new element to the graph.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DestroyElement(Element *elemPtr)
+{
+    Graph *graphPtr = elemPtr->obj.graphPtr;
+
+    Blt_DeleteBindings(graphPtr->bindTable, elemPtr);
+    Blt_Legend_RemoveElement(graphPtr, elemPtr);
+
+    Blt_FreeOptions(elemPtr->configSpecs, (char *)elemPtr,graphPtr->display, 0);
+    /*
+     * Call the element's own destructor to release the memory and
+     * resources allocated for it.
+     */
+    (*elemPtr->procsPtr->destroyProc) (graphPtr, elemPtr);
+
+    /* Remove it also from the element display list */
+    if (elemPtr->link != NULL) {
+	Blt_Chain_DeleteLink(graphPtr->elements.displayList, elemPtr->link);
+	if (!IGNORE_ELEMENT(elemPtr)) {
+	    graphPtr->flags |= RESET_WORLD;
+	    Blt_EventuallyRedrawGraph(graphPtr);
+	}
+    }
+    /* Remove the element for the graph's hash table of elements */
+    if (elemPtr->hashPtr != NULL) {
+	Blt_DeleteHashEntry(&graphPtr->elements.table, elemPtr->hashPtr);
+    }
+    if (elemPtr->obj.name != NULL) {
+      free((void*)(elemPtr->obj.name));
+    }
+    if (elemPtr->label != NULL) {
+      free((void*)(elemPtr->label));
+    }
+    free(elemPtr);
+}
+
+static void FreeElement(char* data)
+{
+    Element *elemPtr = (Element *)data;
+    DestroyElement(elemPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateElement --
+ *
+ *	Add a new element to the graph.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+CreateElement(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	      Tcl_Obj *const *objv, ClassId classId)
+{
+    Element *elemPtr;
+    Blt_HashEntry *hPtr;
+    int isNew;
+    char *string;
+
+    string = Tcl_GetString(objv[3]);
+    if (string[0] == '-') {
+	Tcl_AppendResult(graphPtr->interp, "name of element \"", string, 
+			 "\" can't start with a '-'", (char *)NULL);
+	return TCL_ERROR;
+    }
+    hPtr = Blt_CreateHashEntry(&graphPtr->elements.table, string, &isNew);
+    if (!isNew) {
+	Tcl_AppendResult(interp, "element \"", string, 
+			 "\" already exists in \"", Tcl_GetString(objv[0]), 
+			 "\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (classId == CID_ELEM_BAR) {
+	elemPtr = Blt_BarElement(graphPtr, string, classId);
+    } else { 
+	/* Stripcharts are line graphs with some options enabled. */	
+	elemPtr = Blt_LineElement(graphPtr, string, classId);
+    }
+    assert(elemPtr->configSpecs != NULL);
+    elemPtr->hashPtr = hPtr;
+    Blt_SetHashValue(hPtr, elemPtr);
+
+    if (Blt_ConfigureComponentFromObj(interp, graphPtr->tkwin, 
+	elemPtr->obj.name, "Element", elemPtr->configSpecs, objc - 4, objv + 4,
+	(char *)elemPtr, 0) != TCL_OK) {
+	DestroyElement(elemPtr);
+	return TCL_ERROR;
+    }
+    (*elemPtr->procsPtr->configProc) (graphPtr, elemPtr);
+    elemPtr->link = Blt_Chain_Append(graphPtr->elements.displayList, elemPtr);
+    graphPtr->flags |= CACHE_DIRTY;
+    Blt_EventuallyRedrawGraph(graphPtr);
+    elemPtr->flags |= MAP_ITEM;
+    graphPtr->flags |= RESET_AXES;
+    Tcl_SetObjResult(interp, objv[3]);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DestroyElements --
+ *
+ *	Removes all the graph's elements. This routine is called when
+ *	the graph is destroyed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory allocated for the graph's elements is freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DestroyElements(Graph *graphPtr)
+{
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch iter;
+    Element *elemPtr;
+
+    for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.table, &iter);
+	 hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	elemPtr = Blt_GetHashValue(hPtr);
+	elemPtr->hashPtr = NULL;
+	DestroyElement(elemPtr);
+    }
+    Blt_DeleteHashTable(&graphPtr->elements.table);
+    Blt_DeleteHashTable(&graphPtr->elements.tagTable);
+    Blt_Chain_Destroy(graphPtr->elements.displayList);
+}
+
+void
+Blt_ConfigureElements(Graph *graphPtr)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); 
+	 link != NULL; link = Blt_Chain_NextLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	(*elemPtr->procsPtr->configProc) (graphPtr, elemPtr);
+    }
+}
+
+void
+Blt_MapElements(Graph *graphPtr)
+{
+    Blt_ChainLink link;
+
+    if (graphPtr->mode != BARS_INFRONT) {
+	Blt_ResetBarGroups(graphPtr);
+    }
+    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); 
+	 link != NULL; link = Blt_Chain_NextLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (IGNORE_ELEMENT(elemPtr)) {
+	    continue;
+	}
+	if ((graphPtr->flags & MAP_ALL) || (elemPtr->flags & MAP_ITEM)) {
+	    (*elemPtr->procsPtr->mapProc) (graphPtr, elemPtr);
+	    elemPtr->flags &= ~MAP_ITEM;
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DrawElements --
+ *
+ *	Calls the individual element drawing routines for each
+ *	element.
+ *
+ * Results:
+ *	None
+ *
+ * Side Effects:
+ *	Elements are drawn into the drawable (pixmap) which will
+ *	eventually be displayed in the graph window.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DrawElements(Graph *graphPtr, Drawable drawable)
+{
+    Blt_ChainLink link;
+
+    /* Draw with respect to the stacking order. */
+    for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); 
+	 link != NULL; link = Blt_Chain_PrevLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if ((elemPtr->flags & (HIDE|DELETE_PENDING)) == 0) {
+	    (*elemPtr->procsPtr->drawNormalProc)(graphPtr, drawable, elemPtr);
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DrawActiveElements --
+ *
+ *	Calls the individual element drawing routines to display
+ *	the active colors for each element.
+ *
+ * Results:
+ *	None
+ *
+ * Side Effects:
+ *	Elements are drawn into the drawable (pixmap) which will
+ *	eventually be displayed in the graph window.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DrawActiveElements(Graph *graphPtr, Drawable drawable)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); 
+	 link != NULL; link = Blt_Chain_PrevLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if ((elemPtr->flags & (HIDE|ACTIVE|DELETE_PENDING)) == ACTIVE) {
+	    (*elemPtr->procsPtr->drawActiveProc)(graphPtr, drawable, elemPtr);
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ElementsToPostScript --
+ *
+ *	Generates PostScript output for each graph element in the
+ *	element display list.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_ElementsToPostScript(Graph *graphPtr, Blt_Ps ps)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); 
+	 link != NULL; link = Blt_Chain_PrevLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (elemPtr->flags & (HIDE|DELETE_PENDING)) {
+	    continue;
+	}
+	/* Comment the PostScript to indicate the start of the element */
+	Blt_Ps_Format(ps, "\n%% Element \"%s\"\n\n", elemPtr->obj.name);
+	(*elemPtr->procsPtr->printNormalProc) (graphPtr, ps, elemPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ActiveElementsToPostScript --
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_ActiveElementsToPostScript( Graph *graphPtr, Blt_Ps ps)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); 
+	 link != NULL; link = Blt_Chain_PrevLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if ((elemPtr->flags & (DELETE_PENDING|HIDE|ACTIVE)) == ACTIVE) {
+	    Blt_Ps_Format(ps, "\n%% Active Element \"%s\"\n\n", 
+		elemPtr->obj.name);
+	    (*elemPtr->procsPtr->printActiveProc)(graphPtr, ps, elemPtr);
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ActivateOp --
+ *
+ *	Marks data points of elements (given by their index) as active.
+ *
+ * Results:
+ *	Returns TCL_OK if no errors occurred.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ActivateOp(
+    Graph *graphPtr,			/* Graph widget */
+    Tcl_Interp *interp,			/* Interpreter to report errors to */
+    int objc,				/* Number of element names */
+    Tcl_Obj *const *objv)		/* List of element names */
+{
+    Element *elemPtr;
+    int i;
+    int *indices;
+    int nIndices;
+
+    if (objc == 3) {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch iter;
+	Tcl_Obj *listObjPtr;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	/* List all the currently active elements */
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.table, &iter);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	    elemPtr = Blt_GetHashValue(hPtr);
+	    if (elemPtr->flags & ACTIVE) {
+		Tcl_ListObjAppendElement(interp, listObjPtr, 
+			Tcl_NewStringObj(elemPtr->obj.name, -1));
+	    }
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+	return TCL_OK;
+    }
+    if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) {
+	return TCL_ERROR;	/* Can't find named element */
+    }
+    elemPtr->flags |= ACTIVE | ACTIVE_PENDING;
+
+    indices = NULL;
+    nIndices = -1;
+    if (objc > 4) {
+	int *activePtr;
+
+	nIndices = objc - 4;
+	activePtr = indices = malloc(sizeof(int) * nIndices);
+	for (i = 4; i < objc; i++) {
+	    if (GetIndex(interp, elemPtr, objv[i], activePtr) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    activePtr++;
+	}
+    }
+    if (elemPtr->activeIndices != NULL) {
+	free(elemPtr->activeIndices);
+    }
+    elemPtr->nActiveIndices = nIndices;
+    elemPtr->activeIndices = indices;
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+ClientData
+Blt_MakeElementTag(Graph *graphPtr, const char *tagName)
+{
+    Blt_HashEntry *hPtr;
+    int isNew;
+
+    hPtr = Blt_CreateHashEntry(&graphPtr->elements.tagTable, tagName, &isNew);
+    return Blt_GetHashKey(&graphPtr->elements.tagTable, hPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BindOp --
+ *
+ *	.g element bind elemName sequence command
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+BindOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    if (objc == 3) {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch iter;
+	char *tagName;
+	Tcl_Obj *listObjPtr;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.tagTable, &iter);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	    tagName = Blt_GetHashKey(&graphPtr->elements.tagTable, hPtr);
+	    Tcl_ListObjAppendElement(interp, listObjPtr, 
+				     Tcl_NewStringObj(tagName, -1));
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+	return TCL_OK;
+    }
+    return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable,
+	Blt_MakeElementTag(graphPtr, Tcl_GetString(objv[3])), 
+	objc - 4, objv + 4);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateOp --
+ *
+ *	Add a new element to the graph (using the default type of the
+ *	graph).
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+CreateOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv,
+    ClassId classId)
+{
+    return CreateElement(graphPtr, interp, objc, objv, classId);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CgetOp --
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+CgetOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,			/* Not used. */
+    Tcl_Obj *const *objv)
+{
+    Element *elemPtr;
+
+    if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) {
+	return TCL_ERROR;	/* Can't find named element */
+    }
+    if (Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, elemPtr->configSpecs,
+				  (char *)elemPtr, objv[4], 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ClosestOp --
+ *
+ *	Find the element closest to the specified screen coordinates.
+ *	Options:
+ *	-halo		Consider points only with this maximum distance
+ *			from the picked coordinate.
+ *	-interpolate	Find closest point along element traces, not just
+ *			data points.
+ *	-along
+ *
+ * Results:
+ *	A standard TCL result. If an element could be found within
+ *	the halo distance, the interpreter result is "1", otherwise
+ *	"0".  If a closest element exists, the designated TCL array
+ *	variable will be set with the following information:
+ *
+ *	1) the element name,
+ *	2) the index of the closest point,
+ *	3) the distance (in screen coordinates) from the picked X-Y
+ *	   coordinate and the closest point,
+ *	4) the X coordinate (graph coordinate) of the closest point,
+ *	5) and the Y-coordinate.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Blt_ConfigSpec closestSpecs[] = {
+    {BLT_CONFIG_PIXELS_NNEG, "-halo", (char *)NULL, (char *)NULL,
+	(char *)NULL, Blt_Offset(ClosestSearch, halo), 0},
+    {BLT_CONFIG_BOOLEAN, "-interpolate", (char *)NULL, (char *)NULL,
+	(char *)NULL, Blt_Offset(ClosestSearch, mode), 0 }, 
+    {BLT_CONFIG_CUSTOM, "-along", (char *)NULL, (char *)NULL,
+	(char *)NULL, Blt_Offset(ClosestSearch, along), 0, &alongOption},
+    {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL,
+	(char *)NULL, 0, 0}
+};
+
+static int
+ClosestOp(
+    Graph *graphPtr,		/* Graph widget */
+    Tcl_Interp *interp,		/* Interpreter to report results to */
+    int objc,			/* Number of element names */
+    Tcl_Obj *const *objv)	/* List of element names */
+{
+    Element *elemPtr;
+    ClosestSearch search;
+    int i, x, y;
+    char *string;
+
+    if (graphPtr->flags & RESET_AXES) {
+	Blt_ResetAxes(graphPtr);
+    }
+    if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) {
+	Tcl_AppendResult(interp, ": bad window x-coordinate", (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
+	Tcl_AppendResult(interp, ": bad window y-coordinate", (char *)NULL);
+	return TCL_ERROR;
+    }
+    for (i = 5; i < objc; i += 2) {	/* Count switches-value pairs */
+	string = Tcl_GetString(objv[i]);
+	if ((string[0] != '-') || 
+	    ((string[1] == '-') && (string[2] == '\0'))) {
+	    break;
+	}
+    }
+    if (i > objc) {
+	i = objc;
+    }
+
+    search.mode = SEARCH_POINTS;
+    search.halo = graphPtr->halo;
+    search.index = -1;
+    search.along = SEARCH_BOTH;
+    search.x = x;
+    search.y = y;
+
+    if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, closestSpecs, i - 5,
+	objv + 5, (char *)&search, BLT_CONFIG_OBJV_ONLY) != TCL_OK) {
+	return TCL_ERROR;	/* Error occurred processing an option. */
+    }
+    if (i < objc) {
+	string = Tcl_GetString(objv[i]);
+	if (string[0] == '-') {
+	    i++;			/* Skip "--" */
+	}
+    }
+    search.dist = (double)(search.halo + 1);
+
+    if (i < objc) {
+	for ( /* empty */ ; i < objc; i++) {
+	    if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) {
+		return TCL_ERROR; /* Can't find named element */
+	    }
+	    if (IGNORE_ELEMENT(elemPtr)) {
+		continue;
+	    }
+	    if (elemPtr->flags & (HIDE|MAP_ITEM)) {
+		continue;
+	    }
+	    (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search);
+	}
+    } else {
+	Blt_ChainLink link;
+
+	/* 
+	 * Find the closest point from the set of displayed elements,
+	 * searching the display list from back to front.  That way if
+	 * the points from two different elements overlay each other
+	 * exactly, the last one picked will be the topmost.  
+	 */
+	for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); 
+	     link != NULL; link = Blt_Chain_PrevLink(link)) {
+	    elemPtr = Blt_Chain_GetValue(link);
+	    if (elemPtr->flags & (HIDE|MAP_ITEM|DELETE_PENDING)) {
+		continue;
+	    }
+	    (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search);
+	}
+    }
+    if (search.dist < (double)search.halo) {
+	Tcl_Obj *listObjPtr;
+	/*
+	 *  Return a list of name value pairs.
+	 */
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+				 Tcl_NewStringObj("name", -1));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj(search.elemPtr->obj.name, -1)); 
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj("index", -1));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewIntObj(search.index));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj("x", -1));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewDoubleObj(search.point.x));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj("y", -1));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewDoubleObj(search.point.y));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj("dist", -1));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewDoubleObj(search.dist));
+	Tcl_SetObjResult(interp, listObjPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureOp --
+ *
+ *	Sets the element specifications by the given the command line
+ *	arguments and calls the element specification configuration
+ *	routine. If zero or one command line options are given, only
+ *	information about the option(s) is returned in interp->result.
+ *	If the element configuration has changed and the element is
+ *	currently displayed, the axis limits are updated and
+ *	recomputed.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new display list.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ConfigureOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    int nNames, nOpts;
+    Tcl_Obj *const *options;
+    int i;
+
+    /* Figure out where the option value pairs begin */
+    objc -= 3;
+    objv += 3;
+    for (i = 0; i < objc; i++) {
+	Element *elemPtr;
+	char *string;
+
+	string = Tcl_GetString(objv[i]);
+	if (string[0] == '-') {
+	    break;
+	}
+	if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) {
+	    return TCL_ERROR;	/* Can't find named element */
+	}
+    }
+    nNames = i;			/* Number of element names specified */
+    nOpts = objc - i;		/* Number of options specified */
+    options = objv + nNames;	/* Start of options in objv  */
+
+    for (i = 0; i < nNames; i++) {
+	Element *elemPtr;
+	int flags;
+
+	if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flags = BLT_CONFIG_OBJV_ONLY;
+	if (nOpts == 0) {
+	    return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, 
+		elemPtr->configSpecs, (char *)elemPtr, (Tcl_Obj *)NULL, flags);
+	} else if (nOpts == 1) {
+	    return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, 
+		elemPtr->configSpecs, (char *)elemPtr, options[0], flags);
+	}
+	if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, 
+		elemPtr->configSpecs, nOpts, options, (char *)elemPtr, flags) 
+		!= TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if ((*elemPtr->procsPtr->configProc) (graphPtr, elemPtr) != TCL_OK) {
+	    return TCL_ERROR;	/* Failed to configure element */
+	}
+	if (Blt_ConfigModified(elemPtr->configSpecs, "-hide", (char *)NULL)) {
+	    graphPtr->flags |= RESET_AXES;
+	    elemPtr->flags |= MAP_ITEM;
+	}
+	/* If data points or axes have changed, reset the axes (may
+	 * affect autoscaling) and recalculate the screen points of
+	 * the element. */
+
+	if (Blt_ConfigModified(elemPtr->configSpecs, "-*data", "-map*", "-x",
+		"-y", (char *)NULL)) {
+	    graphPtr->flags |= RESET_WORLD;
+	    elemPtr->flags |= MAP_ITEM;
+	}
+	/* The new label may change the size of the legend */
+	if (Blt_ConfigModified(elemPtr->configSpecs, "-label", (char *)NULL)) {
+	    graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD);
+	}
+    }
+    /* Update the pixmap if any configuration option changed */
+    graphPtr->flags |= CACHE_DIRTY;
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DeactivateOp --
+ *
+ *	Clears the active bit for the named elements.
+ *
+ * Results:
+ *	Returns TCL_OK if no errors occurred.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+DeactivateOp(
+    Graph *graphPtr,		/* Graph widget */
+    Tcl_Interp *interp,		/* Not used. */
+    int objc,			/* Number of element names */
+    Tcl_Obj *const *objv)	/* List of element names */
+{
+    int i;
+
+    for (i = 3; i < objc; i++) {
+	Element *elemPtr;
+
+	if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) {
+	    return TCL_ERROR;	/* Can't find named element */
+	}
+	elemPtr->flags &= ~(ACTIVE | ACTIVE_PENDING);
+	if (elemPtr->activeIndices != NULL) {
+	    free(elemPtr->activeIndices);
+	    elemPtr->activeIndices = NULL;
+	}
+	elemPtr->nActiveIndices = 0;
+    }
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DeleteOp --
+ *
+ *	Delete the named elements from the graph.
+ *
+ * Results:
+ *	TCL_ERROR is returned if any of the named elements can not be
+ *	found.  Otherwise TCL_OK is returned;
+ *
+ * Side Effects:
+ *	If the element is currently displayed, the plotting area of
+ *	the graph is redrawn. Memory and resources allocated by the
+ *	elements are released.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+DeleteOp(
+    Graph *graphPtr,		/* Graph widget */
+    Tcl_Interp *interp,		/* Not used. */
+    int objc,			/* Number of element names */
+    Tcl_Obj *const *objv)	/* List of element names */
+{
+    int i;
+
+    for (i = 3; i < objc; i++) {
+	Element *elemPtr;
+
+	if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) {
+	    return TCL_ERROR;	/* Can't find named element */
+	}
+	elemPtr->flags |= DELETE_PENDING;
+	Tcl_EventuallyFree(elemPtr, FreeElement);
+    }
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ExistsOp --
+ *
+ *	Indicates if the named element exists in the graph.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The interpreter
+ *	result will contain "1" or "0".
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static int
+ExistsOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,			/* Not used. */
+    Tcl_Obj *const *objv)
+{
+    Blt_HashEntry *hPtr;
+
+    hPtr = Blt_FindHashEntry(&graphPtr->elements.table, Tcl_GetString(objv[3]));
+    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (hPtr != NULL));
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetOp --
+ *
+ * 	Returns the name of the picked element (using the element
+ *	bind operation).  Right now, the only name accepted is
+ *	"current".
+ *
+ * Results:
+ *	A standard TCL result.  The interpreter result will contain
+ *	the name of the element.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+GetOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,			/* Not used. */
+    Tcl_Obj *const *objv)
+{
+    char *string;
+
+    string = Tcl_GetString(objv[3]);
+    if ((string[0] == 'c') && (strcmp(string, "current") == 0)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_GetCurrentItem(graphPtr->bindTable);
+	/* Report only on elements. */
+	if ((elemPtr != NULL) && ((elemPtr->flags & DELETE_PENDING) == 0) &&
+	    (elemPtr->obj.classId >= CID_ELEM_BAR) &&
+	    (elemPtr->obj.classId <= CID_ELEM_LINE)) {
+	    Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->obj.name,-1);
+	}
+    }
+    return TCL_OK;
+}
+
+static Tcl_Obj *
+DisplayListObj(Graph *graphPtr)
+{
+    Tcl_Obj *listObjPtr;
+    Blt_ChainLink link;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); 
+	 link != NULL; link = Blt_Chain_NextLink(link)) {
+	Element *elemPtr;
+	Tcl_Obj *objPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1);
+	Tcl_ListObjAppendElement(graphPtr->interp, listObjPtr, objPtr);
+    }
+    return listObjPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LowerOp --
+ *
+ *	Lowers the named elements to the bottom of the display list.
+ *
+ * Results:
+ *	A standard TCL result. The interpreter result will contain the new
+ *	display list of element names.
+ *
+ *	.g element lower elem ?elem...?
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+LowerOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Blt_Chain chain;
+    Blt_ChainLink link, next;
+    int i;
+
+    /* Move the links of lowered elements out of the display list into
+     * a temporary list. */
+    chain = Blt_Chain_Create();
+    for (i = 3; i < objc; i++) {
+	Element *elemPtr;
+
+	if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) {
+	    return TCL_ERROR;	/* Can't find named element */
+	}
+	Blt_Chain_UnlinkLink(graphPtr->elements.displayList, elemPtr->link); 
+	Blt_Chain_LinkAfter(chain, elemPtr->link, NULL); 
+    }
+    /* Append the links to end of the display list. */
+    for (link = Blt_Chain_FirstLink(chain); link != NULL; link = next) {
+	next = Blt_Chain_NextLink(link);
+	Blt_Chain_UnlinkLink(chain, link); 
+	Blt_Chain_LinkAfter(graphPtr->elements.displayList, link, NULL); 
+    }	
+    Blt_Chain_Destroy(chain);
+    Tcl_SetObjResult(interp, DisplayListObj(graphPtr));
+    graphPtr->flags |= RESET_WORLD;
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NamesOp --
+ *
+ *	Returns the names of the elements is the graph matching
+ *	one of more patterns provided.  If no pattern arguments
+ *	are given, then all element names will be returned.
+ *
+ * Results:
+ *	The return value is a standard TCL result. The interpreter
+ *	result will contain a TCL list of the element names.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+NamesOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if (objc == 3) {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch iter;
+
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.table, &iter);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	    Element *elemPtr;
+	    Tcl_Obj *objPtr;
+
+	    elemPtr = Blt_GetHashValue(hPtr);
+	    objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1);
+	    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	}
+    } else {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch iter;
+
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.table, &iter);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	    Element *elemPtr;
+	    int i;
+
+	    elemPtr = Blt_GetHashValue(hPtr);
+	    for (i = 3; i < objc; i++) {
+		if (Tcl_StringMatch(elemPtr->obj.name,Tcl_GetString(objv[i]))) {
+		    Tcl_Obj *objPtr;
+
+		    objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1);
+		    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+		    break;
+		}
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RaiseOp --
+ *
+ *	Reset the element within the display list.
+ *
+ * Results:
+ *	The return value is a standard TCL result. The interpreter
+ *	result will contain the new display list of element names.
+ *
+ *	.g element raise ?elem...?
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+RaiseOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Blt_Chain chain;
+    Blt_ChainLink link, prev;
+    int i;
+
+    /* Move the links of lowered elements out of the display list into
+     * a temporary list. */
+    chain = Blt_Chain_Create();
+    for (i = 3; i < objc; i++) {
+	Element *elemPtr;
+
+	if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) {
+	    return TCL_ERROR;	/* Can't find named element */
+	}
+	Blt_Chain_UnlinkLink(graphPtr->elements.displayList, elemPtr->link); 
+	Blt_Chain_LinkAfter(chain, elemPtr->link, NULL); 
+    }
+    /* Prepend the links to beginning of the display list in reverse order. */
+    for (link = Blt_Chain_LastLink(chain); link != NULL; link = prev) {
+	prev = Blt_Chain_PrevLink(link);
+	Blt_Chain_UnlinkLink(chain, link); 
+	Blt_Chain_LinkBefore(graphPtr->elements.displayList, link, NULL); 
+    }	
+    Blt_Chain_Destroy(chain);
+    Tcl_SetObjResult(interp, DisplayListObj(graphPtr));
+    graphPtr->flags |= RESET_WORLD;
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ShowOp --
+ *
+ *	Queries or resets the element display list.
+ *
+ * Results:
+ *	The return value is a standard TCL result. The interpreter
+ *	result will contain the new display list of element names.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ShowOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    if (objc == 4) {
+	Blt_Chain chain;
+	Blt_ChainLink link;
+	Tcl_Obj **elem;
+	int i, n;
+
+	if (Tcl_ListObjGetElements(interp, objv[3], &n, &elem) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	/* Collect the named elements into a list. */
+	chain = Blt_Chain_Create();
+	for (i = 0; i < n; i++) {
+	    Element *elemPtr;	/* Element information record */
+
+	    if (Blt_GetElement(interp, graphPtr, elem[i], &elemPtr) != TCL_OK) {
+		Blt_Chain_Destroy(chain);
+		return TCL_ERROR;
+	    }
+	    Blt_Chain_Append(chain, elemPtr);
+	}
+	/* Clear the links from the currently displayed elements.  */
+	for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    Element *elemPtr;
+	    
+	    elemPtr = Blt_Chain_GetValue(link);
+	    elemPtr->link = NULL;
+	}
+	Blt_Chain_Destroy(graphPtr->elements.displayList);
+	graphPtr->elements.displayList = chain;
+	/* Set links on all the displayed elements.  */
+	for (link = Blt_Chain_FirstLink(chain); link != NULL; 
+	     link = Blt_Chain_NextLink(link)) {
+	    Element *elemPtr;
+	    
+	    elemPtr = Blt_Chain_GetValue(link);
+	    elemPtr->link = link;
+	}
+	graphPtr->flags |= RESET_WORLD;
+	Blt_EventuallyRedrawGraph(graphPtr);
+    }
+    Tcl_SetObjResult(interp, DisplayListObj(graphPtr));
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TypeOp --
+ *
+ *	Returns the name of the type of the element given by some
+ *	element name.
+ *
+ * Results:
+ *	A standard TCL result. Returns the type of the element in
+ *	interp->result. If the identifier given doesn't represent an
+ *	element, then an error message is left in interp->result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+TypeOp(
+    Graph *graphPtr,		/* Graph widget */
+    Tcl_Interp *interp,
+    int objc,			/* Not used. */
+    Tcl_Obj *const *objv)	/* Element name */
+{
+    Element *elemPtr;
+    const char *string;
+
+    if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) {
+	return TCL_ERROR;	/* Can't find named element */
+    }
+    switch (elemPtr->obj.classId) {
+    case CID_ELEM_BAR:		string = "bar";		break;
+    case CID_ELEM_LINE:		string = "line";	break;
+    default:			string = "???";		break;
+    }
+    Tcl_SetStringObj(Tcl_GetObjResult(interp), string, -1);
+    return TCL_OK;
+}
+
+/*
+ * Global routines:
+ */
+static Blt_OpSpec elemOps[] = {
+    {"activate",   1, ActivateOp,   3, 0, "?elemName? ?index...?",},
+    {"bind",       1, BindOp,       3, 6, "elemName sequence command",},
+    {"cget",       2, CgetOp,       5, 5, "elemName option",},
+    {"closest",    2, ClosestOp,    5, 0,
+	"x y ?option value?... ?elemName?...",},
+    {"configure",  2, ConfigureOp,  4, 0,
+	"elemName ?elemName?... ?option value?...",},
+    {"create",     2, CreateOp,     4, 0, "elemName ?option value?...",},
+    {"deactivate", 3, DeactivateOp, 3, 0, "?elemName?...",},
+    {"delete",     3, DeleteOp,     3, 0, "?elemName?...",},
+    {"exists",     1, ExistsOp,     4, 4, "elemName",},
+    {"get",        1, GetOp,        4, 4, "name",},
+    {"lower",      1, LowerOp,      3, 0, "?elemName?...",},
+    {"names",      1, NamesOp,      3, 0, "?pattern?...",},
+    {"raise",      1, RaiseOp,      3, 0, "?elemName?...",},
+    {"show",       1, ShowOp,       3, 4, "?elemList?",},
+    {"type",       1, TypeOp,       4, 4, "elemName",},
+};
+static int numElemOps = sizeof(elemOps) / sizeof(Blt_OpSpec);
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ElementOp --
+ *
+ *	This procedure is invoked to process the TCL command that
+ *	corresponds to a widget managed by this module.  See the user
+ *	documentation for details on what it does.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_ElementOp(
+    Graph *graphPtr,		/* Graph widget record */
+    Tcl_Interp *interp,
+    int objc,			/* # arguments */
+    Tcl_Obj *const *objv,	/* Argument list */
+    ClassId classId)
+{
+    void *ptr;
+    int result;
+
+    ptr = Blt_GetOpFromObj(interp, numElemOps, elemOps, BLT_OP_ARG2, 
+	objc, objv, 0);
+    if (ptr == NULL) {
+	return TCL_ERROR;
+    }
+    if (ptr == CreateOp) {
+	result = CreateOp(graphPtr, interp, objc, objv, classId);
+    } else {
+	GraphElementProc *proc;
+	
+	proc = ptr;
+	result = (*proc) (graphPtr, interp, objc, objv);
+    }
+    return result;
+}
diff --git a/tlt3.0/bltGrElem.h b/tlt3.0/bltGrElem.h
new file mode 100644
index 0000000..012e071
--- /dev/null
+++ b/tlt3.0/bltGrElem.h
@@ -0,0 +1,251 @@
+
+/*
+ * bltGrElem.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_GR_ELEM_H
+#define _BLT_GR_ELEM_H
+
+#include <bltVector.h>
+
+#define ELEM_SOURCE_VALUES	0
+#define ELEM_SOURCE_VECTOR	1
+
+#define SEARCH_X	0
+#define SEARCH_Y	1
+#define SEARCH_BOTH	2
+
+#define SHOW_NONE	0
+#define SHOW_X		1
+#define SHOW_Y		2
+#define SHOW_BOTH	3
+
+#define SEARCH_POINTS	0	/* Search for closest data point. */
+#define SEARCH_TRACES	1	/* Search for closest point on trace.
+				 * Interpolate the connecting line segments if
+				 * necessary. */
+#define SEARCH_AUTO	2	/* Automatically determine whether to search
+				 * for data points or traces.  Look for traces
+				 * if the linewidth is > 0 and if there is
+				 * more than one data point. */
+
+#define	LABEL_ACTIVE 	(1<<9)	/* Non-zero indicates that the element's entry
+				 * in the legend should be drawn in its active
+				 * foreground and background colors. */
+#define SCALE_SYMBOL	(1<<10)
+
+#define NUMBEROFPOINTS(e)	MIN((e)->x.nValues, (e)->y.nValues)
+
+#define NORMALPEN(e)		((((e)->normalPenPtr == NULL) ?  \
+				  (e)->builtinPenPtr :		 \
+				  (e)->normalPenPtr))
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Weight --
+ *
+ *	Designates a range of values by a minimum and maximum limit.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    double min, max, range;
+} Weight;
+
+#define SetRange(l) \
+	((l).range = ((l).max > (l).min) ? ((l).max - (l).min) : DBL_EPSILON)
+#define SetScale(l) \
+	((l).scale = 1.0 / (l).range)
+#define SetWeight(l, lo, hi) \
+	((l).min = (lo), (l).max = (hi), SetRange(l))
+
+typedef struct {
+    Segment2d *segments;	/* Point to start of this pen's X-error bar
+				 * segments in the element's array. */
+    int nSegments;
+} ErrorBarSegments;
+
+/* 
+ * An element has one or more vectors plus several attributes, such as line
+ * style, thickness, color, and symbol type.  It has an identifier which
+ * distinguishes it among the list of all elements.
+ */
+typedef struct {
+    Weight weight;		/* Weight range where this pen is valid. */
+    Pen *penPtr;		/* Pen to use. */
+} PenStyle;
+
+
+typedef struct {
+    XColor *color;		/* Color of error bar */
+    int lineWidth;		/* Width of the error bar segments. */
+    GC gc;
+    int show;			/* Flags for errorbars: none, x, y, or both */
+} ErrorBarAttributes;
+
+typedef struct {
+    /* Inputs */
+    int halo;			/* Maximal screen distance a candidate point
+				 * can be from the sample window coordinate */
+
+    int mode;			/* Indicates whether to find the closest data
+				 * point or the closest point on the trace by
+				 * interpolating the line segments.  Can also
+				 * be SEARCH_AUTO, indicating to choose how to
+				 * search.*/
+
+    int x, y;			/* Screen coordinates of test point */
+
+    int along;			/* Indicates to let search run along a
+				 * particular axis: x, y, or both. */
+
+    /* Outputs */
+    Element *elemPtr;		/* Name of the closest element */
+
+    Point2d point;		/* Graph coordinates of closest point */
+
+    int index;			/* Index of closest data point */
+
+    double dist;		/* Distance in screen coordinates */
+
+} ClosestSearch;
+
+typedef void (ElementDrawProc) (Graph *graphPtr, Drawable drawable, 
+	Element *elemPtr);
+
+typedef void (ElementToPostScriptProc) (Graph *graphPtr, Blt_Ps ps, 
+	Element *elemPtr);
+
+typedef void (ElementDestroyProc) (Graph *graphPtr, Element *elemPtr);
+
+typedef int (ElementConfigProc) (Graph *graphPtr, Element *elemPtr);
+
+typedef void (ElementMapProc) (Graph *graphPtr, Element *elemPtr);
+
+typedef void (ElementExtentsProc) (Element *elemPtr, Region2d *extsPtr);
+
+typedef void (ElementClosestProc) (Graph *graphPtr, Element *elemPtr, 
+	ClosestSearch *searchPtr);
+
+typedef void (ElementDrawSymbolProc) (Graph *graphPtr, Drawable drawable, 
+	Element *elemPtr, int x, int y, int symbolSize);
+
+typedef void (ElementSymbolToPostScriptProc) (Graph *graphPtr, 
+	Blt_Ps ps, Element *elemPtr, double x, double y, int symSize);
+
+typedef struct {
+    ElementClosestProc *closestProc;
+    ElementConfigProc *configProc;
+    ElementDestroyProc *destroyProc;
+    ElementDrawProc *drawActiveProc;
+    ElementDrawProc *drawNormalProc;
+    ElementDrawSymbolProc *drawSymbolProc;
+    ElementExtentsProc *extentsProc;
+    ElementToPostScriptProc *printActiveProc;
+    ElementToPostScriptProc *printNormalProc;
+    ElementSymbolToPostScriptProc *printSymbolProc;
+    ElementMapProc *mapProc;
+} ElementProcs;
+
+typedef struct {
+    Blt_VectorId vector;
+} VectorDataSource;
+
+/* 
+ * The data structure below contains information pertaining to a line vector.
+ * It consists of an array of floating point data values and for convenience,
+ * the number and minimum/maximum values.
+ */
+typedef struct {
+    int type;			/* Selects the type of data populating this
+				 * vector: ELEM_SOURCE_VECTOR,
+				 * ELEM_SOURCE_TABLE, or ELEM_SOURCE_VALUES
+				 */
+    Element *elemPtr;		/* Element associated with vector. */
+    VectorDataSource vectorSource;
+    double *values;
+    int nValues;
+    int arraySize;
+    double min, max;
+} ElemValues;
+
+
+struct _Element {
+    GraphObj obj;			/* Must be first field in element. */
+    unsigned int flags;		
+    Blt_HashEntry *hashPtr;
+
+    /* Fields specific to elements. */
+    const char *label;			/* Label displayed in legend */
+    unsigned short row, col;		/* Position of the entry in the
+					 * legend. */
+    int legendRelief;			/* Relief of label in legend. */
+    Axis2d axes;			/* X-axis and Y-axis mapping the
+					 * element */
+    ElemValues x, y, w;			/* Contains array of floating point
+					 * graph coordinate values. Also holds
+					 * min/max and the number of
+					 * coordinates */
+    int *activeIndices;			/* Array of indices (malloc-ed) which
+					 * indicate which data points are
+					 * active (drawn with "active"
+					 * colors). */
+    int nActiveIndices;			/* Number of active data points.
+					 * Special case: if nActiveIndices < 0
+					 * and the active bit is set in
+					 * "flags", then all data points are
+					 * drawn active. */
+    ElementProcs *procsPtr;
+    Blt_ConfigSpec *configSpecs;	/* Configuration specifications. */
+    Pen *activePenPtr;			/* Standard Pens */
+    Pen *normalPenPtr;
+    Pen *builtinPenPtr;
+    Blt_Chain stylePalette;		/* Palette of pens. */
+
+    /* Symbol scaling */
+    int scaleSymbols;			/* If non-zero, the symbols will scale
+					 * in size as the graph is zoomed
+					 * in/out.  */
+    double xRange, yRange;		/* Initial X-axis and Y-axis ranges:
+					 * used to scale the size of element's
+					 * symbol. */
+    int state;
+    Blt_ChainLink link;			/* Element's link in display list. */
+};
+
+
+extern double Blt_FindElemValuesMinimum(ElemValues *vecPtr, double minLimit);
+extern void Blt_ResizeStatusArray(Element *elemPtr, int nPoints);
+extern int Blt_GetPenStyle(Graph *graphPtr, char *name, size_t classId, 
+	PenStyle *stylePtr);
+extern void Blt_FreeStylePalette (Blt_Chain stylePalette);
+extern PenStyle **Blt_StyleMap (Element *elemPtr);
+extern void Blt_MapErrorBars(Graph *graphPtr, Element *elemPtr, 
+	PenStyle **dataToStyle);
+extern void Blt_FreeDataValues(ElemValues *evPtr);
+extern int Blt_GetElement(Tcl_Interp *interp, Graph *graphPtr, 
+	Tcl_Obj *objPtr, Element **elemPtrPtr);
+
+#endif /* _BLT_GR_ELEM_H */
diff --git a/tlt3.0/bltGrHairs.c b/tlt3.0/bltGrHairs.c
new file mode 100644
index 0000000..4f1994f
--- /dev/null
+++ b/tlt3.0/bltGrHairs.c
@@ -0,0 +1,535 @@
+
+/*
+ * bltGrHairs.c --
+ *
+ * This module implements crosshairs for the BLT graph widget.
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "bltInt.h"
+#include "bltGraph.h"
+#include "bltOp.h"
+
+typedef int (GraphCrosshairProc)(Graph *graphPtr, Tcl_Interp *interp, 
+	int objc, Tcl_Obj *const *objv);
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Crosshairs
+ *
+ *	Contains the line segments positions and graphics context used
+ *	to simulate crosshairs (by XORing) on the graph.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+struct _Crosshairs {
+
+    XPoint hotSpot;		/* Hot spot for crosshairs */
+    int visible;		/* Internal state of crosshairs. If non-zero,
+				 * crosshairs are displayed. */
+    int hidden;			/* If non-zero, crosshairs are not displayed.
+				 * This is not necessarily consistent with the
+				 * internal state variable.  This is true when
+				 * the hot spot is off the graph.  */
+    Blt_Dashes dashes;		/* Dashstyle of the crosshairs. This represents
+				 * an array of alternatingly drawn pixel
+				 * values. If NULL, the hairs are drawn as a
+				 * solid line */
+    int lineWidth;		/* Width of the simulated crosshair lines */
+    XSegment segArr[2];		/* Positions of line segments representing the
+				 * simulated crosshairs. */
+    XColor *colorPtr;		/* Foreground color of crosshairs */
+    GC gc;			/* Graphics context for crosshairs. Set to
+				 * GXxor to not require redraws of graph */
+};
+
+#define DEF_HAIRS_DASHES	(char *)NULL
+#define DEF_HAIRS_FOREGROUND	RGB_BLACK
+#define DEF_HAIRS_LINE_WIDTH	"0"
+#define DEF_HAIRS_HIDE		"yes"
+#define DEF_HAIRS_POSITION	(char *)NULL
+
+extern Blt_CustomOption bltPointOption;
+
+static Blt_ConfigSpec configSpecs[] =
+{
+    {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_HAIRS_FOREGROUND, 
+	Blt_Offset(Crosshairs, colorPtr), 0},
+    {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_HAIRS_DASHES, 
+	Blt_Offset(Crosshairs, dashes), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", DEF_HAIRS_HIDE, 
+	Blt_Offset(Crosshairs, hidden), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "Linewidth",
+	DEF_HAIRS_LINE_WIDTH, Blt_Offset(Crosshairs, lineWidth),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-position", "position", "Position", 
+	DEF_HAIRS_POSITION, Blt_Offset(Crosshairs, hotSpot), 0, &bltPointOption},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TurnOffHairs --
+ *
+ *	XOR's the existing line segments (representing the crosshairs),
+ *	thereby erasing them.  The internal state of the crosshairs is
+ *	tracked.
+ *
+ * Results:
+ *	None
+ *
+ * Side Effects:
+ *	Crosshairs are erased.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+TurnOffHairs(Tk_Window tkwin, Crosshairs *chPtr)
+{
+    if (Tk_IsMapped(tkwin) && (chPtr->visible)) {
+	XDrawSegments(Tk_Display(tkwin), Tk_WindowId(tkwin), chPtr->gc,
+	    chPtr->segArr, 2);
+	chPtr->visible = FALSE;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TurnOnHairs --
+ *
+ *	Draws (by XORing) new line segments, creating the effect of
+ *	crosshairs. The internal state of the crosshairs is tracked.
+ *
+ * Results:
+ *	None
+ *
+ * Side Effects:
+ *	Crosshairs are displayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+TurnOnHairs(Graph *graphPtr, Crosshairs *chPtr)
+{
+    if (Tk_IsMapped(graphPtr->tkwin) && (!chPtr->visible)) {
+	if (!PointInGraph(graphPtr, chPtr->hotSpot.x, chPtr->hotSpot.y)) {
+	    return;		/* Coordinates are off the graph */
+	}
+	XDrawSegments(graphPtr->display, Tk_WindowId(graphPtr->tkwin),
+	    chPtr->gc, chPtr->segArr, 2);
+	chPtr->visible = TRUE;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureCrosshairs --
+ *
+ *	Configures attributes of the crosshairs such as line width,
+ *	dashes, and position.  The crosshairs are first turned off
+ *	before any of the attributes changes.
+ *
+ * Results:
+ *	None
+ *
+ * Side Effects:
+ *	Crosshair GC is allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_ConfigureCrosshairs(Graph *graphPtr)
+{
+    XGCValues gcValues;
+    unsigned long gcMask;
+    GC newGC;
+    unsigned long int pixel;
+    Crosshairs *chPtr = graphPtr->crosshairs;
+
+    /*
+     * Turn off the crosshairs temporarily. This is in case the new
+     * configuration changes the size, style, or position of the lines.
+     */
+    TurnOffHairs(graphPtr->tkwin, chPtr);
+
+    gcValues.function = GXxor;
+
+    if (graphPtr->plotBg == NULL) {
+	/* The graph's color option may not have been set yet */
+	pixel = WhitePixelOfScreen(Tk_Screen(graphPtr->tkwin));
+    } else {
+	pixel = Blt_BackgroundBorderColor(graphPtr->plotBg)->pixel;
+    }
+    gcValues.background = pixel;
+    gcValues.foreground = (pixel ^ chPtr->colorPtr->pixel);
+
+    gcValues.line_width = LineWidth(chPtr->lineWidth);
+    gcMask = (GCForeground | GCBackground | GCFunction | GCLineWidth);
+    if (LineIsDashed(chPtr->dashes)) {
+	gcValues.line_style = LineOnOffDash;
+	gcMask |= GCLineStyle;
+    }
+    newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (LineIsDashed(chPtr->dashes)) {
+	Blt_SetDashes(graphPtr->display, newGC, &chPtr->dashes);
+    }
+    if (chPtr->gc != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, chPtr->gc);
+    }
+    chPtr->gc = newGC;
+
+    /*
+     * Are the new coordinates on the graph?
+     */
+    chPtr->segArr[0].x2 = chPtr->segArr[0].x1 = chPtr->hotSpot.x;
+    chPtr->segArr[0].y1 = graphPtr->bottom;
+    chPtr->segArr[0].y2 = graphPtr->top;
+    chPtr->segArr[1].y2 = chPtr->segArr[1].y1 = chPtr->hotSpot.y;
+    chPtr->segArr[1].x1 = graphPtr->left;
+    chPtr->segArr[1].x2 = graphPtr->right;
+
+    if (!chPtr->hidden) {
+	TurnOnHairs(graphPtr, chPtr);
+    }
+}
+
+void
+Blt_EnableCrosshairs(Graph *graphPtr)
+{
+    if (!graphPtr->crosshairs->hidden) {
+	TurnOnHairs(graphPtr, graphPtr->crosshairs);
+    }
+}
+
+void
+Blt_DisableCrosshairs(Graph *graphPtr)
+{
+    if (!graphPtr->crosshairs->hidden) {
+	TurnOffHairs(graphPtr->tkwin, graphPtr->crosshairs);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * UpdateCrosshairs --
+ *
+ *	Update the length of the hairs (not the hot spot).
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_UpdateCrosshairs(Graph *graphPtr)
+{
+    Crosshairs *chPtr = graphPtr->crosshairs;
+
+    chPtr->segArr[0].y1 = graphPtr->bottom;
+    chPtr->segArr[0].y2 = graphPtr->top;
+    chPtr->segArr[1].x1 = graphPtr->left;
+    chPtr->segArr[1].x2 = graphPtr->right;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DestroyCrosshairs --
+ *
+ * Results:
+ *	None
+ *
+ * Side Effects:
+ *	Crosshair GC is allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DestroyCrosshairs(Graph *graphPtr)
+{
+    if (graphPtr->crosshairs != NULL) {
+	Crosshairs *chPtr = graphPtr->crosshairs;
+
+	Blt_FreeOptions(configSpecs, (char *)chPtr, graphPtr->display, 0);
+	if (chPtr->gc != NULL) {
+	    Blt_FreePrivateGC(graphPtr->display, chPtr->gc);
+	}
+	free(chPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_CreateCrosshairs --
+ *
+ *	Creates and initializes a new crosshair structure.
+ *
+ * Results:
+ *	Returns TCL_ERROR if the crosshair structure can't be created,
+ *	otherwise TCL_OK.
+ *
+ * Side Effects:
+ *	Crosshair GC is allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_CreateCrosshairs(Graph *graphPtr)
+{
+    Crosshairs *chPtr;
+
+    chPtr = calloc(1, sizeof(Crosshairs));
+    chPtr->hidden = TRUE;
+    chPtr->hotSpot.x = chPtr->hotSpot.y = -1;
+    graphPtr->crosshairs = chPtr;
+
+    if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin,
+	    "crosshairs", "Crosshairs", configSpecs, 0, (Tcl_Obj **)NULL,
+	    (char *)chPtr, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CgetOp --
+ *
+ *	Queries configuration attributes of the crosshairs such as
+ *	line width, dashes, and position.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static int
+CgetOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,			/* Not used. */
+    Tcl_Obj *const *objv)
+{
+    Crosshairs *chPtr = graphPtr->crosshairs;
+
+    return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs,
+	    (char *)chPtr, objv[3], 0);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureOp --
+ *
+ *	Queries or resets configuration attributes of the crosshairs
+ * 	such as line width, dashes, and position.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Crosshairs are reset.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ConfigureOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Crosshairs *chPtr = graphPtr->crosshairs;
+
+    if (objc == 3) {
+	return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs,
+		(char *)chPtr, (Tcl_Obj *)NULL, 0);
+    } else if (objc == 4) {
+	return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs,
+		(char *)chPtr, objv[3], 0);
+    }
+    if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, 
+	objc - 3, objv + 3, (char *)chPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Blt_ConfigureCrosshairs(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * OnOp --
+ *
+ *	Maps the crosshairs.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Crosshairs are reset if necessary.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+OnOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,		/* Not used. */
+    int objc,			/* Not used. */
+    Tcl_Obj *const *objv)	/* Not used. */
+{
+    Crosshairs *chPtr = graphPtr->crosshairs;
+
+    if (chPtr->hidden) {
+	TurnOnHairs(graphPtr, chPtr);
+	chPtr->hidden = FALSE;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * OffOp --
+ *
+ *	Unmaps the crosshairs.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Crosshairs are reset if necessary.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+OffOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,		/* Not used. */
+    int objc,			/* Not used. */
+    Tcl_Obj *const *objv)	/* Not used. */
+{
+    Crosshairs *chPtr = graphPtr->crosshairs;
+
+    if (!chPtr->hidden) {
+	TurnOffHairs(graphPtr->tkwin, chPtr);
+	chPtr->hidden = TRUE;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ToggleOp --
+ *
+ *	Toggles the state of the crosshairs.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Crosshairs are reset.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ToggleOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,		/* Not used. */
+    int objc,			/* Not used. */
+    Tcl_Obj *const *objv)	/* Not used. */
+{
+    Crosshairs *chPtr = graphPtr->crosshairs;
+
+    chPtr->hidden = (chPtr->hidden == 0);
+    if (chPtr->hidden) {
+	TurnOffHairs(graphPtr->tkwin, chPtr);
+    } else {
+	TurnOnHairs(graphPtr, chPtr);
+    }
+    return TCL_OK;
+}
+
+
+static Blt_OpSpec xhairOps[] =
+{
+    {"cget", 2, CgetOp, 4, 4, "option",},
+    {"configure", 2, ConfigureOp, 3, 0, "?options...?",},
+    {"off", 2, OffOp, 3, 3, "",},
+    {"on", 2, OnOp, 3, 3, "",},
+    {"toggle", 1, ToggleOp, 3, 3, "",},
+};
+static int nXhairOps = sizeof(xhairOps) / sizeof(Blt_OpSpec);
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_CrosshairsOp --
+ *
+ *	User routine to configure crosshair simulation.  Crosshairs
+ *	are simulated by drawing line segments parallel to both axes
+ *	using the XOR drawing function. The allows the lines to be
+ *	erased (by drawing them again) without redrawing the entire
+ *	graph.  Care must be taken to erase crosshairs before redrawing
+ *	the graph and redraw them after the graph is redraw.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ * Side Effects:
+ *	Crosshairs may be drawn in the plotting area.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_CrosshairsOp(
+    Graph *graphPtr,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    GraphCrosshairProc *proc;
+
+    proc = Blt_GetOpFromObj(interp, nXhairOps, xhairOps, BLT_OP_ARG2, 
+	objc, objv, 0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    return (*proc) (graphPtr, interp, objc, objv);
+}
diff --git a/tlt3.0/bltGrLegd.c b/tlt3.0/bltGrLegd.c
new file mode 100644
index 0000000..c0f5b08
--- /dev/null
+++ b/tlt3.0/bltGrLegd.c
@@ -0,0 +1,2838 @@
+
+/*
+ * bltGrLegd.c --
+ *
+ * This module implements the legend for the BLT graph widget.
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#include "bltInt.h"
+#include "bltGraph.h"
+#include "bltOp.h"
+#include "bltGrElem.h"
+
+/*
+ *  Selection related flags:
+ *
+ *	SELECT_EXPORT		Export the selection to X11.
+ *
+ *	SELECT_PENDING		A "selection" command idle task is pending.
+ *
+ *	SELECT_CLEAR		Clear selection flag of entry.
+ *
+ *	SELECT_SET		Set selection flag of entry.
+ *
+ *	SELECT_TOGGLE		Toggle selection flag of entry.
+ *
+ *	SELECT_BLTMASK		Mask of selection set/clear/toggle flags.
+ *
+ *	SELECT_SORTED		Indicates if the entries in the selection 
+ *				should be sorted or displayed in the order 
+ *				they were selected.
+ *
+ */
+
+#define SELECT_CLEAR		(1<<16)
+#define SELECT_EXPORT		(1<<17) 
+#define SELECT_PENDING		(1<<18)
+#define SELECT_SET		(1<<19)
+#define SELECT_TOGGLE		(SELECT_SET | SELECT_CLEAR)
+#define SELECT_BLTMASK		(SELECT_SET | SELECT_CLEAR)
+#define SELECT_SORTED		(1<<20)
+
+#define RAISED			(1<<21)
+
+#define SELECT_MODE_SINGLE	(1<<0)
+#define SELECT_MODE_MULTIPLE	(1<<1)
+
+typedef int (GraphLegendProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+/*
+ * Legend --
+ *
+ * 	Contains information specific to how the legend will be displayed.
+ */
+struct _Legend {
+    unsigned int flags;
+    ClassId classId;			/* Type: Element or Marker. */
+
+    int nEntries;			/* Number of element entries in
+					 * table. */
+    short int nColumns, nRows;	        /* Number of columns and rows in
+					 * legend */
+    short int width, height;		/* Dimensions of the legend */
+    short int entryWidth, entryHeight;
+
+    int site;
+    short int xReq, yReq;		/* User-requested site of legend, not
+					 * the final actual position. Used in
+					 * conjunction with the anchor below
+					 * to determine location of the
+					 * legend. */
+
+    Tk_Anchor anchor;			/* Anchor of legend. Used to interpret
+					 * the positioning point of the legend
+					 * in the graph*/
+
+    int x, y;				/* Computed origin of legend. */
+
+    Graph *graphPtr;
+    Tcl_Command cmdToken;		/* Token for graph's widget command. */
+    int reqColumns, reqRows;
+
+    Blt_Pad ixPad, iyPad;		/* # of pixels interior padding around
+					 * legend entries */
+    Blt_Pad xPad, yPad;			/* # of pixels padding to exterior of
+					 * legend */
+    Tk_Window tkwin;			/* If non-NULL, external window to draw
+					 * legend. */
+    TextStyle style;
+
+    int maxSymSize;			/* Size of largest symbol to be
+					 * displayed.  Used to calculate size
+					 * of legend */
+    XColor *fgColor;
+    Blt_Background activeBg;		/* Active legend entry background
+					 * color. */
+    XColor *activeFgColor;
+    int activeRelief;			/* 3-D effect on active entry. */
+    int entryBW;		/* Border width around each entry in
+					 * legend. */
+    Blt_Background normalBg;		/* 3-D effect of legend. */
+    int borderWidth;			/* Width of legend 3-D border */
+    int relief;				/* 3-d effect of border around the
+					 * legend: TK_RELIEF_RAISED etc. */
+
+    Blt_BindTable bindTable;
+
+    int selRelief;
+    int selBW;
+
+    XColor *selInFocusFgColor;		/* Text color of a selected entry. */
+    XColor *selOutFocusFgColor;
+
+    Blt_Background selInFocusBg;
+    Blt_Background selOutFocusBg;
+
+    XColor *focusColor;
+    Blt_Dashes focusDashes;		/* Dash on-off value. */
+    GC focusGC;				/* Graphics context for the active
+					 * label. */
+
+    const char *takeFocus;
+    int focus;				/* Position of the focus entry. */
+
+    int cursorX, cursorY;		/* Position of the insertion cursor in
+					 * the textbox window. */
+    short int cursorWidth;		/* Size of the insertion cursor
+					 * symbol. */
+    short int cursorHeight;
+    Element *focusPtr;			/* Element that currently has the
+					 * focus. If NULL, no legend entry has
+					 * the focus. */
+    Element *selAnchorPtr;		/* Fixed end of selection. Used to
+					 * extend the selection while
+					 * maintaining the other end of the
+					 * selection. */
+    Element *selMarkPtr;
+    Element *selFirstPtr;		/* First element selected in current
+					 * pick. */
+    Element *selLastPtr;		/* Last element selected in current
+					 * pick. */
+    int exportSelection;
+    int active;
+    int cursorOn;			/* Indicates if the cursor is
+					 * displayed. */
+    int onTime, offTime;		/* Time in milliseconds to wait before
+					 * changing the cursor from off-to-on
+					 * and on-to-off. Setting offTime to 0
+					 * makes the * cursor steady. */
+    Tcl_TimerToken timerToken;		/* Handle for a timer event called
+					 * periodically to blink the cursor. */
+    const char *selectCmd;		/* TCL script that's invoked whenever
+					 * the selection changes. */
+    int selectMode;			/* Mode of selection: single or
+					 * multiple. */
+    Blt_HashTable selectTable;		/* Table of selected elements. Used to
+					 * quickly determine whether an element
+					 * is selected. */
+    Blt_Chain selected;			/* List of selected elements. */
+
+    const char *title;
+    unsigned int titleWidth, titleHeight;
+    TextStyle titleStyle;		/* Legend title attributes */
+};
+
+#define padLeft  	xPad.side1
+#define padRight  	xPad.side2
+#define padTop		yPad.side1
+#define padBottom	yPad.side2
+#define PADDING(x)	((x).side1 + (x).side2)
+#define LABEL_PAD	2
+
+#define DEF_LEGEND_ACTIVEBACKGROUND 	RGB_SKYBLUE4
+#define DEF_LEGEND_ACTIVEBORDERWIDTH    "2"
+#define DEF_LEGEND_ACTIVEFOREGROUND	RGB_WHITE
+#define DEF_LEGEND_ACTIVERELIEF		"flat"
+#define DEF_LEGEND_ANCHOR	   	"n"
+#define DEF_LEGEND_BACKGROUND	   	(char *)NULL
+#define DEF_LEGEND_BORDERWIDTH		STD_BORDERWIDTH
+#define DEF_LEGEND_COLUMNS		"0"
+#define DEF_LEGEND_EXPORTSELECTION	"no"
+#define DEF_LEGEND_FONT			"{Sans Serif} 8"
+#define DEF_LEGEND_FOREGROUND		STD_NORMAL_FOREGROUND
+#define DEF_LEGEND_HIDE			"no"
+#define DEF_LEGEND_IPADX		"1"
+#define DEF_LEGEND_IPADY		"1"
+#define DEF_LEGEND_PADX			"1"
+#define DEF_LEGEND_PADY			"1"
+#define DEF_LEGEND_POSITION		"rightmargin"
+#define DEF_LEGEND_RAISED       	"no"
+#define DEF_LEGEND_RELIEF		"flat"
+#define DEF_LEGEND_ROWS			"0"
+#define DEF_LEGEND_SELECTBACKGROUND 	RGB_SKYBLUE4
+#define DEF_LEGEND_SELECT_BG_MONO  	STD_SELECT_BG_MONO
+#define DEF_LEGEND_SELECTBORDERWIDTH	"1"
+#define DEF_LEGEND_SELECTMODE		"multiple"
+#define DEF_LEGEND_SELECT_FG_MONO  	STD_SELECT_FG_MONO
+#define DEF_LEGEND_SELECTFOREGROUND 	RGB_WHITE /*STD_SELECT_FOREGROUND*/
+#define DEF_LEGEND_SELECTRELIEF		"flat"
+#define DEF_LEGEND_FOCUSDASHES		"dot"
+#define DEF_LEGEND_FOCUSEDIT		"no"
+#define DEF_LEGEND_FOCUSFOREGROUND	STD_ACTIVE_FOREGROUND
+#define DEF_LEGEND_FOCUS_FG_MONO	STD_ACTIVE_FG_MONO
+#define DEF_LEGEND_TAKEFOCUS		"1"
+#define DEF_LEGEND_TITLE		(char *)NULL
+#define	DEF_LEGEND_TITLECOLOR		STD_NORMAL_FOREGROUND
+#define DEF_LEGEND_TITLEFONT		"{Sans Serif} 8 bold"
+
+static Blt_OptionParseProc ObjToPosition;
+static Blt_OptionPrintProc PositionToObj;
+static Blt_CustomOption legendPositionOption =
+{
+    ObjToPosition, PositionToObj, NULL, (ClientData)0
+};
+
+static Blt_OptionParseProc ObjToSelectmode;
+static Blt_OptionPrintProc SelectmodeToObj;
+static Blt_CustomOption selectmodeOption = {
+    ObjToSelectmode, SelectmodeToObj, NULL, NULL,
+};
+
+static Blt_ConfigSpec configSpecs[] =
+{
+    {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground",
+	"ActiveBackground", DEF_LEGEND_ACTIVEBACKGROUND, 
+	Blt_Offset(Legend, activeBg), 0},
+    {BLT_CONFIG_PIXELS_NNEG, "-activeborderwidth", "activeBorderWidth",
+	"BorderWidth", DEF_LEGEND_BORDERWIDTH, 
+	Blt_Offset(Legend, entryBW), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground",
+	"ActiveForeground", DEF_LEGEND_ACTIVEFOREGROUND,
+	Blt_Offset(Legend, activeFgColor), 0},
+    {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief",
+	DEF_LEGEND_ACTIVERELIEF, Blt_Offset(Legend, activeRelief),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_LEGEND_ANCHOR, 
+	Blt_Offset(Legend, anchor), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_BACKGROUND, "-background", "background", "Background",
+	DEF_LEGEND_BACKGROUND, Blt_Offset(Legend, normalBg),BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth",
+	DEF_LEGEND_BORDERWIDTH, Blt_Offset(Legend, borderWidth),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0},
+    {BLT_CONFIG_INT_NNEG, "-columns", "columns", "columns",
+	DEF_LEGEND_COLUMNS, Blt_Offset(Legend, reqColumns),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMASK, "-exportselection", "exportSelection",
+	"ExportSelection", DEF_LEGEND_EXPORTSELECTION, 
+	Blt_Offset(Legend, flags), BLT_CONFIG_DONT_SET_DEFAULT, 
+	(Blt_CustomOption *)SELECT_EXPORT},
+    {BLT_CONFIG_DASHES, "-focusdashes", "focusDashes", "FocusDashes",
+	DEF_LEGEND_FOCUSDASHES, Blt_Offset(Legend, focusDashes), 
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_COLOR, "-focusforeground", "focusForeground", "FocusForeground",
+	DEF_LEGEND_FOCUSFOREGROUND, Blt_Offset(Legend, focusColor),
+	BLT_CONFIG_COLOR_ONLY},
+    {BLT_CONFIG_COLOR, "-focusforeground", "focusForeground", "FocusForeground",
+	DEF_LEGEND_FOCUS_FG_MONO, Blt_Offset(Legend, focusColor),
+	BLT_CONFIG_MONO_ONLY},
+    {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_LEGEND_FONT, 
+	Blt_Offset(Legend, style.font), 0},
+    {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
+	DEF_LEGEND_FOREGROUND, Blt_Offset(Legend, fgColor), 0},
+    {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_LEGEND_HIDE, 
+	Blt_Offset(Legend, flags), BLT_CONFIG_DONT_SET_DEFAULT, 
+	(Blt_CustomOption *)HIDE},
+    {BLT_CONFIG_PAD, "-ipadx", "iPadX", "Pad", DEF_LEGEND_IPADX, 
+	Blt_Offset(Legend, ixPad), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PAD, "-ipady", "iPadY", "Pad", DEF_LEGEND_IPADY, 
+	Blt_Offset(Legend, iyPad), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BACKGROUND, "-nofocusselectbackground", 
+	"noFocusSelectBackground", "NoFocusSelectBackground", 
+	DEF_LEGEND_SELECTBACKGROUND, Blt_Offset(Legend, selOutFocusBg), 0},
+    {BLT_CONFIG_COLOR, "-nofocusselectforeground", "noFocusSelectForeground", 
+	"NoFocusSelectForeground", DEF_LEGEND_SELECTFOREGROUND, 
+	Blt_Offset(Legend, selOutFocusFgColor), 0},
+    {BLT_CONFIG_PAD, "-padx", "padX", "Pad", DEF_LEGEND_PADX, 
+	Blt_Offset(Legend, xPad), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PAD, "-pady", "padY", "Pad", DEF_LEGEND_PADY, 
+	Blt_Offset(Legend, yPad), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-position", "position", "Position", 
+	DEF_LEGEND_POSITION, 0, BLT_CONFIG_DONT_SET_DEFAULT, 
+        &legendPositionOption},
+    {BLT_CONFIG_BITMASK, "-raised", "raised", "Raised", DEF_LEGEND_RAISED, 
+	Blt_Offset(Legend, flags), BLT_CONFIG_DONT_SET_DEFAULT,
+	(Blt_CustomOption *)RAISED},
+    {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_LEGEND_RELIEF, 
+	Blt_Offset(Legend, relief), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_INT_NNEG, "-rows", "rows", "rows", DEF_LEGEND_ROWS, 
+	Blt_Offset(Legend, reqRows),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", 
+	"Background", DEF_LEGEND_SELECTBACKGROUND, 
+	Blt_Offset(Legend, selInFocusBg), 0},
+    {BLT_CONFIG_PIXELS_NNEG, "-selectborderwidth", "selectBorderWidth", 
+        "BorderWidth", DEF_LEGEND_SELECTBORDERWIDTH, 
+	Blt_Offset(Legend, selBW), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-selectcommand", "selectCommand", "SelectCommand",
+	(char *)NULL, Blt_Offset(Legend, selectCmd), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Foreground",
+	DEF_LEGEND_SELECT_FG_MONO, Blt_Offset(Legend, selInFocusFgColor),
+	BLT_CONFIG_MONO_ONLY},
+    {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Foreground",
+	DEF_LEGEND_SELECTFOREGROUND, Blt_Offset(Legend, selInFocusFgColor),
+	BLT_CONFIG_COLOR_ONLY},
+    {BLT_CONFIG_CUSTOM, "-selectmode", "selectMode", "SelectMode",
+	DEF_LEGEND_SELECTMODE, Blt_Offset(Legend, selectMode),
+	BLT_CONFIG_DONT_SET_DEFAULT, &selectmodeOption},
+    {BLT_CONFIG_RELIEF, "-selectrelief", "selectRelief", "Relief",
+	DEF_LEGEND_SELECTRELIEF, Blt_Offset(Legend, selRelief),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
+	DEF_LEGEND_TAKEFOCUS, Blt_Offset(Legend, takeFocus), 
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_STRING, "-title", "title", "Title", DEF_LEGEND_TITLE, 
+	Blt_Offset(Legend, title), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_COLOR, "-titlecolor", "titleColor", "Foreground",
+	DEF_LEGEND_TITLECOLOR, Blt_Offset(Legend, titleStyle.color), 0},
+    {BLT_CONFIG_FONT, "-titlefont", "titleFont", "Font",
+	DEF_LEGEND_TITLEFONT, Blt_Offset(Legend, titleStyle.font), 0},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+static Tcl_IdleProc DisplayLegend;
+static Blt_BindPickProc PickEntryProc;
+static Tk_EventProc LegendEventProc;
+static Tcl_TimerProc BlinkCursorProc;
+static Tk_LostSelProc LostSelectionProc;
+static Tk_SelectionProc SelectionProc;
+
+extern Tcl_ObjCmdProc Blt_GraphInstCmdProc;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Legend_EventuallyRedraw --
+ *
+ *	Tells the Tk dispatcher to call the graph display routine at the next
+ *	idle point.  This request is made only if the window is displayed and
+ *	no other redraw request is pending.
+ *
+ * Results: None.
+ *
+ * Side effects:
+ *	The window is eventually redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Legend_EventuallyRedraw(Graph *graphPtr) 
+{
+    Legend *legendPtr = graphPtr->legend;
+
+    if ((legendPtr->tkwin != NULL) && !(legendPtr->flags & REDRAW_PENDING)) {
+	Tcl_DoWhenIdle(DisplayLegend, legendPtr);
+	legendPtr->flags |= REDRAW_PENDING;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectCmdProc --
+ *
+ *      Invoked at the next idle point whenever the current selection changes.
+ *      Executes some application-specific code in the -selectcommand option.
+ *      This provides a way for applications to handle selection changes.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      TCL code gets executed for some application-specific task.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+SelectCmdProc(ClientData clientData) 
+{
+    Legend *legendPtr = clientData;
+
+    Tcl_Preserve(legendPtr);
+    legendPtr->flags &= ~SELECT_PENDING;
+    if (legendPtr->selectCmd != NULL) {
+	Tcl_Interp *interp;
+
+	interp = legendPtr->graphPtr->interp;
+	if (Tcl_GlobalEval(interp, legendPtr->selectCmd) != TCL_OK) {
+	    Tcl_BackgroundError(interp);
+	}
+    }
+    Tcl_Release(legendPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * EventuallyInvokeSelectCmd --
+ *
+ *      Queues a request to execute the -selectcommand code associated with
+ *      the widget at the next idle point.  Invoked whenever the selection
+ *      changes.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      TCL code gets executed for some application-specific task.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+EventuallyInvokeSelectCmd(Legend *legendPtr)
+{
+    if ((legendPtr->flags & SELECT_PENDING) == 0) {
+	legendPtr->flags |= SELECT_PENDING;
+	Tcl_DoWhenIdle(SelectCmdProc, legendPtr);
+    }
+}
+
+static void
+ClearSelection(Legend *legendPtr)
+{
+    Blt_DeleteHashTable(&legendPtr->selectTable);
+    Blt_InitHashTable(&legendPtr->selectTable, BLT_ONE_WORD_KEYS);
+    Blt_Chain_Reset(legendPtr->selected);
+    Blt_Legend_EventuallyRedraw(legendPtr->graphPtr);
+    if (legendPtr->selectCmd != NULL) {
+	EventuallyInvokeSelectCmd(legendPtr);
+    }
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LostSelectionProc --
+ *
+ *	This procedure is called back by Tk when the selection is grabbed away
+ *	from a Text widget.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The existing selection is unhighlighted, and the window is marked as
+ *	not containing a selection.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+LostSelectionProc(ClientData clientData)
+{
+    Legend *legendPtr = clientData;
+
+    if (legendPtr->flags & SELECT_EXPORT) {
+	ClearSelection(legendPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LegendEventProc --
+ *
+ *	This procedure is invoked by the Tk dispatcher for various events on
+ *	graphs.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	When the window gets deleted, internal structures get cleaned up.
+ *	When it gets exposed, the graph is eventually redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+LegendEventProc(ClientData clientData, XEvent *eventPtr)
+{
+    Graph *graphPtr = clientData;
+    Legend *legendPtr;
+
+    legendPtr = graphPtr->legend;
+    if (eventPtr->type == Expose) {
+	if (eventPtr->xexpose.count == 0) {
+	    Blt_Legend_EventuallyRedraw(graphPtr);
+	}
+    } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) {
+	if (eventPtr->xfocus.detail == NotifyInferior) {
+	    return;
+	}
+	if (eventPtr->type == FocusIn) {
+	    legendPtr->flags |= FOCUS;
+	} else {
+	    legendPtr->flags &= ~FOCUS;
+	}
+	Tcl_DeleteTimerHandler(legendPtr->timerToken);
+	if ((legendPtr->active) && (legendPtr->flags & FOCUS)) {
+	    legendPtr->cursorOn = TRUE;
+	    if (legendPtr->offTime != 0) {
+		legendPtr->timerToken = Tcl_CreateTimerHandler(
+			legendPtr->onTime, BlinkCursorProc, graphPtr);
+	    }
+	} else {
+	    legendPtr->cursorOn = FALSE;
+	    legendPtr->timerToken = (Tcl_TimerToken)NULL;
+	}
+	Blt_Legend_EventuallyRedraw(graphPtr);
+    } else if (eventPtr->type == DestroyNotify) {
+	Graph *graphPtr = legendPtr->graphPtr;
+
+	if (legendPtr->site == LEGEND_WINDOW) {
+	    if (legendPtr->cmdToken != NULL) {
+		Tcl_DeleteCommandFromToken(graphPtr->interp, 
+					   legendPtr->cmdToken);
+		legendPtr->cmdToken = NULL;
+	    }
+	    legendPtr->tkwin = graphPtr->tkwin;
+	}
+	if (legendPtr->flags & REDRAW_PENDING) {
+	    Tcl_CancelIdleCall(DisplayLegend, legendPtr);
+	    legendPtr->flags &= ~REDRAW_PENDING;
+	}
+	legendPtr->site = LEGEND_RIGHT;
+	legendPtr->flags |= HIDE;
+	graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD);
+	Blt_MoveBindingTable(legendPtr->bindTable, graphPtr->tkwin);
+	Blt_EventuallyRedrawGraph(graphPtr);
+    } else if (eventPtr->type == ConfigureNotify) {
+	Blt_Legend_EventuallyRedraw(graphPtr);
+    }
+}
+
+static int
+CreateLegendWindow(Tcl_Interp *interp, Legend *legendPtr, const char *pathName)
+{
+    Graph *graphPtr;
+    Tk_Window tkwin;
+
+    graphPtr = legendPtr->graphPtr;
+    tkwin = Tk_CreateWindowFromPath(interp, graphPtr->tkwin, pathName, NULL);
+    if (tkwin == NULL) {
+	return TCL_ERROR;
+    }
+    Blt_SetWindowInstanceData(tkwin, legendPtr);
+    Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask,
+	  LegendEventProc, graphPtr);
+    /* Move the legend's binding table to the new window. */
+    Blt_MoveBindingTable(legendPtr->bindTable, tkwin);
+    if (legendPtr->tkwin != graphPtr->tkwin) {
+	Tk_DestroyWindow(legendPtr->tkwin);
+    }
+    /* Create a command by the same name as the legend window so that Legend
+     * bindings can use %W interchangably.  */
+    legendPtr->cmdToken = Tcl_CreateObjCommand(interp, pathName, 
+	Blt_GraphInstCmdProc, graphPtr, NULL);
+    legendPtr->tkwin = tkwin;
+    legendPtr->site = LEGEND_WINDOW;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToPosition --
+ *
+ *	Convert the string representation of a legend XY position into window
+ *	coordinates.  The form of the string must be "@x,y" or none.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The symbol type is written
+ *	into the widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToPosition(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Interpreter to send results back
+					 * to */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* New legend position string */
+    char *widgRec,			/* Widget record */
+    int offset,				/* Not used. */
+    int flags)				/* Not used. */
+{
+    Graph *graphPtr;
+    Legend *legendPtr = (Legend *)widgRec;
+    char c;
+    int length;
+    const char *string;
+
+    graphPtr = legendPtr->graphPtr;
+    string = Tcl_GetStringFromObj(objPtr, &length);
+    c = string[0];
+    if (c == '\0') {
+	legendPtr->site = LEGEND_RIGHT;
+    } else if ((c == 'l') && (strncmp(string, "leftmargin", length) == 0)) {
+	legendPtr->site = LEGEND_LEFT;
+    } else if ((c == 'r') && (strncmp(string, "rightmargin", length) == 0)) {
+	legendPtr->site = LEGEND_RIGHT;
+    } else if ((c == 't') && (strncmp(string, "topmargin", length) == 0)) {
+	legendPtr->site = LEGEND_TOP;
+    } else if ((c == 'b') && (strncmp(string, "bottommargin", length) == 0)) {
+	legendPtr->site = LEGEND_BOTTOM;
+    } else if ((c == 'p') && (strncmp(string, "plotarea", length) == 0)) {
+	legendPtr->site = LEGEND_PLOT;
+    } else if (c == '@') {
+	char *comma;
+	long x, y;
+	int result;
+	
+	comma = strchr(string + 1, ',');
+	if (comma == NULL) {
+	    Tcl_AppendResult(interp, "bad screen position \"", string,
+			     "\": should be @x,y", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	x = y = 0;
+	*comma = '\0';
+	result = ((Tcl_ExprLong(interp, string + 1, &x) == TCL_OK) &&
+		  (Tcl_ExprLong(interp, comma + 1, &y) == TCL_OK));
+	*comma = ',';
+	if (!result) {
+	    return TCL_ERROR;
+	}
+	legendPtr->xReq = x;
+	legendPtr->yReq = y;
+	legendPtr->site = LEGEND_XY;
+    } else if (c == '.') {
+	if (CreateLegendWindow(interp, legendPtr, string) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	Blt_Legend_EventuallyRedraw(graphPtr);
+    } else {
+	Tcl_AppendResult(interp, "bad position \"", string, "\": should be  \
+\"leftmargin\", \"rightmargin\", \"topmargin\", \"bottommargin\", \
+\"plotarea\", windowName or @x,y", (char *)NULL);
+	return TCL_ERROR;
+    }
+    graphPtr->flags |= RESET_WORLD;
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PositionToObj --
+ *
+ *	Convert the window coordinates into a string.
+ *
+ * Results:
+ *	The string representing the coordinate position is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+PositionToObj(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Not used. */
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* Widget record */
+    int offset,				/* Not used. */
+    int flags)				/* Not used. */
+{
+    Legend *legendPtr = (Legend *)widgRec;
+    Tcl_Obj *objPtr;
+
+    switch (legendPtr->site) {
+    case LEGEND_LEFT:
+	objPtr = Tcl_NewStringObj("leftmargin", -1);
+	break;
+
+    case LEGEND_RIGHT:
+	objPtr = Tcl_NewStringObj("rightmargin", -1);
+	break;
+
+    case LEGEND_TOP:
+	objPtr = Tcl_NewStringObj("topmargin", -1);
+	break;
+
+    case LEGEND_BOTTOM:
+	objPtr = Tcl_NewStringObj("bottommargin", -1);
+	break;
+
+    case LEGEND_PLOT:
+	objPtr = Tcl_NewStringObj("plotarea", -1);
+	break;
+
+    case LEGEND_WINDOW:
+	objPtr = Tcl_NewStringObj(Tk_PathName(legendPtr->tkwin), -1);
+	break;
+
+    case LEGEND_XY:
+	{
+	    char string[200];
+
+	    sprintf_s(string, 200, "@%d,%d", legendPtr->xReq, legendPtr->yReq);
+	    objPtr = Tcl_NewStringObj(string, -1);
+	}
+    default:
+	objPtr = Tcl_NewStringObj("unknown legend position", -1);
+    }
+    return objPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToSelectmode --
+ *
+ *	Convert the string reprsenting a select mode, to its numeric form.
+ *
+ * Results:
+ *	If the string is successfully converted, TCL_OK is returned.
+ *	Otherwise, TCL_ERROR is returned and an error message is left
+ *	in interpreter's result field.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToSelectmode(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tk_Window tkwin,		/* Not used. */
+    Tcl_Obj *objPtr,		/* Tcl_Obj representing the new value. */
+    char *widgRec,
+    int offset,			/* Offset to field in structure */
+    int flags)	
+{
+    char *string;
+    char c;
+    int *modePtr = (int *)(widgRec + offset);
+
+    string = Tcl_GetString(objPtr);
+    c = string[0];
+    if ((c == 's') && (strcmp(string, "single") == 0)) {
+	*modePtr = SELECT_MODE_SINGLE;
+    } else if ((c == 'm') && (strcmp(string, "multiple") == 0)) {
+	*modePtr = SELECT_MODE_MULTIPLE;
+    } else if ((c == 'a') && (strcmp(string, "active") == 0)) {
+	*modePtr = SELECT_MODE_SINGLE;
+    } else {
+	Tcl_AppendResult(interp, "bad select mode \"", string,
+	    "\": should be \"single\" or \"multiple\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectmodeToObj --
+ *
+ * Results:
+ *	The string representation of the select mode is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+SelectmodeToObj(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,
+    int offset,				/* Offset to field in structure */
+    int flags)	
+{
+    int mode = *(int *)(widgRec + offset);
+
+    switch (mode) {
+    case SELECT_MODE_SINGLE:
+	return Tcl_NewStringObj("single", -1);
+    case SELECT_MODE_MULTIPLE:
+	return Tcl_NewStringObj("multiple", -1);
+    default:
+	return Tcl_NewStringObj("unknown scroll mode", -1);
+    }
+}
+
+
+static void
+SetLegendOrigin(Legend *legendPtr)
+{
+    Graph *graphPtr;
+    int x, y, w, h;
+
+    graphPtr = legendPtr->graphPtr;
+    x = y = w = h = 0;			/* Suppress compiler warning. */
+    switch (legendPtr->site) {
+    case LEGEND_RIGHT:
+	w = graphPtr->rightMargin.width - graphPtr->rightMargin.axesOffset;
+	h = graphPtr->bottom - graphPtr->top;
+	x = graphPtr->right + graphPtr->rightMargin.axesOffset;
+	y = graphPtr->top;
+	break;
+
+    case LEGEND_LEFT:
+	w = graphPtr->leftMargin.width - graphPtr->leftMargin.axesOffset;
+	h = graphPtr->bottom - graphPtr->top;
+	x = graphPtr->inset;
+	y = graphPtr->top;
+	break;
+
+    case LEGEND_TOP:
+	w = graphPtr->right - graphPtr->left;
+	h = graphPtr->topMargin.height - graphPtr->topMargin.axesOffset;
+	if (graphPtr->title != NULL) {
+	    h -= graphPtr->titleHeight;
+	}
+	x = graphPtr->left;
+	y = graphPtr->inset;
+	if (graphPtr->title != NULL) {
+	    y += graphPtr->titleHeight;
+	}
+	break;
+
+    case LEGEND_BOTTOM:
+	w = graphPtr->right - graphPtr->left;
+	h = graphPtr->bottomMargin.height - graphPtr->bottomMargin.axesOffset;
+	x = graphPtr->left;
+	y = graphPtr->bottom + graphPtr->bottomMargin.axesOffset;
+	break;
+
+    case LEGEND_PLOT:
+	w = graphPtr->right - graphPtr->left;
+	h = graphPtr->bottom - graphPtr->top;
+	x = graphPtr->left;
+	y = graphPtr->top;
+	break;
+
+    case LEGEND_XY:
+	w = legendPtr->width;
+	h = legendPtr->height;
+	x = legendPtr->xReq;
+	y = legendPtr->yReq;
+	if (x < 0) {
+	    x += graphPtr->width;
+	}
+	if (y < 0) {
+	    y += graphPtr->height;
+	}
+	break;
+
+    case LEGEND_WINDOW:
+	legendPtr->anchor = TK_ANCHOR_NW;
+	legendPtr->x = legendPtr->y = 0;
+	return;
+    }
+
+    switch (legendPtr->anchor) {
+    case TK_ANCHOR_NW:			/* Upper left corner */
+	break;
+    case TK_ANCHOR_W:			/* Left center */
+	if (h > legendPtr->height) {
+	    y += (h - legendPtr->height) / 2;
+	}
+	break;
+    case TK_ANCHOR_SW:			/* Lower left corner */
+	if (h > legendPtr->height) {
+	    y += (h - legendPtr->height);
+	}
+	break;
+    case TK_ANCHOR_N:			/* Top center */
+	if (w > legendPtr->width) {
+	    x += (w - legendPtr->width) / 2;
+	}
+	break;
+    case TK_ANCHOR_CENTER:		/* Center */
+	if (h > legendPtr->height) {
+	    y += (h - legendPtr->height) / 2;
+	}
+	if (w > legendPtr->width) {
+	    x += (w - legendPtr->width) / 2;
+	}
+	break;
+    case TK_ANCHOR_S:			/* Bottom center */
+	if (w > legendPtr->width) {
+	    x += (w - legendPtr->width) / 2;
+	}
+	if (h > legendPtr->height) {
+	    y += (h - legendPtr->height);
+	}
+	break;
+    case TK_ANCHOR_NE:			/* Upper right corner */
+	if (w > legendPtr->width) {
+	    x += w - legendPtr->width;
+	}
+	break;
+    case TK_ANCHOR_E:			/* Right center */
+	if (w > legendPtr->width) {
+	    x += w - legendPtr->width;
+	}
+	if (h > legendPtr->height) {
+	    y += (h - legendPtr->height) / 2;
+	}
+	break;
+    case TK_ANCHOR_SE:		/* Lower right corner */
+	if (w > legendPtr->width) {
+	    x += w - legendPtr->width;
+	}
+	if (h > legendPtr->height) {
+	    y += (h - legendPtr->height);
+	}
+	break;
+    }
+    legendPtr->x = x + legendPtr->padLeft;
+    legendPtr->y = y + legendPtr->padTop;
+}
+
+static int
+EntryIsSelected(Legend *legendPtr, Element *elemPtr)
+{
+    Blt_HashEntry *hPtr;
+
+    hPtr = Blt_FindHashEntry(&legendPtr->selectTable, (char *)elemPtr);
+    return (hPtr != NULL);
+}
+
+static void
+SelectElement(Legend *legendPtr, Element *elemPtr)
+{
+    int isNew;
+    Blt_HashEntry *hPtr;
+
+    hPtr = Blt_CreateHashEntry(&legendPtr->selectTable, (char *)elemPtr,&isNew);
+    if (isNew) {
+	Blt_ChainLink link;
+
+	link = Blt_Chain_Append(legendPtr->selected, elemPtr);
+	Blt_SetHashValue(hPtr, link);
+    }
+}
+
+static void
+DeselectElement(Legend *legendPtr, Element *elemPtr)
+{
+    Blt_HashEntry *hPtr;
+
+    hPtr = Blt_FindHashEntry(&legendPtr->selectTable, (char *)elemPtr);
+    if (hPtr != NULL) {
+	Blt_ChainLink link;
+
+	link = Blt_GetHashValue(hPtr);
+	Blt_Chain_DeleteLink(legendPtr->selected, link);
+	Blt_DeleteHashEntry(&legendPtr->selectTable, hPtr);
+    }
+}
+
+static void
+SelectEntry(Legend *legendPtr, Element *elemPtr)
+{
+    Blt_HashEntry *hPtr;
+
+    switch (legendPtr->flags & SELECT_BLTMASK) {
+    case SELECT_CLEAR:
+	DeselectElement(legendPtr, elemPtr);
+	break;
+
+    case SELECT_SET:
+	SelectElement(legendPtr, elemPtr);
+	break;
+
+    case SELECT_TOGGLE:
+	hPtr = Blt_FindHashEntry(&legendPtr->selectTable, (char *)elemPtr);
+	if (hPtr != NULL) {
+	    DeselectElement(legendPtr, elemPtr);
+	} else {
+	    SelectElement(legendPtr, elemPtr);
+	}
+	break;
+    }
+}
+
+/*ARGSUSED*/
+static ClientData
+PickEntryProc(ClientData clientData, int x, int y, ClientData *contextPtr)
+{
+    Graph *graphPtr = clientData;
+    Legend *legendPtr;
+    int w, h;
+
+    legendPtr = graphPtr->legend;
+    w = legendPtr->width;
+    h = legendPtr->height;
+
+    if (legendPtr->titleHeight > 0) {
+	y -= legendPtr->titleHeight + legendPtr->yPad.side1;
+    }
+    x -= legendPtr->x + legendPtr->borderWidth;
+    y -= legendPtr->y + legendPtr->borderWidth;
+    w -= 2 * legendPtr->borderWidth + PADDING(legendPtr->xPad);
+    h -= 2 * legendPtr->borderWidth + PADDING(legendPtr->yPad);
+
+    if ((x >= 0) && (x < w) && (y >= 0) && (y < h)) {
+	int row, column;
+	int n;
+
+	/*
+	 * It's in the bounding box, so compute the index.
+	 */
+	row    = y / legendPtr->entryHeight;
+	column = x / legendPtr->entryWidth;
+	n = (column * legendPtr->nRows) + row;
+	if (n < legendPtr->nEntries) {
+	    Blt_ChainLink link;
+	    int count;
+
+	    /* Legend entries are stored in bottom-to-top. */
+	    count = 0;
+	    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+		 link != NULL; link = Blt_Chain_NextLink(link)) {
+		Element *elemPtr;
+
+		elemPtr = Blt_Chain_GetValue(link);
+		if (elemPtr->label != NULL) {
+		    if (count == n) {
+			return elemPtr;
+		    }
+		    count++;
+		}
+	    }	      
+	    if (link != NULL) {
+		return Blt_Chain_GetValue(link);
+	    }	
+	}
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_MapLegend --
+ *
+ * 	Calculates the dimensions (width and height) needed for the legend.
+ * 	Also determines the number of rows and columns necessary to list all
+ * 	the valid element labels.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *   	The following fields of the legend are calculated and set.
+ *
+ * 	nEntries   - number of valid labels of elements in the
+ *		      display list.
+ * 	nRows	    - number of rows of entries
+ * 	nColumns    - number of columns of entries
+ * 	entryHeight - height of each entry
+ * 	entryWidth  - width of each entry
+ * 	height	    - width of legend (includes borders and padding)
+ * 	width	    - height of legend (includes borders and padding)
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_MapLegend(
+    Graph *graphPtr,
+    int plotWidth,			/* Maximum width available in window
+					 * to draw the legend. Will calculate
+					 * # of columns from this. */
+    int plotHeight)			/* Maximum height available in window
+					 * to draw the legend. Will calculate
+					 * # of rows from this. */
+{
+    Legend *legendPtr = graphPtr->legend;
+    Blt_ChainLink link;
+    int nRows, nColumns, nEntries;
+    int lw, lh;
+    int maxWidth, maxHeight;
+    int symbolWidth;
+    Blt_FontMetrics fontMetrics;
+
+    /* Initialize legend values to default (no legend displayed) */
+    legendPtr->entryWidth = legendPtr->entryHeight = 0;
+    legendPtr->nRows = legendPtr->nColumns = legendPtr->nEntries = 0;
+    legendPtr->height = legendPtr->width = 0;
+
+    if (legendPtr->site == LEGEND_WINDOW) {
+	if (Tk_Width(legendPtr->tkwin) > 1) {
+	    plotWidth = Tk_Width(legendPtr->tkwin);
+	}
+	if (Tk_Height(legendPtr->tkwin) > 1) {
+	    plotHeight = Tk_Height(legendPtr->tkwin);
+	}
+    }
+    Blt_Ts_GetExtents(&legendPtr->titleStyle, legendPtr->title, 
+		      &legendPtr->titleWidth, &legendPtr->titleHeight);
+    /*   
+     * Count the number of legend entries and determine the widest and tallest
+     * label.  The number of entries would normally be the number of elements,
+     * but elements can have no legend entry (-label "").
+     */
+    nEntries = 0;
+    maxWidth = maxHeight = 0;
+    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+	link != NULL; link = Blt_Chain_NextLink(link)) {
+	unsigned int w, h;
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (elemPtr->label == NULL) {
+	    continue;			/* Element has no legend entry. */
+	}
+	Blt_Ts_GetExtents(&legendPtr->style, elemPtr->label, &w, &h);
+	if (maxWidth < w) {
+	    maxWidth = w;
+	}
+	if (maxHeight < h) {
+	    maxHeight = h;
+	}
+	nEntries++;
+    }
+    if (nEntries == 0) {
+	return;				/* No visible legend entries. */
+    }
+
+
+    Blt_GetFontMetrics(legendPtr->style.font, &fontMetrics);
+    symbolWidth = 2 * fontMetrics.ascent;
+
+    maxWidth += 2 * legendPtr->entryBW + PADDING(legendPtr->ixPad) +
+	+ symbolWidth + 3 * LABEL_PAD;
+
+    maxHeight += 2 * legendPtr->entryBW + PADDING(legendPtr->iyPad);
+
+    maxWidth |= 0x01;
+    maxHeight |= 0x01;
+
+    lw = plotWidth - 2 * legendPtr->borderWidth - PADDING(legendPtr->xPad);
+    lh = plotHeight - 2 * legendPtr->borderWidth - PADDING(legendPtr->yPad);
+
+    /*
+     * The number of rows and columns is computed as one of the following:
+     *
+     *	both options set		User defined. 
+     *  -rows				Compute columns from rows.
+     *  -columns			Compute rows from columns.
+     *	neither set			Compute rows and columns from
+     *					size of plot.  
+     */
+    if (legendPtr->reqRows > 0) {
+	nRows = MIN(legendPtr->reqRows, nEntries); 
+	if (legendPtr->reqColumns > 0) {
+	    nColumns = MIN(legendPtr->reqColumns, nEntries);
+	} else {
+	    nColumns = ((nEntries - 1) / nRows) + 1; /* Only -rows. */
+	}
+    } else if (legendPtr->reqColumns > 0) { /* Only -columns. */
+	nColumns = MIN(legendPtr->reqColumns, nEntries);
+	nRows = ((nEntries - 1) / nColumns) + 1;
+    } else {			
+	/* Compute # of rows and columns from the legend size. */
+	nRows = lh / maxHeight;
+	nColumns = lw / maxWidth;
+	if (nRows < 1) {
+	    nRows = nEntries;
+	}
+	if (nColumns < 1) {
+	    nColumns = nEntries;
+	}
+	if (nRows > nEntries) {
+	    nRows = nEntries;
+	} 
+	switch (legendPtr->site) {
+	case LEGEND_TOP:
+	case LEGEND_BOTTOM:
+	    nRows = ((nEntries - 1) / nColumns) + 1;
+	    break;
+	case LEGEND_LEFT:
+	case LEGEND_RIGHT:
+	default:
+	    nColumns = ((nEntries - 1) / nRows) + 1;
+	    break;
+	}
+    }
+    if (nColumns < 1) {
+	nColumns = 1;
+    } 
+    if (nRows < 1) {
+	nRows = 1;
+    }
+
+    lh = (nRows * maxHeight);
+    if (legendPtr->titleHeight > 0) {
+	lh += legendPtr->titleHeight + legendPtr->yPad.side1;
+    }
+    lw = nColumns * maxWidth;
+    if (lw < legendPtr->titleWidth) {
+	lw = legendPtr->titleWidth;
+    }
+    legendPtr->width = lw + 2 * legendPtr->borderWidth + 
+	PADDING(legendPtr->xPad);
+    legendPtr->height = lh + 2 * legendPtr->borderWidth + 
+	PADDING(legendPtr->yPad);
+    legendPtr->nRows = nRows;
+    legendPtr->nColumns = nColumns;
+    legendPtr->nEntries = nEntries;
+    legendPtr->entryHeight = maxHeight;
+    legendPtr->entryWidth = maxWidth;
+
+    {
+	int row, col, count;
+
+	row = col = count = 0;
+	for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    Element *elemPtr;
+	    
+	    elemPtr = Blt_Chain_GetValue(link);
+	    count++;
+	    elemPtr->row = row;
+	    elemPtr->col = col;
+	    row++;
+	    if ((count % nRows) == 0) {
+		col++;
+		row = 0;
+	    }
+	}
+    }
+    if ((legendPtr->site == LEGEND_WINDOW) &&
+	((Tk_ReqWidth(legendPtr->tkwin) != legendPtr->width) ||
+	 (Tk_ReqHeight(legendPtr->tkwin) != legendPtr->height))) {
+	Tk_GeometryRequest(legendPtr->tkwin,legendPtr->width,legendPtr->height);
+    }
+}
+
+void
+Blt_DrawLegend(Graph *graphPtr, Drawable drawable)
+{
+    Blt_Background bg;
+    Blt_ChainLink link;
+    Blt_FontMetrics fontMetrics;
+    Legend *legendPtr = graphPtr->legend;
+    Pixmap pixmap;
+    Tk_Window tkwin;
+    int count;
+    int symbolSize, xMid, yMid;
+    int x, y, w, h;
+    int xLabel, yStart, xSymbol, ySymbol;
+
+    if ((legendPtr->flags & HIDE) || (legendPtr->nEntries == 0)) {
+	return;
+    }
+
+    SetLegendOrigin(legendPtr);
+    graphPtr = legendPtr->graphPtr;
+    tkwin = legendPtr->tkwin;
+    if (legendPtr->site == LEGEND_WINDOW) {
+	w = Tk_Width(tkwin);
+	h = Tk_Height(tkwin);
+    } else {
+	w = legendPtr->width;
+	h = legendPtr->height;
+    }
+
+    pixmap = Tk_GetPixmap(graphPtr->display, Tk_WindowId(tkwin), w, h, 
+	Tk_Depth(tkwin));
+
+    if (legendPtr->normalBg != NULL) {
+	Blt_FillBackgroundRectangle(tkwin, pixmap, legendPtr->normalBg, 0, 0, 
+		w, h, 0, TK_RELIEF_FLAT);
+    } else if (legendPtr->site & LEGEND_PLOTAREA_MASK) {
+	/* 
+	 * Legend background is transparent and is positioned over the the
+	 * plot area.  Either copy the part of the background from the backing
+	 * store pixmap or (if no backing store exists) just fill it with the
+	 * background color of the plot.
+	 */
+	if (graphPtr->cache != None) {
+	    XCopyArea(graphPtr->display, graphPtr->cache, pixmap, 
+		graphPtr->drawGC, legendPtr->x, legendPtr->y, w, h, 0, 0);
+        } else {
+	    Blt_FillBackgroundRectangle(tkwin, pixmap, graphPtr->plotBg, 0, 0, 
+		w, h, TK_RELIEF_FLAT, 0);
+ 	}
+    } else {
+	int xOrigin, yOrigin;
+	/* 
+	 * The legend is located in one of the margins or the external window.
+	 */
+	Blt_GetBackgroundOrigin(graphPtr->normalBg, &xOrigin, &yOrigin);
+	Blt_SetBackgroundOrigin(graphPtr->tkwin, graphPtr->normalBg, 
+		xOrigin - legendPtr->x,yOrigin - legendPtr->y);
+	Blt_FillBackgroundRectangle(tkwin, pixmap, graphPtr->normalBg, 0, 0, 
+		w, h, 0, TK_RELIEF_FLAT);
+	Blt_SetBackgroundOrigin(tkwin, graphPtr->normalBg, xOrigin, yOrigin);
+    }
+    Blt_GetFontMetrics(legendPtr->style.font, &fontMetrics);
+
+    symbolSize = fontMetrics.ascent;
+    xMid = symbolSize + 1 + legendPtr->entryBW;
+    yMid = (symbolSize / 2) + 1 + legendPtr->entryBW;
+    xLabel = 2 * symbolSize + legendPtr->entryBW + 
+	legendPtr->ixPad.side1 + 2 * LABEL_PAD;
+    ySymbol = yMid + legendPtr->iyPad.side1; 
+    xSymbol = xMid + LABEL_PAD;
+
+    x = legendPtr->padLeft + legendPtr->borderWidth;
+    y = legendPtr->padTop + legendPtr->borderWidth;
+    Blt_DrawText(tkwin, pixmap, legendPtr->title, &legendPtr->titleStyle, x, y);
+    if (legendPtr->titleHeight > 0) {
+	y += legendPtr->titleHeight + legendPtr->yPad.side1;
+    }
+    count = 0;
+    yStart = y;
+    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+	 link != NULL; link = Blt_Chain_NextLink(link)) {
+	Element *elemPtr;
+	int isSelected;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (elemPtr->label == NULL) {
+	    continue;			/* Skip this entry */
+	}
+	isSelected = EntryIsSelected(legendPtr, elemPtr);
+	if (elemPtr->flags & LABEL_ACTIVE) {
+	    int xOrigin, yOrigin;
+
+	    Blt_GetBackgroundOrigin(legendPtr->activeBg, &xOrigin, &yOrigin);
+	    Blt_SetBackgroundOrigin(tkwin, legendPtr->activeBg, 
+		xOrigin - legendPtr->x, yOrigin - legendPtr->y);
+	    Blt_Ts_SetForeground(legendPtr->style, legendPtr->activeFgColor);
+	    Blt_FillBackgroundRectangle(tkwin, pixmap, legendPtr->activeBg, 
+		x, y, legendPtr->entryWidth, legendPtr->entryHeight, 
+		legendPtr->entryBW, legendPtr->activeRelief);
+	    Blt_SetBackgroundOrigin(tkwin, legendPtr->activeBg, 
+		xOrigin, yOrigin);
+	} else if (isSelected) {
+	    int xOrigin, yOrigin;
+	    Blt_Background bg;
+	    XColor *fg;
+
+	    fg = (legendPtr->flags & FOCUS) ?
+		legendPtr->selInFocusFgColor : legendPtr->selOutFocusFgColor;
+	    bg = (legendPtr->flags & FOCUS) ?
+		    legendPtr->selInFocusBg : legendPtr->selOutFocusBg;
+	    Blt_GetBackgroundOrigin(bg, &xOrigin, &yOrigin);
+	    Blt_SetBackgroundOrigin(tkwin, bg, xOrigin - legendPtr->x, 
+		yOrigin - legendPtr->y);
+	    Blt_Ts_SetForeground(legendPtr->style, fg);
+	    Blt_FillBackgroundRectangle(tkwin, pixmap, bg, x, y, 
+		legendPtr->entryWidth, legendPtr->entryHeight, 
+		legendPtr->selBW, legendPtr->selRelief);
+	    Blt_SetBackgroundOrigin(tkwin, bg, xOrigin, yOrigin);
+	} else {
+	    Blt_Ts_SetForeground(legendPtr->style, legendPtr->fgColor);
+	    if (elemPtr->legendRelief != TK_RELIEF_FLAT) {
+		Blt_FillBackgroundRectangle(tkwin, pixmap, graphPtr->normalBg, 
+			x, y, legendPtr->entryWidth, 
+			legendPtr->entryHeight, legendPtr->entryBW, 
+			elemPtr->legendRelief);
+	    }
+	}
+	(*elemPtr->procsPtr->drawSymbolProc) (graphPtr, pixmap, elemPtr,
+		x + xSymbol, y + ySymbol, symbolSize);
+	Blt_DrawText(tkwin, pixmap, elemPtr->label, &legendPtr->style, 
+		x + xLabel, 
+		y + legendPtr->entryBW + legendPtr->iyPad.side1);
+	count++;
+	if (legendPtr->focusPtr == elemPtr) { /* Focus outline */
+	    if (isSelected) {
+		XColor *color;
+
+		color = (legendPtr->flags & FOCUS) ?
+		    legendPtr->selInFocusFgColor :
+		    legendPtr->selOutFocusFgColor;
+		XSetForeground(graphPtr->display, legendPtr->focusGC, 
+			       color->pixel);
+	    }
+	    XDrawRectangle(graphPtr->display, pixmap, legendPtr->focusGC, 
+		x + 1, y + 1, legendPtr->entryWidth - 3, 
+		legendPtr->entryHeight - 3);
+	    if (isSelected) {
+		XSetForeground(graphPtr->display, legendPtr->focusGC, 
+			legendPtr->focusColor->pixel);
+	    }
+	}
+	/* Check when to move to the next column */
+	if ((count % legendPtr->nRows) > 0) {
+	    y += legendPtr->entryHeight;
+	} else {
+	    x += legendPtr->entryWidth;
+	    y = yStart;
+	}
+    }
+    /*
+     * Draw the border and/or background of the legend.
+     */
+    bg = legendPtr->normalBg;
+    if (bg == NULL) {
+	bg = graphPtr->normalBg;
+    }
+    /* Disable crosshairs before redisplaying to the screen */
+    if (legendPtr->site & LEGEND_PLOTAREA_MASK) {
+	Blt_DisableCrosshairs(graphPtr);
+    }
+    Blt_DrawBackgroundRectangle(tkwin, pixmap, bg, 0, 0, w, h, 
+	legendPtr->borderWidth, legendPtr->relief);
+    XCopyArea(graphPtr->display, pixmap, drawable, graphPtr->drawGC, 0, 0, w, h,
+	legendPtr->x, legendPtr->y);
+    if (legendPtr->site & LEGEND_PLOTAREA_MASK) {
+	Blt_EnableCrosshairs(graphPtr);
+    }
+    Tk_FreePixmap(graphPtr->display, pixmap);
+    graphPtr->flags &= ~DRAW_LEGEND;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_LegendToPostScript --
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_LegendToPostScript(Graph *graphPtr, Blt_Ps ps)
+{
+    Legend *legendPtr = graphPtr->legend;
+    double x, y, yStart;
+    int xLabel, xSymbol, ySymbol;
+    int count;
+    Blt_ChainLink link;
+    int symbolSize, xMid, yMid;
+    int width, height;
+    Blt_FontMetrics fontMetrics;
+
+    if ((legendPtr->flags & HIDE) || (legendPtr->nEntries == 0)) {
+	return;
+    }
+    SetLegendOrigin(legendPtr);
+
+    x = legendPtr->x, y = legendPtr->y;
+    width = legendPtr->width - PADDING(legendPtr->xPad);
+    height = legendPtr->height - PADDING(legendPtr->yPad);
+
+    Blt_Ps_Append(ps, "% Legend\n");
+    graphPtr = legendPtr->graphPtr;
+    if (graphPtr->pageSetup->flags & PS_DECORATIONS) {
+	if (legendPtr->normalBg != NULL) {
+	    Tk_3DBorder border;
+
+	    border = Blt_BackgroundBorder(legendPtr->normalBg);
+	    Blt_Ps_Fill3DRectangle(ps, border, x, y, width, height, 
+		legendPtr->borderWidth, legendPtr->relief);
+	} else {
+	    Tk_3DBorder border;
+
+	    border = Blt_BackgroundBorder(graphPtr->normalBg);
+	    Blt_Ps_Draw3DRectangle(ps, border, x, y, width, height, 
+		legendPtr->borderWidth, legendPtr->relief);
+	}
+    } else {
+	Blt_Ps_SetClearBackground(ps);
+	Blt_Ps_XFillRectangle(ps, x, y, width, height);
+    }
+    Blt_GetFontMetrics(legendPtr->style.font, &fontMetrics);
+    symbolSize = fontMetrics.ascent;
+    xMid = symbolSize + 1 + legendPtr->entryBW;
+    yMid = (symbolSize / 2) + 1 + legendPtr->entryBW;
+    xLabel = 2 * symbolSize + legendPtr->entryBW + legendPtr->ixPad.side1 + 5;
+    xSymbol = xMid + legendPtr->ixPad.side1;
+    ySymbol = yMid + legendPtr->iyPad.side1;
+
+    x += legendPtr->borderWidth;
+    y += legendPtr->borderWidth;
+    Blt_Ps_DrawText(ps, legendPtr->title, &legendPtr->titleStyle, x, y);
+    if (legendPtr->titleHeight > 0) {
+	y += legendPtr->titleHeight + legendPtr->yPad.side1;
+    }
+
+    count = 0;
+    yStart = y;
+    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+	link != NULL; link = Blt_Chain_NextLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (elemPtr->label == NULL) {
+	    continue;			/* Skip this label */
+	}
+	if (elemPtr->flags & LABEL_ACTIVE) {
+	    Tk_3DBorder border;
+	    
+	    border = Blt_BackgroundBorder(legendPtr->activeBg);
+	    Blt_Ts_SetForeground(legendPtr->style, legendPtr->activeFgColor);
+	    Blt_Ps_Fill3DRectangle(ps, border, x, y, legendPtr->entryWidth, 
+		legendPtr->entryHeight, legendPtr->entryBW, 
+		legendPtr->activeRelief);
+	} else {
+	    Blt_Ts_SetForeground(legendPtr->style, legendPtr->fgColor);
+	    if (elemPtr->legendRelief != TK_RELIEF_FLAT) {
+		Tk_3DBorder border;
+
+		border = Blt_BackgroundBorder(graphPtr->normalBg);
+		Blt_Ps_Draw3DRectangle(ps, border, x, y, legendPtr->entryWidth,
+			legendPtr->entryHeight, legendPtr->entryBW, 
+			elemPtr->legendRelief);
+	    }
+	}
+	(*elemPtr->procsPtr->printSymbolProc) (graphPtr, ps, elemPtr, 
+		x + xSymbol, y + ySymbol, symbolSize);
+	Blt_Ps_DrawText(ps, elemPtr->label, &legendPtr->style, 
+		x + xLabel, y + legendPtr->entryBW + legendPtr->iyPad.side1);
+	count++;
+	if ((count % legendPtr->nRows) > 0) {
+	    y += legendPtr->entryHeight;
+	} else {
+	    x += legendPtr->entryWidth;
+	    y = yStart;
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DisplayLegend --
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DisplayLegend(ClientData clientData)
+{
+    Legend *legendPtr = clientData;
+    Graph *graphPtr;
+
+    legendPtr->flags &= ~REDRAW_PENDING;
+    if (legendPtr->tkwin == NULL) {
+	return;				/* Window has been destroyed. */
+    }
+    graphPtr = legendPtr->graphPtr;
+    if (legendPtr->site == LEGEND_WINDOW) {
+	int w, h;
+
+	w = Tk_Width(legendPtr->tkwin);
+	h = Tk_Height(legendPtr->tkwin);
+	if ((w != legendPtr->width) || (h != legendPtr->height)) {
+	    Blt_MapLegend(graphPtr, w, h);
+	}
+    }
+    if (Tk_IsMapped(legendPtr->tkwin)) {
+	Blt_DrawLegend(graphPtr, Tk_WindowId(legendPtr->tkwin));
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ConfigureLegend --
+ *
+ * 	Routine to configure the legend.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new legend attributes.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_ConfigureLegend(Graph *graphPtr)
+{
+    GC newGC;
+    XGCValues gcValues;
+    unsigned long gcMask;
+    Legend *legendPtr;
+
+    legendPtr = graphPtr->legend;
+    /* GC for active label. Dashed outline. */
+    gcMask = GCForeground | GCLineStyle;
+    gcValues.foreground = legendPtr->focusColor->pixel;
+    gcValues.line_style = (LineIsDashed(legendPtr->focusDashes))
+	? LineOnOffDash : LineSolid;
+    newGC = Blt_GetPrivateGC(legendPtr->tkwin, gcMask, &gcValues);
+    if (LineIsDashed(legendPtr->focusDashes)) {
+	legendPtr->focusDashes.offset = 2;
+	Blt_SetDashes(graphPtr->display, newGC, &legendPtr->focusDashes);
+    }
+    if (legendPtr->focusGC != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, legendPtr->focusGC);
+    }
+    legendPtr->focusGC = newGC;
+    
+    /*
+     *  Update the layout of the graph (and redraw the elements) if any of
+     *  the following legend options (all of which affect the size of the
+     *  legend) have changed.
+     *
+     *		-activeborderwidth, -borderwidth
+     *		-border
+     *		-font
+     *		-hide
+     *		-ipadx, -ipady, -padx, -pady
+     *		-rows
+     *
+     *  If the position of the legend changed to/from the default
+     *  position, also indicate that a new layout is needed.
+     *
+     */
+    if (legendPtr->site == LEGEND_WINDOW) {
+	Blt_Legend_EventuallyRedraw(graphPtr);
+    } else if (Blt_ConfigModified(configSpecs, "-*border*", "-*pad?",
+	"-hide", "-font", "-rows", (char *)NULL)) {
+	graphPtr->flags |= RESET_WORLD;
+	graphPtr->flags |= (REDRAW_WORLD | CACHE_DIRTY);
+	Blt_EventuallyRedrawGraph(graphPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DestroyLegend --
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Resources associated with the legend are freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DestroyLegend(Graph *graphPtr)
+{
+    Legend *legendPtr = graphPtr->legend;
+
+    if (graphPtr->legend == NULL) {
+	return;
+    }
+
+    Blt_FreeOptions(configSpecs, (char *)legendPtr, graphPtr->display, 0);
+    Blt_Ts_FreeStyle(graphPtr->display, &legendPtr->style);
+    Blt_Ts_FreeStyle(graphPtr->display, &legendPtr->titleStyle);
+    Blt_DestroyBindingTable(legendPtr->bindTable);
+    
+    if (legendPtr->focusGC != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, legendPtr->focusGC);
+    }
+    if (legendPtr->timerToken != NULL) {
+	Tcl_DeleteTimerHandler(legendPtr->timerToken);
+    }
+    if (legendPtr->tkwin != NULL) {
+	Tk_DeleteSelHandler(legendPtr->tkwin, XA_PRIMARY, XA_STRING);
+    }
+    if (legendPtr->site == LEGEND_WINDOW) {
+	Tk_Window tkwin;
+	
+	/* The graph may be in the process of being torn down */
+	if (legendPtr->cmdToken != NULL) {
+	    Tcl_DeleteCommandFromToken(graphPtr->interp, legendPtr->cmdToken);
+	}
+	if (legendPtr->flags & REDRAW_PENDING) {
+	    Tcl_CancelIdleCall(DisplayLegend, legendPtr);
+	    legendPtr->flags &= ~REDRAW_PENDING;
+	}
+	tkwin = legendPtr->tkwin;
+	legendPtr->tkwin = NULL;
+	if (tkwin != NULL) {
+	    Tk_DeleteEventHandler(tkwin, ExposureMask | StructureNotifyMask,
+		LegendEventProc, graphPtr);
+	    Tk_DestroyWindow(tkwin);
+	}
+    }
+    free(legendPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_CreateLegend --
+ *
+ * 	Creates and initializes a legend structure with default settings
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+int
+Blt_CreateLegend(Graph *graphPtr)
+{
+    Legend *legendPtr;
+
+    legendPtr = calloc(1, sizeof(Legend));
+    graphPtr->legend = legendPtr;
+    legendPtr->graphPtr = graphPtr;
+    legendPtr->tkwin = graphPtr->tkwin;
+    legendPtr->xReq = legendPtr->yReq = -SHRT_MAX;
+    legendPtr->relief = TK_RELIEF_SUNKEN;
+    legendPtr->activeRelief = TK_RELIEF_FLAT;
+    legendPtr->entryBW = 2;
+    legendPtr->borderWidth = 2;
+    legendPtr->ixPad.side1 = legendPtr->ixPad.side2 = 1;
+    legendPtr->iyPad.side1 = legendPtr->iyPad.side2 = 1;
+    legendPtr->xPad.side1  = legendPtr->xPad.side2  = 1;
+    legendPtr->yPad.side1  = legendPtr->yPad.side2  = 1;
+    legendPtr->anchor = TK_ANCHOR_N;
+    legendPtr->site = LEGEND_RIGHT;
+    legendPtr->selectMode = SELECT_MODE_MULTIPLE;
+    Blt_Ts_InitStyle(legendPtr->style);
+    Blt_Ts_InitStyle(legendPtr->titleStyle);
+    legendPtr->style.justify = TK_JUSTIFY_LEFT;
+    legendPtr->style.anchor = TK_ANCHOR_NW;
+    legendPtr->titleStyle.justify = TK_JUSTIFY_LEFT;
+    legendPtr->titleStyle.anchor = TK_ANCHOR_NW;
+    legendPtr->bindTable = Blt_CreateBindingTable(graphPtr->interp,
+	graphPtr->tkwin, graphPtr, PickEntryProc, Blt_GraphTags);
+
+    Blt_InitHashTable(&legendPtr->selectTable, BLT_ONE_WORD_KEYS);
+    legendPtr->selected = Blt_Chain_Create();
+    Tk_CreateSelHandler(legendPtr->tkwin, XA_PRIMARY, XA_STRING, 
+	SelectionProc, legendPtr, XA_STRING);
+    legendPtr->selRelief = TK_RELIEF_FLAT;
+    legendPtr->selBW = 1;
+    legendPtr->onTime = 600;
+    legendPtr->offTime = 300;
+    if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin,
+	    "legend", "Legend", configSpecs, 0, (Tcl_Obj **)NULL,
+	    (char *)legendPtr, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Blt_ConfigureLegend(graphPtr);
+    return TCL_OK;
+}
+
+static Element *
+GetNextRow(Graph *graphPtr, Element *focusPtr)
+{
+    Blt_ChainLink link;
+    int row, col;
+
+    col = focusPtr->col;
+    row = focusPtr->row + 1;
+    for (link = focusPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (elemPtr->label == NULL) {
+	    continue;
+	}
+	if ((elemPtr->col == col) && (elemPtr->row == row)) {
+	    return elemPtr;	
+	}
+    }
+    return NULL;
+}
+
+static Element *
+GetNextColumn(Graph *graphPtr, Element *focusPtr)
+{
+    Blt_ChainLink link;
+    int row, col;
+
+    col = focusPtr->col + 1;
+    row = focusPtr->row;
+    for (link = focusPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (elemPtr->label == NULL) {
+	    continue;
+	}
+	if ((elemPtr->col == col) && (elemPtr->row == row)) {
+	    return elemPtr;		/* Don't go beyond legend boundaries. */
+	}
+    }
+    return NULL;
+}
+
+static Element *
+GetPreviousRow(Graph *graphPtr, Element *focusPtr)
+{
+    Blt_ChainLink link;
+    int row, col;
+
+    col = focusPtr->col;
+    row = focusPtr->row - 1;
+    for (link = focusPtr->link; link != NULL; link = Blt_Chain_PrevLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (elemPtr->label == NULL) {
+	    continue;
+	}
+	if ((elemPtr->col == col) && (elemPtr->row == row)) {
+	    return elemPtr;	
+	}
+    }
+    return NULL;
+}
+
+static Element *
+GetPreviousColumn(Graph *graphPtr, Element *focusPtr)
+{
+    Blt_ChainLink link;
+    int row, col;
+
+    col = focusPtr->col - 1;
+    row = focusPtr->row;
+    for (link = focusPtr->link; link != NULL; link = Blt_Chain_PrevLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (elemPtr->label == NULL) {
+	    continue;
+	}
+	if ((elemPtr->col == col) && (elemPtr->row == row)) {
+	    return elemPtr;	
+	}
+    }
+    return NULL;
+}
+
+static Element *
+GetFirstElement(Graph *graphPtr)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); 
+	 link != NULL; link = Blt_Chain_NextLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (elemPtr->label != NULL) {
+	    return elemPtr;
+	}
+    }
+    return NULL;
+}
+
+static Element *
+GetLastElement(Graph *graphPtr)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); 
+	 link != NULL; link = Blt_Chain_PrevLink(link)) {
+	Element *elemPtr;
+
+	elemPtr = Blt_Chain_GetValue(link);
+	if (elemPtr->label != NULL) {
+	    return elemPtr;
+	}
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetElementFromObj --
+ *
+ *	Parse an index into an entry and return either its value or an error.
+ *
+ * Results:
+ *	A standard TCL result.  If all went well, then *indexPtr is filled in
+ *	with the character index (into entryPtr) corresponding to string.  The
+ *	index value is guaranteed to lie between 0 and the number of characters
+ *	in the string, inclusive.  If an error occurs then an error message is
+ *	left in the interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+GetElementFromObj(Graph *graphPtr, Tcl_Obj *objPtr, Element **elemPtrPtr)
+{
+    Element *elemPtr;
+    Legend *legendPtr;
+    Tcl_Interp *interp;
+    char c;
+    const char *string;
+    int last;
+
+    legendPtr = graphPtr->legend;
+    interp = graphPtr->interp;
+    string = Tcl_GetString(objPtr);
+    c = string[0];
+    elemPtr = NULL;
+
+    last = Blt_Chain_GetLength(graphPtr->elements.displayList) - 1;
+    if ((c == 'a') && (strcmp(string, "anchor") == 0)) {
+	elemPtr = legendPtr->selAnchorPtr;
+    } else if ((c == 'c') && (strcmp(string, "current") == 0)) {
+	elemPtr = (Element *)Blt_GetCurrentItem(legendPtr->bindTable);
+    } else if ((c == 'f') && (strcmp(string, "first") == 0)) {
+	elemPtr = GetFirstElement(graphPtr);
+    } else if ((c == 'f') && (strcmp(string, "focus") == 0)) {
+	elemPtr = legendPtr->focusPtr;
+    } else if ((c == 'l') && (strcmp(string, "last") == 0)) {
+	elemPtr = GetLastElement(graphPtr);
+    } else if ((c == 'e') && (strcmp(string, "end") == 0)) {
+	elemPtr = GetLastElement(graphPtr);
+    } else if ((c == 'n') && (strcmp(string, "next.row") == 0)) {
+	elemPtr = GetNextRow(graphPtr, legendPtr->focusPtr);
+    } else if ((c == 'n') && (strcmp(string, "next.column") == 0)) {
+	elemPtr = GetNextColumn(graphPtr, legendPtr->focusPtr);
+    } else if ((c == 'p') && (strcmp(string, "previous.row") == 0)) {
+	elemPtr = GetPreviousRow(graphPtr, legendPtr->focusPtr);
+    } else if ((c == 'p') && (strcmp(string, "previous.column") == 0)) {
+	elemPtr = GetPreviousColumn(graphPtr, legendPtr->focusPtr);
+    } else if ((c == 's') && (strcmp(string, "sel.first") == 0)) {
+	elemPtr = legendPtr->selFirstPtr;
+    } else if ((c == 's') && (strcmp(string, "sel.last") == 0)) {
+	elemPtr = legendPtr->selLastPtr;
+    } else if (c == '@') {
+	int x, y;
+
+	if (Blt_GetXY(interp, legendPtr->tkwin, string, &x, &y) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	elemPtr = (Element *)PickEntryProc(graphPtr, x, y, NULL);
+    } else {
+	if (Blt_GetElement(interp, graphPtr, objPtr, &elemPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (elemPtr->link == NULL) {
+	    Tcl_AppendResult(interp, "bad legend index \"", string, "\"",
+				 (char *)NULL);
+	    return TCL_ERROR;
+	}
+	if (elemPtr->label == NULL) {
+	    elemPtr = NULL;
+	}
+    }
+    *elemPtrPtr = elemPtr;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectRange --
+ *
+ *	Sets the selection flag for a range of nodes.  The range is determined
+ *	by two pointers which designate the first/last nodes of the range.
+ *
+ * Results:
+ *	Always returns TCL_OK.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+SelectRange(Legend *legendPtr, Element *fromPtr, Element *toPtr)
+{
+
+    if (Blt_Chain_IsBefore(fromPtr->link, toPtr->link)) {
+	Blt_ChainLink link;
+
+	for (link = fromPtr->link; link != NULL; 
+	     link = Blt_Chain_NextLink(link)) {
+	    Element *elemPtr;
+	    
+	    elemPtr = Blt_Chain_GetValue(link);
+	    SelectEntry(legendPtr, elemPtr);
+	    if (link == toPtr->link) {
+		break;
+	    }
+	}
+    } else {
+	Blt_ChainLink link;
+
+	for (link = fromPtr->link; link != NULL;
+	     link = Blt_Chain_PrevLink(link)) {
+	    Element *elemPtr;
+	    
+	    elemPtr = Blt_Chain_GetValue(link);
+	    SelectEntry(legendPtr, elemPtr);
+	    if (link == toPtr->link) {
+		break;
+	    }
+	}
+    }
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ActivateOp --
+ *
+ * 	Activates a particular label in the legend.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new legend attributes.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ActivateOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Legend *legendPtr = graphPtr->legend;
+    unsigned int active, redraw;
+    const char *string;
+    int i;
+
+    string = Tcl_GetString(objv[2]);
+    active = (string[0] == 'a') ? LABEL_ACTIVE : 0;
+    redraw = FALSE;
+    for (i = 3; i < objc; i++) {
+	Blt_ChainLink link;
+	const char *pattern;
+
+	pattern = Tcl_GetString(objv[i]);
+	for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    Element *elemPtr;
+	
+	    elemPtr = Blt_Chain_GetValue(link);
+	    if (Tcl_StringMatch(elemPtr->obj.name, pattern)) {
+		fprintf(stderr, "legend %s(%s) %s is currently %d\n",
+			string, pattern, elemPtr->obj.name, 
+			(elemPtr->flags & LABEL_ACTIVE));
+		if (active) {
+		    if ((elemPtr->flags & LABEL_ACTIVE) == 0) {
+			elemPtr->flags |= LABEL_ACTIVE;
+			redraw = TRUE;
+		    }
+		} else {
+		    if (elemPtr->flags & LABEL_ACTIVE) {
+			elemPtr->flags &= ~LABEL_ACTIVE;
+			redraw = TRUE;
+		    }
+		}
+		fprintf(stderr, "legend %s(%s) %s is now %d\n",
+			string, pattern, elemPtr->obj.name, 
+			(elemPtr->flags & LABEL_ACTIVE));
+	    }
+	}
+    }
+    if ((redraw) && ((legendPtr->flags & HIDE) == 0)) {
+	/*
+	 * See if how much we need to draw. If the graph is already scheduled
+	 * for a redraw, just make sure the right flags are set.  Otherwise
+	 * redraw only the legend: it's either in an external window or it's
+	 * the only thing that need updating.
+	 */
+	if ((legendPtr->site != LEGEND_WINDOW) && 
+	    (graphPtr->flags & REDRAW_PENDING)) {
+	    graphPtr->flags |= CACHE_DIRTY;
+	    graphPtr->flags |= REDRAW_WORLD; /* Redraw entire graph. */
+	} else {
+	    Blt_Legend_EventuallyRedraw(graphPtr);
+	}
+    }
+    {
+	Blt_ChainLink link;
+	Tcl_Obj *listObjPtr;
+	
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	/* List active elements in stacking order. */
+	for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    Element *elemPtr;
+
+	    elemPtr = Blt_Chain_GetValue(link);
+	    if (elemPtr->flags & LABEL_ACTIVE) {
+		Tcl_Obj *objPtr;
+
+		objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1);
+		Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	    }
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BindOp --
+ *
+ *	  .t bind index sequence command
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+BindOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    if (objc == 3) {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch iter;
+	Tcl_Obj *listObjPtr;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.tagTable, &iter);
+	    hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	    const char *tagName;
+	    Tcl_Obj *objPtr;
+
+	    tagName = Blt_GetHashKey(&graphPtr->elements.tagTable, hPtr);
+	    objPtr = Tcl_NewStringObj(tagName, -1);
+	    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+	return TCL_OK;
+    }
+    return Blt_ConfigureBindingsFromObj(interp, graphPtr->legend->bindTable,
+	Blt_MakeElementTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, 
+	objv + 4);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CgetOp --
+ *
+ * 	Queries or resets options for the legend.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new legend attributes.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static int
+CgetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs,
+	    (char *)graphPtr->legend, objv[3], 0);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureOp --
+ *
+ * 	Queries or resets options for the legend.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new legend attributes.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ConfigureOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int flags = BLT_CONFIG_OBJV_ONLY;
+    Legend *legendPtr;
+
+    legendPtr = graphPtr->legend;
+    if (objc == 3) {
+	return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs,
+		(char *)legendPtr, (Tcl_Obj *)NULL, flags);
+    } else if (objc == 4) {
+	return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs,
+		(char *)legendPtr, objv[3], flags);
+    }
+    if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, 
+		objc - 3, objv + 3, (char *)legendPtr, flags) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Blt_ConfigureLegend(graphPtr);
+    return TCL_OK;
+}
+
+
+/*ARGSUSED*/
+static int
+CurselectionOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	       Tcl_Obj *const *objv)
+{
+    Legend *legendPtr = graphPtr->legend;
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if (legendPtr->flags & SELECT_SORTED) {
+	Blt_ChainLink link;
+
+	for (link = Blt_Chain_FirstLink(legendPtr->selected); link != NULL;
+	     link = Blt_Chain_NextLink(link)) {
+	    Element *elemPtr;
+	    Tcl_Obj *objPtr;
+
+	    elemPtr = Blt_Chain_GetValue(link);
+	    objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1);
+	    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	}
+    } else {
+	Blt_ChainLink link;
+
+	/* List of selected entries is in stacking order. */
+	for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    Element *elemPtr;
+
+	    elemPtr = Blt_Chain_GetValue(link);
+
+	    if (EntryIsSelected(legendPtr, elemPtr)) {
+		Tcl_Obj *objPtr;
+
+		objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1);
+		Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*ARGSUSED*/
+static int
+FocusOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Legend *legendPtr = graphPtr->legend;
+
+    if (objc == 4) {
+	Element *elemPtr;
+
+	if (GetElementFromObj(graphPtr, objv[3], &elemPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if ((elemPtr != NULL) && (elemPtr != legendPtr->focusPtr)) {
+	    /* Changing focus can only affect the visible entries.  The entry
+	     * layout stays the same. */
+	    legendPtr->focusPtr = elemPtr;
+	}
+	Blt_SetFocusItem(legendPtr->bindTable, legendPtr->focusPtr, 
+			 CID_LEGEND_ENTRY);
+	Blt_Legend_EventuallyRedraw(graphPtr);
+    }
+    if (legendPtr->focusPtr != NULL) {
+	Tcl_SetStringObj(Tcl_GetObjResult(interp), 
+		legendPtr->focusPtr->obj.name, -1);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetOp --
+ *
+ * 	Find the legend entry from the given argument.  The argument can be
+ * 	either a screen position "@x,y" or the name of an element.
+ *
+ *	I don't know how useful it is to test with the name of an element.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new legend attributes.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+GetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Legend *legendPtr = graphPtr->legend;
+
+    if (((legendPtr->flags & HIDE) == 0) && (legendPtr->nEntries > 0)) {
+	Element *elemPtr;
+
+	if (GetElementFromObj(graphPtr, objv[3], &elemPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (elemPtr != NULL) {
+	    Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->obj.name,-1);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectionAnchorOp --
+ *
+ *	Sets the selection anchor to the element given by a index.  The
+ *	selection anchor is the end of the selection that is fixed while
+ *	dragging out a selection with the mouse.  The index "anchor" may be
+ *	used to refer to the anchor element.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The selection changes.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SelectionAnchorOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+		  Tcl_Obj *const *objv)
+{
+    Legend *legendPtr = graphPtr->legend;
+    Element *elemPtr;
+
+    if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    /* Set both the anchor and the mark. Indicates that a single entry
+     * is selected. */
+    legendPtr->selAnchorPtr = elemPtr;
+    legendPtr->selMarkPtr = NULL;
+    if (elemPtr != NULL) {
+	Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->obj.name, -1);
+    }
+    Blt_Legend_EventuallyRedraw(graphPtr);
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectionClearallOp
+ *
+ *	Clears the entire selection.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The selection changes.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SelectionClearallOp(Graph *graphPtr, Tcl_Interp *interp, int objc,
+		    Tcl_Obj *const *objv)
+{
+    Legend *legendPtr = graphPtr->legend;
+
+    ClearSelection(legendPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectionIncludesOp
+ *
+ *	Returns 1 if the element indicated by index is currently
+ *	selected, 0 if it isn't.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The selection changes.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SelectionIncludesOp(Graph *graphPtr, Tcl_Interp *interp, int objc,
+		    Tcl_Obj *const *objv)
+{
+    Legend *legendPtr = graphPtr->legend;
+    Element *elemPtr;
+    int bool;
+
+    if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    bool = EntryIsSelected(legendPtr, elemPtr);
+    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectionMarkOp --
+ *
+ *	Sets the selection mark to the element given by a index.  The
+ *	selection anchor is the end of the selection that is movable while
+ *	dragging out a selection with the mouse.  The index "mark" may be used
+ *	to refer to the anchor element.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The selection changes.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SelectionMarkOp(Graph *graphPtr, Tcl_Interp *interp, int objc,
+		Tcl_Obj *const *objv)
+{
+    Legend *legendPtr = graphPtr->legend;
+    Element *elemPtr;
+
+    if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (legendPtr->selAnchorPtr == NULL) {
+	Tcl_AppendResult(interp, "selection anchor must be set first", 
+		 (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (legendPtr->selMarkPtr != elemPtr) {
+	Blt_ChainLink link, next;
+
+	/* Deselect entry from the list all the way back to the anchor. */
+	for (link = Blt_Chain_LastLink(legendPtr->selected); link != NULL; 
+	     link = next) {
+	    Element *selectPtr;
+
+	    next = Blt_Chain_PrevLink(link);
+	    selectPtr = Blt_Chain_GetValue(link);
+	    if (selectPtr == legendPtr->selAnchorPtr) {
+		break;
+	    }
+	    DeselectElement(legendPtr, selectPtr);
+	}
+	legendPtr->flags &= ~SELECT_BLTMASK;
+	legendPtr->flags |= SELECT_SET;
+	SelectRange(legendPtr, legendPtr->selAnchorPtr, elemPtr);
+	Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->obj.name, -1);
+	legendPtr->selMarkPtr = elemPtr;
+
+	Blt_Legend_EventuallyRedraw(graphPtr);
+	if (legendPtr->selectCmd != NULL) {
+	    EventuallyInvokeSelectCmd(legendPtr);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectionPresentOp
+ *
+ *	Returns 1 if there is a selection and 0 if it isn't.
+ *
+ * Results:
+ *	A standard TCL result.  interp->result will contain a boolean string
+ *	indicating if there is a selection.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SelectionPresentOp(Graph *graphPtr, Tcl_Interp *interp, int objc,
+		   Tcl_Obj *const *objv)
+{
+    Legend *legendPtr = graphPtr->legend;
+    int bool;
+
+    bool = (Blt_Chain_GetLength(legendPtr->selected) > 0);
+    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectionSetOp
+ *
+ *	Selects, deselects, or toggles all of the elements in the range
+ *	between first and last, inclusive, without affecting the selection
+ *	state of elements outside that range.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The selection changes.
+ *
+ *	.g legend selection set first last
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SelectionSetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	       Tcl_Obj *const *objv)
+{
+    Legend *legendPtr = graphPtr->legend;
+    Element *firstPtr, *lastPtr;
+    const char *string;
+
+    legendPtr->flags &= ~SELECT_BLTMASK;
+    string = Tcl_GetString(objv[3]);
+    switch (string[0]) {
+    case 's':
+	legendPtr->flags |= SELECT_SET;
+	break;
+    case 'c':
+	legendPtr->flags |= SELECT_CLEAR;
+	break;
+    case 't':
+	legendPtr->flags |= SELECT_TOGGLE;
+	break;
+    }
+    if (GetElementFromObj(graphPtr, objv[4], &firstPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if ((firstPtr->flags & HIDE) && ((legendPtr->flags & SELECT_CLEAR)==0)) {
+	Tcl_AppendResult(interp, "can't select hidden node \"", 
+		Tcl_GetString(objv[4]), "\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    lastPtr = firstPtr;
+    if (objc > 5) {
+	if (GetElementFromObj(graphPtr, objv[5], &lastPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if ((lastPtr->flags & HIDE) && 
+	    ((legendPtr->flags & SELECT_CLEAR) == 0)) {
+	    Tcl_AppendResult(interp, "can't select hidden node \"", 
+		     Tcl_GetString(objv[5]), "\"", (char *)NULL);
+	    return TCL_ERROR;
+	}
+    }
+    if (firstPtr == lastPtr) {
+	SelectEntry(legendPtr, firstPtr);
+    } else {
+	SelectRange(legendPtr, firstPtr, lastPtr);
+    }
+    /* Set both the anchor and the mark. Indicates that a single entry is
+     * selected. */
+    if (legendPtr->selAnchorPtr == NULL) {
+	legendPtr->selAnchorPtr = firstPtr;
+    }
+    if (legendPtr->flags & SELECT_EXPORT) {
+	Tk_OwnSelection(legendPtr->tkwin, XA_PRIMARY, LostSelectionProc, 
+			legendPtr);
+    }
+    Blt_Legend_EventuallyRedraw(graphPtr);
+    if (legendPtr->selectCmd != NULL) {
+	EventuallyInvokeSelectCmd(legendPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectionOp --
+ *
+ *	This procedure handles the individual options for text selections.
+ *	The selected text is designated by start and end indices into the text
+ *	pool.  The selected segment has both a anchored and unanchored ends.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The selection changes.
+ *
+ *	.g legend selection anchor 
+ *---------------------------------------------------------------------------
+ */
+static Blt_OpSpec selectionOps[] =
+{
+    {"anchor",   1, SelectionAnchorOp,   5, 5, "elem",},
+    {"clear",    5, SelectionSetOp,      5, 6, "firstElem ?lastElem?",},
+    {"clearall", 6, SelectionClearallOp, 4, 4, "",},
+    {"includes", 1, SelectionIncludesOp, 5, 5, "elem",},
+    {"mark",     1, SelectionMarkOp,     5, 5, "elem",},
+    {"present",  1, SelectionPresentOp,  4, 4, "",},
+    {"set",      1, SelectionSetOp,      5, 6, "firstElem ?lastElem?",},
+    {"toggle",   1, SelectionSetOp,      5, 6, "firstElem ?lastElem?",},
+};
+static int nSelectionOps = sizeof(selectionOps) / sizeof(Blt_OpSpec);
+
+static int
+SelectionOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    GraphLegendProc *proc;
+    int result;
+
+    proc = Blt_GetOpFromObj(interp, nSelectionOps, selectionOps, BLT_OP_ARG3, 
+	objc, objv, 0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    result = (*proc) (graphPtr, interp, objc, objv);
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_LegendOp --
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Legend is possibly redrawn.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Blt_OpSpec legendOps[] =
+{
+    {"activate",     1, ActivateOp,      3, 0, "?pattern?...",},
+    {"bind",         1, BindOp,          3, 6, "elem sequence command",},
+    {"cget",         2, CgetOp,          4, 4, "option",},
+    {"configure",    2, ConfigureOp,     3, 0, "?option value?...",},
+    {"curselection", 2, CurselectionOp,  3, 3, "",},
+    {"deactivate",   1, ActivateOp,      3, 0, "?pattern?...",},
+    {"focus",        1, FocusOp,         4, 4, "elem",},
+    {"get",          1, GetOp,           4, 4, "elem",},
+    //    {"icon",         1, IconOp,          5, 5, "elem image",},
+    {"selection",    1, SelectionOp,     3, 0, "args"},
+};
+static int nLegendOps = sizeof(legendOps) / sizeof(Blt_OpSpec);
+
+int
+Blt_LegendOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	     Tcl_Obj *const *objv)
+{
+    GraphLegendProc *proc;
+
+    proc = Blt_GetOpFromObj(interp, nLegendOps, legendOps, BLT_OP_ARG2, 
+	objc, objv,0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    return (*proc) (graphPtr, interp, objc, objv);
+}
+
+int 
+Blt_Legend_Site(Graph *graphPtr)
+{
+    return graphPtr->legend->site;
+}
+
+int 
+Blt_Legend_Width(Graph *graphPtr)
+{
+    return graphPtr->legend->width;
+}
+
+int 
+Blt_Legend_Height(Graph *graphPtr)
+{
+    return graphPtr->legend->height;
+}
+
+int 
+Blt_Legend_IsHidden(Graph *graphPtr)
+{
+    return (graphPtr->legend->flags & HIDE);
+}
+
+int 
+Blt_Legend_IsRaised(Graph *graphPtr)
+{
+    return (graphPtr->legend->flags & RAISED);
+}
+
+int 
+Blt_Legend_X(Graph *graphPtr)
+{
+    return graphPtr->legend->x;
+}
+
+int 
+Blt_Legend_Y(Graph *graphPtr)
+{
+    return graphPtr->legend->y;
+}
+
+void
+Blt_Legend_RemoveElement(Graph *graphPtr, Element *elemPtr)
+{
+    Blt_DeleteBindings(graphPtr->legend->bindTable, elemPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SelectionProc --
+ *
+ *	This procedure is called back by Tk when the selection is requested by
+ *	someone.  It returns part or all of the selection in a buffer provided
+ *	by the caller.
+ *
+ * Results:
+ *	The return value is the number of non-NULL bytes stored at buffer.
+ *	Buffer is filled (or partially filled) with a NUL-terminated string
+ *	containing part or all of the selection, as given by offset and
+ *	maxBytes.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+SelectionProc(
+    ClientData clientData,		/* Information about the widget. */
+    int offset,				/* Offset within selection of first
+					 * character to be returned. */
+    char *buffer,			/* Location in which to place
+					 * selection. */
+    int maxBytes)			/* Maximum number of bytes to place at
+					 * buffer, not including terminating
+					 * NULL character. */
+{
+    Legend *legendPtr = clientData;
+    int nBytes;
+    Tcl_DString dString;
+
+    if ((legendPtr->flags & SELECT_EXPORT) == 0) {
+	return -1;
+    }
+    /* Retrieve the names of the selected entries. */
+    Tcl_DStringInit(&dString);
+    if (legendPtr->flags & SELECT_SORTED) {
+	Blt_ChainLink link;
+
+	for (link = Blt_Chain_FirstLink(legendPtr->selected); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    Element *elemPtr;
+
+	    elemPtr = Blt_Chain_GetValue(link);
+	    Tcl_DStringAppend(&dString, elemPtr->obj.name, -1);
+	    Tcl_DStringAppend(&dString, "\n", -1);
+	}
+    } else {
+	Blt_ChainLink link;
+	Graph *graphPtr;
+
+	graphPtr = legendPtr->graphPtr;
+	/* List of selected entries is in stacking order. */
+	for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    Element *elemPtr;
+	    
+	    elemPtr = Blt_Chain_GetValue(link);
+	    if (EntryIsSelected(legendPtr, elemPtr)) {
+		Tcl_DStringAppend(&dString, elemPtr->obj.name, -1);
+		Tcl_DStringAppend(&dString, "\n", -1);
+	    }
+	}
+    }
+    nBytes = Tcl_DStringLength(&dString) - offset;
+    strncpy(buffer, Tcl_DStringValue(&dString) + offset, maxBytes);
+    Tcl_DStringFree(&dString);
+    buffer[maxBytes] = '\0';
+    return MIN(nBytes, maxBytes);
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BlinkCursorProc --
+ *
+ *	This procedure is called as a timer handler to blink the insertion
+ *	cursor off and on.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The cursor gets turned on or off, redisplay gets invoked, and this
+ *	procedure reschedules itself.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+BlinkCursorProc(ClientData clientData)
+{
+    Graph *graphPtr = clientData;
+    Legend *legendPtr;
+
+    legendPtr = graphPtr->legend;
+    if (!(legendPtr->flags & FOCUS) || (legendPtr->offTime == 0)) {
+	return;
+    }
+    if (legendPtr->active) {
+	int time;
+
+	legendPtr->cursorOn ^= 1;
+	time = (legendPtr->cursorOn) ? legendPtr->onTime : legendPtr->offTime;
+	legendPtr->timerToken = Tcl_CreateTimerHandler(time, BlinkCursorProc, 
+		graphPtr);
+	Blt_Legend_EventuallyRedraw(graphPtr);
+    }
+}
diff --git a/tlt3.0/bltGrLegd.h b/tlt3.0/bltGrLegd.h
new file mode 100644
index 0000000..e12dd78
--- /dev/null
+++ b/tlt3.0/bltGrLegd.h
@@ -0,0 +1,60 @@
+/*
+ * bltGrLegd.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_GR_LEGEND_H
+#define _BLT_GR_LEGEND_H
+
+#define LEGEND_RIGHT	(1<<0)	/* Right margin */
+#define LEGEND_LEFT	(1<<1)	/* Left margin */
+#define LEGEND_BOTTOM	(1<<2)	/* Bottom margin */
+#define LEGEND_TOP	(1<<3)	/* Top margin, below the graph title. */
+#define LEGEND_PLOT	(1<<4)	/* Plot area */
+#define LEGEND_XY	(1<<5)	/* Screen coordinates in the plotting 
+				 * area. */
+#define LEGEND_WINDOW	(1<<6)	/* External window. */
+#define LEGEND_MARGIN_MASK \
+	(LEGEND_RIGHT | LEGEND_LEFT | LEGEND_BOTTOM | LEGEND_TOP)
+#define LEGEND_PLOTAREA_MASK  (LEGEND_PLOT | LEGEND_XY)
+
+extern int Blt_CreateLegend(Graph *graphPtr);
+extern void Blt_DestroyLegend(Graph *graphPtr);
+extern void Blt_DrawLegend(Graph *graphPtr, Drawable drawable);
+extern void Blt_MapLegend(Graph *graphPtr, int width, int height);
+extern int Blt_LegendOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+extern int Blt_Legend_Site(Graph *graphPtr);
+extern int Blt_Legend_Width(Graph *graphPtr);
+extern int Blt_Legend_Height(Graph *graphPtr);
+extern int Blt_Legend_IsHidden(Graph *graphPtr);
+extern int Blt_Legend_IsRaised(Graph *graphPtr);
+extern int Blt_Legend_X(Graph *graphPtr);
+extern int Blt_Legend_Y(Graph *graphPtr);
+extern void Blt_Legend_RemoveElement(Graph *graphPtr, Element *elemPtr);
+extern void Blt_Legend_EventuallyRedraw(Graph *graphPtr);
+
+#endif /* BLT_GR_LEGEND_H */
diff --git a/tlt3.0/bltGrLine.c b/tlt3.0/bltGrLine.c
new file mode 100644
index 0000000..d4f6a50
--- /dev/null
+++ b/tlt3.0/bltGrLine.c
@@ -0,0 +1,4798 @@
+
+/*
+ * bltGrLine.c --
+ *
+ * This module implements line graph and stripchart elements for the BLT graph
+ * widget.
+ *
+ *	Copyright (c) 1993 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <X11/Xutil.h>
+
+#include "bltInt.h"
+#include "bltSpline.h"
+#include "bltMath.h"
+#include "bltGraph.h"
+#include "bltGrElem.h"
+#include "bltBitmap.h"
+
+#define COLOR_DEFAULT	(XColor *)1
+#define PATTERN_SOLID	((Pixmap)1)
+
+#define PEN_INCREASING  1		/* Draw line segments for only those
+					 * data points whose abscissas are
+					 * monotonically increasing in
+					 * order. */
+#define PEN_DECREASING  2		/* Lines will be drawn between only
+					 * those points whose abscissas are
+					 * decreasing in order. */
+
+#define PEN_BOTH_DIRECTIONS	(PEN_INCREASING | PEN_DECREASING)
+
+/* Lines will be drawn between points regardless of the ordering of the
+ * abscissas */
+
+#define BROKEN_TRACE(dir,last,next) \
+    (((((dir) & PEN_DECREASING) == 0) && ((next) < (last))) || \
+     ((((dir) & PEN_INCREASING) == 0) && ((next) > (last))))
+
+#define DRAW_SYMBOL(linePtr) \
+	(((linePtr)->symbolCounter % (linePtr)->symbolInterval) == 0)
+
+typedef enum { 
+    PEN_SMOOTH_LINEAR,			/* Line segments */
+    PEN_SMOOTH_STEP,			/* Step-and-hold */
+    PEN_SMOOTH_NATURAL,			/* Natural cubic spline */
+    PEN_SMOOTH_QUADRATIC,		/* Quadratic spline */
+    PEN_SMOOTH_CATROM,			/* Catrom parametric spline */
+    PEN_SMOOTH_LAST			/* Sentinel */
+} Smoothing;
+
+typedef struct {
+    const char *name;
+    Smoothing value;
+} SmoothingInfo;
+
+static SmoothingInfo smoothingInfo[] = {
+    { "none",		PEN_SMOOTH_LINEAR	},
+    { "linear",		PEN_SMOOTH_LINEAR	},
+    { "step",		PEN_SMOOTH_STEP		},
+    { "natural",	PEN_SMOOTH_NATURAL	},
+    { "cubic",		PEN_SMOOTH_NATURAL	},
+    { "quadratic",	PEN_SMOOTH_QUADRATIC	},
+    { "catrom",		PEN_SMOOTH_CATROM	},
+    { (char *)NULL,	PEN_SMOOTH_LAST		}
+};
+
+
+typedef struct {
+    Point2d *screenPts;			/* Array of transformed coordinates */
+    int nScreenPts;			/* Number of coordinates */
+    int *styleMap;			/* Index of pen styles  */
+    int *map;				/* Maps segments/traces to data
+					 * points */
+} MapInfo;
+
+/* Symbol types for line elements */
+typedef enum {
+    SYMBOL_NONE,
+    SYMBOL_SQUARE,
+    SYMBOL_CIRCLE,
+    SYMBOL_DIAMOND,
+    SYMBOL_PLUS,
+    SYMBOL_CROSS,
+    SYMBOL_SPLUS,
+    SYMBOL_SCROSS,
+    SYMBOL_TRIANGLE,
+    SYMBOL_ARROW,
+    SYMBOL_BITMAP,
+    SYMBOL_IMAGE
+} SymbolType;
+
+typedef struct {
+    const char *name;
+    unsigned int minChars;
+    SymbolType type;
+} GraphSymbolType;
+
+static GraphSymbolType graphSymbols[] = {
+    { "arrow",	  1, SYMBOL_ARROW,	},
+    { "circle",	  2, SYMBOL_CIRCLE,	},
+    { "cross",	  2, SYMBOL_CROSS,	}, 
+    { "diamond",  1, SYMBOL_DIAMOND,	}, 
+    { "none",	  1, SYMBOL_NONE,	}, 
+    { "plus",	  1, SYMBOL_PLUS,	}, 
+    { "scross",	  2, SYMBOL_SCROSS,	}, 
+    { "splus",	  2, SYMBOL_SPLUS,	}, 
+    { "square",	  2, SYMBOL_SQUARE,	}, 
+    { "triangle", 1, SYMBOL_TRIANGLE,	}, 
+    { NULL,       0, 0			}, 
+};
+
+typedef struct {
+    SymbolType type;			/* Type of symbol to be drawn/printed */
+
+    int size;				/* Requested size of symbol in pixels */
+
+    XColor *outlineColor;		/* Outline color */
+
+    int outlineWidth;			/* Width of the outline */
+
+    GC outlineGC;			/* Outline graphics context */
+
+    XColor *fillColor;			/* Normal fill color */
+
+    GC fillGC;				/* Fill graphics context */
+
+    Tk_Image image;			/* This is used of image symbols.  */
+
+    /* The last two fields are used only for bitmap symbols. */
+
+    Pixmap bitmap;			/* Bitmap to determine
+					* foreground/background pixels of the
+					* symbol */
+    Pixmap mask;			/* Bitmap representing the transparent
+					 * pixels of the symbol */
+} Symbol;
+
+typedef struct {
+    int start;				/* Index into the X-Y coordinate arrays
+					 * indicating where trace starts. */
+    GraphPoints screenPts;		/* Array of screen coordinates
+					 * (malloc-ed) representing the
+					 * trace. */
+} bltTrace;
+
+typedef struct {
+    const char *name;			/* Pen style identifier.  If NULL pen
+					 * was statically allocated. */
+    ClassId classId;			/* Type of pen */
+    const char *typeId;			/* String token identifying the type of
+					 * pen */
+    unsigned int flags;			/* Indicates if the pen element is
+					 * active or normal */
+    int refCount;			/* Reference count for elements using
+					 * this pen. */
+    Blt_HashEntry *hashPtr;
+
+    Blt_ConfigSpec *configSpecs;	/* Configuration specifications */
+
+    PenConfigureProc *configProc;
+    PenDestroyProc *destroyProc;
+    Graph *graphPtr;			/* Graph that the pen is associated
+					 * with. */
+
+    /* Symbol attributes. */
+    Symbol symbol;			/* Element symbol type */
+
+    /* Trace attributes. */
+    int traceWidth;			/* Width of the line segments. If
+					 * lineWidth is 0, no line will be
+					 * drawn, only symbols. */
+
+    Blt_Dashes traceDashes;		/* Dash on-off list value */
+
+    XColor *traceColor;			/* Line segment color */
+
+    XColor *traceOffColor;		/* Line segment dash gap color */
+
+    GC traceGC;				/* Line segment graphics context */
+    
+    /* Error bar attributes. */
+    int errorBarShow;		       /* Describes which error bars to display:
+					* none, x, y, or * both. */
+
+    int errorBarLineWidth;		/* Width of the error bar segments. */
+
+    int errorBarCapWidth;		/* Width of the cap on error bars. */
+
+    XColor *errorBarColor;		/* Color of the error bar. */
+
+    GC errorBarGC;			/* Error bar graphics context. */
+
+    /* Show value attributes. */
+    int valueShow;			/* Indicates whether to display data
+					 * value.  Values are x, y, both, or
+					 * none. */
+    const char *valueFormat;		/* A printf format string. */
+
+    TextStyle valueStyle;		/* Text attributes (color, font,
+					 * rotation, etc.) of the value. */
+} LinePen;
+
+typedef struct {
+    Weight weight;			/* Weight range where this pen is
+					 * valid. */
+    LinePen *penPtr;			/* Pen to use. */
+    GraphPoints symbolPts;
+
+    GraphSegments lines;		/* Points to start of the line segments
+					 * for this pen. */
+    GraphSegments xeb, yeb;		/* X and Y axis error bars. */
+
+    int symbolSize;			/* Size of the pen's symbol scaled to
+					 * the current graph size. */
+    int errorBarCapWidth;		/* Length of the cap ends on each error
+					 * bar. */
+} LineStyle;
+
+typedef struct {
+    GraphObj obj;			/* Must be first field in element. */
+    unsigned int flags;		
+    Blt_HashEntry *hashPtr;
+
+    /* Fields specific to elements. */
+    const char *label;			/* Label displayed in legend */
+    unsigned short row, col;		/* Position of the entry in the
+					 * legend. */
+    int legendRelief;			/* Relief of label in legend. */
+    Axis2d axes;			/* X-axis and Y-axis mapping the
+					 * element */
+    ElemValues x, y, w;			/* Contains array of floating point
+					 * graph coordinate values. Also holds
+					 * min/max * and the number of
+					 * coordinates */
+    int *activeIndices;			/* Array of indices (malloc-ed) which
+					 * indicate which data points are active
+					 * (drawn * with "active" colors). */
+    int nActiveIndices;			/* Number of active data points.
+					 * Special case: if nActiveIndices < 0
+					 * and the * active bit is set in
+					 * "flags", then all data points are
+					 * drawn active. */
+    ElementProcs *procsPtr;
+    Blt_ConfigSpec *configSpecs;	/* Configuration specifications. */
+    LinePen *activePenPtr;		/* Standard Pens */
+    LinePen *normalPenPtr;
+    LinePen *builtinPenPtr;
+    Blt_Chain styles;			/* Palette of pens. */
+
+    /* Symbol scaling */
+    int scaleSymbols;			/* If non-zero, the symbols will scale
+					 * in size as the graph is zoomed
+					 * in/out.  */
+
+    double xRange, yRange;		/* Initial X-axis and Y-axis ranges:
+					 * used to scale the size of element's
+					 * symbol. */
+    int state;
+    Blt_ChainLink link;			/* Element's link in display list. */
+
+    /* The line element specific fields start here. */
+
+    ElemValues xError;			/* Relative/symmetric X error values. */
+    ElemValues yError;			/* Relative/symmetric Y error values. */
+    ElemValues xHigh, xLow;		/* Absolute/asymmetric X-coordinate
+					 * high/low error values. */
+    ElemValues yHigh, yLow;		/* Absolute/asymmetric Y-coordinate
+					 * high/low error values. */
+    LinePen builtinPen;
+    int errorBarCapWidth;		/* Length of cap on error bars */
+
+    /* Line smoothing */
+    Smoothing reqSmooth;		/* Requested smoothing function to use
+					 * for connecting the data points */
+    Smoothing smooth;			/* Smoothing function used. */
+    float rTolerance;			/* Tolerance to reduce the number of
+					 * points displayed. */
+
+    /* Drawing-related data structures. */
+
+    /* Area-under-curve fill attributes. */
+    XColor *fillFgColor;
+    XColor *fillBgColor;
+    GC fillGC;
+
+    Blt_Background fillBg;		/* Background for fill area. */
+
+    Point2d *fillPts;			/* Array of points used to draw polygon
+					 * to fill area under the curve */
+    int nFillPts;
+
+    /* Symbol points */
+    GraphPoints symbolPts;
+
+    /* Active symbol points */
+    GraphPoints activePts;
+    GraphSegments xeb, yeb;		/* Point to start of this pen's X-error
+					 * bar segments in the element's
+					 * array. */
+    int reqMaxSymbols;
+    int symbolInterval;
+    int symbolCounter;
+
+    /* X-Y graph-specific fields */
+
+    int penDir;				/* Indicates if a change in the pen
+					 * direction should be considered a
+					 * retrace (line segment is not
+					 * drawn). */
+    Blt_Chain traces;			/* List of traces (a trace is a series
+					 * of contiguous line segments).  New
+					 * traces are generated when either
+					 * the next segment changes the pen
+					 * direction, or the end point is
+					 * clipped by the plotting area. */
+
+    /* Stripchart-specific fields */
+
+    GraphSegments lines;		/* Holds the the line segments of the
+					 * element trace. The segments are
+					 * grouped by pen style. */
+} LineElement;
+
+static Blt_OptionParseProc ObjToSmoothProc;
+static Blt_OptionPrintProc SmoothToObjProc;
+static Blt_CustomOption smoothOption =
+{
+    ObjToSmoothProc, SmoothToObjProc, NULL, (ClientData)0
+};
+
+static Blt_OptionParseProc ObjToPenDirProc;
+static Blt_OptionPrintProc PenDirToObjProc;
+static Blt_CustomOption penDirOption =
+{
+    ObjToPenDirProc, PenDirToObjProc, NULL, (ClientData)0
+};
+
+static Blt_OptionFreeProc FreeSymbolProc;
+static Blt_OptionParseProc ObjToSymbolProc;
+static Blt_OptionPrintProc SymbolToObjProc;
+static Blt_CustomOption symbolOption =
+{
+    ObjToSymbolProc, SymbolToObjProc, FreeSymbolProc, (ClientData)0
+};
+
+extern Blt_CustomOption bltLineStylesOption;
+extern Blt_CustomOption bltColorOption;
+extern Blt_CustomOption bltValuesOption;
+extern Blt_CustomOption bltValuePairsOption;
+extern Blt_CustomOption bltLinePenOption;
+extern Blt_CustomOption bltXAxisOption;
+extern Blt_CustomOption bltYAxisOption;
+
+#define DEF_LINE_ACTIVE_PEN		"activeLine"
+#define DEF_LINE_AXIS_X			"x"
+#define DEF_LINE_AXIS_Y			"y"
+#define DEF_LINE_DASHES			(char *)NULL
+#define DEF_LINE_DATA			(char *)NULL
+#define DEF_LINE_FILL_COLOR    		"defcolor"
+#define DEF_LINE_HIDE			"no"
+#define DEF_LINE_LABEL			(char *)NULL
+#define DEF_LINE_LABEL_RELIEF		"flat"
+#define DEF_LINE_MAX_SYMBOLS		"0"
+#define DEF_LINE_OFFDASH_COLOR    	(char *)NULL
+#define DEF_LINE_OUTLINE_COLOR		"defcolor"
+#define DEF_LINE_OUTLINE_WIDTH 		"1"
+#define DEF_LINE_PATTERN_BG		(char *)NULL
+#define DEF_LINE_PATTERN_FG		"black"
+#define DEF_LINE_PEN_COLOR		RGB_NAVYBLUE
+#define DEF_LINE_PEN_DIRECTION		"both"
+#define DEF_LINE_PEN_WIDTH		"1"
+#define DEF_LINE_PIXELS			"0.1i"
+#define DEF_LINE_REDUCE			"0.0"
+#define DEF_LINE_SCALE_SYMBOLS		"yes"
+#define DEF_LINE_SMOOTH			"linear"
+#define DEF_LINE_STATE			"normal"
+#define DEF_LINE_STIPPLE		(char *)NULL
+#define DEF_LINE_STYLES			""
+#define DEF_LINE_SYMBOL			"circle"
+#define DEF_LINE_TAGS			"all"
+#define DEF_LINE_X_DATA			(char *)NULL
+#define DEF_LINE_Y_DATA			(char *)NULL
+
+#define DEF_LINE_ERRORBAR_COLOR		"defcolor"
+#define DEF_LINE_ERRORBAR_LINE_WIDTH	"2"
+#define DEF_LINE_ERRORBAR_CAP_WIDTH	"2"
+#define DEF_LINE_SHOW_ERRORBARS		"both"
+
+#define DEF_PEN_ACTIVE_COLOR		RGB_BLUE
+#define DEF_PEN_DASHES			(char *)NULL
+#define DEF_PEN_FILL_COLOR    		"defcolor"
+#define DEF_PEN_LINE_WIDTH		"1"
+#define DEF_PEN_NORMAL_COLOR		RGB_NAVYBLUE
+#define DEF_PEN_OFFDASH_COLOR    	(char *)NULL
+#define DEF_PEN_OUTLINE_COLOR		"defcolor"
+#define DEF_PEN_OUTLINE_WIDTH 		"1"
+#define DEF_PEN_PIXELS			"0.1i"
+#define DEF_PEN_SYMBOL			"circle"
+#define DEF_PEN_TYPE			"line"
+#define	DEF_PEN_VALUE_ANCHOR		"s"
+#define	DEF_PEN_VALUE_COLOR		RGB_BLACK
+#define	DEF_PEN_VALUE_FONT		STD_FONT_NUMBERS
+#define	DEF_PEN_VALUE_FORMAT		"%g"
+#define	DEF_PEN_VALUE_ANGLE		(char *)NULL
+#define DEF_PEN_SHOW_VALUES		"no"
+
+static Blt_ConfigSpec lineElemConfigSpecs[] =
+{
+    {BLT_CONFIG_CUSTOM, "-activepen", "activePen", "ActivePen",
+	DEF_LINE_ACTIVE_PEN, Blt_Offset(LineElement, activePenPtr),
+	BLT_CONFIG_NULL_OK, &bltLinePenOption},
+    {BLT_CONFIG_COLOR, "-areaforeground", "areaForeground", "AreaForeground",
+	DEF_LINE_PATTERN_FG, Blt_Offset(LineElement, fillFgColor), 
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_BACKGROUND, "-areabackground", "areaBackground", 
+	"AreaBackground", DEF_LINE_PATTERN_BG, Blt_Offset(LineElement, fillBg),
+	 BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_LINE_TAGS, 
+	Blt_Offset(LineElement, obj.tags), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_LINE_PEN_COLOR, 
+	Blt_Offset(LineElement, builtinPen.traceColor), 0},
+    {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_LINE_DASHES, 
+	Blt_Offset(LineElement, builtinPen.traceDashes), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_CUSTOM, "-data", "data", "Data", DEF_LINE_DATA, 0, 0, 
+	&bltValuePairsOption},
+    {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor",
+	DEF_LINE_ERRORBAR_COLOR, 
+	Blt_Offset(LineElement, builtinPen.errorBarColor), 0, &bltColorOption},
+    {BLT_CONFIG_PIXELS_NNEG,"-errorbarwidth", "errorBarWidth", "ErrorBarWidth",
+	DEF_LINE_ERRORBAR_LINE_WIDTH, 
+	Blt_Offset(LineElement, builtinPen.errorBarLineWidth),
+        BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-errorbarcap", "errorBarCap", "ErrorBarCap", 
+	DEF_LINE_ERRORBAR_CAP_WIDTH, 
+	Blt_Offset(LineElement, builtinPen.errorBarCapWidth),
+        BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-fill", "fill", "Fill", DEF_LINE_FILL_COLOR, 
+	Blt_Offset(LineElement, builtinPen.symbol.fillColor), 
+	BLT_CONFIG_NULL_OK, &bltColorOption},
+    {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_LINE_HIDE, 
+        Blt_Offset(LineElement, flags), BLT_CONFIG_DONT_SET_DEFAULT,
+        (Blt_CustomOption *)HIDE},
+    {BLT_CONFIG_STRING, "-label", "label", "Label", (char *)NULL, 
+	Blt_Offset(LineElement, label), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_RELIEF, "-legendrelief", "legendRelief", "LegendRelief",
+	DEF_LINE_LABEL_RELIEF, Blt_Offset(LineElement, legendRelief),
+	BLT_CONFIG_DONT_SET_DEFAULT}, 
+    {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth",
+	DEF_LINE_PEN_WIDTH, Blt_Offset(LineElement, builtinPen.traceWidth),
+        BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX",
+        DEF_LINE_AXIS_X, Blt_Offset(LineElement, axes.x), 0, &bltXAxisOption},
+    {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY",
+	DEF_LINE_AXIS_Y, Blt_Offset(LineElement, axes.y), 0, &bltYAxisOption},
+    {BLT_CONFIG_INT_NNEG, "-maxsymbols", "maxSymbols", "MaxSymbols",
+	DEF_LINE_MAX_SYMBOLS, Blt_Offset(LineElement, reqMaxSymbols),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-offdash", "offDash", "OffDash", 
+	DEF_LINE_OFFDASH_COLOR, 
+	Blt_Offset(LineElement, builtinPen.traceOffColor),
+	BLT_CONFIG_NULL_OK, &bltColorOption},
+    {BLT_CONFIG_CUSTOM, "-outline", "outline", "Outline", 
+	DEF_LINE_OUTLINE_COLOR, 
+	Blt_Offset(LineElement, builtinPen.symbol.outlineColor), 
+	0, &bltColorOption},
+    {BLT_CONFIG_PIXELS_NNEG, "-outlinewidth", "outlineWidth", "OutlineWidth",
+	DEF_LINE_OUTLINE_WIDTH, 
+	Blt_Offset(LineElement, builtinPen.symbol.outlineWidth),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-pen", "pen", "Pen", (char *)NULL, 
+	Blt_Offset(LineElement, normalPenPtr), BLT_CONFIG_NULL_OK, 
+	&bltLinePenOption},
+    {BLT_CONFIG_PIXELS_NNEG, "-pixels", "pixels", "Pixels", DEF_LINE_PIXELS, 
+	Blt_Offset(LineElement, builtinPen.symbol.size), GRAPH | STRIPCHART}, 
+    {BLT_CONFIG_FLOAT, "-reduce", "reduce", "Reduce",
+	DEF_LINE_REDUCE, Blt_Offset(LineElement, rTolerance),
+	GRAPH | STRIPCHART | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BOOLEAN, "-scalesymbols", "scaleSymbols", "ScaleSymbols",
+	DEF_LINE_SCALE_SYMBOLS, Blt_Offset(LineElement, scaleSymbols),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_FILL, "-showerrorbars", "showErrorBars", "ShowErrorBars",
+	DEF_LINE_SHOW_ERRORBARS, 
+	Blt_Offset(LineElement, builtinPen.errorBarShow), 
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues",
+	DEF_PEN_SHOW_VALUES, Blt_Offset(LineElement, builtinPen.valueShow),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-smooth", "smooth", "Smooth", DEF_LINE_SMOOTH, 
+	Blt_Offset(LineElement, reqSmooth), BLT_CONFIG_DONT_SET_DEFAULT, 
+	&smoothOption},
+    {BLT_CONFIG_STATE, "-state", "state", "State", DEF_LINE_STATE, 
+	Blt_Offset(LineElement, state), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-styles", "styles", "Styles", DEF_LINE_STYLES, 
+	Blt_Offset(LineElement, styles), 0, &bltLineStylesOption},
+    {BLT_CONFIG_CUSTOM, "-symbol", "symbol", "Symbol", DEF_LINE_SYMBOL, 
+	Blt_Offset(LineElement, builtinPen.symbol), 
+	BLT_CONFIG_DONT_SET_DEFAULT, &symbolOption},
+    {BLT_CONFIG_CUSTOM, "-trace", "trace", "Trace", DEF_LINE_PEN_DIRECTION, 
+	Blt_Offset(LineElement, penDir), 
+	BLT_CONFIG_DONT_SET_DEFAULT, &penDirOption},
+    {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor",
+	DEF_PEN_VALUE_ANCHOR, 
+	Blt_Offset(LineElement, builtinPen.valueStyle.anchor), 0},
+    {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor",
+	DEF_PEN_VALUE_COLOR, 
+	Blt_Offset(LineElement, builtinPen.valueStyle.color), 0},
+    {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont",
+	DEF_PEN_VALUE_FONT, 
+	Blt_Offset(LineElement, builtinPen.valueStyle.font), 0},
+    {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat",
+	DEF_PEN_VALUE_FORMAT, Blt_Offset(LineElement, builtinPen.valueFormat),
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate",
+	DEF_PEN_VALUE_ANGLE, 
+	Blt_Offset(LineElement, builtinPen.valueStyle.angle), 0},
+    {BLT_CONFIG_CUSTOM, "-weights", "weights", "Weights", (char *)NULL, 
+	Blt_Offset(LineElement, w), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-x", "xData", "XData", (char *)NULL, 
+        Blt_Offset(LineElement, x), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-xdata", "xData", "XData", (char *)NULL, 
+	Blt_Offset(LineElement, x), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-xerror", "xError", "XError", (char *)NULL, 
+	Blt_Offset(LineElement, xError), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-xhigh", "xHigh", "XHigh", (char *)NULL, 
+	Blt_Offset(LineElement, xHigh), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-xlow", "xLow", "XLow", (char *)NULL, 
+	Blt_Offset(LineElement, xLow), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-y", "yData", "YData", (char *)NULL, 
+	Blt_Offset(LineElement, y), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-ydata", "yData", "YData", (char *)NULL, 
+	Blt_Offset(LineElement, y), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-yerror", "yError", "YError", (char *)NULL, 
+	Blt_Offset(LineElement, yError), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-yhigh", "yHigh", "YHigh", (char *)NULL, 
+	Blt_Offset(LineElement, yHigh), 0, &bltValuesOption},
+    {BLT_CONFIG_CUSTOM, "-ylow", "yLow", "YLow", (char *)NULL, 
+	Blt_Offset(LineElement, yLow), 0, &bltValuesOption},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+
+static Blt_ConfigSpec linePenConfigSpecs[] =
+{
+    {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_PEN_ACTIVE_COLOR, 
+	Blt_Offset(LinePen, traceColor), ACTIVE_PEN},
+    {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_PEN_NORMAL_COLOR, 
+	Blt_Offset(LinePen, traceColor), NORMAL_PEN},
+    {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_PEN_DASHES, 
+	Blt_Offset(LinePen, traceDashes), BLT_CONFIG_NULL_OK | ALL_PENS},
+    {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor",
+	DEF_LINE_ERRORBAR_COLOR, Blt_Offset(LinePen, errorBarColor), 
+	ALL_PENS, &bltColorOption},
+    {BLT_CONFIG_PIXELS_NNEG, "-errorbarwidth", "errorBarWidth", "ErrorBarWidth",
+	DEF_LINE_ERRORBAR_LINE_WIDTH, Blt_Offset(LinePen, errorBarLineWidth),
+        ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-errorbarcap", "errorBarCap", "ErrorBarCap", 
+	DEF_LINE_ERRORBAR_CAP_WIDTH, Blt_Offset(LinePen, errorBarCapWidth),
+        BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-fill", "fill", "Fill", DEF_PEN_FILL_COLOR, 
+	Blt_Offset(LinePen, symbol.fillColor), BLT_CONFIG_NULL_OK | ALL_PENS, 
+	&bltColorOption},
+    {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth",
+        (char *)NULL, Blt_Offset(LinePen, traceWidth), 
+	ALL_PENS| BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-offdash", "offDash", "OffDash", DEF_PEN_OFFDASH_COLOR,
+	Blt_Offset(LinePen, traceOffColor), BLT_CONFIG_NULL_OK | ALL_PENS, 
+	&bltColorOption},
+    {BLT_CONFIG_CUSTOM, "-outline", "outline", "Outline", DEF_PEN_OUTLINE_COLOR,
+	Blt_Offset(LinePen, symbol.outlineColor), ALL_PENS, &bltColorOption},
+    {BLT_CONFIG_PIXELS_NNEG, "-outlinewidth", "outlineWidth", "OutlineWidth",
+	DEF_PEN_OUTLINE_WIDTH, Blt_Offset(LinePen, symbol.outlineWidth),
+	BLT_CONFIG_DONT_SET_DEFAULT | ALL_PENS},
+    {BLT_CONFIG_PIXELS_NNEG, "-pixels", "pixels", "Pixels", DEF_PEN_PIXELS, 
+	Blt_Offset(LinePen, symbol.size), ALL_PENS},
+    {BLT_CONFIG_FILL, "-showerrorbars", "showErrorBars", "ShowErrorBars",
+	DEF_LINE_SHOW_ERRORBARS, Blt_Offset(LinePen, errorBarShow),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues",
+	DEF_PEN_SHOW_VALUES, Blt_Offset(LinePen, valueShow),
+	ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-symbol", "symbol", "Symbol", DEF_PEN_SYMBOL, 
+	Blt_Offset(LinePen, symbol), BLT_CONFIG_DONT_SET_DEFAULT | ALL_PENS, 
+	&symbolOption},
+    {BLT_CONFIG_STRING, "-type", (char *)NULL, (char *)NULL, DEF_PEN_TYPE, 
+	Blt_Offset(Pen, typeId), ALL_PENS | BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor",
+	DEF_PEN_VALUE_ANCHOR, Blt_Offset(LinePen, valueStyle.anchor), ALL_PENS},
+    {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor",
+	DEF_PEN_VALUE_COLOR, Blt_Offset(LinePen, valueStyle.color), ALL_PENS},
+    {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont",
+	DEF_PEN_VALUE_FONT, Blt_Offset(LinePen, valueStyle.font), ALL_PENS},
+    {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat",
+	DEF_PEN_VALUE_FORMAT, Blt_Offset(LinePen, valueFormat),
+	ALL_PENS | BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate",
+	DEF_PEN_VALUE_ANGLE, Blt_Offset(LinePen, valueStyle.angle), ALL_PENS},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+typedef double (DistanceProc)(int x, int y, Point2d *p, Point2d *q, Point2d *t);
+
+/* Forward declarations */
+static PenConfigureProc ConfigurePenProc;
+static PenDestroyProc DestroyPenProc;
+static ElementClosestProc ClosestLineProc;
+static ElementConfigProc ConfigureLineProc;
+static ElementDestroyProc DestroyLineProc;
+static ElementDrawProc DrawActiveLineProc;
+static ElementDrawProc DrawNormalLineProc;
+static ElementDrawSymbolProc DrawSymbolProc;
+static ElementExtentsProc GetLineExtentsProc;
+static ElementToPostScriptProc ActiveLineToPostScriptProc;
+static ElementToPostScriptProc NormalLineToPostScriptProc;
+static ElementSymbolToPostScriptProc SymbolToPostScriptProc;
+static ElementMapProc MapLineProc;
+static DistanceProc DistanceToYProc;
+static DistanceProc DistanceToXProc;
+static DistanceProc DistanceToLineProc;
+static Blt_BackgroundChangedProc BackgroundChangedProc;
+
+INLINE static int
+Round(double x)
+{
+    return (int) (x + ((x < 0.0) ? -0.5 : 0.5));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * 	Custom configuration option (parse and print) routines
+ *---------------------------------------------------------------------------
+ */
+
+static void
+DestroySymbol(Display *display, Symbol *symbolPtr)
+{
+    if (symbolPtr->image != NULL) {
+	Tk_FreeImage(symbolPtr->image);
+	symbolPtr->image = NULL;
+    }
+    if (symbolPtr->bitmap != None) {
+	Tk_FreeBitmap(display, symbolPtr->bitmap);
+	symbolPtr->bitmap = None;
+    }
+    if (symbolPtr->mask != None) {
+	Tk_FreeBitmap(display, symbolPtr->mask);
+	symbolPtr->mask = None;
+    }
+    symbolPtr->type = SYMBOL_NONE;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ImageChangedProc
+ *
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static void
+ImageChangedProc(
+    ClientData clientData,
+    int x, int y, int w, int h,		/* Not used. */
+    int imageWidth, int imageHeight)	/* Not used. */
+{
+    Element *elemPtr;
+    Graph *graphPtr;
+
+    elemPtr = clientData;
+    elemPtr->flags |= MAP_ITEM;
+    graphPtr = elemPtr->obj.graphPtr;
+    graphPtr->flags |= CACHE_DIRTY;
+    Blt_EventuallyRedrawGraph(graphPtr);
+}
+
+/*ARGSUSED*/
+static void
+FreeSymbolProc(
+    ClientData clientData,		/* Not used. */
+    Display *display,			/* Not used. */
+    char *widgRec,
+    int offset)
+{
+    Symbol *symbolPtr = (Symbol *)(widgRec + offset);
+
+    DestroySymbol(display, symbolPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToSymbol --
+ *
+ *	Convert the string representation of a line style or symbol name into
+ *	its numeric form.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The symbol type is written
+ *	into the widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToSymbolProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Interpreter to send results back
+					 * to */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* String representing symbol type */
+    char *widgRec,			/* Element information record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    Symbol *symbolPtr = (Symbol *)(widgRec + offset);
+    const char *string;
+
+    {
+	int length;
+	GraphSymbolType *p;
+	char c;
+
+	string = Tcl_GetStringFromObj(objPtr, &length);
+	if (length == 0) {
+	    DestroySymbol(Tk_Display(tkwin), symbolPtr);
+	    symbolPtr->type = SYMBOL_NONE;
+	    return TCL_OK;
+	}
+	c = string[0];
+	for (p = graphSymbols; p->name != NULL; p++) {
+	    if (length < p->minChars) {
+		continue;
+	    }
+	    if ((c == p->name[0]) && (strncmp(string, p->name, length) == 0)) {
+		DestroySymbol(Tk_Display(tkwin), symbolPtr);
+		symbolPtr->type = p->type;
+		return TCL_OK;
+	    }
+	}
+    }
+    {
+	Tk_Image tkImage;
+	Element *elemPtr = (Element *)widgRec;
+
+	tkImage = Tk_GetImage(interp, tkwin, string, ImageChangedProc, elemPtr);
+	if (tkImage != NULL) {
+	    DestroySymbol(Tk_Display(tkwin), symbolPtr);
+	    symbolPtr->image = tkImage;
+	    symbolPtr->type = SYMBOL_IMAGE;
+	    return TCL_OK;
+	}
+    }
+    {
+	Pixmap bitmap, mask;
+	Tcl_Obj **objv;
+	int objc;
+
+	if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) || 
+	    (objc > 2)) {
+	    goto error;
+	}
+	bitmap = mask = None;
+	if (objc > 0) {
+	    bitmap = Tk_AllocBitmapFromObj((Tcl_Interp *)NULL, tkwin, objv[0]);
+	    if (bitmap == None) {
+		goto error;
+	    }
+	}
+	if (objc > 1) {
+	    mask = Tk_AllocBitmapFromObj((Tcl_Interp *)NULL, tkwin, objv[1]);
+	    if (mask == None) {
+		goto error;
+	    }
+	}
+	DestroySymbol(Tk_Display(tkwin), symbolPtr);
+	symbolPtr->bitmap = bitmap;
+	symbolPtr->mask = mask;
+	symbolPtr->type = SYMBOL_BITMAP;
+	return TCL_OK;
+    }
+ error:
+    Tcl_AppendResult(interp, "bad symbol \"", string, 
+	"\": should be \"none\", \"circle\", \"square\", \"diamond\", "
+	"\"plus\", \"cross\", \"splus\", \"scross\", \"triangle\", "
+	"\"arrow\" or the name of a bitmap", (char *)NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SymbolToObj --
+ *
+ *	Convert the symbol value into a string.
+ *
+ * Results:
+ *	The string representing the symbol type or line style is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+SymbolToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,
+    Tk_Window tkwin,
+    char *widgRec,			/* Element information record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    Symbol *symbolPtr = (Symbol *)(widgRec + offset);
+
+    if (symbolPtr->type == SYMBOL_BITMAP) {
+	Tcl_Obj *listObjPtr, *objPtr;
+	const char *name;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	name = Tk_NameOfBitmap(Tk_Display(tkwin), symbolPtr->bitmap);
+	objPtr = Tcl_NewStringObj(name, -1);
+	Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	if (symbolPtr->mask == None) {
+	    objPtr = Tcl_NewStringObj("", -1);
+	} else {
+	    name = Tk_NameOfBitmap(Tk_Display(tkwin), symbolPtr->mask);
+	    objPtr = Tcl_NewStringObj(name, -1);
+	}
+	Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	return listObjPtr;
+    } else {
+	GraphSymbolType *p;
+
+	for (p = graphSymbols; p->name != NULL; p++) {
+	    if (p->type == symbolPtr->type) {
+		return Tcl_NewStringObj(p->name, -1);
+	    }
+	}
+	return Tcl_NewStringObj("?unknown symbol type?", -1);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NameOfSmooth --
+ *
+ *	Converts the smooth value into its string representation.
+ *
+ * Results:
+ *	The static string representing the smooth type is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+static const char *
+NameOfSmooth(Smoothing value)
+{
+    SmoothingInfo *siPtr;
+
+    for (siPtr = smoothingInfo; siPtr->name != NULL; siPtr++) {
+	if (siPtr->value == value) {
+	    return siPtr->name;
+	}
+    }
+    return "unknown smooth value";
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToSmooth --
+ *
+ *	Convert the string representation of a line style or smooth name
+ *	into its numeric form.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The smooth type is
+ *	written into the widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToSmoothProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Interpreter to send results back
+					 * to */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* String representing smooth type */
+    char *widgRec,			/* Element information record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    Smoothing *valuePtr = (Smoothing *)(widgRec + offset);
+    SmoothingInfo *siPtr;
+    const char *string;
+    char c;
+
+    string = Tcl_GetString(objPtr);
+    c = string[0];
+    for (siPtr = smoothingInfo; siPtr->name != NULL; siPtr++) {
+	if ((c == siPtr->name[0]) && (strcmp(string, siPtr->name) == 0)) {
+	    *valuePtr = siPtr->value;
+	    return TCL_OK;
+	}
+    }
+    Tcl_AppendResult(interp, "bad smooth value \"", string, "\": should be \
+linear, step, natural, or quadratic", (char *)NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SmoothToObj --
+ *
+ *	Convert the smooth value into a string.
+ *
+ * Results:
+ *	The string representing the smooth type or line style is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+SmoothToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Not used. */
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* Element information record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    int smooth = *(int *)(widgRec + offset);
+
+    return Tcl_NewStringObj(NameOfSmooth(smooth), -1);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToPenDir --
+ *
+ *	Convert the string representation of a line style or symbol name
+ *	into its numeric form.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The symbol type is
+ *	written into the widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToPenDirProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Interpreter to send results back
+					 * to */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* String representing pen direction */
+    char *widgRec,			/* Element information record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    int *penDirPtr = (int *)(widgRec + offset);
+    int length;
+    char c;
+    char *string;
+
+    string = Tcl_GetStringFromObj(objPtr, &length);
+    c = string[0];
+    if ((c == 'i') && (strncmp(string, "increasing", length) == 0)) {
+	*penDirPtr = PEN_INCREASING;
+    } else if ((c == 'd') && (strncmp(string, "decreasing", length) == 0)) {
+	*penDirPtr = PEN_DECREASING;
+    } else if ((c == 'b') && (strncmp(string, "both", length) == 0)) {
+	*penDirPtr = PEN_BOTH_DIRECTIONS;
+    } else {
+	Tcl_AppendResult(interp, "bad trace value \"", string,
+	    "\" : should be \"increasing\", \"decreasing\", or \"both\"",
+	    (char *)NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NameOfPenDir --
+ *
+ *	Convert the pen direction into a string.
+ *
+ * Results:
+ *	The static string representing the pen direction is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+static const char *
+NameOfPenDir(int penDir)
+{
+    switch (penDir) {
+    case PEN_INCREASING:
+	return "increasing";
+    case PEN_DECREASING:
+	return "decreasing";
+    case PEN_BOTH_DIRECTIONS:
+	return "both";
+    default:
+	return "unknown trace direction";
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PenDirToObj --
+ *
+ *	Convert the pen direction into a string.
+ *
+ * Results:
+ *	The string representing the pen drawing direction is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+PenDirToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Not used. */
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* Element information record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    int penDir = *(int *)(widgRec + offset);
+
+    return Tcl_NewStringObj(NameOfPenDir(penDir), -1);
+}
+
+
+/*
+ * Reset the number of points and segments, in case there are no segments or
+ * points
+ */
+static void
+ResetStylePalette(Blt_Chain styles)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_FirstLink(styles); link != NULL;
+	 link = Blt_Chain_NextLink(link)) {
+	LineStyle *stylePtr;
+
+	stylePtr = Blt_Chain_GetValue(link);
+	stylePtr->lines.length = stylePtr->symbolPts.length = 0;
+	stylePtr->xeb.length = stylePtr->yeb.length = 0;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigurePenProc --
+ *
+ *	Sets up the appropriate configuration parameters in the GC.  It is
+ *	assumed the parameters have been previously set by a call to
+ *	Blt_ConfigureWidget.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  If TCL_ERROR is returned,
+ *	then interp->result contains an error message.
+ *
+ * Side effects:
+ *	Configuration information such as line width, line style, color
+ *	etc. get set in a new GC.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ConfigurePenProc(Graph *graphPtr, Pen *penPtr)
+{
+    LinePen *lpPtr = (LinePen *)penPtr;
+    unsigned long gcMask;
+    GC newGC;
+    XGCValues gcValues;
+    XColor *colorPtr;
+
+    /*
+     * Set the outline GC for this pen: GCForeground is outline color.
+     * GCBackground is the fill color (only used for bitmap symbols).
+     */
+    gcMask = (GCLineWidth | GCForeground);
+    colorPtr = lpPtr->symbol.outlineColor;
+    if (colorPtr == COLOR_DEFAULT) {
+	colorPtr = lpPtr->traceColor;
+    }
+    gcValues.foreground = colorPtr->pixel;
+    if (lpPtr->symbol.type == SYMBOL_BITMAP) {
+	colorPtr = lpPtr->symbol.fillColor;
+	if (colorPtr == COLOR_DEFAULT) {
+	    colorPtr = lpPtr->traceColor;
+	}
+	/*
+	 * Set a clip mask if either
+	 *	1) no background color was designated or
+	 *	2) a masking bitmap was specified.
+	 *
+	 * These aren't necessarily the bitmaps we'll be using for clipping. But
+	 * this makes it unlikely that anyone else will be sharing this GC when
+	 * we set the clip origin (at the time the bitmap is drawn).
+	 */
+	if (colorPtr != NULL) {
+	    gcValues.background = colorPtr->pixel;
+	    gcMask |= GCBackground;
+	    if (lpPtr->symbol.mask != None) {
+		gcValues.clip_mask = lpPtr->symbol.mask;
+		gcMask |= GCClipMask;
+	    }
+	} else {
+	    gcValues.clip_mask = lpPtr->symbol.bitmap;
+	    gcMask |= GCClipMask;
+	}
+    }
+    gcValues.line_width = LineWidth(lpPtr->symbol.outlineWidth);
+    newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (lpPtr->symbol.outlineGC != NULL) {
+	Tk_FreeGC(graphPtr->display, lpPtr->symbol.outlineGC);
+    }
+    lpPtr->symbol.outlineGC = newGC;
+
+    /* Fill GC for symbols: GCForeground is fill color */
+
+    gcMask = (GCLineWidth | GCForeground);
+    colorPtr = lpPtr->symbol.fillColor;
+    if (colorPtr == COLOR_DEFAULT) {
+	colorPtr = lpPtr->traceColor;
+    }
+    newGC = NULL;
+    if (colorPtr != NULL) {
+	gcValues.foreground = colorPtr->pixel;
+	newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    }
+    if (lpPtr->symbol.fillGC != NULL) {
+	Tk_FreeGC(graphPtr->display, lpPtr->symbol.fillGC);
+    }
+    lpPtr->symbol.fillGC = newGC;
+
+    /* Line segments */
+
+    gcMask = (GCLineWidth | GCForeground | GCLineStyle | GCCapStyle |
+	GCJoinStyle);
+    gcValues.cap_style = CapButt;
+    gcValues.join_style = JoinRound;
+    gcValues.line_style = LineSolid;
+    gcValues.line_width = LineWidth(lpPtr->traceWidth);
+
+    colorPtr = lpPtr->traceOffColor;
+    if (colorPtr == COLOR_DEFAULT) {
+	colorPtr = lpPtr->traceColor;
+    }
+    if (colorPtr != NULL) {
+	gcMask |= GCBackground;
+	gcValues.background = colorPtr->pixel;
+    }
+    gcValues.foreground = lpPtr->traceColor->pixel;
+    if (LineIsDashed(lpPtr->traceDashes)) {
+	gcValues.line_width = lpPtr->traceWidth;
+	gcValues.line_style = 
+	    (colorPtr == NULL) ? LineOnOffDash : LineDoubleDash;
+    }
+    newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (lpPtr->traceGC != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, lpPtr->traceGC);
+    }
+    if (LineIsDashed(lpPtr->traceDashes)) {
+	lpPtr->traceDashes.offset = lpPtr->traceDashes.values[0] / 2;
+	Blt_SetDashes(graphPtr->display, newGC, &lpPtr->traceDashes);
+    }
+    lpPtr->traceGC = newGC;
+
+    gcMask = (GCLineWidth | GCForeground);
+    colorPtr = lpPtr->errorBarColor;
+    if (colorPtr == COLOR_DEFAULT) {
+	colorPtr = lpPtr->traceColor;
+    }
+    gcValues.line_width = LineWidth(lpPtr->errorBarLineWidth);
+    gcValues.foreground = colorPtr->pixel;
+    newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (lpPtr->errorBarGC != NULL) {
+	Tk_FreeGC(graphPtr->display, lpPtr->errorBarGC);
+    }
+    lpPtr->errorBarGC = newGC;
+
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DestroyPenProc --
+ *
+ *	Release memory and resources allocated for the style.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Everything associated with the pen style is freed up.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DestroyPenProc(Graph *graphPtr, Pen *basePtr)
+{
+    LinePen *penPtr = (LinePen *)basePtr;
+
+    Blt_Ts_FreeStyle(graphPtr->display, &penPtr->valueStyle);
+    if (penPtr->symbol.outlineGC != NULL) {
+	Tk_FreeGC(graphPtr->display, penPtr->symbol.outlineGC);
+    }
+    if (penPtr->symbol.fillGC != NULL) {
+	Tk_FreeGC(graphPtr->display, penPtr->symbol.fillGC);
+    }
+    if (penPtr->errorBarGC != NULL) {
+	Tk_FreeGC(graphPtr->display, penPtr->errorBarGC);
+    }
+    if (penPtr->traceGC != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, penPtr->traceGC);
+    }
+    if (penPtr->symbol.bitmap != None) {
+	Tk_FreeBitmap(graphPtr->display, penPtr->symbol.bitmap);
+	penPtr->symbol.bitmap = None;
+    }
+    if (penPtr->symbol.mask != None) {
+	Tk_FreeBitmap(graphPtr->display, penPtr->symbol.mask);
+	penPtr->symbol.mask = None;
+    }
+}
+
+
+static void
+InitLinePen(LinePen *penPtr)
+{
+    Blt_Ts_InitStyle(penPtr->valueStyle);
+    penPtr->errorBarLineWidth = 2;
+    penPtr->errorBarShow = SHOW_BOTH;
+    penPtr->configProc = ConfigurePenProc;
+    penPtr->configSpecs = linePenConfigSpecs;
+    penPtr->destroyProc = DestroyPenProc;
+    penPtr->flags = NORMAL_PEN;
+    penPtr->name = "";
+    penPtr->symbol.bitmap = penPtr->symbol.mask = None;
+    penPtr->symbol.outlineColor = penPtr->symbol.fillColor = COLOR_DEFAULT;
+    penPtr->symbol.outlineWidth = penPtr->traceWidth = 1;
+    penPtr->symbol.type = SYMBOL_CIRCLE;
+    penPtr->valueShow = SHOW_NONE;
+}
+
+Pen *
+Blt_LinePen(const char *penName)
+{
+    LinePen *penPtr;
+
+    penPtr = calloc(1, sizeof(LinePen));
+    InitLinePen(penPtr);
+    penPtr->name = Blt_Strdup(penName);
+    penPtr->classId = CID_ELEM_LINE;
+    if (strcmp(penName, "activeLine") == 0) {
+	penPtr->flags = ACTIVE_PEN;
+    }
+    return (Pen *)penPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ *	In this section, the routines deal with building and filling the
+ *	element's data structures with transformed screen coordinates.  They are
+ *	triggered from TranformLine which is called whenever the data or
+ *	coordinates axes have changed and new screen coordinates need to be
+ *	calculated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ScaleSymbol --
+ *
+ *	Returns the scaled size for the line element. Scaling depends upon when
+ *	the base line ranges for the element were set and the current range of
+ *	the graph.
+ *
+ * Results:
+ *	The new size of the symbol, after considering how much the graph has
+ *	been scaled, is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ScaleSymbol(LineElement *elemPtr, int normalSize)
+{
+    int maxSize;
+    double scale;
+    int newSize;
+
+    scale = 1.0;
+    if (elemPtr->scaleSymbols) {
+	double xRange, yRange;
+
+	xRange = (elemPtr->axes.x->max - elemPtr->axes.x->min);
+	yRange = (elemPtr->axes.y->max - elemPtr->axes.y->min);
+	if (elemPtr->flags & SCALE_SYMBOL) {
+	    /* Save the ranges as a baseline for future scaling. */
+	    elemPtr->xRange = xRange;
+	    elemPtr->yRange = yRange;
+	    elemPtr->flags &= ~SCALE_SYMBOL;
+	} else {
+	    double xScale, yScale;
+
+	    /* Scale the symbol by the smallest change in the X or Y axes */
+	    xScale = elemPtr->xRange / xRange;
+	    yScale = elemPtr->yRange / yRange;
+	    scale = MIN(xScale, yScale);
+	}
+    }
+    newSize = Round(normalSize * scale);
+
+    /*
+     * Don't let the size of symbols go unbounded. Both X and Win32 drawing
+     * routines assume coordinates to be a signed short int.
+     */
+    maxSize = (int)MIN(elemPtr->obj.graphPtr->hRange, 
+		       elemPtr->obj.graphPtr->vRange);
+    if (newSize > maxSize) {
+	newSize = maxSize;
+    }
+
+    /* Make the symbol size odd so that its center is a single pixel. */
+    newSize |= 0x01;
+    return newSize;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetScreenPoints --
+ *
+ *	Generates a coordinate array of transformed screen coordinates from
+ *	the data points.  Coordinates with Inf, -Inf, or NaN values are
+ *	removed.
+ *
+ * Results:
+ *	The transformed screen coordinates are returned.
+ *
+ * Side effects:
+ *	Memory is allocated for the coordinate array.
+ *
+ *
+ * Future ideas:
+ *	Allow bad values to be removed (as done currently) or break
+ *	into separate traces.  Smoothing would be affected.  
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+GetScreenPoints(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr)
+{
+    double *x, *y;
+    int i, np;
+    int count;
+    Point2d *points;
+    int *map;
+
+    np = NUMBEROFPOINTS(elemPtr);
+    x = elemPtr->x.values;
+    y = elemPtr->y.values;
+    points = malloc(sizeof(Point2d) * np);
+    map = malloc(sizeof(int) * np);
+
+    count = 0;			      /* Count the valid screen coordinates */
+    if (graphPtr->inverted) {
+	for (i = 0; i < np; i++) {
+	    if ((isfinite(x[i])) && (isfinite(y[i]))) {
+ 		points[count].x = Blt_HMap(elemPtr->axes.y, y[i]);
+		points[count].y = Blt_VMap(elemPtr->axes.x, x[i]);
+		map[count] = i;
+		count++;
+	    }
+	}
+    } else {
+	for (i = 0; i < np; i++) {
+	    if ((isfinite(x[i])) && (isfinite(y[i]))) {
+		points[count].x = Blt_HMap(elemPtr->axes.x, x[i]);
+		points[count].y = Blt_VMap(elemPtr->axes.y, y[i]);
+		map[count] = i;
+		count++;
+	    }
+	}
+    }
+    mapPtr->screenPts = points;
+    mapPtr->nScreenPts = count;
+    mapPtr->map = map;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ReducePoints --
+ *
+ *	Generates a coordinate array of transformed screen coordinates from
+ *	the data points.
+ *
+ * Results:
+ *	The transformed screen coordinates are returned.
+ *
+ * Side effects:
+ *	Memory is allocated for the coordinate array.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+ReducePoints(MapInfo *mapPtr, double tolerance)
+{
+    int i, np;
+    Point2d *screenPts;
+    int *map, *simple;
+
+    simple    = malloc(mapPtr->nScreenPts * sizeof(int));
+    map	      = malloc(mapPtr->nScreenPts * sizeof(int));
+    screenPts = malloc(mapPtr->nScreenPts * sizeof(Point2d));
+    np = Blt_SimplifyLine(mapPtr->screenPts, 0, mapPtr->nScreenPts - 1, 
+		 tolerance, simple);
+    for (i = 0; i < np; i++) {
+	int k;
+
+	k = simple[i];
+	screenPts[i] = mapPtr->screenPts[k];
+	map[i] = mapPtr->map[k];
+    }
+    free(mapPtr->screenPts);
+    free(mapPtr->map);
+    free(simple);
+    mapPtr->screenPts = screenPts;
+    mapPtr->map = map;
+    mapPtr->nScreenPts = np;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GenerateSteps --
+ *
+ *	Resets the coordinate and pen index arrays adding new points for
+ *	step-and-hold type smoothing.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	The temporary arrays for screen coordinates and pen indices
+ *	are updated.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+GenerateSteps(MapInfo *mapPtr)
+{
+    int newSize;
+    int i, count;
+    Point2d *screenPts;
+    int *map;
+
+    newSize = ((mapPtr->nScreenPts - 1) * 2) + 1;
+    screenPts = malloc(newSize * sizeof(Point2d));
+    map = malloc(sizeof(int) * newSize);
+    screenPts[0] = mapPtr->screenPts[0];
+    map[0] = 0;
+
+    count = 1;
+    for (i = 1; i < mapPtr->nScreenPts; i++) {
+	screenPts[count + 1] = mapPtr->screenPts[i];
+
+	/* Hold last y-coordinate, use new x-coordinate */
+	screenPts[count].x = screenPts[count + 1].x;
+	screenPts[count].y = screenPts[count - 1].y;
+
+	/* Use the same style for both the hold and the step points */
+	map[count] = map[count + 1] = mapPtr->map[i];
+	count += 2;
+    }
+    free(mapPtr->screenPts);
+    free(mapPtr->map);
+    mapPtr->map = map;
+    mapPtr->screenPts = screenPts;
+    mapPtr->nScreenPts = newSize;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GenerateSpline --
+ *
+ *	Computes a spline based upon the data points, returning a new (larger)
+ *	coordinate array or points.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	The temporary arrays for screen coordinates and data map are updated
+ *	based upon spline.
+ *
+ * FIXME:  Can't interpolate knots along the Y-axis.   Need to break
+ *	   up point array into interchangable X and Y vectors earlier.
+ *	   Pass extents (left/right or top/bottom) as parameters.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+GenerateSpline(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr)
+{
+    Point2d *origPts, *iPts;
+    int *map;
+    int extra;
+    int niPts, nOrigPts;
+    int result;
+    int i, j, count;
+
+    nOrigPts = mapPtr->nScreenPts;
+    origPts = mapPtr->screenPts;
+    assert(mapPtr->nScreenPts > 0);
+    for (i = 0, j = 1; j < nOrigPts; i++, j++) {
+	if (origPts[j].x <= origPts[i].x) {
+	    return;			/* Points are not monotonically
+					 * increasing */
+	}
+    }
+    if (((origPts[0].x > (double)graphPtr->right)) ||
+	((origPts[mapPtr->nScreenPts - 1].x < (double)graphPtr->left))) {
+	return;				/* All points are clipped */
+    }
+
+    /*
+     * The spline is computed in screen coordinates instead of data points so
+     * that we can select the abscissas of the interpolated points from each
+     * pixel horizontally across the plotting area.
+     */
+    extra = (graphPtr->right - graphPtr->left) + 1;
+    if (extra < 1) {
+	return;
+    }
+    niPts = nOrigPts + extra + 1;
+    iPts = malloc(niPts * sizeof(Point2d));
+    map = malloc(sizeof(int) * niPts);
+    /* Populate the x2 array with both the original X-coordinates and extra
+     * X-coordinates for each horizontal pixel that the line segment
+     * contains. */
+    count = 0;
+    for (i = 0, j = 1; j < nOrigPts; i++, j++) {
+
+	/* Add the original x-coordinate */
+	iPts[count].x = origPts[i].x;
+
+	/* Include the starting offset of the point in the offset array */
+	map[count] = mapPtr->map[i];
+	count++;
+
+	/* Is any part of the interval (line segment) in the plotting area?  */
+	if ((origPts[j].x >= (double)graphPtr->left) || 
+	    (origPts[i].x <= (double)graphPtr->right)) {
+	    double x, last;
+
+	    x = origPts[i].x + 1.0;
+
+	    /*
+	     * Since the line segment may be partially clipped on the left or
+	     * right side, the points to interpolate are always interior to
+	     * the plotting area.
+	     *
+	     *           left			    right
+	     *      x1----|---------------------------|---x2
+	     *
+	     * Pick the max of the starting X-coordinate and the left edge and
+	     * the min of the last X-coordinate and the right edge.
+	     */
+	    x = MAX(x, (double)graphPtr->left);
+	    last = MIN(origPts[j].x, (double)graphPtr->right);
+
+	    /* Add the extra x-coordinates to the interval. */
+	    while (x < last) {
+		map[count] = mapPtr->map[i];
+		iPts[count++].x = x;
+		x++;
+	    }
+	}
+    }
+    niPts = count;
+    result = FALSE;
+    if (elemPtr->smooth == PEN_SMOOTH_NATURAL) {
+	result = Blt_NaturalSpline(origPts, nOrigPts, iPts, niPts);
+    } else if (elemPtr->smooth == PEN_SMOOTH_QUADRATIC) {
+	result = Blt_QuadraticSpline(origPts, nOrigPts, iPts, niPts);
+    }
+    if (!result) {
+	/* The spline interpolation failed.  We'll fallback to the current
+	 * coordinates and do no smoothing (standard line segments).  */
+	elemPtr->smooth = PEN_SMOOTH_LINEAR;
+	free(iPts);
+	free(map);
+    } else {
+	free(mapPtr->screenPts);
+	free(mapPtr->map);
+	mapPtr->map = map;
+	mapPtr->screenPts = iPts;
+	mapPtr->nScreenPts = niPts;
+    }
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GenerateParametricSpline --
+ *
+ *	Computes a spline based upon the data points, returning a new (larger)
+ *	coordinate array or points.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	The temporary arrays for screen coordinates and data map are updated
+ *	based upon spline.
+ *
+ * FIXME:  Can't interpolate knots along the Y-axis.   Need to break
+ *	   up point array into interchangable X and Y vectors earlier.
+ *	   Pass extents (left/right or top/bottom) as parameters.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+GenerateParametricSpline(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr)
+{
+    Region2d exts;
+    Point2d *origPts, *iPts;
+    int *map;
+    int niPts, nOrigPts;
+    int result;
+    int i, j, count;
+
+    nOrigPts = mapPtr->nScreenPts;
+    origPts = mapPtr->screenPts;
+    assert(mapPtr->nScreenPts > 0);
+
+    Blt_GraphExtents(graphPtr, &exts);
+
+    /* 
+     * Populate the x2 array with both the original X-coordinates and extra
+     * X-coordinates for each horizontal pixel that the line segment contains.
+     */
+    count = 1;
+    for (i = 0, j = 1; j < nOrigPts; i++, j++) {
+	Point2d p, q;
+
+        p = origPts[i];
+        q = origPts[j];
+	count++;
+        if (Blt_LineRectClip(&exts, &p, &q)) {
+	    count += (int)(hypot(q.x - p.x, q.y - p.y) * 0.5);
+	}
+    }
+    niPts = count;
+    iPts = malloc(niPts * sizeof(Point2d));
+    map = malloc(sizeof(int) * niPts);
+
+    /* 
+     * FIXME: This is just plain wrong.  The spline should be computed
+     *        and evaluated in separate steps.  This will mean breaking
+     *	      up this routine since the catrom coefficients can be
+     *	      independently computed for original data point.  This 
+     *	      also handles the problem of allocating enough points 
+     *	      since evaluation is independent of the number of points 
+     *		to be evalualted.  The interpolated 
+     *	      line segments should be clipped, not the original segments.
+     */
+    count = 0;
+    for (i = 0, j = 1; j < nOrigPts; i++, j++) {
+	Point2d p, q;
+	double d;
+
+        p = origPts[i];
+        q = origPts[j];
+
+        d = hypot(q.x - p.x, q.y - p.y);
+        /* Add the original x-coordinate */
+        iPts[count].x = (double)i;
+        iPts[count].y = 0.0;
+
+        /* Include the starting offset of the point in the offset array */
+        map[count] = mapPtr->map[i];
+        count++;
+
+        /* Is any part of the interval (line segment) in the plotting
+         * area?  */
+
+        if (Blt_LineRectClip(&exts, &p, &q)) {
+            double dp, dq;
+
+	    /* Distance of original point to p. */
+            dp = hypot(p.x - origPts[i].x, p.y - origPts[i].y);
+	    /* Distance of original point to q. */
+            dq = hypot(q.x - origPts[i].x, q.y - origPts[i].y);
+            dp += 2.0;
+            while(dp <= dq) {
+                /* Point is indicated by its interval and parameter t. */
+                iPts[count].x = (double)i;
+                iPts[count].y =  dp / d;
+                map[count] = mapPtr->map[i];
+                count++;
+                dp += 2.0;
+            }
+        }
+    }
+    iPts[count].x = (double)i;
+    iPts[count].y = 0.0;
+    map[count] = mapPtr->map[i];
+    count++;
+    niPts = count;
+    result = FALSE;
+    if (elemPtr->smooth == PEN_SMOOTH_NATURAL) {
+        result = Blt_NaturalParametricSpline(origPts, nOrigPts, &exts, FALSE,
+		iPts, niPts);
+    } else if (elemPtr->smooth == PEN_SMOOTH_CATROM) {
+        result = Blt_CatromParametricSpline(origPts, nOrigPts, iPts, niPts);
+    }
+    if (!result) {
+        /* The spline interpolation failed.  We will fall back to the current
+         * coordinates and do no smoothing (standard line segments).  */
+        elemPtr->smooth = PEN_SMOOTH_LINEAR;
+        free(iPts);
+        free(map);
+    } else {
+        free(mapPtr->screenPts);
+        free(mapPtr->map);
+        mapPtr->map = map;
+        mapPtr->screenPts = iPts;
+        mapPtr->nScreenPts = niPts;
+    }
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapSymbols --
+ *
+ *	Creates two arrays of points and pen map, filled with the screen
+ *	coordinates of the visible
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is freed and allocated for the index array.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapSymbols(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr)
+{
+    Region2d exts;
+    Point2d *pp, *points;
+    int *map;
+    int i, count;
+
+    points = malloc(sizeof(Point2d) * mapPtr->nScreenPts);
+    map    = malloc(sizeof(int)     * mapPtr->nScreenPts);
+
+    Blt_GraphExtents(graphPtr, &exts);
+    count = 0;			/* Count the number of visible points */
+
+    for (pp = mapPtr->screenPts, i = 0; i < mapPtr->nScreenPts; i++, pp++) {
+	if (PointInRegion(&exts, pp->x, pp->y)) {
+	    points[count].x = pp->x;
+	    points[count].y = pp->y;
+	    map[count] = mapPtr->map[i];
+	    count++;
+	}
+    }
+    elemPtr->symbolPts.points = points;
+    elemPtr->symbolPts.length = count;
+    elemPtr->symbolPts.map = map;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapActiveSymbols --
+ *
+ *	Creates an array of points of the active graph coordinates.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is freed and allocated for the active point array.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapActiveSymbols(Graph *graphPtr, LineElement *elemPtr)
+{
+    Point2d *points;
+    Region2d exts;
+    int *map;
+    int count, i, np;
+
+    if (elemPtr->activePts.points != NULL) {
+	free(elemPtr->activePts.points);
+	elemPtr->activePts.points = NULL;
+    }
+    if (elemPtr->activePts.map != NULL) {
+	free(elemPtr->activePts.map);
+	elemPtr->activePts.map = NULL;
+    }
+    Blt_GraphExtents(graphPtr, &exts);
+    points = malloc(sizeof(Point2d) * elemPtr->nActiveIndices);
+    map    = malloc(sizeof(int)     * elemPtr->nActiveIndices);
+    np = NUMBEROFPOINTS(elemPtr);
+    count = 0;				/* Count the visible active points */
+    for (i = 0; i < elemPtr->nActiveIndices; i++) {
+	double x, y;
+	int iPoint;
+
+	iPoint = elemPtr->activeIndices[i];
+	if (iPoint >= np) {
+	    continue;			/* Index not available */
+	}
+	x = elemPtr->x.values[iPoint];
+	y = elemPtr->y.values[iPoint];
+	points[count] = Blt_Map2D(graphPtr, x, y, &elemPtr->axes);
+	map[count] = iPoint;
+	if (PointInRegion(&exts, points[count].x, points[count].y)) {
+	    count++;
+	}
+    }
+    if (count > 0) {
+	elemPtr->activePts.points = points;
+	elemPtr->activePts.map = map;
+    } else {
+	/* No active points were visible. */
+	free(points);
+	free(map);	
+    }
+    elemPtr->activePts.length = count;
+    elemPtr->flags &= ~ACTIVE_PENDING;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MergePens --
+ *
+ *	Reorders the both arrays of points and segments to merge pens.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The old arrays are freed and new ones allocated containing
+ *	the reordered points and segments.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MergePens(LineElement *elemPtr, LineStyle **styleMap)
+{
+    if (Blt_Chain_GetLength(elemPtr->styles) < 2) {
+	Blt_ChainLink link;
+	LineStyle *stylePtr;
+
+	link = Blt_Chain_FirstLink(elemPtr->styles);
+	stylePtr = Blt_Chain_GetValue(link);
+	stylePtr->errorBarCapWidth = elemPtr->errorBarCapWidth;
+	stylePtr->lines.length = elemPtr->lines.length;
+	stylePtr->lines.segments = elemPtr->lines.segments;
+	stylePtr->symbolPts.length = elemPtr->symbolPts.length;
+	stylePtr->symbolPts.points = elemPtr->symbolPts.points;
+	stylePtr->xeb.length = elemPtr->xeb.length;
+	stylePtr->xeb.segments = elemPtr->xeb.segments;
+	stylePtr->yeb.length = elemPtr->yeb.length;
+	stylePtr->yeb.segments = elemPtr->yeb.segments;
+	return;
+    }
+
+    /* We have more than one style. Group line segments and points of like pen
+     * styles.  */
+    if (elemPtr->lines.length > 0) {
+	Blt_ChainLink link;
+	Segment2d *sp, *segments;
+	int *ip;
+	int *map;
+
+	segments = malloc(elemPtr->lines.length * sizeof(Segment2d));
+	map = malloc(elemPtr->lines.length * sizeof(int));
+	sp = segments, ip = map;
+	for (link = Blt_Chain_FirstLink(elemPtr->styles); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    LineStyle *stylePtr;
+	    int i;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    stylePtr->lines.segments = sp;
+	    for (i = 0; i < elemPtr->lines.length; i++) {
+		int iData;
+
+		iData = elemPtr->lines.map[i];
+		if (styleMap[iData] == stylePtr) {
+		    *sp++ = elemPtr->lines.segments[i];
+		    *ip++ = iData;
+		}
+	    }
+	    stylePtr->lines.length = sp - stylePtr->lines.segments;
+	}
+	free(elemPtr->lines.segments);
+	elemPtr->lines.segments = segments;
+	free(elemPtr->lines.map);
+	elemPtr->lines.map = map;
+    }
+    if (elemPtr->symbolPts.length > 0) {
+	Blt_ChainLink link;
+	int *ip;
+	Point2d *points, *pp;
+	int *map;
+
+	points = malloc(elemPtr->symbolPts.length * sizeof(Point2d));
+	map = malloc(elemPtr->symbolPts.length * sizeof(int));
+	pp = points, ip = map;
+	for (link = Blt_Chain_FirstLink(elemPtr->styles); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    LineStyle *stylePtr;
+	    int i;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    stylePtr->symbolPts.points = pp;
+	    for (i = 0; i < elemPtr->symbolPts.length; i++) {
+		int iData;
+
+		iData = elemPtr->symbolPts.map[i];
+		if (styleMap[iData] == stylePtr) {
+		    *pp++ = elemPtr->symbolPts.points[i];
+		    *ip++ = iData;
+		}
+	    }
+	    stylePtr->symbolPts.length = pp - stylePtr->symbolPts.points;
+	}
+	free(elemPtr->symbolPts.points);
+	free(elemPtr->symbolPts.map);
+	elemPtr->symbolPts.points = points;
+	elemPtr->symbolPts.map = map;
+    }
+    if (elemPtr->xeb.length > 0) {
+	Segment2d *segments, *sp;
+	int *map, *ip;
+	Blt_ChainLink link;
+
+	segments = malloc(elemPtr->xeb.length * sizeof(Segment2d));
+	map = malloc(elemPtr->xeb.length * sizeof(int));
+	sp = segments, ip = map;
+	for (link = Blt_Chain_FirstLink(elemPtr->styles); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    LineStyle *stylePtr;
+	    int i;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    stylePtr->xeb.segments = sp;
+	    for (i = 0; i < elemPtr->xeb.length; i++) {
+		int iData;
+
+		iData = elemPtr->xeb.map[i];
+		if (styleMap[iData] == stylePtr) {
+		    *sp++ = elemPtr->xeb.segments[i];
+		    *ip++ = iData;
+		}
+	    }
+	    stylePtr->xeb.length = sp - stylePtr->xeb.segments;
+	}
+	free(elemPtr->xeb.segments);
+	free(elemPtr->xeb.map);
+	elemPtr->xeb.segments = segments;
+	elemPtr->xeb.map = map;
+    }
+    if (elemPtr->yeb.length > 0) {
+	Segment2d *segments, *sp;
+	int *map, *ip;
+	Blt_ChainLink link;
+
+	segments = malloc(elemPtr->yeb.length * sizeof(Segment2d));
+	map = malloc(elemPtr->yeb.length * sizeof(int));
+	sp = segments, ip = map;
+	for (link = Blt_Chain_FirstLink(elemPtr->styles); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    LineStyle *stylePtr;
+	    int i;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    stylePtr->yeb.segments = sp;
+	    for (i = 0; i < elemPtr->yeb.length; i++) {
+		int iData;
+
+		iData = elemPtr->yeb.map[i];
+		if (styleMap[iData] == stylePtr) {
+		    *sp++ = elemPtr->yeb.segments[i];
+		    *ip++ = iData;
+		}
+	    }
+	    stylePtr->yeb.length = sp - stylePtr->yeb.segments;
+	}
+	free(elemPtr->yeb.segments);
+	elemPtr->yeb.segments = segments;
+	free(elemPtr->yeb.map);
+	elemPtr->yeb.map = map;
+    }
+}
+
+#define CLIP_TOP	(1<<0)
+#define CLIP_BOTTOM	(1<<1)
+#define CLIP_RIGHT	(1<<2)
+#define CLIP_LEFT	(1<<3)
+
+INLINE static int
+OutCode(Region2d *extsPtr, Point2d *p)
+{
+    int code;
+
+    code = 0;
+    if (p->x > extsPtr->right) {
+	code |= CLIP_RIGHT;
+    } else if (p->x < extsPtr->left) {
+	code |= CLIP_LEFT;
+    }
+    if (p->y > extsPtr->bottom) {
+	code |= CLIP_BOTTOM;
+    } else if (p->y < extsPtr->top) {
+	code |= CLIP_TOP;
+    }
+    return code;
+}
+
+static int
+ClipSegment(
+    Region2d *extsPtr,
+    int code1, int code2,
+    Point2d *p, Point2d *q)
+{
+    int inside, outside;
+
+    inside = ((code1 | code2) == 0);
+    outside = ((code1 & code2) != 0);
+
+    /*
+     * In the worst case, we'll clip the line segment against each of the four
+     * sides of the bounding rectangle.
+     */
+    while ((!outside) && (!inside)) {
+	if (code1 == 0) {
+	    Point2d *tmp;
+	    int code;
+
+	    /* Swap pointers and out codes */
+	    tmp = p, p = q, q = tmp;
+	    code = code1, code1 = code2, code2 = code;
+	}
+	if (code1 & CLIP_LEFT) {
+	    p->y += (q->y - p->y) *
+		(extsPtr->left - p->x) / (q->x - p->x);
+	    p->x = extsPtr->left;
+	} else if (code1 & CLIP_RIGHT) {
+	    p->y += (q->y - p->y) *
+		(extsPtr->right - p->x) / (q->x - p->x);
+	    p->x = extsPtr->right;
+	} else if (code1 & CLIP_BOTTOM) {
+	    p->x += (q->x - p->x) *
+		(extsPtr->bottom - p->y) / (q->y - p->y);
+	    p->y = extsPtr->bottom;
+	} else if (code1 & CLIP_TOP) {
+	    p->x += (q->x - p->x) *
+		(extsPtr->top - p->y) / (q->y - p->y);
+	    p->y = extsPtr->top;
+	}
+	code1 = OutCode(extsPtr, p);
+
+	inside = ((code1 | code2) == 0);
+	outside = ((code1 & code2) != 0);
+    }
+    return (!inside);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SaveTrace --
+ *
+ *	Creates a new trace and inserts it into the line's list of traces.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+SaveTrace(
+    LineElement *elemPtr,
+    int start,			/* Starting index of the trace in data point
+				 * array.  Used to figure out closest point */
+    int length,			/* Number of points forming the trace */
+    MapInfo *mapPtr)
+{
+    bltTrace *tracePtr;
+    Point2d *screenPts;
+    int *map;
+    int i, j;
+
+    tracePtr  = malloc(sizeof(bltTrace));
+    screenPts = malloc(sizeof(Point2d) * length);
+    map       = malloc(sizeof(int) * length);
+
+    /* Copy the screen coordinates of the trace into the point array */
+
+    if (mapPtr->map != NULL) {
+	for (i = 0, j = start; i < length; i++, j++) {
+	    screenPts[i].x = mapPtr->screenPts[j].x;
+	    screenPts[i].y = mapPtr->screenPts[j].y;
+	    map[i] = mapPtr->map[j];
+	}
+    } else {
+	for (i = 0, j = start; i < length; i++, j++) {
+	    screenPts[i].x = mapPtr->screenPts[j].x;
+	    screenPts[i].y = mapPtr->screenPts[j].y;
+	    map[i] = j;
+	}
+    }
+    tracePtr->screenPts.length = length;
+    tracePtr->screenPts.points = screenPts;
+    tracePtr->screenPts.map = map;
+    tracePtr->start = start;
+    if (elemPtr->traces == NULL) {
+	elemPtr->traces = Blt_Chain_Create();
+    }
+    Blt_Chain_Append(elemPtr->traces, tracePtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FreeTraces --
+ *
+ *	Deletes all the traces for the line.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+FreeTraces(LineElement *elemPtr)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_FirstLink(elemPtr->traces); link != NULL;
+	link = Blt_Chain_NextLink(link)) {
+	bltTrace *tracePtr;
+
+	tracePtr = Blt_Chain_GetValue(link);
+	free(tracePtr->screenPts.map);
+	free(tracePtr->screenPts.points);
+	free(tracePtr);
+    }
+    Blt_Chain_Destroy(elemPtr->traces);
+    elemPtr->traces = NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapTraces --
+ *
+ *	Creates an array of line segments of the graph coordinates.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is  allocated for the line segment array.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapTraces(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr)
+{
+    Point2d *p, *q;
+    Region2d exts;
+    int code1;
+    int i;
+    int start, count;
+
+    Blt_GraphExtents(graphPtr, &exts);
+    count = 1;
+    code1 = OutCode(&exts, mapPtr->screenPts);
+    p = mapPtr->screenPts;
+    q = p + 1;
+    for (i = 1; i < mapPtr->nScreenPts; i++, p++, q++) {
+	Point2d s;
+	int code2;
+	int broken, offscreen;
+
+	s.x = s.y = 0;
+	code2 = OutCode(&exts, q);
+	if (code2 != 0) {
+	    /* Save the coordinates of the last point, before clipping */
+	    s = *q;
+	}
+	broken = BROKEN_TRACE(elemPtr->penDir, p->x, q->x);
+	offscreen = ClipSegment(&exts, code1, code2, p, q);
+	if (broken || offscreen) {
+
+	    /*
+	     * The last line segment is either totally clipped by the plotting
+	     * area or the x-direction is wrong, breaking the trace.  Either
+	     * way, save information about the last trace (if one exists),
+	     * discarding the current line segment
+	     */
+
+	    if (count > 1) {
+		start = i - count;
+		SaveTrace(elemPtr, start, count, mapPtr);
+		count = 1;
+	    }
+	} else {
+	    count++;		/* Add the point to the trace. */
+	    if (code2 != 0) {
+
+		/*
+		 * If the last point is clipped, this means that the trace is
+		 * broken after this point.  Restore the original coordinate
+		 * (before clipping) after saving the trace.
+		 */
+
+		start = i - (count - 1);
+		SaveTrace(elemPtr, start, count, mapPtr);
+		mapPtr->screenPts[i] = s;
+		count = 1;
+	    }
+	}
+	code1 = code2;
+    }
+    if (count > 1) {
+	start = i - count;
+	SaveTrace(elemPtr, start, count, mapPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapFillArea --
+ *
+ *	Creates an array of points that represent a polygon that fills
+ *	the area under the element.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is allocated for the polygon point array.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapFillArea(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr)
+{
+    Point2d *origPts, *clipPts;
+    Region2d exts;
+    int np;
+
+    if (elemPtr->fillPts != NULL) {
+	free(elemPtr->fillPts);
+	elemPtr->fillPts = NULL;
+	elemPtr->nFillPts = 0;
+    }
+    if (mapPtr->nScreenPts < 3) {
+	return;
+    }
+    np = mapPtr->nScreenPts + 3;
+    Blt_GraphExtents(graphPtr, &exts);
+
+    origPts = malloc(sizeof(Point2d) * np);
+    if (graphPtr->inverted) {
+	double minX;
+	int i;
+
+	minX = (double)elemPtr->axes.y->screenMin;
+	for (i = 0; i < mapPtr->nScreenPts; i++) {
+	    origPts[i].x = mapPtr->screenPts[i].x + 1;
+	    origPts[i].y = mapPtr->screenPts[i].y;
+	    if (origPts[i].x < minX) {
+		minX = origPts[i].x;
+	    }
+	}	
+	/* Add edges to make (if necessary) the polygon fill to the bottom of
+	 * plotting window */
+	origPts[i].x = minX;
+	origPts[i].y = origPts[i - 1].y;
+	i++;
+	origPts[i].x = minX;
+	origPts[i].y = origPts[0].y; 
+	i++;
+	origPts[i] = origPts[0];
+    } else {
+	double maxY;
+	int i;
+
+	maxY = (double)elemPtr->axes.y->bottom;
+	for (i = 0; i < mapPtr->nScreenPts; i++) {
+	    origPts[i].x = mapPtr->screenPts[i].x + 1;
+	    origPts[i].y = mapPtr->screenPts[i].y;
+	    if (origPts[i].y > maxY) {
+		maxY = origPts[i].y;
+	    }
+	}	
+	/* Add edges to extend the fill polygon to the bottom of plotting
+	 * window */
+	origPts[i].x = origPts[i - 1].x;
+	origPts[i].y = maxY;
+	i++;
+	origPts[i].x = origPts[0].x; 
+	origPts[i].y = maxY;
+	i++;
+	origPts[i] = origPts[0];
+    }
+
+    clipPts = malloc(sizeof(Point2d) * np * 3);
+    np = Blt_PolyRectClip(&exts, origPts, np - 1, clipPts);
+
+    free(origPts);
+    if (np < 3) {
+	free(clipPts);
+    } else {
+	elemPtr->fillPts = clipPts;
+	elemPtr->nFillPts = np;
+    }
+}
+
+static void
+ResetLine(LineElement *elemPtr)
+{
+    FreeTraces(elemPtr);
+    ResetStylePalette(elemPtr->styles);
+    if (elemPtr->symbolPts.points != NULL) {
+	free(elemPtr->symbolPts.points);
+    }
+    if (elemPtr->symbolPts.map != NULL) {
+	free(elemPtr->symbolPts.map);
+    }
+    if (elemPtr->lines.segments != NULL) {
+	free(elemPtr->lines.segments);
+    }
+    if (elemPtr->lines.map != NULL) {
+	free(elemPtr->lines.map);
+    }
+    if (elemPtr->activePts.points != NULL) {
+	free(elemPtr->activePts.points);
+    }
+    if (elemPtr->activePts.map != NULL) {
+	free(elemPtr->activePts.map);
+    }
+    if (elemPtr->xeb.segments != NULL) {
+	free(elemPtr->xeb.segments);
+    }
+    if (elemPtr->xeb.map != NULL) {
+	free(elemPtr->xeb.map);
+    }
+    if (elemPtr->yeb.segments != NULL) {
+	free(elemPtr->yeb.segments);
+    }
+    if (elemPtr->yeb.map != NULL) {
+	free(elemPtr->yeb.map);
+    }
+    elemPtr->xeb.segments = elemPtr->yeb.segments = elemPtr->lines.segments = NULL;
+    elemPtr->symbolPts.points = elemPtr->activePts.points = NULL;
+    elemPtr->lines.map = elemPtr->symbolPts.map = elemPtr->xeb.map = 
+	elemPtr->yeb.map = elemPtr->activePts.map = NULL;
+    elemPtr->activePts.length = elemPtr->symbolPts.length = 
+	elemPtr->lines.length = elemPtr->xeb.length = elemPtr->yeb.length = 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapErrorBars --
+ *
+ *	Creates two arrays of points and pen indices, filled with the screen
+ *	coordinates of the visible
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is freed and allocated for the index array.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapErrorBars(Graph *graphPtr, LineElement *elemPtr, LineStyle **styleMap)
+{
+    int n, np;
+    Region2d exts;
+
+    Blt_GraphExtents(graphPtr, &exts);
+    np = NUMBEROFPOINTS(elemPtr);
+    if (elemPtr->xError.nValues > 0) {
+	n = MIN(elemPtr->xError.nValues, np);
+    } else {
+	n = MIN3(elemPtr->xHigh.nValues, elemPtr->xLow.nValues, np);
+    }
+    if (n > 0) {
+	Segment2d *errorBars;
+	Segment2d *segPtr;
+	int *errorToData;
+	int *indexPtr;
+	int i;
+		
+	segPtr = errorBars = malloc(n * 3 * sizeof(Segment2d));
+	indexPtr = errorToData = malloc(n * 3 * sizeof(int));
+	for (i = 0; i < n; i++) {
+	    double x, y;
+	    double high, low;
+	    LineStyle *stylePtr;
+
+	    x = elemPtr->x.values[i];
+	    y = elemPtr->y.values[i];
+	    stylePtr = styleMap[i];
+	    if ((isfinite(x)) && (isfinite(y))) {
+		if (elemPtr->xError.nValues > 0) {
+		    high = x + elemPtr->xError.values[i];
+		    low = x - elemPtr->xError.values[i];
+		} else {
+		    high = elemPtr->xHigh.values[i];
+		    low = elemPtr->xLow.values[i];
+		}
+		if ((isfinite(high)) && (isfinite(low)))  {
+		    Point2d p, q;
+
+		    p = Blt_Map2D(graphPtr, high, y, &elemPtr->axes);
+		    q = Blt_Map2D(graphPtr, low, y, &elemPtr->axes);
+		    segPtr->p = p;
+		    segPtr->q = q;
+		    if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		    /* Left cap */
+		    segPtr->p.x = segPtr->q.x = p.x;
+		    segPtr->p.y = p.y - stylePtr->errorBarCapWidth;
+		    segPtr->q.y = p.y + stylePtr->errorBarCapWidth;
+		    if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		    /* Right cap */
+		    segPtr->p.x = segPtr->q.x = q.x;
+		    segPtr->p.y = q.y - stylePtr->errorBarCapWidth;
+		    segPtr->q.y = q.y + stylePtr->errorBarCapWidth;
+		    if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		}
+	    }
+	}
+	elemPtr->xeb.segments = errorBars;
+	elemPtr->xeb.length = segPtr - errorBars;
+	elemPtr->xeb.map = errorToData;
+    }
+    if (elemPtr->yError.nValues > 0) {
+	n = MIN(elemPtr->yError.nValues, np);
+    } else {
+	n = MIN3(elemPtr->yHigh.nValues, elemPtr->yLow.nValues, np);
+    }
+    if (n > 0) {
+	Segment2d *errorBars;
+	Segment2d *segPtr;
+	int *errorToData;
+	int *indexPtr;
+	int i;
+		
+	segPtr = errorBars = malloc(n * 3 * sizeof(Segment2d));
+	indexPtr = errorToData = malloc(n * 3 * sizeof(int));
+	for (i = 0; i < n; i++) {
+	    double x, y;
+	    double high, low;
+	    LineStyle *stylePtr;
+
+	    x = elemPtr->x.values[i];
+	    y = elemPtr->y.values[i];
+	    stylePtr = styleMap[i];
+	    if ((isfinite(x)) && (isfinite(y))) {
+		if (elemPtr->yError.nValues > 0) {
+		    high = y + elemPtr->yError.values[i];
+		    low = y - elemPtr->yError.values[i];
+		} else {
+		    high = elemPtr->yHigh.values[i];
+		    low = elemPtr->yLow.values[i];
+		}
+		if ((isfinite(high)) && (isfinite(low)))  {
+		    Point2d p, q;
+		    
+		    p = Blt_Map2D(graphPtr, x, high, &elemPtr->axes);
+		    q = Blt_Map2D(graphPtr, x, low, &elemPtr->axes);
+		    segPtr->p = p;
+		    segPtr->q = q;
+		    if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		    /* Top cap. */
+		    segPtr->p.y = segPtr->q.y = p.y;
+		    segPtr->p.x = p.x - stylePtr->errorBarCapWidth;
+		    segPtr->q.x = p.x + stylePtr->errorBarCapWidth;
+		    if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		    /* Bottom cap. */
+		    segPtr->p.y = segPtr->q.y = q.y;
+		    segPtr->p.x = q.x - stylePtr->errorBarCapWidth;
+		    segPtr->q.x = q.x + stylePtr->errorBarCapWidth;
+		    if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) {
+			segPtr++;
+			*indexPtr++ = i;
+		    }
+		}
+	    }
+	}
+	elemPtr->yeb.segments = errorBars;
+	elemPtr->yeb.length = segPtr - errorBars;
+	elemPtr->yeb.map = errorToData;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapLineProc --
+ *
+ *	Calculates the actual window coordinates of the line element.  The
+ *	window coordinates are saved in an allocated point array.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is (re)allocated for the point array.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapLineProc(Graph *graphPtr, Element *basePtr)
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+    MapInfo mi;
+    int size, np;
+    LineStyle **styleMap;
+    Blt_ChainLink link;
+    
+    ResetLine(elemPtr);
+    np = NUMBEROFPOINTS(elemPtr);
+    if (np < 1) {
+	return;				/* No data points */
+    }
+    GetScreenPoints(graphPtr, elemPtr, &mi);
+    MapSymbols(graphPtr, elemPtr, &mi);
+
+    if ((elemPtr->flags & ACTIVE_PENDING) && (elemPtr->nActiveIndices > 0)) {
+	MapActiveSymbols(graphPtr, elemPtr);
+    }
+    /*
+     * Map connecting line segments if they are to be displayed.
+     */
+    elemPtr->smooth = elemPtr->reqSmooth;
+    if ((np > 1) && (elemPtr->builtinPen.traceWidth > 0)) {
+	/*
+	 * Do smoothing if necessary.  This can extend the coordinate array,
+	 * so both mi.points and mi.nPoints may change.
+	 */
+	switch (elemPtr->smooth) {
+	case PEN_SMOOTH_STEP:
+	    GenerateSteps(&mi);
+	    break;
+
+	case PEN_SMOOTH_NATURAL:
+	case PEN_SMOOTH_QUADRATIC:
+	    if (mi.nScreenPts < 3) {
+		/* Can't interpolate with less than three points. */
+		elemPtr->smooth = PEN_SMOOTH_LINEAR;
+	    } else {
+		GenerateSpline(graphPtr, elemPtr, &mi);
+	    }
+	    break;
+
+	case PEN_SMOOTH_CATROM:
+	    if (mi.nScreenPts < 3) {
+		/* Can't interpolate with less than three points. */
+		elemPtr->smooth = PEN_SMOOTH_LINEAR;
+	    } else {
+		GenerateParametricSpline(graphPtr, elemPtr, &mi);
+	    }
+	    break;
+
+	default:
+	    break;
+	}
+	if (elemPtr->rTolerance > 0.0) {
+	    ReducePoints(&mi, elemPtr->rTolerance);
+	}
+	if (elemPtr->fillBg != NULL) {
+	    MapFillArea(graphPtr, elemPtr, &mi);
+	}
+	MapTraces(graphPtr, elemPtr, &mi);
+    }
+    free(mi.screenPts);
+    free(mi.map);
+
+    /* Set the symbol size of all the pen styles. */
+    for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL;
+	 link = Blt_Chain_NextLink(link)) {
+	LineStyle *stylePtr;
+	LinePen *penPtr;
+
+	stylePtr = Blt_Chain_GetValue(link);
+	penPtr = (LinePen *)stylePtr->penPtr;
+	size = ScaleSymbol(elemPtr, penPtr->symbol.size);
+	stylePtr->symbolSize = size;
+	stylePtr->errorBarCapWidth = (penPtr->errorBarCapWidth > 0) 
+	    ? penPtr->errorBarCapWidth : Round(size * 0.6666666);
+	stylePtr->errorBarCapWidth /= 2;
+    }
+    styleMap = (LineStyle **)Blt_StyleMap((Element *)elemPtr);
+    if (((elemPtr->yHigh.nValues > 0) && (elemPtr->yLow.nValues > 0)) ||
+	((elemPtr->xHigh.nValues > 0) && (elemPtr->xLow.nValues > 0)) ||
+	(elemPtr->xError.nValues > 0) || (elemPtr->yError.nValues > 0)) {
+	MapErrorBars(graphPtr, elemPtr, styleMap);
+    }
+    MergePens(elemPtr, styleMap);
+    free(styleMap);
+}
+
+static double
+DistanceToLineProc(
+    int x, int y,			/* Sample X-Y coordinate. */
+    Point2d *p, Point2d *q,		/* End points of the line segment. */
+    Point2d *t)				/* (out) Point on line segment. */
+{
+    double right, left, top, bottom;
+
+    *t = Blt_GetProjection(x, y, p, q);
+    if (p->x > q->x) {
+	right = p->x, left = q->x;
+    } else {
+	left = p->x, right = q->x;
+    }
+    if (p->y > q->y) {
+	bottom = p->y, top = q->y;
+    } else {
+	top = p->y, bottom = q->y;
+    }
+    if (t->x > right) {
+	t->x = right;
+    } else if (t->x < left) {
+	t->x = left;
+    }
+    if (t->y > bottom) {
+	t->y = bottom;
+    } else if (t->y < top) {
+	t->y = top;
+    }
+    return hypot((t->x - x), (t->y - y));
+}
+
+static double
+DistanceToXProc(
+    int x, int y,			/* Search X-Y coordinate. */
+    Point2d *p, 
+    Point2d *q,				/* End points of the line segment. */
+    Point2d *t)				/* (out) Point on line segment. */
+{
+    double dx, dy;
+    double d;
+
+    if (p->x > q->x) {
+	if ((x > p->x) || (x < q->x)) {
+	    return DBL_MAX;		/* X-coordinate outside line segment. */
+	}
+    } else {
+	if ((x > q->x) || (x < p->x)) {
+	    return DBL_MAX;		/* X-coordinate outside line segment. */
+	}
+    }
+    dx = p->x - q->x;
+    dy = p->y - q->y;
+    t->x = (double)x;
+    if (fabs(dx) < DBL_EPSILON) {
+	double d1, d2;
+	/* 
+	 * Same X-coordinate indicates a vertical line.  Pick the closest end
+	 * point.
+	 */
+	d1 = p->y - y;
+	d2 = q->y - y;
+	if (fabs(d1) < fabs(d2)) {
+	    t->y = p->y, d = d1;
+	} else {
+	    t->y = q->y, d = d2;
+	}
+    } else if (fabs(dy) < DBL_EPSILON) {
+	/* Horizontal line. */
+	t->y = p->y, d = p->y - y;
+    } else {
+	double m, b;
+		
+	m = dy / dx;
+	b = p->y - (m * p->x);
+	t->y = (x * m) + b;
+	d = y - t->y;
+    }
+   return fabs(d);
+}
+
+static double
+DistanceToYProc(
+    int x, int y,		/* Search X-Y coordinate. */
+    Point2d *p, Point2d *q,	/* End points of the line segment. */
+    Point2d *t)			/* (out) Point on line segment. */
+{
+    double dx, dy;
+    double d;
+
+    if (p->y > q->y) {
+	if ((y > p->y) || (y < q->y)) {
+	    return DBL_MAX;
+	}
+    } else {
+	if ((y > q->y) || (y < p->y)) {
+	    return DBL_MAX;
+	}
+    }
+    dx = p->x - q->x;
+    dy = p->y - q->y;
+    t->y = y;
+    if (fabs(dy) < DBL_EPSILON) {
+	double d1, d2;
+
+	/* Save Y-coordinate indicates an horizontal line. Pick the closest end
+	 * point. */
+	d1 = p->x - x;
+	d2 = q->x - x;
+	if (fabs(d1) < fabs(d2)) {
+	    t->x = p->x, d = d1;
+	} else {
+	    t->x = q->x, d = d2;
+	}
+    } else if (fabs(dx) < DBL_EPSILON) {
+	/* Vertical line. */
+	t->x = p->x, d = p->x - x;
+    } else {
+	double m, b;
+	
+	m = dy / dx;
+	b = p->y - (m * p->x);
+	t->x = (y - b) / m;
+	d = x - t->x;
+    }
+    return fabs(d);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ClosestTrace --
+ *
+ *	Find the line segment closest to the given window coordinate in the
+ *	element.
+ *
+ * Results:
+ *	If a new minimum distance is found, the information regarding it is
+ *	returned via searchPtr.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ClosestTrace(
+    Graph *graphPtr,			/* Graph widget record */
+    LineElement *elemPtr,
+    ClosestSearch *searchPtr,		/* Info about closest point in
+					 * element */
+    DistanceProc *distProc)
+{
+    Blt_ChainLink link;
+    Point2d closest;
+    double dMin;
+    int iClose;
+
+    iClose = -1;			/* Suppress compiler warning. */
+    dMin = searchPtr->dist;
+    closest.x = closest.y = 0;		/* Suppress compiler warning. */
+    for (link = Blt_Chain_FirstLink(elemPtr->traces); link != NULL;
+	link = Blt_Chain_NextLink(link)) {
+	bltTrace *tracePtr;
+	Point2d *p, *pend;
+
+	tracePtr = Blt_Chain_GetValue(link);
+	for (p = tracePtr->screenPts.points, 
+		pend = p + (tracePtr->screenPts.length - 1); p < pend; p++) {
+	    Point2d b;
+	    double d;
+
+	    d = (*distProc)(searchPtr->x, searchPtr->y, p, p + 1, &b);
+	    if (d < dMin) {
+		closest = b;
+		iClose = tracePtr->screenPts.map[p-tracePtr->screenPts.points];
+		dMin = d;
+	    }
+	}
+    }
+    if (dMin < searchPtr->dist) {
+	searchPtr->dist = dMin;
+	searchPtr->elemPtr = (Element *)elemPtr;
+	searchPtr->index = iClose;
+	searchPtr->point = Blt_InvMap2D(graphPtr, closest.x, closest.y,
+	    &elemPtr->axes);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ClosestPoint --
+ *
+ *	Find the element whose data point is closest to the given screen
+ *	coordinate.
+ *
+ * Results:
+ *	If a new minimum distance is found, the information regarding
+ *	it is returned via searchPtr.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+ClosestPoint(
+    LineElement *elemPtr,		/* Line element to be searched. */
+    ClosestSearch *searchPtr)		/* Assorted information related to
+					 * searching for the closest point */
+{
+    double dMin;
+    int count, iClose;
+    Point2d *pp;
+
+    dMin = searchPtr->dist;
+    iClose = 0;
+
+    /*
+     * Instead of testing each data point in graph coordinates, look at the
+     * array of mapped screen coordinates. The advantages are
+     *   1) only examine points that are visible (unclipped), and
+     *   2) the computed distance is already in screen coordinates.
+     */
+    for (pp = elemPtr->symbolPts.points, count = 0; 
+	 count < elemPtr->symbolPts.length; count++, pp++) {
+	double dx, dy;
+	double d;
+
+	dx = (double)(searchPtr->x - pp->x);
+	dy = (double)(searchPtr->y - pp->y);
+	if (searchPtr->along == SEARCH_BOTH) {
+	    d = hypot(dx, dy);
+	} else if (searchPtr->along == SEARCH_X) {
+	    d = dx;
+	} else if (searchPtr->along == SEARCH_Y) {
+	    d = dy;
+	} else {
+	    /* This can't happen */
+	    continue;
+	}
+	if (d < dMin) {
+	    iClose = elemPtr->symbolPts.map[count];
+	    dMin = d;
+	}
+    }
+    if (dMin < searchPtr->dist) {
+	searchPtr->elemPtr = (Element *)elemPtr;
+	searchPtr->dist = dMin;
+	searchPtr->index = iClose;
+	searchPtr->point.x = elemPtr->x.values[iClose];
+	searchPtr->point.y = elemPtr->y.values[iClose];
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetLineExtentsProc --
+ *
+ *	Retrieves the range of the line element
+ *
+ * Results:
+ *	Returns the number of data points in the element.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+GetLineExtentsProc(Element *basePtr, Region2d *extsPtr)
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+    int np;
+
+    extsPtr->top = extsPtr->left = DBL_MAX;
+    extsPtr->bottom = extsPtr->right = -DBL_MAX;
+
+    np = NUMBEROFPOINTS(elemPtr);
+    if (np < 1) {
+	return;
+    } 
+    extsPtr->right = elemPtr->x.max;
+    if ((elemPtr->x.min <= 0.0) && (elemPtr->axes.x->logScale)) {
+	extsPtr->left = Blt_FindElemValuesMinimum(&elemPtr->x, DBL_MIN);
+    } else {
+	extsPtr->left = elemPtr->x.min;
+    }
+    extsPtr->bottom = elemPtr->y.max;
+    if ((elemPtr->y.min <= 0.0) && (elemPtr->axes.y->logScale)) {
+	extsPtr->top = Blt_FindElemValuesMinimum(&elemPtr->y, DBL_MIN);
+    } else {
+	extsPtr->top = elemPtr->y.min;
+    }
+
+    /* Correct the data limits for error bars */
+
+    if (elemPtr->xError.nValues > 0) {
+	int i;
+	
+	np = MIN(elemPtr->xError.nValues, np);
+	for (i = 0; i < np; i++) {
+	    double x;
+
+	    x = elemPtr->x.values[i] + elemPtr->xError.values[i];
+	    if (x > extsPtr->right) {
+		extsPtr->right = x;
+	    }
+	    x = elemPtr->x.values[i] - elemPtr->xError.values[i];
+	    if (elemPtr->axes.x->logScale) {
+		if (x < 0.0) {
+		    x = -x;		/* Mirror negative values, instead of
+					 * ignoring them. */
+		}
+		if ((x > DBL_MIN) && (x < extsPtr->left)) {
+		    extsPtr->left = x;
+		}
+	    } else if (x < extsPtr->left) {
+		extsPtr->left = x;
+	    }
+	}		     
+    } else {
+	if ((elemPtr->xHigh.nValues > 0) && 
+	    (elemPtr->xHigh.max > extsPtr->right)) {
+	    extsPtr->right = elemPtr->xHigh.max;
+	}
+	if (elemPtr->xLow.nValues > 0) {
+	    double left;
+	    
+	    if ((elemPtr->xLow.min <= 0.0) && 
+		(elemPtr->axes.x->logScale)) {
+		left = Blt_FindElemValuesMinimum(&elemPtr->xLow, DBL_MIN);
+	    } else {
+		left = elemPtr->xLow.min;
+	    }
+	    if (left < extsPtr->left) {
+		extsPtr->left = left;
+	    }
+	}
+    }
+    
+    if (elemPtr->yError.nValues > 0) {
+	int i;
+	
+	np = MIN(elemPtr->yError.nValues, np);
+	for (i = 0; i < np; i++) {
+	    double y;
+
+	    y = elemPtr->y.values[i] + elemPtr->yError.values[i];
+	    if (y > extsPtr->bottom) {
+		extsPtr->bottom = y;
+	    }
+	    y = elemPtr->y.values[i] - elemPtr->yError.values[i];
+	    if (elemPtr->axes.y->logScale) {
+		if (y < 0.0) {
+		    y = -y;		/* Mirror negative values, instead of
+					 * ignoring them. */
+		}
+		if ((y > DBL_MIN) && (y < extsPtr->left)) {
+		    extsPtr->top = y;
+		}
+	    } else if (y < extsPtr->top) {
+		extsPtr->top = y;
+	    }
+	}		     
+    } else {
+	if ((elemPtr->yHigh.nValues > 0) && 
+	    (elemPtr->yHigh.max > extsPtr->bottom)) {
+	    extsPtr->bottom = elemPtr->yHigh.max;
+	}
+	if (elemPtr->yLow.nValues > 0) {
+	    double top;
+	    
+	    if ((elemPtr->yLow.min <= 0.0) && 
+		(elemPtr->axes.y->logScale)) {
+		top = Blt_FindElemValuesMinimum(&elemPtr->yLow, DBL_MIN);
+	    } else {
+		top = elemPtr->yLow.min;
+	    }
+	    if (top < extsPtr->top) {
+		extsPtr->top = top;
+	    }
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BackgroundChangedProc
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static void
+BackgroundChangedProc(ClientData clientData)
+{
+    Element *elemPtr = clientData;
+    Graph *graphPtr;
+
+    graphPtr = elemPtr->obj.graphPtr;
+    if (graphPtr->tkwin != NULL) {
+	graphPtr->flags |= REDRAW_WORLD;
+	Blt_EventuallyRedrawGraph(graphPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureLineProc --
+ *
+ *	Sets up the appropriate configuration parameters in the GC.  It is
+ *	assumed the parameters have been previously set by a call to
+ *	Blt_ConfigureWidget.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  If TCL_ERROR is returned,
+ *	then interp->result contains an error message.
+ *
+ * Side effects:
+ *	Configuration information such as line width, line style, color
+ *	etc. get set in a new GC.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ConfigureLineProc(Graph *graphPtr, Element *basePtr)
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+    unsigned long gcMask;
+    XGCValues gcValues;
+    GC newGC;
+    Blt_ChainLink link;
+    LineStyle *stylePtr;
+
+    if (ConfigurePenProc(graphPtr, (Pen *)&elemPtr->builtinPen) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    /*
+     * Point to the static normal/active pens if no external pens have been
+     * selected.
+     */
+    link = Blt_Chain_FirstLink(elemPtr->styles);
+    if (link == NULL) {
+	link = Blt_Chain_AllocLink(sizeof(LineStyle));
+	Blt_Chain_LinkAfter(elemPtr->styles, link, NULL);
+    } 
+    stylePtr = Blt_Chain_GetValue(link);
+    stylePtr->penPtr = NORMALPEN(elemPtr);
+
+    if (elemPtr->fillBg != NULL) {
+	Blt_SetBackgroundChangedProc(elemPtr->fillBg, BackgroundChangedProc, 
+		elemPtr);
+    }
+    /*
+     * Set the outline GC for this pen: GCForeground is outline color.
+     * GCBackground is the fill color (only used for bitmap symbols).
+     */
+    gcMask = 0;
+    if (elemPtr->fillFgColor != NULL) {
+	gcMask |= GCForeground;
+	gcValues.foreground = elemPtr->fillFgColor->pixel;
+    }
+    if (elemPtr->fillBgColor != NULL) {
+	gcMask |= GCBackground;
+	gcValues.background = elemPtr->fillBgColor->pixel;
+    }
+    newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (elemPtr->fillGC != NULL) {
+	Tk_FreeGC(graphPtr->display, elemPtr->fillGC);
+    }
+    elemPtr->fillGC = newGC;
+
+    if (Blt_ConfigModified(elemPtr->configSpecs, "-scalesymbols", 
+			   (char *)NULL)) {
+	elemPtr->flags |= (MAP_ITEM | SCALE_SYMBOL);
+    }
+    if (Blt_ConfigModified(elemPtr->configSpecs, "-pixels", "-trace", 
+	"-*data", "-smooth", "-map*", "-label", "-hide", "-x", "-y", 
+	"-areabackground", (char *)NULL)) {
+	elemPtr->flags |= MAP_ITEM;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ClosestLineProc --
+ *
+ *	Find the closest point or line segment (if interpolated) to the given
+ *	window coordinate in the line element.
+ *
+ * Results:
+ *	Returns the distance of the closest point among other information.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+ClosestLineProc(Graph *graphPtr, Element *basePtr, ClosestSearch *searchPtr)
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+    int mode;
+
+    mode = searchPtr->mode;
+    if (mode == SEARCH_AUTO) {
+	LinePen *penPtr;
+
+	penPtr = NORMALPEN(elemPtr);
+	mode = SEARCH_POINTS;
+	if ((NUMBEROFPOINTS(elemPtr) > 1) && (penPtr->traceWidth > 0)) {
+	    mode = SEARCH_TRACES;
+	}
+    }
+    if (mode == SEARCH_POINTS) {
+	ClosestPoint(elemPtr, searchPtr);
+    } else {
+	DistanceProc *distProc;
+	int found;
+
+	if (searchPtr->along == SEARCH_X) {
+	    distProc = DistanceToXProc;
+	} else if (searchPtr->along == SEARCH_Y) {
+	    distProc = DistanceToYProc;
+	} else {
+	    distProc = DistanceToLineProc;
+	}
+	found = ClosestTrace(graphPtr, elemPtr, searchPtr, distProc);
+	if ((!found) && (searchPtr->along != SEARCH_BOTH)) {
+	    ClosestPoint(elemPtr, searchPtr);
+	}
+    }
+}
+
+/*
+ * XDrawLines() points: XMaxRequestSize(dpy) - 3
+ * XFillPolygon() points:  XMaxRequestSize(dpy) - 4
+ * XDrawSegments() segments:  (XMaxRequestSize(dpy) - 3) / 2
+ * XDrawRectangles() rectangles:  (XMaxRequestSize(dpy) - 3) / 2
+ * XFillRectangles() rectangles:  (XMaxRequestSize(dpy) - 3) / 2
+ * XDrawArcs() or XFillArcs() arcs:  (XMaxRequestSize(dpy) - 3) / 3
+ */
+
+#define MAX_DRAWLINES(d)	Blt_MaxRequestSize(d, sizeof(XPoint))
+#define MAX_DRAWPOLYGON(d)	Blt_MaxRequestSize(d, sizeof(XPoint))
+#define MAX_DRAWSEGMENTS(d)	Blt_MaxRequestSize(d, sizeof(XSegment))
+#define MAX_DRAWRECTANGLES(d)	Blt_MaxRequestSize(d, sizeof(XRectangle))
+#define MAX_DRAWARCS(d)		Blt_MaxRequestSize(d, sizeof(XArc))
+
+static void
+DrawCircles(Display *display, Drawable drawable, LineElement *elemPtr,
+	    LinePen *penPtr, int nSymbolPts, Point2d *symbolPts, int radius)
+{
+    int i;
+    XArc *arcs;				/* Array of arcs (circle) */
+    int reqSize;
+    int s;
+    int count;
+
+    s = radius + radius;
+    arcs = malloc(nSymbolPts * sizeof(XArc));
+
+    if (elemPtr->symbolInterval > 0) {
+	Point2d *pp, *pend;
+	XArc *ap;
+
+        ap = arcs;
+	count = 0;
+	for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) {
+	    if (DRAW_SYMBOL(elemPtr)) {
+		ap->x = Round(pp->x) - radius;
+		ap->y = Round(pp->y) - radius;
+		ap->width = ap->height = (unsigned short)s;
+		ap->angle1 = 0;
+		ap->angle2 = 23040;
+		ap++, count++;
+	    }
+	    elemPtr->symbolCounter++;
+	}
+    } else {
+	Point2d *pp, *pend;
+	XArc *ap;
+
+        ap = arcs;
+	for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) {
+	    ap->x = Round(pp->x) - radius;
+	    ap->y = Round(pp->y) - radius;
+	    ap->width = ap->height = (unsigned short)s;
+	    ap->angle1 = 0;
+	    ap->angle2 = 23040;
+	    ap++;
+	}
+	count = nSymbolPts;
+    }
+    reqSize = MAX_DRAWARCS(display);
+    for (i = 0; i < count; i += reqSize) {
+	int n;
+
+	n = ((i + reqSize) > count) ? (count - i) : reqSize;
+	if (penPtr->symbol.fillGC != NULL) {
+	    XFillArcs(display, drawable, penPtr->symbol.fillGC, arcs + i, n);
+	}
+	if (penPtr->symbol.outlineWidth > 0) {
+	    XDrawArcs(display, drawable, penPtr->symbol.outlineGC, arcs + i, n);
+	}
+    }
+    free(arcs);
+}
+
+static void
+DrawSquares(Display *display, Drawable drawable, LineElement *elemPtr,
+	    LinePen *penPtr, int nSymbolPts, Point2d *symbolPts, int r)
+{
+    XRectangle *rectangles;
+    XRectangle *rp, *rend;
+    int reqSize;
+    int s, count;
+
+    s = r + r;
+    rectangles = malloc(nSymbolPts * sizeof(XRectangle));
+    if (elemPtr->symbolInterval > 0) {
+	Point2d *pp, *pend;
+	XRectangle *rp;
+
+	count = 0;
+	rp = rectangles;
+	for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) {
+	    if (DRAW_SYMBOL(elemPtr)) {
+		rp->x = Round(pp->x) - r;
+		rp->y = Round(pp->y) - r;
+		rp->width = rp->height = (unsigned short)s;
+		rp++, count++;
+	    }
+	    elemPtr->symbolCounter++;
+	}
+    } else {
+	Point2d *pp, *pend;
+	XRectangle *rp;
+
+	rp = rectangles;
+	for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) {
+	    rp->x = Round(pp->x) - r;
+	    rp->y = Round(pp->y) - r;
+	    rp->width = rp->height = (unsigned short)s;
+	    rp++;
+	}
+	count = nSymbolPts;
+    }
+    reqSize = MAX_DRAWRECTANGLES(display) - 3;
+    for (rp = rectangles, rend = rp + count; rp < rend; rp += reqSize) {
+	int n;
+
+	n = rend - rp;
+	if (n > reqSize) {
+	    n = reqSize;
+	}
+	if (penPtr->symbol.fillGC != NULL) {
+	    XFillRectangles(display, drawable, penPtr->symbol.fillGC, rp, n);
+	}
+	if (penPtr->symbol.outlineWidth > 0) {
+	    XDrawRectangles(display, drawable, penPtr->symbol.outlineGC, rp, n);
+	}
+    }
+    free(rectangles);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawSymbols --
+ *
+ * 	Draw the symbols centered at the each given x,y coordinate in the array
+ * 	of points.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Draws a symbol at each coordinate given.  If active, only those
+ *	coordinates which are currently active are drawn.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawSymbols(
+    Graph *graphPtr,			/* Graph widget record */
+    Drawable drawable,			/* Pixmap or window to draw into */
+    LineElement *elemPtr,
+    LinePen *penPtr,
+    int size,				/* Size of element */
+    int nSymbolPts,			/* Number of coordinates in array */
+    Point2d *symbolPts)			/* Array of x,y coordinates for line */
+{
+    XPoint pattern[13];			/* Template for polygon symbols */
+    int r1, r2;
+    int count;
+#define SQRT_PI		1.77245385090552
+#define S_RATIO		0.886226925452758
+
+    if (size < 3) {
+	if (penPtr->symbol.fillGC != NULL) {
+	    Point2d *pp, *endp;
+	    XPoint *points, *xpp;
+	    
+	    xpp = points = malloc(nSymbolPts * sizeof(XPoint));
+	    for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		xpp->x = Round(pp->x);
+		xpp->y = Round(pp->y);
+		xpp++;
+	    }
+	    XDrawPoints(graphPtr->display, drawable, penPtr->symbol.fillGC, 
+			points, nSymbolPts, CoordModeOrigin);
+	    free(points);
+	}
+	return;
+    }
+    r1 = (int)ceil(size * 0.5);
+    r2 = (int)ceil(size * S_RATIO * 0.5);
+
+    switch (penPtr->symbol.type) {
+    case SYMBOL_NONE:
+	break;
+
+    case SYMBOL_SQUARE:
+	DrawSquares(graphPtr->display, drawable, elemPtr, penPtr, nSymbolPts,
+	    symbolPts, r2);
+	break;
+
+    case SYMBOL_CIRCLE:
+	DrawCircles(graphPtr->display, drawable, elemPtr, penPtr, nSymbolPts,
+	    symbolPts, r1);
+	break;
+
+    case SYMBOL_SPLUS:
+    case SYMBOL_SCROSS:
+	{
+	    XSegment *segments;		/* Array of line segments (splus,
+					 * scross) */
+	    int i;
+	    int reqSize, nSegs;
+
+	    if (penPtr->symbol.type == SYMBOL_SCROSS) {
+		r2 = Round((double)r2 * M_SQRT1_2);
+		pattern[3].y = pattern[2].x = pattern[0].x = pattern[0].y = -r2;
+		pattern[3].x = pattern[2].y = pattern[1].y = pattern[1].x = r2;
+	    } else {
+		pattern[0].y = pattern[1].y = pattern[2].x = pattern[3].x = 0;
+		pattern[0].x = pattern[2].y = -r2;
+		pattern[1].x = pattern[3].y = r2;
+	    }
+	    segments = malloc(nSymbolPts * 2 * sizeof(XSegment));
+	    if (elemPtr->symbolInterval > 0) {
+		Point2d *pp, *endp;
+		XSegment *sp;
+
+		sp = segments;
+		count = 0;
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    if (DRAW_SYMBOL(elemPtr)) {
+			int rndx, rndy;
+			rndx = Round(pp->x), rndy = Round(pp->y);
+			sp->x1 = pattern[0].x + rndx;
+			sp->y1 = pattern[0].y + rndy;
+			sp->x2 = pattern[1].x + rndx;
+			sp->y2 = pattern[1].y + rndy;
+			sp++;
+			sp->x1 = pattern[2].x + rndx;
+			sp->y1 = pattern[2].y + rndy;
+			sp->x2 = pattern[3].x + rndx;
+			sp->y2 = pattern[3].y + rndy;
+			sp++;
+			count++;
+		    }
+		    elemPtr->symbolCounter++;
+		}
+	    } else {
+		Point2d *pp, *endp;
+		XSegment *sp;
+
+		sp = segments;
+		count = nSymbolPts;
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    int rndx, rndy;
+		    rndx = Round(pp->x), rndy = Round(pp->y);
+		    sp->x1 = pattern[0].x + rndx;
+		    sp->y1 = pattern[0].y + rndy;
+		    sp->x2 = pattern[1].x + rndx;
+		    sp->y2 = pattern[1].y + rndy;
+		    sp++;
+		    sp->x1 = pattern[2].x + rndx;
+		    sp->y1 = pattern[2].y + rndy;
+		    sp->x2 = pattern[3].x + rndx;
+		    sp->y2 = pattern[3].y + rndy;
+		    sp++;
+		}
+	    }
+	    nSegs = count * 2;
+	    /* Always draw skinny symbols regardless of the outline width */
+	    reqSize = MAX_DRAWSEGMENTS(graphPtr->display);
+	    for (i = 0; i < nSegs; i += reqSize) {
+		int chunk;
+
+		chunk = ((i + reqSize) > nSegs) ? (nSegs - i) : reqSize;
+		XDrawSegments(graphPtr->display, drawable, 
+			penPtr->symbol.outlineGC, segments + i, chunk);
+	    }
+	    free(segments);
+	}
+	break;
+
+    case SYMBOL_PLUS:
+    case SYMBOL_CROSS:
+	{
+	    XPoint *polygon;
+	    int d;			/* Small delta for cross/plus
+					 * thickness */
+
+	    d = (r2 / 3);
+
+	    /*
+	     *
+	     *          2   3       The plus/cross symbol is a closed polygon
+	     *                      of 12 points. The diagram to the left
+	     *    0,12  1   4    5  represents the positions of the points
+	     *           x,y        which are computed below. The extra
+	     *     11  10   7    6  (thirteenth) point connects the first and
+	     *                      last points.
+	     *          9   8
+	     */
+
+	    pattern[0].x = pattern[11].x = pattern[12].x = -r2;
+	    pattern[2].x = pattern[1].x = pattern[10].x = pattern[9].x = -d;
+	    pattern[3].x = pattern[4].x = pattern[7].x = pattern[8].x = d;
+	    pattern[5].x = pattern[6].x = r2;
+	    pattern[2].y = pattern[3].y = -r2;
+	    pattern[0].y = pattern[1].y = pattern[4].y = pattern[5].y =
+		pattern[12].y = -d;
+	    pattern[11].y = pattern[10].y = pattern[7].y = pattern[6].y = d;
+	    pattern[9].y = pattern[8].y = r2;
+
+	    if (penPtr->symbol.type == SYMBOL_CROSS) {
+		int i;
+
+		/* For the cross symbol, rotate the points by 45 degrees. */
+		for (i = 0; i < 12; i++) {
+		    double dx, dy;
+
+		    dx = (double)pattern[i].x * M_SQRT1_2;
+		    dy = (double)pattern[i].y * M_SQRT1_2;
+		    pattern[i].x = Round(dx - dy);
+		    pattern[i].y = Round(dx + dy);
+		}
+		pattern[12] = pattern[0];
+	    }
+	    polygon = malloc(nSymbolPts * 13 * sizeof(XPoint));
+	    if (elemPtr->symbolInterval > 0) {
+		Point2d *pp, *endp;
+		XPoint *xpp;
+
+		count = 0;
+		xpp = polygon;
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    if (DRAW_SYMBOL(elemPtr)) {
+			int i;
+			int rndx, rndy;
+
+			rndx = Round(pp->x), rndy = Round(pp->y);
+			for (i = 0; i < 13; i++) {
+			    xpp->x = pattern[i].x + rndx;
+			    xpp->y = pattern[i].y + rndy;
+			    xpp++;
+			}
+			count++;
+		    }
+		    elemPtr->symbolCounter++;
+		}
+	    } else {
+		Point2d *pp, *endp;
+		XPoint *xpp;
+
+		xpp = polygon;
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    int i;
+		    int rndx, rndy;
+
+		    rndx = Round(pp->x), rndy = Round(pp->y);
+		    for (i = 0; i < 13; i++) {
+			xpp->x = pattern[i].x + rndx;
+			xpp->y = pattern[i].y + rndy;
+			xpp++;
+		    }
+		}
+		count = nSymbolPts;
+	    }
+	    if (penPtr->symbol.fillGC != NULL) {
+		int i;
+		XPoint *xpp;
+
+		for (xpp = polygon, i = 0; i < count; i++, xpp += 13) {
+		    XFillPolygon(graphPtr->display, drawable, 
+			penPtr->symbol.fillGC, xpp, 13, Complex, 
+			CoordModeOrigin);
+		}
+	    }
+	    if (penPtr->symbol.outlineWidth > 0) {
+		int i;
+		XPoint *xpp;
+
+		for (xpp = polygon, i = 0; i < count; i++, xpp += 13) {
+		    XDrawLines(graphPtr->display, drawable, 
+			penPtr->symbol.outlineGC, xpp, 13, CoordModeOrigin);
+		}
+	    }
+	    free(polygon);
+	}
+	break;
+
+    case SYMBOL_DIAMOND:
+	{
+	    XPoint *polygon;
+
+	    /*
+	     *
+	     *                      The plus symbol is a closed polygon
+	     *            1         of 4 points. The diagram to the left
+	     *                      represents the positions of the points
+	     *       0,4 x,y  2     which are computed below. The extra
+	     *                      (fifth) point connects the first and
+	     *            3         last points.
+	     *
+	     */
+	    pattern[1].y = pattern[0].x = -r1;
+	    pattern[2].y = pattern[3].x = pattern[0].y = pattern[1].x = 0;
+	    pattern[3].y = pattern[2].x = r1;
+	    pattern[4] = pattern[0];
+
+	    polygon = malloc(nSymbolPts * 5 * sizeof(XPoint));
+	    if (elemPtr->symbolInterval > 0) {
+		Point2d *pp, *endp;
+		XPoint *xpp;
+
+		xpp = polygon;
+		count = 0;
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    int i;
+
+		    if (DRAW_SYMBOL(elemPtr)) {
+			int rndx, rndy;
+			
+			rndx = Round(pp->x), rndy = Round(pp->y);
+			for (i = 0; i < 5; i++) {
+			    xpp->x = pattern[i].x + rndx;
+			    xpp->y = pattern[i].y + rndy;
+			    xpp++;
+			}
+			count++;
+		    }
+		    elemPtr->symbolCounter++;
+		}
+	    } else {
+		Point2d *pp, *endp;
+		XPoint *xpp;
+
+		xpp = polygon;
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    int i;
+		    int rndx, rndy;
+			
+		    rndx = Round(pp->x), rndy = Round(pp->y);
+		    for (i = 0; i < 5; i++) {
+			xpp->x = pattern[i].x + rndx;
+			xpp->y = pattern[i].y + rndy;
+			xpp++;
+		    }
+		}
+		count = nSymbolPts;
+	    }
+	    if (penPtr->symbol.fillGC != NULL) {
+		XPoint *xpp;
+		int i;
+
+		for (xpp = polygon, i = 0; i < count; i++, xpp += 5) {
+		    XFillPolygon(graphPtr->display, drawable, 
+			penPtr->symbol.fillGC, xpp, 5, Convex, CoordModeOrigin);
+
+		}
+	    }
+	    if (penPtr->symbol.outlineWidth > 0) {
+		XPoint *xpp;
+		int i;
+
+		for (xpp = polygon, i = 0; i < count; i++, xpp += 5) {
+		    XDrawLines(graphPtr->display, drawable, 
+		       penPtr->symbol.outlineGC, xpp, 5, CoordModeOrigin);
+		}
+	    }
+	    free(polygon);
+	}
+	break;
+
+    case SYMBOL_TRIANGLE:
+    case SYMBOL_ARROW:
+	{
+	    XPoint *polygon;
+	    double b;
+	    int b2, h1, h2;
+#define H_RATIO		1.1663402261671607
+#define B_RATIO		1.3467736870885982
+#define TAN30		0.57735026918962573
+#define COS30		0.86602540378443871
+
+	    b = Round(size * B_RATIO * 0.7);
+	    b2 = Round(b * 0.5);
+	    h2 = Round(TAN30 * b2);
+	    h1 = Round(b2 / COS30);
+	    /*
+	     *
+	     *                      The triangle symbol is a closed polygon
+	     *           0,3         of 3 points. The diagram to the left
+	     *                      represents the positions of the points
+	     *           x,y        which are computed below. The extra
+	     *                      (fourth) point connects the first and
+	     *      2           1   last points.
+	     *
+	     */
+
+	    if (penPtr->symbol.type == SYMBOL_ARROW) {
+		pattern[3].x = pattern[0].x = 0;
+		pattern[3].y = pattern[0].y = h1;
+		pattern[1].x = b2;
+		pattern[2].y = pattern[1].y = -h2;
+		pattern[2].x = -b2;
+	    } else {
+		pattern[3].x = pattern[0].x = 0;
+		pattern[3].y = pattern[0].y = -h1;
+		pattern[1].x = b2;
+		pattern[2].y = pattern[1].y = h2;
+		pattern[2].x = -b2;
+	    }
+	    polygon = malloc(nSymbolPts * 4 * sizeof(XPoint));
+	    if (elemPtr->symbolInterval > 0) {
+		Point2d *pp, *endp;
+		XPoint *xpp;
+
+		xpp = polygon;
+		count = 0;
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    int i;
+
+		    if (DRAW_SYMBOL(elemPtr)) {
+			int rndx, rndy;
+
+			rndx = Round(pp->x), rndy = Round(pp->y);
+			for (i = 0; i < 4; i++) {
+			    xpp->x = pattern[i].x + rndx;
+			    xpp->y = pattern[i].y + rndy;
+			    xpp++;
+			}
+			count++;
+		    }
+		    elemPtr->symbolCounter++;
+		}
+	    } else {
+		Point2d *pp, *endp;
+		XPoint *xpp;
+
+		xpp = polygon;
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    int i;
+		    int rndx, rndy;
+
+		    rndx = Round(pp->x), rndy = Round(pp->y);
+		    for (i = 0; i < 4; i++) {
+			xpp->x = pattern[i].x + rndx;
+			xpp->y = pattern[i].y + rndy;
+			xpp++;
+		    }
+		}
+		count = nSymbolPts;
+	    }
+	    if (penPtr->symbol.fillGC != NULL) {
+		XPoint *xpp;
+		int i;
+
+		xpp = polygon;
+		for (xpp = polygon, i = 0; i < count; i++, xpp += 4) {
+		    XFillPolygon(graphPtr->display, drawable, 
+			penPtr->symbol.fillGC, xpp, 4, Convex, CoordModeOrigin);
+		}
+	    }
+	    if (penPtr->symbol.outlineWidth > 0) {
+		XPoint *xpp;
+		int i;
+
+		xpp = polygon;
+		for (xpp = polygon, i = 0; i < count; i++, xpp += 4) {
+		    XDrawLines(graphPtr->display, drawable, 
+			penPtr->symbol.outlineGC, xpp, 4, CoordModeOrigin);
+		}
+	    }
+	    free(polygon);
+	}
+	break;
+
+    case SYMBOL_IMAGE:
+	{
+	    int w, h;
+	    int dx, dy;
+
+	    Tk_SizeOfImage(penPtr->symbol.image, &w, &h);
+
+	    dx = w / 2;
+	    dy = h / 2;
+	    if (elemPtr->symbolInterval > 0) {
+		Point2d *pp, *endp;
+
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    if (DRAW_SYMBOL(elemPtr)) {
+			int x, y;
+	    
+			x = Round(pp->x) - dx;
+			y = Round(pp->y) - dy;
+			Tk_RedrawImage(penPtr->symbol.image, 0, 0, w, h, 
+				       drawable, x, y);
+		    }
+		    elemPtr->symbolCounter++;
+		}
+	    } else {
+		Point2d *pp, *endp;
+
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    int x, y;
+
+		    x = Round(pp->x) - dx;
+		    y = Round(pp->y) - dy;
+		    Tk_RedrawImage(penPtr->symbol.image, 0, 0, w, h, 
+				   drawable, x, y);
+		}
+	    }
+	}
+	break;
+
+    case SYMBOL_BITMAP:
+	{
+	    Pixmap bitmap, mask;
+	    int w, h, bw, bh;
+	    double scale, sx, sy;
+	    int dx, dy;
+
+	    Tk_SizeOfBitmap(graphPtr->display, penPtr->symbol.bitmap, &w, &h);
+	    mask = None;
+
+	    /*
+	     * Compute the size of the scaled bitmap.  Stretch the bitmap to fit
+	     * a nxn bounding box.
+	     */
+	    sx = (double)size / (double)w;
+	    sy = (double)size / (double)h;
+	    scale = MIN(sx, sy);
+	    bw = (int)(w * scale);
+	    bh = (int)(h * scale);
+
+	    XSetClipMask(graphPtr->display, penPtr->symbol.outlineGC, None);
+	    if (penPtr->symbol.mask != None) {
+		mask = Blt_ScaleBitmap(graphPtr->tkwin, penPtr->symbol.mask,
+		    w, h, bw, bh);
+		XSetClipMask(graphPtr->display, penPtr->symbol.outlineGC, mask);
+	    }
+	    bitmap = Blt_ScaleBitmap(graphPtr->tkwin, penPtr->symbol.bitmap,
+		w, h, bw, bh);
+	    if (penPtr->symbol.fillGC == NULL) {
+		XSetClipMask(graphPtr->display, penPtr->symbol.outlineGC, 
+			     bitmap);
+	    }
+	    dx = bw / 2;
+	    dy = bh / 2;
+	    if (elemPtr->symbolInterval > 0) {
+		Point2d *pp, *endp;
+
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    if (DRAW_SYMBOL(elemPtr)) {
+			int x, y;
+	    
+			x = Round(pp->x) - dx;
+			y = Round(pp->y) - dy;
+			if ((penPtr->symbol.fillGC == NULL) || (mask !=None)) {
+			    XSetClipOrigin(graphPtr->display,
+				penPtr->symbol.outlineGC, x, y);
+			}
+			XCopyPlane(graphPtr->display, bitmap, drawable,
+			    penPtr->symbol.outlineGC, 0, 0, bw, bh, x, y, 1);
+		    }
+		    elemPtr->symbolCounter++;
+		}
+	    } else {
+		Point2d *pp, *endp;
+
+		for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
+		    int x, y;
+
+		    x = Round(pp->x) - dx;
+		    y = Round(pp->y) - dy;
+		    if ((penPtr->symbol.fillGC == NULL) || (mask != None)) {
+			XSetClipOrigin(graphPtr->display, 
+				penPtr->symbol.outlineGC, x, y);
+		    }
+		    XCopyPlane(graphPtr->display, bitmap, drawable,
+			penPtr->symbol.outlineGC, 0, 0, bw, bh, x, y, 1);
+		}
+	    }
+	    Tk_FreePixmap(graphPtr->display, bitmap);
+	    if (mask != None) {
+		Tk_FreePixmap(graphPtr->display, mask);
+	    }
+	}
+	break;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawSymbolProc --
+ *
+ * 	Draw the symbol centered at the each given x,y coordinate.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Draws a symbol at the coordinate given.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawSymbolProc(
+    Graph *graphPtr,			/* Graph widget record */
+    Drawable drawable,			/* Pixmap or window to draw into */
+    Element *basePtr,			/* Line element information */
+    int x, int y,			/* Center position of symbol */
+    int size)				/* Size of symbol. */
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+    LinePen *penPtr;
+
+    penPtr = NORMALPEN(elemPtr);
+    if (penPtr->traceWidth > 0) {
+	/*
+	 * Draw an extra line offset by one pixel from the previous to give a
+	 * thicker appearance.  This is only for the legend entry.  This routine
+	 * is never called for drawing the actual line segments.
+	 */
+	XDrawLine(graphPtr->display, drawable, penPtr->traceGC, x - size, y, 
+		x + size, y);
+	XDrawLine(graphPtr->display, drawable, penPtr->traceGC, x - size, y + 1,
+		x + size, y + 1);
+    }
+    if (penPtr->symbol.type != SYMBOL_NONE) {
+	Point2d point;
+
+	point.x = x, point.y = y;
+	DrawSymbols(graphPtr, drawable, elemPtr, penPtr, size, 1, &point);
+    }
+}
+
+static void
+DrawTraces(Graph *graphPtr, Drawable drawable, LineElement *elemPtr, 
+	   LinePen *penPtr)
+{
+    Blt_ChainLink link;
+    XPoint *points;
+    int np;
+
+    np = Blt_MaxRequestSize(graphPtr->display, sizeof(XPoint)) - 1;
+    points = malloc((np + 1) * sizeof(XPoint));
+	    
+    for (link = Blt_Chain_FirstLink(elemPtr->traces); link != NULL;
+	link = Blt_Chain_NextLink(link)) {
+	XPoint *xpp;
+	bltTrace *tracePtr;
+	int remaining, count;
+	int n;
+
+	tracePtr = Blt_Chain_GetValue(link);
+
+	/*
+	 * If the trace has to be split into separate XDrawLines calls, then the
+	 * end point of the current trace is also the starting point of the new
+	 * split.
+	 */
+	/* Step 1. Convert and draw the first section of the trace.
+	 *	   It may contain the entire trace. */
+
+	n = MIN(np, tracePtr->screenPts.length); 
+	for (xpp = points, count = 0; count < n; count++, xpp++) {
+	    xpp->x = Round(tracePtr->screenPts.points[count].x);
+	    xpp->y = Round(tracePtr->screenPts.points[count].y);
+	}
+	XDrawLines(graphPtr->display, drawable, penPtr->traceGC, points, 
+	   count, CoordModeOrigin);
+
+	/* Step 2. Next handle any full-size chunks left. */
+
+	while ((count + np) < tracePtr->screenPts.length) {
+	    int j;
+
+	    /* Start with the last point of the previous trace. */
+	    points[0].x = points[np - 1].x;
+	    points[0].y = points[np - 1].y;
+	    
+	    for (xpp = points + 1, j = 0; j < np; j++, count++, xpp++) {
+		xpp->x = Round(tracePtr->screenPts.points[count].x);
+		xpp->y = Round(tracePtr->screenPts.points[count].y);
+	    }
+	    XDrawLines(graphPtr->display, drawable, penPtr->traceGC, points, 
+		       np + 1, CoordModeOrigin);
+	}
+	
+	/* Step 3. Convert and draw the remaining points. */
+
+	remaining = tracePtr->screenPts.length - count;
+	if (remaining > 0) {
+	    /* Start with the last point of the previous trace. */
+	    points[0].x = points[np - 1].x;
+	    points[0].y = points[np - 1].y;
+	    for (xpp = points + 1; count < tracePtr->screenPts.length; count++, 
+		     xpp++) {
+		xpp->x = Round(tracePtr->screenPts.points[count].x);
+		xpp->y = Round(tracePtr->screenPts.points[count].y);
+	    }	    
+	    XDrawLines(graphPtr->display, drawable, penPtr->traceGC, points, 
+		remaining + 1, CoordModeOrigin);
+	}
+    }
+    free(points);
+}
+
+static void
+DrawValues(Graph *graphPtr, Drawable drawable, LineElement *elemPtr, 
+	   LinePen *penPtr, int length, Point2d *points, int *map)
+{
+    Point2d *pp, *endp;
+    double *xval, *yval;
+    const char *fmt;
+    char string[TCL_DOUBLE_SPACE * 2 + 2];
+    int count;
+    
+    fmt = penPtr->valueFormat;
+    if (fmt == NULL) {
+	fmt = "%g";
+    }
+    count = 0;
+    xval = elemPtr->x.values, yval = elemPtr->y.values;
+    for (pp = points, endp = points + length; pp < endp; pp++) {
+	double x, y;
+
+	x = xval[map[count]];
+	y = yval[map[count]];
+	count++;
+	if (penPtr->valueShow == SHOW_X) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); 
+	} else if (penPtr->valueShow == SHOW_Y) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y); 
+	} else if (penPtr->valueShow == SHOW_BOTH) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x);
+	    strcat(string, ",");
+	    sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y);
+	}
+	Blt_DrawText(graphPtr->tkwin, drawable, string, &penPtr->valueStyle, 
+		Round(pp->x), Round(pp->y));
+    } 
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawActiveLineProc --
+ *
+ *	Draws the connected line(s) representing the element. If the line is
+ *	made up of non-line symbols and the line width parameter has been set
+ *	(linewidth > 0), the element will also be drawn as a line (with the
+ *	linewidth requested).  The line may consist of separate line segments.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	X drawing commands are output.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawActiveLineProc(Graph *graphPtr, Drawable drawable, Element *basePtr)
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+    LinePen *penPtr = (LinePen *)elemPtr->activePenPtr;
+    int symbolSize;
+
+    if (penPtr == NULL) {
+	return;
+    }
+    symbolSize = ScaleSymbol(elemPtr, penPtr->symbol.size);
+
+    /* 
+     * nActiveIndices 
+     *	  > 0		Some points are active.  Uses activeArr.
+     *	  < 0		All points are active.
+     *    == 0		No points are active.
+     */
+    if (elemPtr->nActiveIndices > 0) {
+	if (elemPtr->flags & ACTIVE_PENDING) {
+	    MapActiveSymbols(graphPtr, elemPtr);
+	}
+	if (penPtr->symbol.type != SYMBOL_NONE) {
+	    DrawSymbols(graphPtr, drawable, elemPtr, penPtr, symbolSize,
+		elemPtr->activePts.length, elemPtr->activePts.points);
+	}
+	if (penPtr->valueShow != SHOW_NONE) {
+	    DrawValues(graphPtr, drawable, elemPtr, penPtr, 
+		elemPtr->activePts.length,
+		elemPtr->activePts.points, 
+		elemPtr->activePts.map);
+	}
+    } else if (elemPtr->nActiveIndices < 0) { 
+	if (penPtr->traceWidth > 0) {
+	    if (elemPtr->lines.length > 0) {
+		Blt_Draw2DSegments(graphPtr->display, drawable, 
+			penPtr->traceGC, elemPtr->lines.segments, 
+			elemPtr->lines.length);
+	    } else if (Blt_Chain_GetLength(elemPtr->traces) > 0) {
+		DrawTraces(graphPtr, drawable, elemPtr, penPtr);
+	    }
+	}
+	if (penPtr->symbol.type != SYMBOL_NONE) {
+	    DrawSymbols(graphPtr, drawable, elemPtr, penPtr, symbolSize,
+		elemPtr->symbolPts.length, elemPtr->symbolPts.points);
+	}
+	if (penPtr->valueShow != SHOW_NONE) {
+	    DrawValues(graphPtr, drawable, elemPtr, penPtr, 
+		elemPtr->symbolPts.length, elemPtr->symbolPts.points, 
+		elemPtr->symbolPts.map);
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawNormalLine --
+ *
+ *	Draws the connected line(s) representing the element. If the line is
+ *	made up of non-line symbols and the line width parameter has been set
+ *	(linewidth > 0), the element will also be drawn as a line (with the
+ *	linewidth requested).  The line may consist of separate line segments.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	X drawing commands are output.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawNormalLineProc(Graph *graphPtr, Drawable drawable, Element *basePtr)
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+    Blt_ChainLink link;
+    unsigned int count;
+
+    /* Fill area under the curve */
+    if (elemPtr->fillPts != NULL) {
+	XPoint *points;
+	Point2d *endp, *pp;
+
+	points = malloc(sizeof(XPoint) * elemPtr->nFillPts);
+	count = 0;
+	for (pp = elemPtr->fillPts, endp = pp + elemPtr->nFillPts; 
+	     pp < endp; pp++) {
+	    points[count].x = Round(pp->x);
+	    points[count].y = Round(pp->y);
+	    count++;
+	}
+	if (elemPtr->fillBg != NULL) {
+	    Blt_SetBackgroundOrigin(graphPtr->tkwin, elemPtr->fillBg, 0, 0);
+	    Blt_FillBackgroundPolygon(graphPtr->tkwin, drawable, 
+		elemPtr->fillBg, points, elemPtr->nFillPts, 0, TK_RELIEF_FLAT);
+	}
+	free(points);
+    }
+
+    /* Lines: stripchart segments or graph traces. */
+    if (elemPtr->lines.length > 0) {
+	for (link = Blt_Chain_FirstLink(elemPtr->styles); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    LineStyle *stylePtr;
+	    LinePen *penPtr;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    penPtr = (LinePen *)stylePtr->penPtr;
+	    if ((stylePtr->lines.length > 0) && 
+		(penPtr->errorBarLineWidth > 0)) {
+		Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->traceGC,
+			stylePtr->lines.segments, stylePtr->lines.length);
+	    }
+	}
+    } else {
+	LinePen *penPtr;
+
+	penPtr = NORMALPEN(elemPtr);
+	if ((Blt_Chain_GetLength(elemPtr->traces) > 0) && 
+	    (penPtr->traceWidth > 0)) {
+	    DrawTraces(graphPtr, drawable, elemPtr, penPtr);
+	}
+    }
+
+    if (elemPtr->reqMaxSymbols > 0) {
+	int total;
+
+	total = 0;
+	for (link = Blt_Chain_FirstLink(elemPtr->styles); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    LineStyle *stylePtr;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    total += stylePtr->symbolPts.length;
+	}
+	elemPtr->symbolInterval = total / elemPtr->reqMaxSymbols;
+	elemPtr->symbolCounter = 0;
+    }
+
+    /* Symbols, error bars, values. */
+
+    count = 0;
+    for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL;
+	 link = Blt_Chain_NextLink(link)) {
+	LineStyle *stylePtr;
+	LinePen *penPtr;
+
+	stylePtr = Blt_Chain_GetValue(link);
+	penPtr = (LinePen *)stylePtr->penPtr;
+	if ((stylePtr->xeb.length > 0) && (penPtr->errorBarShow & SHOW_X)) {
+	    Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC, 
+		stylePtr->xeb.segments, stylePtr->xeb.length);
+	}
+	if ((stylePtr->yeb.length > 0) && (penPtr->errorBarShow & SHOW_Y)) {
+	    Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC, 
+		stylePtr->yeb.segments, stylePtr->yeb.length);
+	}
+	if ((stylePtr->symbolPts.length > 0) && 
+	    (penPtr->symbol.type != SYMBOL_NONE)) {
+	    DrawSymbols(graphPtr, drawable, elemPtr, penPtr, 
+		stylePtr->symbolSize, stylePtr->symbolPts.length, 
+		stylePtr->symbolPts.points);
+	}
+	if (penPtr->valueShow != SHOW_NONE) {
+	    DrawValues(graphPtr, drawable, elemPtr, penPtr, 
+		stylePtr->symbolPts.length, stylePtr->symbolPts.points, 
+		elemPtr->symbolPts.map + count);
+	}
+	count += stylePtr->symbolPts.length;
+    }
+    elemPtr->symbolInterval = 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetSymbolPostScriptInfo --
+ *
+ *	Set up the PostScript environment with the macros and attributes needed
+ *	to draw the symbols of the element.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+GetSymbolPostScriptInfo(
+    Graph *graphPtr,
+    Blt_Ps ps,
+    LinePen *penPtr,
+    int size)
+{
+    XColor *outlineColor, *fillColor, *defaultColor;
+
+    /* Set line and foreground attributes */
+    outlineColor = penPtr->symbol.outlineColor;
+    fillColor = penPtr->symbol.fillColor;
+    defaultColor = penPtr->traceColor;
+
+    if (fillColor == COLOR_DEFAULT) {
+	fillColor = defaultColor;
+    }
+    if (outlineColor == COLOR_DEFAULT) {
+	outlineColor = defaultColor;
+    }
+    if (penPtr->symbol.type == SYMBOL_NONE) {
+	Blt_Ps_XSetLineAttributes(ps, defaultColor, penPtr->traceWidth + 2,
+		 &penPtr->traceDashes, CapButt, JoinMiter);
+    } else {
+	Blt_Ps_XSetLineWidth(ps, penPtr->symbol.outlineWidth);
+	Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL);
+    }
+
+    /*
+     * Build a PostScript procedure to draw the symbols.  For bitmaps, paint
+     * both the bitmap and its mask. Otherwise fill and stroke the path formed
+     * already.
+     */
+    Blt_Ps_Append(ps, "\n/DrawSymbolProc {\n");
+    switch (penPtr->symbol.type) {
+    case SYMBOL_NONE:
+	break;				/* Do nothing */
+    case SYMBOL_BITMAP:
+	{
+	    int w, h;
+	    double sx, sy, scale;
+
+	    /*
+	     * Compute how much to scale the bitmap.  Don't let the scaled
+	     * bitmap exceed the bounding square for the symbol.
+	     */
+	    Tk_SizeOfBitmap(graphPtr->display, penPtr->symbol.bitmap, &w, &h);
+	    sx = (double)size / (double)w;
+	    sy = (double)size / (double)h;
+	    scale = MIN(sx, sy);
+
+	    if ((penPtr->symbol.mask != None) && (fillColor != NULL)) {
+		Blt_Ps_VarAppend(ps, "\n  % Bitmap mask is \"",
+		    Tk_NameOfBitmap(graphPtr->display, penPtr->symbol.mask),
+		    "\"\n\n  ", (char *)NULL);
+		Blt_Ps_XSetBackground(ps, fillColor);
+		Blt_Ps_DrawBitmap(ps, graphPtr->display, penPtr->symbol.mask, 
+			scale, scale);
+	    }
+	    Blt_Ps_VarAppend(ps, "\n  % Bitmap symbol is \"",
+		Tk_NameOfBitmap(graphPtr->display, penPtr->symbol.bitmap),
+		"\"\n\n  ", (char *)NULL);
+	    Blt_Ps_XSetForeground(ps, outlineColor);
+	    Blt_Ps_DrawBitmap(ps, graphPtr->display, penPtr->symbol.bitmap, 
+		scale, scale);
+	}
+	break;
+    default:
+	if (fillColor != NULL) {
+	    Blt_Ps_Append(ps, "  ");
+	    Blt_Ps_XSetBackground(ps, fillColor);
+	    Blt_Ps_Append(ps, "  gsave fill grestore\n");
+	}
+	if ((outlineColor != NULL) && (penPtr->symbol.outlineWidth > 0)) {
+	    Blt_Ps_Append(ps, "  ");
+	    Blt_Ps_XSetForeground(ps, outlineColor);
+	    Blt_Ps_Append(ps, "  stroke\n");
+	}
+	break;
+    }
+    Blt_Ps_Append(ps, "} def\n\n");
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SymbolsToPostScript --
+ *
+ * 	Draw a symbol centered at the given x,y window coordinate based upon the
+ * 	element symbol type and size.
+ *
+ * Results:
+ *	None.
+ *
+ * Problems:
+ *	Most notable is the round-off errors generated when calculating the
+ *	centered position of the symbol.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+SymbolsToPostScript(
+    Graph *graphPtr,
+    Blt_Ps ps,
+    LinePen *penPtr,
+    int size,
+    int nSymbolPts,
+    Point2d *symbolPts)
+{
+    double symbolSize;
+    static const char *symbolMacros[] =
+    {
+	"Li", "Sq", "Ci", "Di", "Pl", "Cr", "Sp", "Sc", "Tr", "Ar", "Bm", 
+	(char *)NULL,
+    };
+    GetSymbolPostScriptInfo(graphPtr, ps, penPtr, size);
+
+    symbolSize = (double)size;
+    switch (penPtr->symbol.type) {
+    case SYMBOL_SQUARE:
+    case SYMBOL_CROSS:
+    case SYMBOL_PLUS:
+    case SYMBOL_SCROSS:
+    case SYMBOL_SPLUS:
+	symbolSize = (double)Round(size * S_RATIO);
+	break;
+    case SYMBOL_TRIANGLE:
+    case SYMBOL_ARROW:
+	symbolSize = (double)Round(size * 0.7);
+	break;
+    case SYMBOL_DIAMOND:
+	symbolSize = (double)Round(size * M_SQRT1_2);
+	break;
+
+    default:
+	break;
+    }
+    {
+	Point2d *pp, *endp;
+
+	for (pp = symbolPts, endp = symbolPts + nSymbolPts; pp < endp; pp++) {
+	    Blt_Ps_Format(ps, "%g %g %g %s\n", pp->x, pp->y, 
+		symbolSize, symbolMacros[penPtr->symbol.type]);
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SymbolToPostScriptProc --
+ *
+ * 	Draw the symbol centered at the each given x,y coordinate.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Draws a symbol at the coordinate given.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+SymbolToPostScriptProc(
+    Graph *graphPtr,			/* Graph widget record */
+    Blt_Ps ps,
+    Element *basePtr,			/* Line element information */
+    double x, double y,			/* Center position of symbol */
+    int size)				/* Size of element */
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+    LinePen *penPtr;
+
+    penPtr = NORMALPEN(elemPtr);
+    if (penPtr->traceWidth > 0) {
+	/*
+	 * Draw an extra line offset by one pixel from the previous to give a
+	 * thicker appearance.  This is only for the legend entry.  This routine
+	 * is never called for drawing the actual line segments.
+	 */
+	Blt_Ps_XSetLineAttributes(ps, penPtr->traceColor,
+	    penPtr->traceWidth, &penPtr->traceDashes, CapButt, JoinMiter);
+	Blt_Ps_Format(ps, "%g %g %d Li\n", x, y, size + size);
+    }
+    if (penPtr->symbol.type != SYMBOL_NONE) {
+	Point2d point;
+
+	point.x = x, point.y = y;
+	SymbolsToPostScript(graphPtr, ps, penPtr, size, 1, &point);
+    }
+}
+
+static void
+SetLineAttributes(Blt_Ps ps, LinePen *penPtr)
+{
+    /* Set the attributes of the line (color, dashes, linewidth) */
+    Blt_Ps_XSetLineAttributes(ps, penPtr->traceColor,
+	penPtr->traceWidth, &penPtr->traceDashes, CapButt, JoinMiter);
+    if ((LineIsDashed(penPtr->traceDashes)) && 
+	(penPtr->traceOffColor != NULL)) {
+	Blt_Ps_Append(ps, "/DashesProc {\n  gsave\n    ");
+	Blt_Ps_XSetBackground(ps, penPtr->traceOffColor);
+	Blt_Ps_Append(ps, "    ");
+	Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL);
+	Blt_Ps_Append(ps, "stroke\n  grestore\n} def\n");
+    } else {
+	Blt_Ps_Append(ps, "/DashesProc {} def\n");
+    }
+}
+
+static void
+TracesToPostScript(Blt_Ps ps, LineElement *elemPtr, LinePen *penPtr)
+{
+    Blt_ChainLink link;
+
+    SetLineAttributes(ps, penPtr);
+    for (link = Blt_Chain_FirstLink(elemPtr->traces); link != NULL;
+	link = Blt_Chain_NextLink(link)) {
+	bltTrace *tracePtr;
+
+	tracePtr = Blt_Chain_GetValue(link);
+	if (tracePtr->screenPts.length > 0) {
+	    Blt_Ps_Append(ps, "% start trace\n");
+	    Blt_Ps_DrawPolyline(ps, tracePtr->screenPts.points, 
+		tracePtr->screenPts.length);
+	    Blt_Ps_Append(ps, "% end trace\n");
+	}
+    }
+}
+
+
+static void
+ValuesToPostScript(Blt_Ps ps, LineElement *elemPtr, LinePen *penPtr,
+		   int nSymbolPts, Point2d *symbolPts, int *pointToData)
+{
+    Point2d *pp, *endp;
+    int count;
+    char string[TCL_DOUBLE_SPACE * 2 + 2];
+    const char *fmt;
+    
+    fmt = penPtr->valueFormat;
+    if (fmt == NULL) {
+	fmt = "%g";
+    }
+    count = 0;
+    for (pp = symbolPts, endp = symbolPts + nSymbolPts; pp < endp; pp++) {
+	double x, y;
+
+	x = elemPtr->x.values[pointToData[count]];
+	y = elemPtr->y.values[pointToData[count]];
+	count++;
+	if (penPtr->valueShow == SHOW_X) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); 
+	} else if (penPtr->valueShow == SHOW_Y) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y); 
+	} else if (penPtr->valueShow == SHOW_BOTH) {
+	    sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x);
+	    strcat(string, ",");
+	    sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y);
+	}
+	Blt_Ps_DrawText(ps, string, &penPtr->valueStyle, pp->x, pp->y);
+    } 
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ActiveLineToPostScript --
+ *
+ *	Generates PostScript commands to draw as "active" the points (symbols)
+ *	and or line segments (trace) representing the element.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	PostScript pen width, dashes, and color settings are changed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+ActiveLineToPostScriptProc(Graph *graphPtr, Blt_Ps ps, Element *basePtr)
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+    LinePen *penPtr = (LinePen *)elemPtr->activePenPtr;
+    int symbolSize;
+
+    if (penPtr == NULL) {
+	return;
+    }
+    symbolSize = ScaleSymbol(elemPtr, penPtr->symbol.size);
+    if (elemPtr->nActiveIndices > 0) {
+	if (elemPtr->flags & ACTIVE_PENDING) {
+	    MapActiveSymbols(graphPtr, elemPtr);
+	}
+	if (penPtr->symbol.type != SYMBOL_NONE) {
+	    SymbolsToPostScript(graphPtr, ps, penPtr, symbolSize,
+		elemPtr->activePts.length, elemPtr->activePts.points);
+	}
+	if (penPtr->valueShow != SHOW_NONE) {
+	    ValuesToPostScript(ps, elemPtr, penPtr, elemPtr->activePts.length,
+		       elemPtr->activePts.points, elemPtr->activePts.map);
+	}
+    } else if (elemPtr->nActiveIndices < 0) {
+	if (penPtr->traceWidth > 0) {
+	    if (elemPtr->lines.length > 0) {
+		SetLineAttributes(ps, penPtr);
+		Blt_Ps_Draw2DSegments(ps, elemPtr->lines.segments, 
+			elemPtr->lines.length);
+	    }
+	    if (Blt_Chain_GetLength(elemPtr->traces) > 0) {
+		TracesToPostScript(ps, elemPtr, (LinePen *)penPtr);
+	    }
+	}
+	if (penPtr->symbol.type != SYMBOL_NONE) {
+	    SymbolsToPostScript(graphPtr, ps, penPtr, symbolSize,
+		elemPtr->symbolPts.length, elemPtr->symbolPts.points);
+	}
+	if (penPtr->valueShow != SHOW_NONE) {
+	    ValuesToPostScript(ps, elemPtr, penPtr, elemPtr->symbolPts.length, 
+		elemPtr->symbolPts.points, elemPtr->symbolPts.map);
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NormalLineToPostScriptProc --
+ *
+ *	Similar to the DrawLine procedure, prints PostScript related commands to
+ *	form the connected line(s) representing the element.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	PostScript pen width, dashes, and color settings are changed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+NormalLineToPostScriptProc(Graph *graphPtr, Blt_Ps ps, Element *basePtr)
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+    Blt_ChainLink link;
+    unsigned int count;
+
+    /* Draw fill area */
+    if (elemPtr->fillPts != NULL) {
+	/* Create a path to use for both the polygon and its outline. */
+	Blt_Ps_Append(ps, "% start fill area\n");
+	Blt_Ps_Polyline(ps, elemPtr->fillPts, elemPtr->nFillPts);
+
+	/* If the background fill color was specified, draw the polygon in a
+	 * solid fashion with that color.  */
+	if (elemPtr->fillBgColor != NULL) {
+	    Blt_Ps_XSetBackground(ps, elemPtr->fillBgColor);
+	    Blt_Ps_Append(ps, "gsave fill grestore\n");
+	}
+	Blt_Ps_XSetForeground(ps, elemPtr->fillFgColor);
+	if (elemPtr->fillBg != NULL) {
+	    Blt_Ps_Append(ps, "gsave fill grestore\n");
+	    /* TBA: Transparent tiling is the hard part. */
+	} else {
+	    Blt_Ps_Append(ps, "gsave fill grestore\n");
+	}
+	Blt_Ps_Append(ps, "% end fill area\n");
+    }
+
+    /* Draw lines (strip chart) or traces (xy graph) */
+    if (elemPtr->lines.length > 0) {
+	for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; 
+	     link = Blt_Chain_NextLink(link)) {
+	    LineStyle *stylePtr;
+	    LinePen *penPtr;
+
+	    stylePtr = Blt_Chain_GetValue(link);
+	    penPtr = (LinePen *)stylePtr->penPtr;
+	    if ((stylePtr->lines.length > 0) && (penPtr->traceWidth > 0)) {
+		SetLineAttributes(ps, penPtr);
+		Blt_Ps_Append(ps, "% start segments\n");
+		Blt_Ps_Draw2DSegments(ps, stylePtr->lines.segments, 
+			stylePtr->lines.length);
+		Blt_Ps_Append(ps, "% end segments\n");
+	    }
+	}
+    } else {
+	LinePen *penPtr;
+
+	penPtr = NORMALPEN(elemPtr);
+	if ((Blt_Chain_GetLength(elemPtr->traces) > 0) && 
+	    (penPtr->traceWidth > 0)) {
+	    TracesToPostScript(ps, elemPtr, penPtr);
+	}
+    }
+
+    /* Draw symbols, error bars, values. */
+
+    count = 0;
+    for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL;
+	 link = Blt_Chain_NextLink(link)) {
+	LineStyle *stylePtr;
+	LinePen *penPtr;
+	XColor *colorPtr;
+
+	stylePtr = Blt_Chain_GetValue(link);
+	penPtr = (LinePen *)stylePtr->penPtr;
+	colorPtr = penPtr->errorBarColor;
+	if (colorPtr == COLOR_DEFAULT) {
+	    colorPtr = penPtr->traceColor;
+	}
+	if ((stylePtr->xeb.length > 0) && (penPtr->errorBarShow & SHOW_X)) {
+	    Blt_Ps_XSetLineAttributes(ps, colorPtr, penPtr->errorBarLineWidth, 
+		NULL, CapButt, JoinMiter);
+	    Blt_Ps_Draw2DSegments(ps, stylePtr->xeb.segments, 
+		stylePtr->xeb.length);
+	}
+	if ((stylePtr->yeb.length > 0) && (penPtr->errorBarShow & SHOW_Y)) {
+	    Blt_Ps_XSetLineAttributes(ps, colorPtr, penPtr->errorBarLineWidth, 
+		NULL, CapButt, JoinMiter);
+	    Blt_Ps_Draw2DSegments(ps, stylePtr->yeb.segments,
+		stylePtr->yeb.length);
+	}
+	if ((stylePtr->symbolPts.length > 0) &&
+	    (penPtr->symbol.type != SYMBOL_NONE)) {
+	    SymbolsToPostScript(graphPtr, ps, penPtr, stylePtr->symbolSize, 
+		stylePtr->symbolPts.length, stylePtr->symbolPts.points);
+	}
+	if (penPtr->valueShow != SHOW_NONE) {
+	    ValuesToPostScript(ps, elemPtr, penPtr, stylePtr->symbolPts.length, 
+		stylePtr->symbolPts.points, elemPtr->symbolPts.map + count);
+	}
+	count += stylePtr->symbolPts.length;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DestroyLineProc --
+ *
+ *	Release memory and resources allocated for the line element.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Everything associated with the line element is freed up.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+DestroyLineProc(Graph *graphPtr, Element *basePtr)
+{
+    LineElement *elemPtr = (LineElement *)basePtr;
+
+    DestroyPenProc(graphPtr, (Pen *)&elemPtr->builtinPen);
+    if (elemPtr->activePenPtr != NULL) {
+	Blt_FreePen((Pen *)elemPtr->activePenPtr);
+    }
+    ResetLine(elemPtr);
+    if (elemPtr->styles != NULL) {
+	Blt_FreeStylePalette(elemPtr->styles);
+	Blt_Chain_Destroy(elemPtr->styles);
+    }
+    if (elemPtr->activeIndices != NULL) {
+	free(elemPtr->activeIndices);
+    }
+    if (elemPtr->fillPts != NULL) {
+	free(elemPtr->fillPts);
+    }
+    if (elemPtr->fillGC != NULL) {
+	Tk_FreeGC(graphPtr->display, elemPtr->fillGC);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_LineElement --
+ *
+ *	Allocate memory and initialize methods for the new line element.
+ *
+ * Results:
+ *	The pointer to the newly allocated element structure is returned.
+ *
+ * Side effects:
+ *	Memory is allocated for the line element structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static ElementProcs lineProcs =
+{
+    ClosestLineProc,			/* Finds the closest element/data
+					 * point */
+    ConfigureLineProc,			/* Configures the element. */
+    DestroyLineProc,			/* Destroys the element. */
+    DrawActiveLineProc,			/* Draws active element */
+    DrawNormalLineProc,			/* Draws normal element */
+    DrawSymbolProc,			/* Draws the element symbol. */
+    GetLineExtentsProc,			/* Find the extents of the element's
+					 * data. */
+    ActiveLineToPostScriptProc,		/* Prints active element. */
+    NormalLineToPostScriptProc,		/* Prints normal element. */
+    SymbolToPostScriptProc,		/* Prints the line's symbol. */
+    MapLineProc				/* Compute element's screen
+					 * coordinates. */
+};
+
+Element *
+Blt_LineElement(Graph *graphPtr, const char *name, ClassId classId)
+{
+    LineElement *elemPtr;
+
+    elemPtr = calloc(1, sizeof(LineElement));
+    elemPtr->procsPtr = &lineProcs;
+    elemPtr->configSpecs = lineElemConfigSpecs;
+    elemPtr->obj.name = Blt_Strdup(name);
+    Blt_GraphSetObjectClass(&elemPtr->obj, classId);
+    elemPtr->flags = SCALE_SYMBOL;
+    elemPtr->obj.graphPtr = graphPtr;
+    /* By default an element's name and label are the same. */
+    elemPtr->label = Blt_Strdup(name);
+    elemPtr->legendRelief = TK_RELIEF_FLAT;
+    elemPtr->penDir = PEN_BOTH_DIRECTIONS;
+    elemPtr->styles = Blt_Chain_Create();
+    elemPtr->builtinPenPtr = &elemPtr->builtinPen;
+    elemPtr->reqSmooth = PEN_SMOOTH_LINEAR;
+    InitLinePen(elemPtr->builtinPenPtr);
+    bltLineStylesOption.clientData = (ClientData)sizeof(LineStyle);
+    return (Element *)elemPtr;
+}
+
diff --git a/tlt3.0/bltGrMarker.c b/tlt3.0/bltGrMarker.c
new file mode 100644
index 0000000..89f587b
--- /dev/null
+++ b/tlt3.0/bltGrMarker.c
@@ -0,0 +1,4372 @@
+/*
+ * bltGrMarker.c --
+ *
+ * This module implements markers for the BLT graph widget.
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "bltInt.h"
+#include "bltMath.h"
+#include "bltGraph.h"
+#include "bltOp.h"
+#include "bltImage.h"
+#include "bltGrElem.h"
+#include "bltBitmap.h"
+
+typedef int (GraphMarkerProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+#define GETBITMAP(b) \
+	(((b)->destBitmap == None) ? (b)->srcBitmap : (b)->destBitmap)
+
+#define MAX_OUTLINE_POINTS	12
+
+#define IMAGE_PHOTO		(1<<7)
+
+/* Map graph coordinates to normalized coordinates [0..1] */
+#define NORMALIZE(A,x) 	(((x) - (A)->axisRange.min) * (A)->axisRange.scale)
+
+#define DEF_MARKER_ANCHOR	"center"
+#define DEF_MARKER_BACKGROUND	RGB_WHITE
+#define DEF_MARKER_BITMAP	(char *)NULL
+#define DEF_MARKER_CAP_STYLE	"butt"
+#define DEF_MARKER_COORDS	(char *)NULL
+#define DEF_MARKER_DASHES	(char *)NULL
+#define DEF_MARKER_DASH_OFFSET	"0"
+#define DEF_MARKER_ELEMENT	(char *)NULL
+#define DEF_MARKER_FOREGROUND	RGB_BLACK
+#define DEF_MARKER_FILL_COLOR	RGB_RED
+#define DEF_MARKER_FONT		STD_FONT
+#define DEF_MARKER_GAP_COLOR	RGB_PINK
+#define DEF_MARKER_HEIGHT	"0"
+#define DEF_MARKER_HIDE		"no"
+#define DEF_MARKER_JOIN_STYLE	"miter"
+#define DEF_MARKER_JUSTIFY	"left"
+#define DEF_MARKER_LINE_WIDTH	"1"
+#define DEF_MARKER_MAP_X	"x"
+#define DEF_MARKER_MAP_Y	"y"
+#define DEF_MARKER_NAME		(char *)NULL
+#define DEF_MARKER_OUTLINE_COLOR RGB_BLACK
+#define DEF_MARKER_PAD		"4"
+#define DEF_MARKER_ANGLE	"0.0"
+#define DEF_MARKER_SCALE	"1.0"
+#define DEF_MARKER_STATE	"normal"
+#define DEF_MARKER_STIPPLE	(char *)NULL
+#define DEF_MARKER_TEXT		(char *)NULL
+#define DEF_MARKER_UNDER	"no"
+#define DEF_MARKER_WIDTH	"0"
+#define DEF_MARKER_WINDOW	(char *)NULL
+#define DEF_MARKER_XOR		"no"
+#define DEF_MARKER_X_OFFSET	"0"
+#define DEF_MARKER_Y_OFFSET	"0"
+#define DEF_MARKER_FILTER	"box"
+
+#define DEF_TEXT_TAGS		"Text all"
+#define DEF_IMAGE_TAGS		"Image all"
+#define DEF_BITMAP_TAGS		"Bitmap all"
+#define DEF_WINDOW_TAGS		"Window all"
+#define DEF_POLYGON_TAGS	"Polygon all"
+#define DEF_LINE_TAGS		"Line all"
+
+static Blt_OptionParseProc ObjToCoordsProc;
+static Blt_OptionPrintProc CoordsToObjProc;
+static Blt_OptionFreeProc FreeCoordsProc;
+static Blt_CustomOption coordsOption =
+{
+    ObjToCoordsProc, CoordsToObjProc, FreeCoordsProc, (ClientData)0
+};
+static Blt_OptionFreeProc FreeColorPairProc;
+static Blt_OptionParseProc ObjToColorPairProc;
+static Blt_OptionPrintProc ColorPairToObjProc;
+static Blt_CustomOption colorPairOption =
+{
+    ObjToColorPairProc, ColorPairToObjProc, FreeColorPairProc, (ClientData)0
+};
+
+extern Blt_CustomOption bltXAxisOption;
+extern Blt_CustomOption bltYAxisOption;
+extern Blt_CustomOption bltFilterOption;
+
+typedef Marker *(MarkerCreateProc)(void);
+typedef void    (MarkerDrawProc)(Marker *markerPtr, Drawable drawable);
+typedef void    (MarkerFreeProc)(Marker *markerPtr);
+typedef int     (MarkerConfigProc)(Marker *markerPtr);
+typedef void    (MarkerMapProc)(Marker *markerPtr);
+typedef void    (MarkerPostscriptProc)(Marker *markerPtr, Blt_Ps ps);
+typedef int     (MarkerPointProc)(Marker *markerPtr, Point2d *samplePtr);
+typedef int     (MarkerRegionProc)(Marker *markerPtr, Region2d *extsPtr, 
+				   int enclosed);
+
+static Tcl_FreeProc FreeMarker;
+
+typedef struct {
+    Blt_ConfigSpec *configSpecs;	/* Marker configuration
+					 * specifications */
+    MarkerConfigProc *configProc;
+    MarkerDrawProc *drawProc;
+    MarkerFreeProc *freeProc;
+    MarkerMapProc *mapProc;
+    MarkerPointProc *pointProc;
+    MarkerRegionProc *regionProc;
+    MarkerPostscriptProc *postscriptProc;
+
+}  MarkerClass;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Marker --
+ *
+ *	Structure defining the generic marker.  In C++ parlance this would be
+ *	the base class from which all markers are derived.
+ *
+ *	This structure corresponds with the specific types of markers.  Don't
+ *	change this structure without changing the individual marker
+ *	structures of each type below.
+ *
+ * -------------------------------------------------------------------------- 
+ */
+struct _Marker {
+    GraphObj obj;			/* Must be first field in marker. */
+
+    MarkerClass *classPtr;
+
+    Blt_HashEntry *hashPtr;
+
+    Blt_ChainLink link;
+
+    const char *elemName;		/* Element associated with marker. Let's
+					 * you link a marker to an element. The
+					 * marker is drawn only if the element
+					 * is also visible. */
+    Axis2d axes;
+    Point2d *worldPts;		        /* Coordinate array to position
+					 * marker */
+    int nWorldPts;			/* Number of points in above array */
+    int drawUnder;			/* If non-zero, draw the marker
+					 * underneath any elements. This can be
+					 * a performance penalty because the
+					 * graph must be redraw entirely each
+					 * time the marker is redrawn. */
+
+    int clipped;			/* Indicates if the marker is totally
+					 * clipped by the plotting area. */
+
+    unsigned int flags;		
+
+
+    int xOffset, yOffset;		/* Pixel offset from graph position */
+
+    int state;
+};
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BitmapMarker --
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    GraphObj obj;			/* Must be first field in marker. */
+
+    MarkerClass *classPtr;
+
+    Blt_HashEntry *hashPtr;
+
+    Blt_ChainLink link;
+
+    const char *elemName;		/* Element associated with marker. Let's
+					 * you link a marker to an element. The
+					 * marker is drawn only if the element
+					 * is also visible. */
+    Axis2d axes;
+
+    Point2d *worldPts;			/* Coordinate array to position
+					 * marker. */
+    int nWorldPts;			/* # of points in above array. */
+
+    int drawUnder;			/* If non-zero, draw the marker
+					 * underneath any elements. This can be
+					 * a performance penalty because the
+					 * graph must be redraw entirely each
+					 * time the marker is redrawn. */
+
+    int clipped;			/* Indicates if the marker is totally
+					 * clipped by the plotting area. */
+
+    unsigned int flags;		
+
+
+    int xOffset, yOffset;		/* Pixel offset from graph position */
+
+    int state;
+
+    /* Fields specific to bitmap markers. */
+
+    Pixmap srcBitmap;			/* Original bitmap. May be further
+					 * scaled or rotated. */
+    float reqAngle;			/* Requested rotation of the bitmap */
+    float angle;			/* Normalized rotation (0..360
+					 * degrees) */
+    Tk_Anchor anchor;			/* If only one X-Y coordinate is given,
+					* indicates how to translate the given
+					* marker position.  Otherwise, if there
+					* are two X-Y coordinates, then this
+					* value is ignored. */
+    Point2d anchorPt;			/* Translated anchor point. */
+
+    XColor *outlineColor;		/* Foreground color */
+    XColor *fillColor;			/* Background color */
+
+    GC gc;				/* Private graphic context */
+    GC fillGC;				/* Shared graphic context */
+    Pixmap destBitmap;			/* Bitmap to be drawn. */
+    int destWidth, destHeight;		/* Dimensions of the final bitmap */
+
+    Point2d outline[MAX_OUTLINE_POINTS];/* Polygon representing the background
+					 * of the bitmap. */
+    int nOutlinePts;
+} BitmapMarker;
+
+static Blt_ConfigSpec bitmapConfigSpecs[] =
+{
+    {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MARKER_ANCHOR, 
+	Blt_Offset(BitmapMarker, anchor), 0},
+    {BLT_CONFIG_COLOR, "-background", "background", "Background",
+	DEF_MARKER_BACKGROUND, Blt_Offset(BitmapMarker, fillColor),
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_BITMAP_TAGS, 
+	Blt_Offset(BitmapMarker, obj.tags), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_BITMAP, "-bitmap", "bitmap", "Bitmap", DEF_MARKER_BITMAP, 
+	Blt_Offset(BitmapMarker, srcBitmap), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, 
+	Blt_Offset(BitmapMarker, worldPts), BLT_CONFIG_NULL_OK, 
+	&coordsOption},
+    {BLT_CONFIG_STRING, "-element", "element", "Element", DEF_MARKER_ELEMENT, 
+	Blt_Offset(BitmapMarker, elemName), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_SYNONYM, "-fill", "background", (char *)NULL, (char *)NULL, 
+	0, 0},
+    {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
+	DEF_MARKER_FOREGROUND, Blt_Offset(BitmapMarker, outlineColor),
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, 
+	Blt_Offset(BitmapMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT,
+        (Blt_CustomOption *)HIDE},
+    {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, 
+	Blt_Offset(BitmapMarker, axes.x), 0, &bltXAxisOption},
+    {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, 
+	Blt_Offset(BitmapMarker, axes.y), 0, &bltYAxisOption},
+    {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, 
+	Blt_Offset(BitmapMarker, obj.name), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char *)NULL, (char *)NULL, 
+	0, 0},
+    {BLT_CONFIG_FLOAT, "-rotate", "rotate", "Rotate", DEF_MARKER_ANGLE, 
+	Blt_Offset(BitmapMarker, reqAngle), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, 
+	Blt_Offset(BitmapMarker, state), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, 
+	Blt_Offset(BitmapMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, 
+	Blt_Offset(BitmapMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, 
+	Blt_Offset(BitmapMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+static MarkerConfigProc ConfigureBitmapProc;
+static MarkerCreateProc CreateBitmapProc;
+static MarkerDrawProc DrawBitmapProc;
+static MarkerFreeProc FreeBitmapProc;
+static MarkerMapProc MapBitmapProc;
+static MarkerPointProc PointInBitmapProc;
+static MarkerPostscriptProc BitmapToPostscriptProc;
+static MarkerRegionProc RegionInBitmapProc;
+
+static MarkerClass bitmapMarkerClass = {
+    bitmapConfigSpecs,
+    ConfigureBitmapProc,
+    DrawBitmapProc,
+    FreeBitmapProc,
+    MapBitmapProc,
+    PointInBitmapProc,
+    RegionInBitmapProc,
+    BitmapToPostscriptProc,
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LineMarker --
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    GraphObj obj;			/* Must be first field in marker. */
+
+    MarkerClass *classPtr;
+
+    Blt_HashEntry *hashPtr;
+
+    Blt_ChainLink link;
+
+    const char *elemName;		/* Element associated with marker. Let's
+					 * you link a marker to an element. The
+					 * marker is drawn only if the element
+					 * is also visible. */
+    Axis2d axes;
+
+    Point2d *worldPts;			/* Coordinate array to position
+					 * marker. */
+
+    int nWorldPts;			/* Number of points in above array */
+
+    int drawUnder;			/* If non-zero, draw the marker
+					 * underneath any elements. This can be
+					 * a performance penalty because the
+					 * graph must be redraw entirely each
+					 * time the marker is redrawn. */
+
+    int clipped;			/* Indicates if the marker is totally
+					 * clipped by the plotting area. */
+
+    unsigned int flags;		
+
+
+    int xOffset, yOffset;		/* Pixel offset from graph position */
+
+    int state;
+
+    XColor *fillColor;
+    XColor *outlineColor;		/* Foreground and background colors */
+
+    int lineWidth;			/* Line width. */
+    int capStyle;			/* Cap style. */
+    int joinStyle;			/* Join style.*/
+    Blt_Dashes dashes;			/* Dash list values (max 11) */
+
+    GC gc;				/* Private graphic context */
+
+    Segment2d *segments;		/* Malloc'ed array of points.
+					 * Represents individual line segments
+					 * (2 points per segment) comprising the
+					 * mapped line.  The segments may not
+					 * necessarily be connected after
+					 * clipping. */
+    int nSegments;			/* # segments in the above array. */
+    int xor;
+    int xorState;			/* State of the XOR drawing. Indicates
+					 * if the marker is currently drawn. */
+} LineMarker;
+
+static Blt_ConfigSpec lineConfigSpecs[] =
+{
+    {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_LINE_TAGS, 
+	Blt_Offset(LineMarker, obj.tags), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_CAP_STYLE, "-cap", "cap", "Cap", DEF_MARKER_CAP_STYLE, 
+	Blt_Offset(LineMarker, capStyle), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, 
+	Blt_Offset(LineMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption},
+    {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_MARKER_DASHES, 
+	Blt_Offset(LineMarker, dashes), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_PIXELS_NNEG, "-dashoffset", "dashOffset", "DashOffset",
+	DEF_MARKER_DASH_OFFSET, Blt_Offset(LineMarker, dashes.offset),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-element", "element", "Element", DEF_MARKER_ELEMENT, 
+	Blt_Offset(LineMarker, elemName), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_COLOR, "-fill", "fill", "Fill", (char *)NULL, 
+	Blt_Offset(LineMarker, fillColor), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_JOIN_STYLE, "-join", "join", "Join", DEF_MARKER_JOIN_STYLE, 
+     Blt_Offset(LineMarker, joinStyle), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth",
+	DEF_MARKER_LINE_WIDTH, Blt_Offset(LineMarker, lineWidth),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, 
+	Blt_Offset(LineMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT,
+        (Blt_CustomOption *)HIDE},
+    {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, 
+	Blt_Offset(LineMarker, axes.x), 0, &bltXAxisOption},
+    {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, 
+	Blt_Offset(LineMarker, axes.y), 0, &bltYAxisOption},
+    {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, 
+	Blt_Offset(LineMarker, obj.name), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_COLOR, "-outline", "outline", "Outline",
+	DEF_MARKER_OUTLINE_COLOR, Blt_Offset(LineMarker, outlineColor),
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, 
+	Blt_Offset(LineMarker, state), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, 
+	Blt_Offset(LineMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, 
+	Blt_Offset(LineMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BOOLEAN, "-xor", "xor", "Xor", DEF_MARKER_XOR, 
+	Blt_Offset(LineMarker, xor), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, 
+	Blt_Offset(LineMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+static MarkerConfigProc ConfigureLineProc;
+static MarkerCreateProc CreateLineProc;
+static MarkerDrawProc DrawLineProc;
+static MarkerFreeProc FreeLineProc;
+static MarkerMapProc MapLineProc;
+static MarkerPointProc PointInLineProc;
+static MarkerPostscriptProc LineToPostscriptProc;
+static MarkerRegionProc RegionInLineProc;
+
+static MarkerClass lineMarkerClass = {
+    lineConfigSpecs,
+    ConfigureLineProc,
+    DrawLineProc,
+    FreeLineProc,
+    MapLineProc,
+    PointInLineProc,
+    RegionInLineProc,
+    LineToPostscriptProc,
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PolygonMarker --
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    GraphObj obj;			/* Must be first field in marker. */
+
+    MarkerClass *classPtr;
+
+    Blt_HashEntry *hashPtr;
+
+    Blt_ChainLink link;
+
+    const char *elemName;		/* Element associated with marker. Let's
+					 * you link a marker to an element. The
+					 * marker is drawn only if the element
+					 * is also visible. */
+    Axis2d axes;
+
+    Point2d *worldPts;			/* Coordinate array to position
+					 * marker. */
+
+    int nWorldPts;			/* Number of points in above array */
+
+    int drawUnder;			/* If non-zero, draw the marker
+					 * underneath any elements. This can be
+					 * a performance penalty because the
+					 * graph must be redraw entirely each
+					 * time the marker is redrawn. */
+
+    int clipped;			/* Indicates if the marker is totally
+					 * clipped by the plotting area. */
+
+    unsigned int flags;		
+
+
+    int xOffset, yOffset;		/* Pixel offset from graph position */
+
+    int state;
+
+    Point2d *screenPts;			/* Array of points representing the
+					 * polygon in screen coordinates. It's
+					 * not used for drawing, but to generate
+					 * the outlinePts and fillPts arrays
+					 * that are the coordinates of the
+					 * possibly clipped outline and filled
+					 * polygon. */
+
+    ColorPair outline;
+    ColorPair fill;
+
+    Pixmap stipple;			/* Stipple pattern to fill the
+					 * polygon. */
+    int lineWidth;			/* Width of polygon outline. */
+    int capStyle;
+    int joinStyle;
+    Blt_Dashes dashes;			/* List of dash values.  Indicates how
+					 * to draw the dashed line.  If no dash
+					 * values are provided, or the first
+					 * value is zero, then the line is drawn
+					 * solid. */
+
+    GC outlineGC;			/* Graphics context to draw the outline
+					 * of the polygon. */
+    GC fillGC;				/* Graphics context to draw the filled
+					 * polygon. */
+
+    Point2d *fillPts;			/* Malloc'ed array of points used to
+					 * draw the filled polygon. These points
+					 * may form a degenerate polygon after
+					 * clipping. */
+    int nFillPts;			/* # points in the above array. */
+    Segment2d *outlinePts;		/* Malloc'ed array of points.
+					 * Represents individual line segments
+					 * (2 points per segment) comprising the
+					 * outline of the polygon.  The segments
+					 * may not necessarily be closed or
+					 * connected after clipping. */
+    int nOutlinePts;			/* # points in the above array. */
+    int xor;
+    int xorState;			/* State of the XOR drawing. Indicates
+					 * if the marker is visible. We have to
+					 * drawn it again to erase it. */
+} PolygonMarker;
+
+static Blt_ConfigSpec polygonConfigSpecs[] =
+{
+    {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_POLYGON_TAGS, 
+	Blt_Offset(PolygonMarker, obj.tags), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_CAP_STYLE, "-cap", "cap", "Cap", DEF_MARKER_CAP_STYLE, 
+	Blt_Offset(PolygonMarker, capStyle), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, 
+	Blt_Offset(PolygonMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption},
+    {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_MARKER_DASHES, 
+	Blt_Offset(PolygonMarker, dashes), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_STRING, "-element", "element", "Element", DEF_MARKER_ELEMENT, 
+	Blt_Offset(PolygonMarker, elemName), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_CUSTOM, "-fill", "fill", "Fill", DEF_MARKER_FILL_COLOR, 
+	Blt_Offset(PolygonMarker, fill), BLT_CONFIG_NULL_OK, &colorPairOption},
+    {BLT_CONFIG_JOIN_STYLE, "-join", "join", "Join", DEF_MARKER_JOIN_STYLE, 
+	Blt_Offset(PolygonMarker, joinStyle), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth",
+	DEF_MARKER_LINE_WIDTH, Blt_Offset(PolygonMarker, lineWidth),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, 
+	Blt_Offset(PolygonMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT,
+        (Blt_CustomOption *)HIDE},
+    {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, 
+	Blt_Offset(PolygonMarker, axes.x), 0, &bltXAxisOption},
+    {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, 
+	Blt_Offset(PolygonMarker, axes.y), 0, &bltYAxisOption},
+    {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, 
+	Blt_Offset(PolygonMarker, obj.name), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_CUSTOM, "-outline", "outline", "Outline", 
+	DEF_MARKER_OUTLINE_COLOR, Blt_Offset(PolygonMarker, outline),
+	BLT_CONFIG_NULL_OK, &colorPairOption},
+    {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, 
+	Blt_Offset(PolygonMarker, state), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple", DEF_MARKER_STIPPLE, 
+	Blt_Offset(PolygonMarker, stipple), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, 
+	Blt_Offset(PolygonMarker, drawUnder), 
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, 
+	Blt_Offset(PolygonMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BOOLEAN, "-xor", "xor", "Xor", DEF_MARKER_XOR, 
+	Blt_Offset(PolygonMarker, xor), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, 
+	Blt_Offset(PolygonMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+static MarkerConfigProc ConfigurePolygonProc;
+static MarkerCreateProc CreatePolygonProc;
+static MarkerDrawProc DrawPolygonProc;
+static MarkerFreeProc FreePolygonProc;
+static MarkerMapProc MapPolygonProc;
+static MarkerPointProc PointInPolygonProc;
+static MarkerPostscriptProc PolygonToPostscriptProc;
+static MarkerRegionProc RegionInPolygonProc;
+
+static MarkerClass polygonMarkerClass = {
+    polygonConfigSpecs,
+    ConfigurePolygonProc,
+    DrawPolygonProc,
+    FreePolygonProc,
+    MapPolygonProc,
+    PointInPolygonProc,
+    RegionInPolygonProc,
+    PolygonToPostscriptProc,
+};
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TextMarker --
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    GraphObj obj;			/* Must be first field in marker. */
+    MarkerClass *classPtr;
+    Blt_HashEntry *hashPtr;
+    Blt_ChainLink link;
+    const char *elemName;		/* Element associated with marker. Let's
+					 * you link a marker to an element. The
+					 * marker is drawn only if the element
+					 * is also visible. */
+    Axis2d axes;
+    Point2d *worldPts;			/* Coordinate array to position
+					 * marker. */
+    int nWorldPts;			/* # of points in above array */
+    int drawUnder;			/* If non-zero, draw the marker
+					 * underneath any elements. This can be
+					 * a performance penalty because the
+					 * graph must be redraw entirely each
+					 * time the marker is redrawn. */
+    int clipped;			/* Indicates if the marker is totally
+					 * clipped by the plotting area. */
+    unsigned int flags;		
+
+
+    int xOffset, yOffset;		/* Pixel offset from graph position */
+    int state;
+
+    /* Fields specific to text markers. */
+    const char *string;			/* Text string to be display.  The
+					 * string make contain newlines. */
+    Tk_Anchor anchor;			/* Indicates how to translate the given
+					 * marker position. */
+    Point2d anchorPt;			/* Translated anchor point. */
+    int width, height;			/* Dimension of bounding box. */
+    TextStyle style;			/* Text attributes (font, fg, anchor,
+					 * etc) */
+    Point2d outline[5];
+    XColor *fillColor;
+    GC fillGC;
+} TextMarker;
+
+
+static Blt_ConfigSpec textConfigSpecs[] =
+{
+    {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MARKER_ANCHOR, 
+	Blt_Offset(TextMarker, anchor), 0},
+    {BLT_CONFIG_COLOR, "-background", "background", "MarkerBackground",
+	(char *)NULL, Blt_Offset(TextMarker, fillColor), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-bg", "background", "Background", (char *)NULL, 0, 0},
+    {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_TEXT_TAGS,
+	Blt_Offset(TextMarker, obj.tags), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, 
+	Blt_Offset(TextMarker, worldPts), BLT_CONFIG_NULL_OK, 
+        &coordsOption},
+    {BLT_CONFIG_STRING, "-element", "element", "Element",
+	DEF_MARKER_ELEMENT, Blt_Offset(TextMarker, elemName), 
+        BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-fg", "foreground", "Foreground", (char *)NULL, 0, 0},
+    {BLT_CONFIG_SYNONYM, "-fill", "background", (char *)NULL, (char *)NULL, 
+	0, 0},
+    {BLT_CONFIG_FONT, "-font", "font", "Font", 	DEF_MARKER_FONT, 
+	Blt_Offset(TextMarker, style.font), 0},
+    {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
+	DEF_MARKER_FOREGROUND, Blt_Offset(TextMarker, style.color), 0},
+    {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify",
+	DEF_MARKER_JUSTIFY, Blt_Offset(TextMarker, style.justify),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, 
+	Blt_Offset(TextMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT, 
+	(Blt_CustomOption *)HIDE},
+    {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, 
+	Blt_Offset(TextMarker, axes.x), 0, &bltXAxisOption},
+    {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, 
+	Blt_Offset(TextMarker, axes.y), 0, &bltYAxisOption},
+    {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, 
+	Blt_Offset(TextMarker, obj.name), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char *)NULL, (char *)NULL, 
+	0, 0},
+    {BLT_CONFIG_PAD, "-padx", "padX", "PadX", DEF_MARKER_PAD, 
+	Blt_Offset(TextMarker, style.xPad), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PAD, "-pady", "padY", "PadY", DEF_MARKER_PAD, 
+	Blt_Offset(TextMarker, style.yPad), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_FLOAT, "-rotate", "rotate", "Rotate", DEF_MARKER_ANGLE, 
+	Blt_Offset(TextMarker, style.angle), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, 
+	Blt_Offset(TextMarker, state), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-text", "text", "Text", DEF_MARKER_TEXT, 
+	Blt_Offset(TextMarker, string), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, 
+	Blt_Offset(TextMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, 
+	Blt_Offset(TextMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, 
+	Blt_Offset(TextMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+static MarkerConfigProc ConfigureTextProc;
+static MarkerCreateProc CreateTextProc;
+static MarkerDrawProc DrawTextProc;
+static MarkerFreeProc FreeTextProc;
+static MarkerMapProc MapTextProc;
+static MarkerPointProc PointInTextProc;
+static MarkerPostscriptProc TextToPostscriptProc;
+static MarkerRegionProc RegionInTextProc;
+
+static MarkerClass textMarkerClass = {
+    textConfigSpecs,
+    ConfigureTextProc,
+    DrawTextProc,
+    FreeTextProc,
+    MapTextProc,
+    PointInTextProc,
+    RegionInTextProc,
+    TextToPostscriptProc,
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * WindowMarker --
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    GraphObj obj;			/* Must be first field in marker. */
+
+    MarkerClass *classPtr;
+
+    Blt_HashEntry *hashPtr;
+
+    Blt_ChainLink link;
+
+    const char *elemName;		/* Element associated with marker. Let's
+					 * you link a marker to an element. The
+					 * marker is drawn only if the element
+					 * is also visible. */
+    Axis2d axes;
+
+    Point2d *worldPts;			/* Coordinate array to position
+					 * marker */
+
+    int nWorldPts;			/* # of points in above array */
+
+    int drawUnder;			/* If non-zero, draw the marker
+					 * underneath any elements. This can be
+					 * a performance penalty because the
+					 * graph must be redraw entirely each
+					 * time the marker is redrawn. */
+
+    int clipped;			/* Indicates if the marker is totally
+					 * clipped by the plotting area. */
+
+    unsigned int flags;		
+
+
+    int xOffset, yOffset;		/* Pixel offset from graph position */
+
+    int state;
+
+    /* Fields specific to window markers. */
+
+    const char *childName;		/* Name of child widget. */
+    Tk_Window child;			/* Window to display. */
+    int reqWidth, reqHeight;		/* If non-zero, this overrides the size
+					 * requested by the child widget. */
+
+    Tk_Anchor anchor;			/* Indicates how to translate the given
+					 * marker position. */
+
+    Point2d anchorPt;			/* Translated anchor point. */
+    int width, height;			/* Current size of the child window. */
+
+} WindowMarker;
+
+static Blt_ConfigSpec windowConfigSpecs[] =
+{
+    {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MARKER_ANCHOR, 
+	Blt_Offset(WindowMarker, anchor), 0},
+    {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_WINDOW_TAGS, 
+	Blt_Offset(WindowMarker, obj.tags), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, 
+	Blt_Offset(WindowMarker, worldPts), BLT_CONFIG_NULL_OK, 
+	&coordsOption},
+    {BLT_CONFIG_STRING, "-element", "element", "Element", DEF_MARKER_ELEMENT, 
+	Blt_Offset(WindowMarker, elemName), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_PIXELS_POS, "-height", "height", "Height", DEF_MARKER_HEIGHT, 
+	Blt_Offset(WindowMarker, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, 
+        Blt_Offset(WindowMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT,
+        (Blt_CustomOption *)HIDE},
+    {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, 
+	Blt_Offset(WindowMarker, axes.x), 0, &bltXAxisOption},
+    {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, 
+	Blt_Offset(WindowMarker, axes.y), 0, &bltYAxisOption},
+    {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, 
+	Blt_Offset(WindowMarker, obj.name), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, 
+	Blt_Offset(WindowMarker, state), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, 
+	Blt_Offset(WindowMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_POS, "-width", "width", "Width", DEF_MARKER_WIDTH, 
+	Blt_Offset(WindowMarker, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-window", "window", "Window", DEF_MARKER_WINDOW, 
+	Blt_Offset(WindowMarker, childName), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, 
+	Blt_Offset(WindowMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, 
+	Blt_Offset(WindowMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+static MarkerConfigProc ConfigureWindowProc;
+static MarkerCreateProc CreateWindowProc;
+static MarkerDrawProc DrawWindowProc;
+static MarkerFreeProc FreeWindowProc;
+static MarkerMapProc MapWindowProc;
+static MarkerPointProc PointInWindowProc;
+static MarkerPostscriptProc WindowToPostscriptProc;
+static MarkerRegionProc RegionInWindowProc;
+
+static MarkerClass windowMarkerClass = {
+    windowConfigSpecs,
+    ConfigureWindowProc,
+    DrawWindowProc,
+    FreeWindowProc,
+    MapWindowProc,
+    PointInWindowProc,
+    RegionInWindowProc,
+    WindowToPostscriptProc,
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BoxesDontOverlap --
+ *
+ *	Tests if the bounding box of a marker overlaps the plotting area in
+ *	any way.  If so, the marker will be drawn.  Just do a min/max test on
+ *	the extents of both boxes.
+ *
+ *	Note: It's assumed that the extents of the bounding box lie 
+ *	      within the area.  So for a 10x10 rectangle, bottom and
+ *	      left would be 9.
+ *
+ * Results:
+ *	Returns 0 is the marker is visible in the plotting area, and 1
+ *	otherwise (marker is clipped).
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+BoxesDontOverlap(Graph *graphPtr, Region2d *extsPtr)
+{
+    assert(extsPtr->right >= extsPtr->left);
+    assert(extsPtr->bottom >= extsPtr->top);
+    assert(graphPtr->right >= graphPtr->left);
+    assert(graphPtr->bottom >= graphPtr->top);
+
+    return (((double)graphPtr->right < extsPtr->left) ||
+	    ((double)graphPtr->bottom < extsPtr->top) ||
+	    (extsPtr->right < (double)graphPtr->left) ||
+	    (extsPtr->bottom < (double)graphPtr->top));
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetCoordinate --
+ *
+ * 	Convert the expression string into a floating point value. The * only
+ * 	reason we use this routine instead of Blt_ExprDouble is to * handle
+ * 	"elastic" bounds.  That is, convert the strings "-Inf", * "Inf" into
+ * 	-(DBL_MAX) and DBL_MAX respectively.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The value of the
+ * 	expression is passed back via valuePtr.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+GetCoordinate(
+    Tcl_Interp *interp,			/* Interpreter to return results */
+    Tcl_Obj *objPtr,			/* Numeric expression string to
+					 * parse */
+    double *valuePtr)			/* Real-valued result of expression */
+{
+    char c;
+    const char *expr;
+    
+    expr = Tcl_GetString(objPtr);
+    c = expr[0];
+    if ((c == 'I') && (strcmp(expr, "Inf") == 0)) {
+	*valuePtr = DBL_MAX;		/* Elastic upper bound */
+    } else if ((c == '-') && (expr[1] == 'I') && (strcmp(expr, "-Inf") == 0)) {
+	*valuePtr = -DBL_MAX;		/* Elastic lower bound */
+    } else if ((c == '+') && (expr[1] == 'I') && (strcmp(expr, "+Inf") == 0)) {
+	*valuePtr = DBL_MAX;		/* Elastic upper bound */
+    } else if (Blt_ExprDoubleFromObj(interp, objPtr, valuePtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PrintCoordinate --
+ *
+ * 	Convert the floating point value into its string representation.  The
+ * 	only reason this routine is used in instead of sprintf, is to handle
+ * 	the "elastic" bounds.  That is, convert the values DBL_MAX and
+ * 	-(DBL_MAX) into "+Inf" and "-Inf" respectively.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The string of the *
+ *	expression is passed back via string.
+ *
+ * -------------------------------------------------------------------------- */
+static Tcl_Obj *
+PrintCoordinate(double x)
+{
+    if (x == DBL_MAX) {
+	return Tcl_NewStringObj("+Inf", -1);
+    } else if (x == -DBL_MAX) {
+	return Tcl_NewStringObj("-Inf", -1);
+    } else {
+	return Tcl_NewDoubleObj(x);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ParseCoordinates --
+ *
+ *	The TCL coordinate list is converted to their floating point
+ *	values. It will then replace the current marker coordinates.
+ *
+ *	Since different marker types require different number of coordinates
+ *	this must be checked here.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ * Side effects:
+ *	If the marker coordinates are reset, the graph is eventually redrawn
+ *	with at the new marker coordinates.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ParseCoordinates(
+    Tcl_Interp *interp,
+    Marker *markerPtr,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    int nWorldPts;
+    int minArgs, maxArgs;
+    Point2d *worldPts;
+    int i;
+
+    if (objc == 0) {
+	return TCL_OK;
+    }
+    if (objc & 1) {
+	Tcl_AppendResult(interp, "odd number of marker coordinates specified",
+	    (char *)NULL);
+	return TCL_ERROR;
+    }
+    switch (markerPtr->obj.classId) {
+    case CID_MARKER_LINE:
+	minArgs = 4, maxArgs = 0;
+	break;
+    case CID_MARKER_POLYGON:
+	minArgs = 6, maxArgs = 0;
+	break;
+    case CID_MARKER_WINDOW:
+    case CID_MARKER_TEXT:
+	minArgs = 2, maxArgs = 2;
+	break;
+    case CID_MARKER_IMAGE:
+    case CID_MARKER_BITMAP:
+	minArgs = 2, maxArgs = 4;
+	break;
+    default:
+	Tcl_AppendResult(interp, "unknown marker type", (char *)NULL);
+	return TCL_ERROR;
+    }
+
+    if (objc < minArgs) {
+	Tcl_AppendResult(interp, "too few marker coordinates specified",
+	    (char *)NULL);
+	return TCL_ERROR;
+    }
+    if ((maxArgs > 0) && (objc > maxArgs)) {
+	Tcl_AppendResult(interp, "too many marker coordinates specified",
+	    (char *)NULL);
+	return TCL_ERROR;
+    }
+    nWorldPts = objc / 2;
+    worldPts = malloc(nWorldPts * sizeof(Point2d));
+    if (worldPts == NULL) {
+	Tcl_AppendResult(interp, "can't allocate new coordinate array",
+	    (char *)NULL);
+	return TCL_ERROR;
+    }
+
+    {
+	Point2d *pp;
+
+	pp = worldPts;
+	for (i = 0; i < objc; i += 2) {
+	    double x, y;
+	    
+	    if ((GetCoordinate(interp, objv[i], &x) != TCL_OK) ||
+		(GetCoordinate(interp, objv[i + 1], &y) != TCL_OK)) {
+		free(worldPts);
+		return TCL_ERROR;
+	    }
+	    pp->x = x, pp->y = y, pp++;
+	}
+    }
+    /* Don't free the old coordinate array until we've parsed the new
+     * coordinates without errors.  */
+    if (markerPtr->worldPts != NULL) {
+	free(markerPtr->worldPts);
+    }
+    markerPtr->worldPts = worldPts;
+    markerPtr->nWorldPts = nWorldPts;
+    markerPtr->flags |= MAP_ITEM;
+    return TCL_OK;
+}
+
+/*ARGSUSED*/
+static void
+FreeCoordsProc(
+    ClientData clientData,		/* Not used. */
+    Display *display,			/* Not used. */
+    char *widgRec,
+    int offset)
+{
+    Marker *markerPtr = (Marker *)widgRec;
+    Point2d **pointsPtr = (Point2d **)(widgRec + offset);
+
+    if (*pointsPtr != NULL) {
+	free(*pointsPtr);
+	*pointsPtr = NULL;
+    }
+    markerPtr->nWorldPts = 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToCoordsProc --
+ *
+ *	Given a TCL list of numeric expression representing the element
+ *	values, convert into an array of floating point values. In addition,
+ *	the minimum and maximum values are saved.  Since elastic values are
+ *	allow (values which translate to the min/max of the graph), we must
+ *	try to get the non-elastic minimum and maximum.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The vector is
+ *	passed back via the vecPtr.
+ *
+ * -------------------------------------------------------------------------- 
+ */
+/*ARGSUSED*/
+static int
+ObjToCoordsProc(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter to return results */
+    Tk_Window tkwin,		/* Not used. */
+    Tcl_Obj *objPtr,		/* TCL list of numeric expressions */
+    char *widgRec,		/* Marker record */
+    int offset,			/* Not used. */
+    int flags)			/* Not used. */
+{
+    Marker *markerPtr = (Marker *)widgRec;
+    int objc;
+    Tcl_Obj **objv;
+
+    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (objc == 0) {
+	return TCL_OK;
+    }
+    return ParseCoordinates(interp, markerPtr, objc, objv);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CoordsToObjProc --
+ *
+ *	Convert the vector of floating point values into a TCL list.
+ *
+ * Results:
+ *	The string representation of the vector is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+CoordsToObjProc(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,
+    Tk_Window tkwin,		/* Not used. */
+    char *widgRec,		/* Marker record */
+    int offset,			/* Not used. */
+    int flags)			/* Not used. */
+{
+    Marker *markerPtr = (Marker *)widgRec;
+    Tcl_Obj *listObjPtr;
+    Point2d *pp, *pend;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    for (pp = markerPtr->worldPts, pend = pp + markerPtr->nWorldPts; pp < pend;
+	 pp++) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, PrintCoordinate(pp->x));
+	Tcl_ListObjAppendElement(interp, listObjPtr, PrintCoordinate(pp->y));
+    }
+    return listObjPtr;
+}
+
+/*LINTLIBRARY*/
+static int
+GetColorPair(
+    Tcl_Interp *interp,
+    Tk_Window tkwin,
+    Tcl_Obj *fgObjPtr, Tcl_Obj *bgObjPtr,
+    ColorPair *pairPtr,
+    int allowDefault)
+{
+    XColor *fgColor, *bgColor;
+    const char *string;
+
+    fgColor = bgColor = NULL;
+    if (fgObjPtr != NULL) {
+	int length;
+
+	string = Tcl_GetStringFromObj(fgObjPtr, &length);
+	if (string[0] == '\0') {
+	    fgColor = NULL;
+	} else if ((allowDefault) && (string[0] == 'd') &&
+		   (strncmp(string, "defcolor", length) == 0)) {
+	    fgColor = COLOR_DEFAULT;
+	} else {
+	    fgColor = Tk_AllocColorFromObj(interp, tkwin, fgObjPtr);
+	    if (fgColor == NULL) {
+		return TCL_ERROR;
+	    }
+	}
+    }
+    if (bgObjPtr != NULL) {
+	int length;
+
+	string = Tcl_GetStringFromObj(bgObjPtr, &length);
+	if (string[0] == '\0') {
+	    bgColor = NULL;
+	} else if ((allowDefault) && (string[0] == 'd') &&
+		   (strncmp(string, "defcolor", length) == 0)) {
+	    bgColor = COLOR_DEFAULT;
+	} else {
+	    bgColor = Tk_AllocColorFromObj(interp, tkwin, bgObjPtr);
+	    if (bgColor == NULL) {
+		return TCL_ERROR;
+	    }
+	}
+    }
+    if (pairPtr->fgColor != NULL) {
+	Tk_FreeColor(pairPtr->fgColor);
+    }
+    if (pairPtr->bgColor != NULL) {
+	Tk_FreeColor(pairPtr->bgColor);
+    }
+    pairPtr->fgColor = fgColor;
+    pairPtr->bgColor = bgColor;
+    return TCL_OK;
+}
+
+void
+Blt_FreeColorPair(ColorPair *pairPtr)
+{
+    if ((pairPtr->bgColor != NULL) && (pairPtr->bgColor != COLOR_DEFAULT)) {
+	Tk_FreeColor(pairPtr->bgColor);
+    }
+    if ((pairPtr->fgColor != NULL) && (pairPtr->fgColor != COLOR_DEFAULT)) {
+	Tk_FreeColor(pairPtr->fgColor);
+    }
+    pairPtr->bgColor = pairPtr->fgColor = NULL;
+}
+
+static void
+FreeColorPairProc(
+    ClientData clientData,		/* Not used. */
+    Display *display,			/* Not used. */
+    char *widgRec,
+    int offset)
+{
+    ColorPair *pairPtr = (ColorPair *)(widgRec + offset);
+
+    Blt_FreeColorPair(pairPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToColorPairProc --
+ *
+ *	Convert the color names into pair of XColor pointers.
+ *
+ * Results:
+ *	A standard TCL result.  The color pointer is written into the
+ *	widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToColorPairProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Interpreter to return results */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* String representing color */
+    char *widgRec,			/* Widget record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    ColorPair *pairPtr = (ColorPair *)(widgRec + offset);
+    long longValue = (long)clientData;
+    int bool;
+    int objc;
+    Tcl_Obj **objv;
+
+    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (objc > 2) {
+	Tcl_AppendResult(interp, "too many names in colors list", 
+		(char *)NULL);
+	return TCL_ERROR;
+    }
+    if (objc == 0) {
+	Blt_FreeColorPair(pairPtr);
+	return TCL_OK;
+    }
+    bool = (int)longValue;
+    if (objc == 1) {
+	if (GetColorPair(interp, tkwin, objv[0], NULL, pairPtr, bool) 
+	    != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    } else {
+	if (GetColorPair(interp, tkwin, objv[0], objv[1], pairPtr, bool) 
+	    != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NameOfColor --
+ *
+ *	Convert the color option value into a string.
+ *
+ * Results:
+ *	The static string representing the color option is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+static const char *
+NameOfColor(XColor *colorPtr)
+{
+    if (colorPtr == NULL) {
+	return "";
+    } else if (colorPtr == COLOR_DEFAULT) {
+	return "defcolor";
+    } else {
+	return Tk_NameOfColor(colorPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ColorPairToObjProc --
+ *
+ *	Convert the color pairs into color names.
+ *
+ * Results:
+ *	The string representing the symbol color is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+ColorPairToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* Element information record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    ColorPair *pairPtr = (ColorPair *)(widgRec + offset);
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj(NameOfColor(pairPtr->fgColor), -1));
+    Tcl_ListObjAppendElement(interp, listObjPtr,
+		Tcl_NewStringObj(NameOfColor(pairPtr->bgColor), -1));
+    return listObjPtr;
+}
+
+static INLINE int
+IsElementHidden(Marker *markerPtr)
+{
+    Blt_HashEntry *hPtr;
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+
+    /* Look up the named element and see if it's hidden */
+    hPtr = Blt_FindHashEntry(&graphPtr->elements.table, markerPtr->elemName);
+    if (hPtr != NULL) {
+	Element *elemPtr;
+	
+	elemPtr = Blt_GetHashValue(hPtr);
+	if ((elemPtr->link == NULL) || (elemPtr->flags & HIDE)) {
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * HMap --
+ *
+ *	Maps the given graph coordinate value to its axis, returning a window
+ *	position.  This is a slight variation on the normal Blt_HMap routine.
+ *	It treats -Inf as the minimum axis value and Inf as the maximum.
+ *
+ * Results:
+ *	Returns a floating point number representing the window coordinate
+ *	position on the given axis.
+ *
+ * -------------------------------------------------------------------------- 
+ */
+static double
+HMap(Axis *axisPtr, double x)
+{
+    if (x == DBL_MAX) {
+	x = 1.0;
+    } else if (x == -DBL_MAX) {
+	x = 0.0;
+    } else {
+	if (axisPtr->logScale) {
+	    if (x > 0.0) {
+		x = log10(x);
+	    } else if (x < 0.0) {
+		x = 0.0;
+	    }
+	}
+	x = NORMALIZE(axisPtr, x);
+    }
+    if (axisPtr->descending) {
+	x = 1.0 - x;
+    }
+    /* Horizontal transformation */
+    return (x * axisPtr->screenRange + axisPtr->screenMin);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VMap --
+ *
+ *	Map the given graph coordinate value to its axis, returning a window
+ *	position.  This is a slight variation on the normal Blt_VMap routine.
+ *	It treats -Inf as the minimum axis value and Inf as the maximum.
+ *
+ * Results:
+ *	Returns a double precision number representing the window coordinate
+ *	position on the given axis.
+ *
+ *---------------------------------------------------------------------------
+ */
+static double
+VMap(Axis *axisPtr, double y)
+{
+    if (y == DBL_MAX) {
+	y = 1.0;
+    } else if (y == -DBL_MAX) {
+	y = 0.0;
+    } else {
+	if (axisPtr->logScale) {
+	    if (y > 0.0) {
+		y = log10(y);
+	    } else if (y < 0.0) {
+		y = 0.0;
+	    }
+	}
+	y = NORMALIZE(axisPtr, y);
+    }
+    if (axisPtr->descending) {
+	y = 1.0 - y;
+    }
+    /* Vertical transformation. */
+    return (((1.0 - y) * axisPtr->screenRange) + axisPtr->screenMin);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapPoint --
+ *
+ *	Maps the given graph x,y coordinate values to a window position.
+ *
+ * Results:
+ *	Returns a XPoint structure containing the window coordinates of the
+ *	given graph x,y coordinate.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Point2d
+MapPoint(
+    Point2d *pointPtr,		/* Graph X-Y coordinate. */
+    Axis2d *axesPtr)		/* Specifies which axes to use */
+{
+    Point2d result;
+    Graph *graphPtr = axesPtr->y->obj.graphPtr;
+
+    if (graphPtr->inverted) {
+	result.x = HMap(axesPtr->y, pointPtr->y);
+	result.y = VMap(axesPtr->x, pointPtr->x);
+    } else {
+	result.x = HMap(axesPtr->x, pointPtr->x);
+	result.y = VMap(axesPtr->y, pointPtr->y);
+    }
+    return result;			/* Result is screen coordinate. */
+}
+
+static Marker *
+CreateMarker(
+    Graph *graphPtr,
+    const char *name,
+    ClassId classId)
+{    
+    Marker *markerPtr;
+
+    /* Create the new marker based upon the given type */
+    switch (classId) {
+    case CID_MARKER_BITMAP:
+	markerPtr = CreateBitmapProc(); /* bitmap */
+	break;
+    case CID_MARKER_LINE:
+	markerPtr = CreateLineProc();	/* line */
+	break;
+    case CID_MARKER_IMAGE:
+      return NULL; /* not supported */
+	break;
+    case CID_MARKER_TEXT:
+	markerPtr = CreateTextProc();	/* text */
+	break;
+    case CID_MARKER_POLYGON:
+	markerPtr = CreatePolygonProc(); /* polygon */
+	break;
+    case CID_MARKER_WINDOW:
+	markerPtr = CreateWindowProc(); /* window */
+	break;
+    default:
+	return NULL;
+    }
+    markerPtr->obj.graphPtr = graphPtr;
+    markerPtr->drawUnder = FALSE;
+    markerPtr->flags |= MAP_ITEM;
+    markerPtr->obj.name = Blt_Strdup(name);
+    Blt_GraphSetObjectClass(&markerPtr->obj, classId);
+    return markerPtr;
+}
+
+
+static void
+DestroyMarker(Marker *markerPtr)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+
+    if (markerPtr->drawUnder) {
+	/* If the marker to be deleted is currently displayed below the
+	 * elements, then backing store needs to be repaired. */
+	graphPtr->flags |= CACHE_DIRTY;
+    }
+    /* 
+     * Call the marker's type-specific deallocation routine. We do it first
+     * while all the marker fields are still valid.
+     */
+    (*markerPtr->classPtr->freeProc)(markerPtr);
+
+    /* Dump any bindings that might be registered for the marker. */
+    Blt_DeleteBindings(graphPtr->bindTable, markerPtr);
+
+    /* Release all the X resources associated with the marker. */
+    Blt_FreeOptions(markerPtr->classPtr->configSpecs, (char *)markerPtr,
+	graphPtr->display, 0);
+
+    if (markerPtr->hashPtr != NULL) {
+	Blt_DeleteHashEntry(&graphPtr->markers.table, 
+			    markerPtr->hashPtr);
+    }
+    if (markerPtr->link != NULL) {
+	Blt_Chain_DeleteLink(graphPtr->markers.displayList, markerPtr->link);
+    }
+    if (markerPtr->obj.name != NULL) {
+      free((void*)(markerPtr->obj.name));
+    }
+    free(markerPtr);
+}
+
+static void FreeMarker(char* dataPtr) 
+{
+    Marker *markerPtr = (Marker *)dataPtr;
+    DestroyMarker(markerPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureBitmapProc --
+ *
+ *	This procedure is called to process an objv/objc list, plus the Tk
+ *	option database, in order to configure (or reconfigure) a bitmap
+ *	marker.
+ *
+ * Results:
+ *	A standard TCL result.  If TCL_ERROR is returned, then interp->result
+ *	contains an error message.
+ *
+ * Side effects:
+ *	Configuration information, such as bitmap pixmap, colors, rotation,
+ *	etc. get set for markerPtr; old resources get freed, if there were
+ *	any.  The marker is eventually redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static int
+ConfigureBitmapProc(Marker *markerPtr)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    BitmapMarker *bmPtr = (BitmapMarker *)markerPtr;
+    GC newGC;
+    XGCValues gcValues;
+    unsigned long gcMask;
+
+    if (bmPtr->srcBitmap == None) {
+	return TCL_OK;
+    }
+    bmPtr->angle = fmod(bmPtr->reqAngle, 360.0);
+    if (bmPtr->angle < 0.0) {
+	bmPtr->angle += 360.0;
+    }
+    gcMask = 0;
+
+    if (bmPtr->outlineColor != NULL) {
+	gcMask |= GCForeground;
+	gcValues.foreground = bmPtr->outlineColor->pixel;
+    }
+
+    if (bmPtr->fillColor != NULL) {
+	/* Opaque bitmap: both foreground and background (fill) colors
+	 * are used. */
+	gcValues.background = bmPtr->fillColor->pixel;
+	gcMask |= GCBackground;
+    } else {
+	/* Transparent bitmap: set the clip mask to the current bitmap. */
+	gcValues.clip_mask = bmPtr->srcBitmap;
+	gcMask |= GCClipMask;
+    }
+
+    /* 
+     * This is technically a shared GC, but we're going to set/change the clip
+     * origin anyways before we draw the bitmap.  This relies on the fact that
+     * no other client will be allocated this GC with the GCClipMask set to
+     * this particular bitmap.
+     */
+    newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (bmPtr->gc != NULL) {
+	Tk_FreeGC(graphPtr->display, bmPtr->gc);
+    }
+    bmPtr->gc = newGC;
+
+    /* Create the background GC containing the fill color. */
+
+    if (bmPtr->fillColor != NULL) {
+	gcValues.foreground = bmPtr->fillColor->pixel;
+	newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+	if (bmPtr->fillGC != NULL) {
+	    Tk_FreeGC(graphPtr->display, bmPtr->fillGC);
+	}
+	bmPtr->fillGC = newGC;
+    }
+
+    markerPtr->flags |= MAP_ITEM;
+    if (markerPtr->drawUnder) {
+	graphPtr->flags |= CACHE_DIRTY;
+    }
+
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapBitmapProc --
+ *
+ * 	This procedure gets called each time the layout of the graph changes.
+ * 	The x, y window coordinates of the bitmap marker are saved in the
+ * 	marker structure.
+ *
+ *	Additionly, if no background color was specified, the
+ *	GCTileStipXOrigin and GCTileStipYOrigin attributes are set in the
+ *	private GC.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Window coordinates are saved and if no background color was set, the
+ *	GC stipple origins are changed to calculated window coordinates.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapBitmapProc(Marker *markerPtr)
+{
+    BitmapMarker *bmPtr = (BitmapMarker *)markerPtr;
+    Region2d extents;
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    Point2d anchorPt;
+    Point2d corner1, corner2;
+    int destWidth, destHeight;
+    int srcWidth, srcHeight;
+    int i;
+
+    if (bmPtr->srcBitmap == None) {
+	return;
+    }
+    if (bmPtr->destBitmap != None) {
+	Tk_FreePixmap(graphPtr->display, bmPtr->destBitmap);
+	bmPtr->destBitmap = None;
+    }
+    /* 
+     * Collect the coordinates.  The number of coordinates will determine the
+     * calculations to be made.
+     * 
+     *	   x1 y1	A single pair of X-Y coordinates.  They represent
+     *			the anchor position of the bitmap.  
+     *
+     *	x1 y1 x2 y2	Two pairs of X-Y coordinates.  They represent
+     *			two opposite corners of a bounding rectangle. The
+     *			bitmap is possibly rotated and scaled to fit into
+     *			this box.
+     *
+     */   
+    Tk_SizeOfBitmap(graphPtr->display, bmPtr->srcBitmap, &srcWidth, 
+		    &srcHeight);
+    corner1 = MapPoint(markerPtr->worldPts, &markerPtr->axes);
+    if (markerPtr->nWorldPts > 1) {
+	double hold;
+
+	corner2 = MapPoint(markerPtr->worldPts + 1, &markerPtr->axes);
+	/* Flip the corners if necessary */
+	if (corner1.x > corner2.x) {
+	    hold = corner1.x, corner1.x = corner2.x, corner2.x = hold;
+	}
+	if (corner1.y > corner2.y) {
+	    hold = corner1.y, corner1.y = corner2.y, corner2.y = hold;
+	}
+    } else {
+	corner2.x = corner1.x + srcWidth - 1;
+	corner2.y = corner1.y + srcHeight - 1;
+    }
+    destWidth = (int)(corner2.x - corner1.x) + 1;
+    destHeight = (int)(corner2.y - corner1.y) + 1;
+
+    if (markerPtr->nWorldPts == 1) {
+	anchorPt = Blt_AnchorPoint(corner1.x, corner1.y, (double)destWidth, 
+		(double)destHeight, bmPtr->anchor);
+    } else {
+	anchorPt = corner1;
+    }
+    anchorPt.x += markerPtr->xOffset;
+    anchorPt.y += markerPtr->yOffset;
+
+    /* Check if the bitmap sits at least partially in the plot area. */
+    extents.left   = anchorPt.x;
+    extents.top    = anchorPt.y;
+    extents.right  = anchorPt.x + destWidth - 1;
+    extents.bottom = anchorPt.y + destHeight - 1;
+    markerPtr->clipped = BoxesDontOverlap(graphPtr, &extents);
+    if (markerPtr->clipped) {
+	return;				/* Bitmap is offscreen. Don't generate
+					 * rotated or scaled bitmaps. */
+    }
+
+    /*  
+     * Scale the bitmap if necessary. It's a little tricky because we only
+     * want to scale what's visible on the screen, not the entire bitmap.
+     */
+    if ((bmPtr->angle != 0.0f) || (destWidth != srcWidth) || 
+	(destHeight != srcHeight)) {
+	int regionX, regionY, regionWidth, regionHeight; 
+	double left, right, top, bottom;
+
+	/* Ignore parts of the bitmap outside of the plot area. */
+	left   = MAX(graphPtr->left, extents.left);
+	right  = MIN(graphPtr->right, extents.right);
+	top    = MAX(graphPtr->top, extents.top);
+	bottom = MIN(graphPtr->bottom, extents.bottom);
+
+	/* Determine the portion of the scaled bitmap to display. */
+	regionX = regionY = 0;
+	if (graphPtr->left > extents.left) {
+	    regionX = (int)(graphPtr->left - extents.left);
+	}
+	if (graphPtr->top > extents.top) {
+	    regionY = (int)(graphPtr->top - extents.top);
+	}	    
+	regionWidth = (int)(right - left) + 1;
+	regionHeight = (int)(bottom - top) + 1;
+	
+	anchorPt.x = left;
+	anchorPt.y = top;
+	bmPtr->destBitmap = Blt_ScaleRotateBitmapArea(graphPtr->tkwin, 
+		bmPtr->srcBitmap, srcWidth, srcHeight, regionX, regionY, 
+		regionWidth, regionHeight, destWidth, destHeight, bmPtr->angle);
+	bmPtr->destWidth = regionWidth;
+	bmPtr->destHeight = regionHeight;
+    } else {
+	bmPtr->destWidth = srcWidth;
+	bmPtr->destHeight = srcHeight;
+	bmPtr->destBitmap = None;
+    }
+    bmPtr->anchorPt = anchorPt;
+    {
+	double xScale, yScale;
+	double tx, ty;
+	double rotWidth, rotHeight;
+	Point2d polygon[5];
+	int n;
+
+	/* 
+	 * Compute a polygon to represent the background area of the bitmap.
+	 * This is needed for backgrounds of arbitrarily rotated bitmaps.  We
+	 * also use it to print a background in PostScript.
+	 */
+	Blt_GetBoundingBox(srcWidth, srcHeight, bmPtr->angle, &rotWidth, 
+			   &rotHeight, polygon);
+	xScale = (double)destWidth / rotWidth;
+	yScale = (double)destHeight / rotHeight;
+	
+	/* 
+	 * Adjust each point of the polygon. Both scale it to the new size and
+	 * translate it to the actual screen position of the bitmap.
+	 */
+	tx = extents.left + destWidth * 0.5;
+	ty = extents.top + destHeight * 0.5;
+	for (i = 0; i < 4; i++) {
+	    polygon[i].x = (polygon[i].x * xScale) + tx;
+	    polygon[i].y = (polygon[i].y * yScale) + ty;
+	}
+	Blt_GraphExtents(graphPtr, &extents);
+	n = Blt_PolyRectClip(&extents, polygon, 4, bmPtr->outline); 
+	assert(n <= MAX_OUTLINE_POINTS);
+	if (n < 3) { 
+	    memcpy(&bmPtr->outline, polygon, sizeof(Point2d) * 4);
+	    bmPtr->nOutlinePts = 4;
+	} else {
+	    bmPtr->nOutlinePts = n;
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PointInBitmapProc --
+ *
+ *	Indicates if the given point is over the bitmap marker.  The area of
+ *	the bitmap is the rectangle.
+ *
+ * Results:
+ *	Returns 1 is the point is over the bitmap marker, 0 otherwise.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+PointInBitmapProc(Marker *markerPtr, Point2d *samplePtr)
+{
+    BitmapMarker *bmPtr = (BitmapMarker *)markerPtr;
+
+    if (bmPtr->srcBitmap == None) {
+	return 0;
+    }
+    if (bmPtr->angle != 0.0f) {
+	Point2d points[MAX_OUTLINE_POINTS];
+	int i;
+
+	/*  
+	 * Generate the bounding polygon (isolateral) for the bitmap and see
+	 * if the point is inside of it.
+	 */
+	for (i = 0; i < bmPtr->nOutlinePts; i++) {
+	    points[i].x = bmPtr->outline[i].x + bmPtr->anchorPt.x;
+	    points[i].y = bmPtr->outline[i].y + bmPtr->anchorPt.y;
+	}
+	return Blt_PointInPolygon(samplePtr, points, bmPtr->nOutlinePts);
+    }
+    return ((samplePtr->x >= bmPtr->anchorPt.x) && 
+	    (samplePtr->x < (bmPtr->anchorPt.x + bmPtr->destWidth)) &&
+	    (samplePtr->y >= bmPtr->anchorPt.y) && 
+	    (samplePtr->y < (bmPtr->anchorPt.y + bmPtr->destHeight)));
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RegionInBitmapProc --
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+RegionInBitmapProc(Marker *markerPtr, Region2d *extsPtr, int enclosed)
+{
+    BitmapMarker *bmPtr = (BitmapMarker *)markerPtr;
+
+    if (markerPtr->nWorldPts < 1) {
+	return FALSE;
+    }
+    if (bmPtr->angle != 0.0f) {
+	Point2d points[MAX_OUTLINE_POINTS];
+	int i;
+	
+	/*  
+	 * Generate the bounding polygon (isolateral) for the bitmap and see
+	 * if the point is inside of it.
+	 */
+	for (i = 0; i < bmPtr->nOutlinePts; i++) {
+	    points[i].x = bmPtr->outline[i].x + bmPtr->anchorPt.x;
+	    points[i].y = bmPtr->outline[i].y + bmPtr->anchorPt.y;
+	}
+	return Blt_RegionInPolygon(extsPtr, points, bmPtr->nOutlinePts, 
+		   enclosed);
+    }
+    if (enclosed) {
+	return ((bmPtr->anchorPt.x >= extsPtr->left) &&
+		(bmPtr->anchorPt.y >= extsPtr->top) && 
+		((bmPtr->anchorPt.x + bmPtr->destWidth) <= extsPtr->right) &&
+		((bmPtr->anchorPt.y + bmPtr->destHeight) <= extsPtr->bottom));
+    }
+    return !((bmPtr->anchorPt.x >= extsPtr->right) ||
+	     (bmPtr->anchorPt.y >= extsPtr->bottom) ||
+	     ((bmPtr->anchorPt.x + bmPtr->destWidth) <= extsPtr->left) ||
+	     ((bmPtr->anchorPt.y + bmPtr->destHeight) <= extsPtr->top));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawBitmapProc --
+ *
+ *	Draws the bitmap marker that have a transparent of filled background.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	GC stipple origins are changed to current window coordinates.
+ *	Commands are output to X to draw the marker in its current mode.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawBitmapProc(Marker *markerPtr, Drawable drawable)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    BitmapMarker *bmPtr = (BitmapMarker *)markerPtr;
+    double rangle;
+    Pixmap bitmap;
+
+    bitmap = GETBITMAP(bmPtr);
+    if ((bitmap == None) || (bmPtr->destWidth < 1) || (bmPtr->destHeight < 1)) {
+	return;
+    }
+    rangle = fmod(bmPtr->angle, 90.0);
+    if ((bmPtr->fillColor == NULL) || (rangle != 0.0)) {
+
+	/* 
+	 * If the bitmap is rotated and a filled background is required, then
+	 * a filled polygon is drawn before the bitmap.
+	 */
+	if (bmPtr->fillColor != NULL) {
+	    int i;
+	    XPoint polygon[MAX_OUTLINE_POINTS];
+
+	    for (i = 0; i < bmPtr->nOutlinePts; i++) {
+		polygon[i].x = (short int)bmPtr->outline[i].x;
+		polygon[i].y = (short int)bmPtr->outline[i].y;
+	    }
+	    XFillPolygon(graphPtr->display, drawable, bmPtr->fillGC,
+		 polygon, bmPtr->nOutlinePts, Convex, CoordModeOrigin);
+	}
+	XSetClipMask(graphPtr->display, bmPtr->gc, bitmap);
+	XSetClipOrigin(graphPtr->display, bmPtr->gc, (int)bmPtr->anchorPt.x, 
+	       (int)bmPtr->anchorPt.y);
+    } else {
+	XSetClipMask(graphPtr->display, bmPtr->gc, None);
+	XSetClipOrigin(graphPtr->display, bmPtr->gc, 0, 0);
+    }
+    XCopyPlane(graphPtr->display, bitmap, drawable, bmPtr->gc, 0, 0,
+	bmPtr->destWidth, bmPtr->destHeight, (int)bmPtr->anchorPt.x, 
+	(int)bmPtr->anchorPt.y, 1);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BitmapToPostscriptProc --
+ *
+ *	Generates PostScript to print a bitmap marker.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+BitmapToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    BitmapMarker *bmPtr = (BitmapMarker *)markerPtr;
+    Pixmap bitmap;
+
+    bitmap = GETBITMAP(bmPtr);
+    if ((bitmap == None) || (bmPtr->destWidth < 1) || (bmPtr->destHeight < 1)) {
+	return;				/* No bitmap to display. */
+    }
+    if (bmPtr->fillColor != NULL) {
+	Blt_Ps_XSetBackground(ps, bmPtr->fillColor);
+	Blt_Ps_XFillPolygon(ps, bmPtr->outline, 4);
+    }
+    Blt_Ps_XSetForeground(ps, bmPtr->outlineColor);
+
+    Blt_Ps_Format(ps,
+	"  gsave\n    %g %g translate\n    %d %d scale\n", 
+	   bmPtr->anchorPt.x, bmPtr->anchorPt.y + bmPtr->destHeight, 
+	   bmPtr->destWidth, -bmPtr->destHeight);
+    Blt_Ps_Format(ps, "    %d %d true [%d 0 0 %d 0 %d] {",
+	bmPtr->destWidth, bmPtr->destHeight, bmPtr->destWidth, 
+	-bmPtr->destHeight, bmPtr->destHeight);
+    Blt_Ps_XSetBitmapData(ps, graphPtr->display, bitmap,
+	bmPtr->destWidth, bmPtr->destHeight);
+    Blt_Ps_VarAppend(ps, 
+		     "    } imagemask\n",
+		     "grestore\n", (char *)NULL);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FreeBitmapProc --
+ *
+ *	Releases the memory and attributes of the bitmap marker.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Bitmap attributes (GCs, colors, bitmap, etc) get destroyed.  Memory is
+ *	released, X resources are freed, and the graph is redrawn.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+FreeBitmapProc(Marker *markerPtr)
+{
+    BitmapMarker *bmPtr = (BitmapMarker *)markerPtr;
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+
+    if (bmPtr->gc != NULL) {
+	Tk_FreeGC(graphPtr->display, bmPtr->gc);
+    }
+    if (bmPtr->fillGC != NULL) {
+	Tk_FreeGC(graphPtr->display, bmPtr->fillGC);
+    }
+    if (bmPtr->destBitmap != None) {
+	Tk_FreePixmap(graphPtr->display, bmPtr->destBitmap);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateBitmapProc --
+ *
+ *	Allocate memory and initialize methods for the new bitmap marker.
+ *
+ * Results:
+ *	The pointer to the newly allocated marker structure is returned.
+ *
+ * Side effects:
+ *	Memory is allocated for the bitmap marker structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Marker *
+CreateBitmapProc(void)
+{
+    BitmapMarker *bmPtr;
+
+    bmPtr = calloc(1, sizeof(BitmapMarker));
+    bmPtr->classPtr = &bitmapMarkerClass;
+    return (Marker *)bmPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureTextProc --
+ *
+ *	This procedure is called to process an objv/objc list, plus the Tk
+ *	option database, in order to configure (or reconfigure) a text marker.
+ *
+ * Results:
+ *	A standard TCL result.  If TCL_ERROR is returned, then interp->result
+ *	contains an error message.
+ *
+ * Side effects:
+ *	Configuration information, such as text string, colors, font, etc. get
+ *	set for markerPtr; old resources get freed, if there were any.  The
+ *	marker is eventually redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ConfigureTextProc(Marker *markerPtr)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    TextMarker *tmPtr = (TextMarker *)markerPtr;
+    GC newGC;
+    XGCValues gcValues;
+    unsigned long gcMask;
+
+    tmPtr->style.angle = (float)fmod(tmPtr->style.angle, 360.0);
+    if (tmPtr->style.angle < 0.0f) {
+	tmPtr->style.angle += 360.0f;
+    }
+    newGC = NULL;
+    if (tmPtr->fillColor != NULL) {
+	gcMask = GCForeground;
+	gcValues.foreground = tmPtr->fillColor->pixel;
+	newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    }
+    if (tmPtr->fillGC != NULL) {
+	Tk_FreeGC(graphPtr->display, tmPtr->fillGC);
+    }
+    tmPtr->fillGC = newGC;
+
+    markerPtr->flags |= MAP_ITEM;
+    if (markerPtr->drawUnder) {
+	graphPtr->flags |= CACHE_DIRTY;
+    }
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapTextProc --
+ *
+ *	Calculate the layout position for a text marker.  Positional information
+ *	is saved in the marker.  If the text is rotated, a bitmap containing the
+ *	text is created.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If no background color has been specified, the GC stipple origins are
+ *	changed to current window coordinates. For both rotated and
+ *	non-rotated text, if any old bitmap is leftover, it is freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapTextProc(Marker *markerPtr)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    TextMarker *tmPtr = (TextMarker *)markerPtr;
+    Region2d extents;
+    Point2d anchorPt;
+    int i;
+    unsigned int w, h;
+    double rw, rh;
+
+    tmPtr->width = tmPtr->height = 0;
+    if (tmPtr->string == NULL) {
+	return;
+    }
+    Blt_Ts_GetExtents(&tmPtr->style, tmPtr->string, &w, &h);
+    Blt_GetBoundingBox(w, h, tmPtr->style.angle, &rw, &rh, tmPtr->outline);
+    tmPtr->width = ROUND(rw);
+    tmPtr->height = ROUND(rh);
+    for (i = 0; i < 4; i++) {
+	tmPtr->outline[i].x += ROUND(rw * 0.5);
+	tmPtr->outline[i].y += ROUND(rh * 0.5);
+    }
+    tmPtr->outline[4].x = tmPtr->outline[0].x;
+    tmPtr->outline[4].y = tmPtr->outline[0].y;
+    anchorPt = MapPoint(markerPtr->worldPts, &markerPtr->axes);
+    anchorPt = Blt_AnchorPoint(anchorPt.x, anchorPt.y, (double)(tmPtr->width), 
+	(double)(tmPtr->height), tmPtr->anchor);
+    anchorPt.x += markerPtr->xOffset;
+    anchorPt.y += markerPtr->yOffset;
+    /*
+     * Determine the bounding box of the text and test to see if it is at
+     * least partially contained within the plotting area.
+     */
+    extents.left = anchorPt.x;
+    extents.top = anchorPt.y;
+    extents.right = anchorPt.x + tmPtr->width - 1;
+    extents.bottom = anchorPt.y + tmPtr->height - 1;
+    markerPtr->clipped = BoxesDontOverlap(graphPtr, &extents);
+    tmPtr->anchorPt = anchorPt;
+
+}
+
+static int
+PointInTextProc(Marker *markerPtr, Point2d *samplePtr)
+{
+    TextMarker *tmPtr = (TextMarker *)markerPtr;
+
+    if (tmPtr->string == NULL) {
+	return 0;
+    }
+    if (tmPtr->style.angle != 0.0f) {
+	Point2d points[5];
+	int i;
+
+	/* 
+	 * Figure out the bounding polygon (isolateral) for the text and see
+	 * if the point is inside of it.
+	 */
+	for (i = 0; i < 5; i++) {
+	    points[i].x = tmPtr->outline[i].x + tmPtr->anchorPt.x;
+	    points[i].y = tmPtr->outline[i].y + tmPtr->anchorPt.y;
+	}
+	return Blt_PointInPolygon(samplePtr, points, 5);
+    } 
+    return ((samplePtr->x >= tmPtr->anchorPt.x) && 
+	    (samplePtr->x < (tmPtr->anchorPt.x + tmPtr->width)) &&
+	    (samplePtr->y >= tmPtr->anchorPt.y) && 
+	    (samplePtr->y < (tmPtr->anchorPt.y + tmPtr->height)));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RegionInTextProc --
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+RegionInTextProc(Marker *markerPtr, Region2d *extsPtr, int enclosed)
+{
+    TextMarker *tmPtr = (TextMarker *)markerPtr;
+
+    if (markerPtr->nWorldPts < 1) {
+	return FALSE;
+    }
+    if (tmPtr->style.angle != 0.0f) {
+	Point2d points[5];
+	int i;
+	
+	/*  
+	 * Generate the bounding polygon (isolateral) for the bitmap and see
+	 * if the point is inside of it.
+	 */
+	for (i = 0; i < 4; i++) {
+	    points[i].x = tmPtr->outline[i].x + tmPtr->anchorPt.x;
+	    points[i].y = tmPtr->outline[i].y + tmPtr->anchorPt.y;
+	}
+	return Blt_RegionInPolygon(extsPtr, points, 4, enclosed);
+    } 
+    if (enclosed) {
+	return ((tmPtr->anchorPt.x >= extsPtr->left) &&
+		(tmPtr->anchorPt.y >= extsPtr->top) && 
+		((tmPtr->anchorPt.x + tmPtr->width) <= extsPtr->right) &&
+		((tmPtr->anchorPt.y + tmPtr->height) <= extsPtr->bottom));
+    }
+    return !((tmPtr->anchorPt.x >= extsPtr->right) ||
+	     (tmPtr->anchorPt.y >= extsPtr->bottom) ||
+	     ((tmPtr->anchorPt.x + tmPtr->width) <= extsPtr->left) ||
+	     ((tmPtr->anchorPt.y + tmPtr->height) <= extsPtr->top));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawTextProc --
+ *
+ *	Draws the text marker on the graph.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Commands are output to X to draw the marker in its current mode.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawTextProc(Marker *markerPtr, Drawable drawable) 
+{
+    TextMarker *tmPtr = (TextMarker *)markerPtr;
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+
+    if (tmPtr->string == NULL) {
+	return;
+    }
+    if (tmPtr->fillGC != NULL) {
+	XPoint points[4];
+	int i;
+
+	/*
+	 * Simulate the rotated background of the bitmap by filling a bounding
+	 * polygon with the background color.
+	 */
+	for (i = 0; i < 4; i++) {
+	    points[i].x = (short int)(tmPtr->outline[i].x + tmPtr->anchorPt.x);
+	    points[i].y = (short int)(tmPtr->outline[i].y + tmPtr->anchorPt.y);
+	}
+	XFillPolygon(graphPtr->display, drawable, tmPtr->fillGC, points, 4,
+	    Convex, CoordModeOrigin);
+    }
+    if (tmPtr->style.color != NULL) {
+	Blt_Ts_DrawText(graphPtr->tkwin, drawable, tmPtr->string, -1,
+	    &tmPtr->style, (int)tmPtr->anchorPt.x, (int)tmPtr->anchorPt.y);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TextToPostscriptProc --
+ *
+ *	Outputs PostScript commands to draw a text marker at a given x,y
+ *	coordinate, rotation, anchor, and font.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	PostScript font and color settings are changed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+TextToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
+{
+    TextMarker *tmPtr = (TextMarker *)markerPtr;
+
+    if (tmPtr->string == NULL) {
+	return;
+    }
+    if (tmPtr->fillGC != NULL) {
+	Point2d points[4];
+	int i;
+
+	/*
+	 * Simulate the rotated background of the bitmap by filling a bounding
+	 * polygon with the background color.
+	 */
+	for (i = 0; i < 4; i++) {
+	    points[i].x = tmPtr->outline[i].x + tmPtr->anchorPt.x;
+	    points[i].y = tmPtr->outline[i].y + tmPtr->anchorPt.y;
+	}
+	Blt_Ps_XSetBackground(ps, tmPtr->fillColor);
+	Blt_Ps_XFillPolygon(ps, points, 4);
+    }
+    Blt_Ps_DrawText(ps, tmPtr->string, &tmPtr->style, tmPtr->anchorPt.x, 
+	tmPtr->anchorPt.y);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FreeTextProc --
+ *
+ *	Destroys the structure containing the attributes of the text marker.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Text attributes (GCs, colors, stipple, font, etc) get destroyed.
+ *	Memory is released, X resources are freed, and the graph is redrawn.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+FreeTextProc(Marker *markerPtr)
+{
+    TextMarker *tmPtr = (TextMarker *)markerPtr;
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+
+    Blt_Ts_FreeStyle(graphPtr->display, &tmPtr->style);
+}
+
+/*
+ *---------------------------------------------------------------------------
+
+ * CreateTextProc --
+ *
+ *	Allocate memory and initialize methods for the new text marker.
+ *
+ * Results:
+ *	The pointer to the newly allocated marker structure is returned.
+ *
+ * Side effects:
+ *	Memory is allocated for the text marker structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Marker *
+CreateTextProc(void)
+{
+    TextMarker *tmPtr;
+
+    tmPtr = calloc(1, sizeof(TextMarker));
+    tmPtr->classPtr = &textMarkerClass;
+    Blt_Ts_InitStyle(tmPtr->style);
+    tmPtr->style.anchor = TK_ANCHOR_NW;
+    tmPtr->style.padLeft = tmPtr->style.padRight = 4;
+    tmPtr->style.padTop = tmPtr->style.padBottom = 4;
+    return (Marker *)tmPtr;
+}
+
+static Tk_EventProc ChildEventProc;
+static Tk_GeomRequestProc ChildGeometryProc;
+static Tk_GeomLostSlaveProc ChildCustodyProc;
+static Tk_GeomMgr winMarkerMgrInfo =
+{
+    (char *)"graph",			/* Name of geometry manager used by
+					 * winfo */
+    ChildGeometryProc,			/* Procedure to for new geometry
+					 * requests. */
+    ChildCustodyProc,			/* Procedure when window is taken
+					 * away. */
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureWindowProc --
+ *
+ *	This procedure is called to process an objv/objc list, plus the Tk
+ *	option database, in order to configure (or reconfigure) a window
+ *	marker.
+ *
+ * Results:
+ *	A standard TCL result.  If TCL_ERROR is returned, then interp->result
+ *	contains an error message.
+ *
+ * Side effects:
+ *	Configuration information, such as window pathname, placement,
+ *	etc. get set for markerPtr; old resources get freed, if there were
+ *	any.  The marker is eventually redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ConfigureWindowProc(Marker *markerPtr)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    WindowMarker *wmPtr = (WindowMarker *)markerPtr;
+    Tk_Window tkwin;
+
+    if (wmPtr->childName == NULL) {
+	return TCL_OK;
+    }
+    tkwin = Tk_NameToWindow(graphPtr->interp, wmPtr->childName, 
+	    graphPtr->tkwin);
+    if (tkwin == NULL) {
+	return TCL_ERROR;
+    }
+    if (Tk_Parent(tkwin) != graphPtr->tkwin) {
+	Tcl_AppendResult(graphPtr->interp, "\"", wmPtr->childName,
+	    "\" is not a child of \"", Tk_PathName(graphPtr->tkwin), "\"",
+	    (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (tkwin != wmPtr->child) {
+	if (wmPtr->child != NULL) {
+	    Tk_DeleteEventHandler(wmPtr->child, StructureNotifyMask,
+		ChildEventProc, wmPtr);
+	    Tk_ManageGeometry(wmPtr->child, (Tk_GeomMgr *) 0, (ClientData)0);
+	    Tk_UnmapWindow(wmPtr->child);
+	}
+	Tk_CreateEventHandler(tkwin, StructureNotifyMask, ChildEventProc, 
+		wmPtr);
+	Tk_ManageGeometry(tkwin, &winMarkerMgrInfo, wmPtr);
+    }
+    wmPtr->child = tkwin;
+    markerPtr->flags |= MAP_ITEM;
+    if (markerPtr->drawUnder) {
+	graphPtr->flags |= CACHE_DIRTY;
+    }
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapWindowProc --
+ *
+ *	Calculate the layout position for a window marker.  Positional
+ *	information is saved in the marker.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapWindowProc(Marker *markerPtr)
+{
+    WindowMarker *wmPtr = (WindowMarker *)markerPtr;
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    Point2d anchorPt;
+    Region2d extents;
+    int width, height;
+
+    if (wmPtr->child == (Tk_Window)NULL) {
+	return;
+    }
+    anchorPt = MapPoint(markerPtr->worldPts, &markerPtr->axes);
+
+    width = Tk_ReqWidth(wmPtr->child);
+    height = Tk_ReqHeight(wmPtr->child);
+    if (wmPtr->reqWidth > 0) {
+	width = wmPtr->reqWidth;
+    }
+    if (wmPtr->reqHeight > 0) {
+	height = wmPtr->reqHeight;
+    }
+    wmPtr->anchorPt = Blt_AnchorPoint(anchorPt.x, anchorPt.y, (double)width, 
+	(double)height, wmPtr->anchor);
+    wmPtr->anchorPt.x += markerPtr->xOffset;
+    wmPtr->anchorPt.y += markerPtr->yOffset;
+    wmPtr->width = width;
+    wmPtr->height = height;
+
+    /*
+     * Determine the bounding box of the window and test to see if it is at
+     * least partially contained within the plotting area.
+     */
+    extents.left = wmPtr->anchorPt.x;
+    extents.top = wmPtr->anchorPt.y;
+    extents.right = wmPtr->anchorPt.x + wmPtr->width - 1;
+    extents.bottom = wmPtr->anchorPt.y + wmPtr->height - 1;
+    markerPtr->clipped = BoxesDontOverlap(graphPtr, &extents);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PointInWindowProc --
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+PointInWindowProc(Marker *markerPtr, Point2d *samplePtr)
+{
+    WindowMarker *wmPtr = (WindowMarker *)markerPtr;
+
+    return ((samplePtr->x >= wmPtr->anchorPt.x) && 
+	    (samplePtr->x < (wmPtr->anchorPt.x + wmPtr->width)) &&
+	    (samplePtr->y >= wmPtr->anchorPt.y) && 
+	    (samplePtr->y < (wmPtr->anchorPt.y + wmPtr->height)));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RegionInWindowProc --
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+RegionInWindowProc(Marker *markerPtr, Region2d *extsPtr, int enclosed)
+{
+    WindowMarker *wmPtr = (WindowMarker *)markerPtr;
+
+    if (markerPtr->nWorldPts < 1) {
+	return FALSE;
+    }
+    if (enclosed) {
+	return ((wmPtr->anchorPt.x >= extsPtr->left) &&
+		(wmPtr->anchorPt.y >= extsPtr->top) && 
+		((wmPtr->anchorPt.x + wmPtr->width) <= extsPtr->right) &&
+		((wmPtr->anchorPt.y + wmPtr->height) <= extsPtr->bottom));
+    }
+    return !((wmPtr->anchorPt.x >= extsPtr->right) ||
+	     (wmPtr->anchorPt.y >= extsPtr->bottom) ||
+	     ((wmPtr->anchorPt.x + wmPtr->width) <= extsPtr->left) ||
+	     ((wmPtr->anchorPt.y + wmPtr->height) <= extsPtr->top));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawWindowProc --
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static void
+DrawWindowProc(Marker *markerPtr, Drawable drawable)
+{
+    WindowMarker *wmPtr = (WindowMarker *)markerPtr;
+
+    if (wmPtr->child == NULL) {
+	return;
+    }
+    if ((wmPtr->height != Tk_Height(wmPtr->child)) ||
+	(wmPtr->width != Tk_Width(wmPtr->child)) ||
+	((int)wmPtr->anchorPt.x != Tk_X(wmPtr->child)) ||
+	((int)wmPtr->anchorPt.y != Tk_Y(wmPtr->child))) {
+	Tk_MoveResizeWindow(wmPtr->child, (int)wmPtr->anchorPt.x, 
+	    (int)wmPtr->anchorPt.y, wmPtr->width, wmPtr->height);
+    }
+    if (!Tk_IsMapped(wmPtr->child)) {
+	Tk_MapWindow(wmPtr->child);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * WindowToPostscriptProc --
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+WindowToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
+{
+    WindowMarker *wmPtr = (WindowMarker *)markerPtr;
+
+    if (wmPtr->child == NULL) {
+	return;
+    }
+    if (Tk_IsMapped(wmPtr->child)) {
+      //	Blt_Ps_XDrawWindow(ps, wmPtr->child, wmPtr->anchorPt.x, wmPtr->anchorPt.y);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FreeWindowProc --
+ *
+ *	Destroys the structure containing the attributes of the window *
+ *	marker.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Window is destroyed and removed from the screen.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+FreeWindowProc(Marker *markerPtr)
+{
+    WindowMarker *wmPtr = (WindowMarker *)markerPtr;
+
+    if (wmPtr->child != NULL) {
+	Tk_DeleteEventHandler(wmPtr->child, StructureNotifyMask,
+	    ChildEventProc, wmPtr);
+	Tk_ManageGeometry(wmPtr->child, (Tk_GeomMgr *) 0, (ClientData)0);
+	Tk_DestroyWindow(wmPtr->child);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateWindowProc --
+ *
+ *	Allocate memory and initialize methods for the new window marker.
+ *
+ * Results:
+ *	The pointer to the newly allocated marker structure is returned.
+ *
+ * Side effects:
+ *	Memory is allocated for the window marker structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Marker *
+CreateWindowProc(void)
+{
+    WindowMarker *wmPtr;
+
+    wmPtr = calloc(1, sizeof(WindowMarker));
+    wmPtr->classPtr = &windowMarkerClass;
+    return (Marker *)wmPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ChildEventProc --
+ *
+ *	This procedure is invoked whenever StructureNotify events occur for a
+ *	window that's managed as part of a graph window marker. This
+ *	procedure's only purpose is to clean up when windows are deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The window is disassociated from the window item when it is
+ *	deleted.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+ChildEventProc(ClientData clientData, XEvent *eventPtr)
+{
+    WindowMarker *wmPtr = clientData;
+
+    if (eventPtr->type == DestroyNotify) {
+	wmPtr->child = NULL;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ChildGeometryProc --
+ *
+ *	This procedure is invoked whenever a window that's associated with a
+ *	window item changes its requested dimensions.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The size and location on the window of the window may change,
+ *	depending on the options specified for the window item.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static void
+ChildGeometryProc(ClientData clientData, Tk_Window tkwin)
+{
+    WindowMarker *wmPtr = clientData;
+
+    if (wmPtr->reqWidth == 0) {
+	wmPtr->width = Tk_ReqWidth(tkwin);
+    }
+    if (wmPtr->reqHeight == 0) {
+	wmPtr->height = Tk_ReqHeight(tkwin);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ChildCustodyProc --
+ *
+ *	This procedure is invoked when an embedded window has been stolen by
+ *	another geometry manager.  The information and memory associated with
+ *	the widget is released.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Arranges for the graph to be redrawn without the embedded widget at
+ *	the next idle point.
+ *
+ *---------------------------------------------------------------------------
+ */
+ /* ARGSUSED */
+static void
+ChildCustodyProc(ClientData clientData, Tk_Window tkwin)
+{
+    Marker *markerPtr = clientData;
+    Graph *graphPtr;
+
+    graphPtr = markerPtr->obj.graphPtr;
+    markerPtr->flags |= DELETE_PENDING;
+    Tcl_EventuallyFree(markerPtr, FreeMarker);
+    /*
+     * Not really needed. We should get an Expose event when the child window
+     * is unmapped.
+     */
+    Blt_EventuallyRedrawGraph(graphPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapLineProc --
+ *
+ *	Calculate the layout position for a line marker.  Positional
+ *	information is saved in the marker.  The line positions are stored in
+ *	an array of points (malloc'ed).
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapLineProc(Marker *markerPtr)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    LineMarker *lmPtr = (LineMarker *)markerPtr;
+    Point2d *srcPtr, *pend;
+    Segment2d *segments, *segPtr;
+    Point2d p, q;
+    Region2d extents;
+
+    lmPtr->nSegments = 0;
+    if (lmPtr->segments != NULL) {
+	free(lmPtr->segments);
+    }
+    if (markerPtr->nWorldPts < 2) {
+	return;				/* Too few points */
+    }
+    Blt_GraphExtents(graphPtr, &extents);
+
+    /* 
+     * Allow twice the number of world coordinates. The line will represented
+     * as series of line segments, not one continous polyline.  This is
+     * because clipping against the plot area may chop the line into several
+     * disconnected segments.
+     */
+    segments = malloc(markerPtr->nWorldPts * sizeof(Segment2d));
+    srcPtr = markerPtr->worldPts;
+    p = MapPoint(srcPtr, &markerPtr->axes);
+    p.x += markerPtr->xOffset;
+    p.y += markerPtr->yOffset;
+
+    segPtr = segments;
+    for (srcPtr++, pend = markerPtr->worldPts + markerPtr->nWorldPts; 
+	 srcPtr < pend; srcPtr++) {
+	Point2d next;
+
+	next = MapPoint(srcPtr, &markerPtr->axes);
+	next.x += markerPtr->xOffset;
+	next.y += markerPtr->yOffset;
+	q = next;
+	if (Blt_LineRectClip(&extents, &p, &q)) {
+	    segPtr->p = p;
+	    segPtr->q = q;
+	    segPtr++;
+	}
+	p = next;
+    }
+    lmPtr->nSegments = segPtr - segments;
+    lmPtr->segments = segments;
+    markerPtr->clipped = (lmPtr->nSegments == 0);
+}
+
+static int
+PointInLineProc(Marker *markerPtr, Point2d *samplePtr)
+{
+    LineMarker *lmPtr = (LineMarker *)markerPtr;
+
+    return Blt_PointInSegments(samplePtr, lmPtr->segments, lmPtr->nSegments, 
+	   (double)markerPtr->obj.graphPtr->halo);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RegionInLineProc --
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+RegionInLineProc(Marker *markerPtr, Region2d *extsPtr, int enclosed)
+{
+    if (markerPtr->nWorldPts < 2) {
+	return FALSE;
+    }
+    if (enclosed) {
+	Point2d *pp, *pend;
+
+	for (pp = markerPtr->worldPts, pend = pp + markerPtr->nWorldPts; 
+	     pp < pend; pp++) {
+	    Point2d p;
+
+	    p = MapPoint(pp, &markerPtr->axes);
+	    if ((p.x < extsPtr->left) && (p.x > extsPtr->right) &&
+		(p.y < extsPtr->top) && (p.y > extsPtr->bottom)) {
+		return FALSE;
+	    }
+	}
+	return TRUE;			/* All points inside bounding box. */
+    } else {
+	int count;
+	Point2d *pp, *pend;
+
+	count = 0;
+	for (pp = markerPtr->worldPts, pend = pp + (markerPtr->nWorldPts - 1); 
+		pp < pend; pp++) {
+	    Point2d p, q;
+
+	    p = MapPoint(pp, &markerPtr->axes);
+	    q = MapPoint(pp + 1, &markerPtr->axes);
+	    if (Blt_LineRectClip(extsPtr, &p, &q)) {
+		count++;
+	    }
+	}
+	return (count > 0);		/* At least 1 segment passes through
+					 * region. */
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawLineProc --
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawLineProc(Marker *markerPtr, Drawable drawable)
+{
+    LineMarker *lmPtr = (LineMarker *)markerPtr;
+
+    if (lmPtr->nSegments > 0) {
+	Graph *graphPtr = markerPtr->obj.graphPtr;
+
+	Blt_Draw2DSegments(graphPtr->display, drawable, lmPtr->gc, 
+		lmPtr->segments, lmPtr->nSegments);
+	if (lmPtr->xor) {		/* Toggle the drawing state */
+	    lmPtr->xorState = (lmPtr->xorState == 0);
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureLineProc --
+ *
+ *	This procedure is called to process an objv/objc list, plus the Tk
+ *	option database, in order to configure (or reconfigure) a line marker.
+ *
+ * Results:
+ *	A standard TCL result.  If TCL_ERROR is returned, then interp->result
+ *	contains an error message.
+ *
+ * Side effects:
+ *	Configuration information, such as line width, colors, dashes,
+ *	etc. get set for markerPtr; old resources get freed, if there were
+ *	any.  The marker is eventually redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ConfigureLineProc(Marker *markerPtr)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    LineMarker *lmPtr = (LineMarker *)markerPtr;
+    GC newGC;
+    XGCValues gcValues;
+    unsigned long gcMask;
+    Drawable drawable;
+
+    drawable = Tk_WindowId(graphPtr->tkwin);
+    gcMask = (GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle);
+    if (lmPtr->outlineColor != NULL) {
+	gcMask |= GCForeground;
+	gcValues.foreground = lmPtr->outlineColor->pixel;
+    }
+    if (lmPtr->fillColor != NULL) {
+	gcMask |= GCBackground;
+	gcValues.background = lmPtr->fillColor->pixel;
+    }
+    gcValues.cap_style = lmPtr->capStyle;
+    gcValues.join_style = lmPtr->joinStyle;
+    gcValues.line_width = LineWidth(lmPtr->lineWidth);
+    gcValues.line_style = LineSolid;
+    if (LineIsDashed(lmPtr->dashes)) {
+	gcValues.line_style = 
+	    (gcMask & GCBackground) ? LineDoubleDash : LineOnOffDash;
+    }
+    if (lmPtr->xor) {
+	unsigned long pixel;
+	gcValues.function = GXxor;
+
+	gcMask |= GCFunction;
+	if (graphPtr->plotBg == NULL) {
+	    pixel = WhitePixelOfScreen(Tk_Screen(graphPtr->tkwin));
+	} else {
+	    pixel = Blt_BackgroundBorderColor(graphPtr->plotBg)->pixel;
+	}
+	if (gcMask & GCBackground) {
+	    gcValues.background ^= pixel;
+	}
+	gcValues.foreground ^= pixel;
+	if (drawable != None) {
+	    DrawLineProc(markerPtr, drawable);
+	}
+    }
+    newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (lmPtr->gc != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, lmPtr->gc);
+    }
+    if (LineIsDashed(lmPtr->dashes)) {
+	Blt_SetDashes(graphPtr->display, newGC, &lmPtr->dashes);
+    }
+    lmPtr->gc = newGC;
+    if (lmPtr->xor) {
+	if (drawable != None) {
+	    MapLineProc(markerPtr);
+	    DrawLineProc(markerPtr, drawable);
+	}
+	return TCL_OK;
+    }
+    markerPtr->flags |= MAP_ITEM;
+    if (markerPtr->drawUnder) {
+	graphPtr->flags |= CACHE_DIRTY;
+    }
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LineToPostscriptProc --
+ *
+ *	Prints postscript commands to display the connect line.  Dashed lines
+ *	need to be handled specially, especially if a background color is
+ *	designated.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+  *	PostScript output commands are saved in the interpreter
+ *	(infoPtr->interp) result field.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+LineToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
+{
+    LineMarker *lmPtr = (LineMarker *)markerPtr;
+
+    if (lmPtr->nSegments > 0) {
+	Blt_Ps_XSetLineAttributes(ps, lmPtr->outlineColor, 
+		lmPtr->lineWidth, &lmPtr->dashes, lmPtr->capStyle,
+		lmPtr->joinStyle);
+	if ((LineIsDashed(lmPtr->dashes)) && (lmPtr->fillColor != NULL)) {
+	    Blt_Ps_Append(ps, "/DashesProc {\n  gsave\n    ");
+	    Blt_Ps_XSetBackground(ps, lmPtr->fillColor);
+	    Blt_Ps_Append(ps, "    ");
+	    Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL);
+	    Blt_Ps_VarAppend(ps,
+			     "stroke\n",
+			     "  grestore\n",
+			     "} def\n", (char *)NULL);
+	} else {
+	    Blt_Ps_Append(ps, "/DashesProc {} def\n");
+	}
+	Blt_Ps_Draw2DSegments(ps, lmPtr->segments, lmPtr->nSegments);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FreeLineProc --
+ *
+ *	Destroys the structure and attributes of a line marker.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Line attributes (GCs, colors, stipple, etc) get released.  Memory is
+ *	deallocated, X resources are freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+FreeLineProc(Marker *markerPtr)
+{
+    LineMarker *lmPtr = (LineMarker *)markerPtr;
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+
+    if (lmPtr->gc != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, lmPtr->gc);
+    }
+    if (lmPtr->segments != NULL) {
+	free(lmPtr->segments);
+    }
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateLineProc --
+ *
+ *	Allocate memory and initialize methods for a new line marker.
+ *
+ * Results:
+ *	The pointer to the newly allocated marker structure is returned.
+ *
+ * Side effects:
+ *	Memory is allocated for the line marker structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Marker *
+CreateLineProc(void)
+{
+    LineMarker *lmPtr;
+
+    lmPtr = calloc(1, sizeof(LineMarker));
+    lmPtr->classPtr = &lineMarkerClass;
+    lmPtr->xor = FALSE;
+    lmPtr->capStyle = CapButt;
+    lmPtr->joinStyle = JoinMiter;
+    return (Marker *)lmPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapPolygonProc --
+ *
+ *	Calculate the layout position for a polygon marker.  Positional
+ *	information is saved in the polygon in an array of points (malloc'ed).
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MapPolygonProc(Marker *markerPtr)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    PolygonMarker *pmPtr = (PolygonMarker *)markerPtr;
+    Point2d *screenPts;
+    Region2d extents;
+    int nScreenPts;
+
+    if (pmPtr->outlinePts != NULL) {
+	free(pmPtr->outlinePts);
+	pmPtr->outlinePts = NULL;
+	pmPtr->nOutlinePts = 0;
+    }
+    if (pmPtr->fillPts != NULL) {
+	free(pmPtr->fillPts);
+	pmPtr->fillPts = NULL;
+	pmPtr->nFillPts = 0;
+    }
+    if (pmPtr->screenPts != NULL) {
+	free(pmPtr->screenPts);
+	pmPtr->screenPts = NULL;
+    }
+    if (markerPtr->nWorldPts < 3) {
+	return;				/* Too few points */
+    }
+
+    /* 
+     * Allocate and fill a temporary array to hold the screen coordinates of
+     * the polygon.
+     */
+    nScreenPts = markerPtr->nWorldPts + 1;
+    screenPts = malloc((nScreenPts + 1) * sizeof(Point2d));
+    {
+	Point2d *sp, *dp, *send;
+
+	dp = screenPts;
+	for (sp = markerPtr->worldPts, send = sp + markerPtr->nWorldPts; 
+	     sp < send; sp++) {
+	    *dp = MapPoint(sp, &markerPtr->axes);
+	    dp->x += markerPtr->xOffset;
+	    dp->y += markerPtr->yOffset;
+	    dp++;
+	}
+	*dp = screenPts[0];
+    }
+    Blt_GraphExtents(graphPtr, &extents);
+    markerPtr->clipped = TRUE;
+    if (pmPtr->fill.fgColor != NULL) {	/* Polygon fill required. */
+	Point2d *fillPts;
+	int n;
+
+	fillPts = malloc(sizeof(Point2d) * nScreenPts * 3);
+	n = Blt_PolyRectClip(&extents, screenPts, markerPtr->nWorldPts,fillPts);
+	if (n < 3) { 
+	    free(fillPts);
+	} else {
+	    pmPtr->nFillPts = n;
+	    pmPtr->fillPts = fillPts;
+	    markerPtr->clipped = FALSE;
+	}
+    }
+    if ((pmPtr->outline.fgColor != NULL) && (pmPtr->lineWidth > 0)) { 
+	Segment2d *outlinePts;
+	Segment2d *segPtr;
+	Point2d *sp, *send;
+
+	/* 
+	 * Generate line segments representing the polygon outline.  The
+	 * resulting outline may or may not be closed from viewport clipping.
+	 */
+	outlinePts = malloc(nScreenPts * sizeof(Segment2d));
+	if (outlinePts == NULL) {
+	    return;			/* Can't allocate point array */
+	}
+	/* 
+	 * Note that this assumes that the point array contains an extra point
+	 * that closes the polygon.
+	 */
+	segPtr = outlinePts;
+	for (sp = screenPts, send = sp + (nScreenPts - 1); sp < send; sp++) {
+	    segPtr->p = sp[0];
+	    segPtr->q = sp[1];
+	    if (Blt_LineRectClip(&extents, &segPtr->p, &segPtr->q)) {
+		segPtr++;
+	    }
+	}
+	pmPtr->nOutlinePts = segPtr - outlinePts;
+	pmPtr->outlinePts = outlinePts;
+	if (pmPtr->nOutlinePts > 0) {
+	    markerPtr->clipped = FALSE;
+	}
+    }
+    pmPtr->screenPts = screenPts;
+}
+
+static int
+PointInPolygonProc(Marker *markerPtr, Point2d *samplePtr)
+{
+    PolygonMarker *pmPtr = (PolygonMarker *)markerPtr;
+
+    if ((markerPtr->nWorldPts >= 3) && (pmPtr->screenPts != NULL)) {
+	return Blt_PointInPolygon(samplePtr, pmPtr->screenPts, 
+		markerPtr->nWorldPts + 1);
+    }
+    return FALSE;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RegionInPolygonProc --
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+RegionInPolygonProc(Marker *markerPtr, Region2d *extsPtr, int enclosed)
+{
+    PolygonMarker *pmPtr = (PolygonMarker *)markerPtr;
+    
+    if ((markerPtr->nWorldPts >= 3) && (pmPtr->screenPts != NULL)) {
+	return Blt_RegionInPolygon(extsPtr, pmPtr->screenPts, 
+		markerPtr->nWorldPts, enclosed);
+    }
+    return FALSE;
+}
+
+static void
+DrawPolygonProc(Marker *markerPtr, Drawable drawable)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    PolygonMarker *pmPtr = (PolygonMarker *)markerPtr;
+
+    /* Draw polygon fill region */
+    if ((pmPtr->nFillPts > 0) && (pmPtr->fill.fgColor != NULL)) {
+	XPoint *dp, *points;
+	Point2d *sp, *send;
+	
+	points = malloc(pmPtr->nFillPts * sizeof(XPoint));
+	if (points == NULL) {
+	    return;
+	}
+	dp = points;
+	for (sp = pmPtr->fillPts, send = sp + pmPtr->nFillPts; sp < send; 
+	     sp++) {
+	    dp->x = (short int)sp->x;
+	    dp->y = (short int)sp->y;
+	    dp++;
+	}
+
+	XFillPolygon(graphPtr->display, drawable, pmPtr->fillGC, points, 
+		pmPtr->nFillPts, Complex, CoordModeOrigin);
+	free(points);
+    }
+    /* and then the outline */
+    if ((pmPtr->nOutlinePts > 0) && (pmPtr->lineWidth > 0) && 
+	(pmPtr->outline.fgColor != NULL)) {
+	Blt_Draw2DSegments(graphPtr->display, drawable, pmPtr->outlineGC,
+	    pmPtr->outlinePts, pmPtr->nOutlinePts);
+    }
+}
+
+
+static void
+PolygonToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    PolygonMarker *pmPtr = (PolygonMarker *)markerPtr;
+
+    if (pmPtr->fill.fgColor != NULL) {
+
+	/*
+	 * Options:  fg bg
+	 *			Draw outline only.
+	 *	     x          Draw solid or stipple.
+	 *	     x  x       Draw solid or stipple.
+	 */
+
+	/* Create a path to use for both the polygon and its outline. */
+	Blt_Ps_Polyline(ps, pmPtr->fillPts, pmPtr->nFillPts);
+
+	/* If the background fill color was specified, draw the polygon in a
+	 * solid fashion with that color.  */
+	if (pmPtr->fill.bgColor != NULL) {
+	    /* Draw the solid background as the background layer of the opaque
+	     * stipple  */
+	    Blt_Ps_XSetBackground(ps, pmPtr->fill.bgColor);
+	    /* Retain the path. We'll need it for the foreground layer. */
+	    Blt_Ps_Append(ps, "gsave fill grestore\n");
+	}
+	Blt_Ps_XSetForeground(ps, pmPtr->fill.fgColor);
+	if (pmPtr->stipple != None) {
+	    /* Draw the stipple in the foreground color. */
+	    Blt_Ps_XSetStipple(ps, graphPtr->display, pmPtr->stipple);
+	} else {
+	    Blt_Ps_Append(ps, "fill\n");
+	}
+    }
+
+    /* Draw the outline in the foreground color.  */
+    if ((pmPtr->lineWidth > 0) && (pmPtr->outline.fgColor != NULL)) {
+
+	/*  Set up the line attributes.  */
+	Blt_Ps_XSetLineAttributes(ps, pmPtr->outline.fgColor,
+	    pmPtr->lineWidth, &pmPtr->dashes, pmPtr->capStyle,
+	    pmPtr->joinStyle);
+
+	/*  
+	 * Define on-the-fly a PostScript macro "DashesProc" that will be
+	 * executed for each call to the Polygon drawing routine.  If the line
+	 * isn't dashed, simply make this an empty definition.
+	 */
+	if ((pmPtr->outline.bgColor != NULL) && (LineIsDashed(pmPtr->dashes))) {
+	    Blt_Ps_Append(ps, "/DashesProc {\ngsave\n    ");
+	    Blt_Ps_XSetBackground(ps, pmPtr->outline.bgColor);
+	    Blt_Ps_Append(ps, "    ");
+	    Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL);
+	    Blt_Ps_Append(ps, "stroke\n  grestore\n} def\n");
+	} else {
+	    Blt_Ps_Append(ps, "/DashesProc {} def\n");
+	}
+	Blt_Ps_Draw2DSegments(ps, pmPtr->outlinePts, pmPtr->nOutlinePts);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigurePolygonProc --
+ *
+ *	This procedure is called to process an objv/objc list, plus the Tk
+ *	option database, in order to configure (or reconfigure) a polygon
+ *	marker.
+ *
+ * Results:
+ *	A standard TCL result.  If TCL_ERROR is returned, then interp->result
+ *	contains an error message.
+ *
+ * Side effects:
+ *	Configuration information, such as polygon color, dashes, fillstyle,
+ *	etc. get set for markerPtr; old resources get freed, if there were
+ *	any.  The marker is eventually redisplayed.
+ *
+ * -------------------------------------------------------------------------- 
+ */
+/*ARGSUSED*/
+static int
+ConfigurePolygonProc(Marker *markerPtr)
+{
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+    PolygonMarker *pmPtr = (PolygonMarker *)markerPtr;
+    GC newGC;
+    XGCValues gcValues;
+    unsigned long gcMask;
+    Drawable drawable;
+
+    drawable = Tk_WindowId(graphPtr->tkwin);
+    gcMask = (GCLineWidth | GCLineStyle);
+    if (pmPtr->outline.fgColor != NULL) {
+	gcMask |= GCForeground;
+	gcValues.foreground = pmPtr->outline.fgColor->pixel;
+    }
+    if (pmPtr->outline.bgColor != NULL) {
+	gcMask |= GCBackground;
+	gcValues.background = pmPtr->outline.bgColor->pixel;
+    }
+    gcMask |= (GCCapStyle | GCJoinStyle);
+    gcValues.cap_style = pmPtr->capStyle;
+    gcValues.join_style = pmPtr->joinStyle;
+    gcValues.line_style = LineSolid;
+    gcValues.dash_offset = 0;
+    gcValues.line_width = LineWidth(pmPtr->lineWidth);
+    if (LineIsDashed(pmPtr->dashes)) {
+	gcValues.line_style = (pmPtr->outline.bgColor == NULL)
+	    ? LineOnOffDash : LineDoubleDash;
+    }
+    if (pmPtr->xor) {
+	unsigned long pixel;
+	gcValues.function = GXxor;
+
+	gcMask |= GCFunction;
+	if (graphPtr->plotBg == NULL) {
+	    /* The graph's color option may not have been set yet */
+	    pixel = WhitePixelOfScreen(Tk_Screen(graphPtr->tkwin));
+	} else {
+	    pixel = Blt_BackgroundBorderColor(graphPtr->plotBg)->pixel;
+	}
+	if (gcMask & GCBackground) {
+	    gcValues.background ^= pixel;
+	}
+	gcValues.foreground ^= pixel;
+	if (drawable != None) {
+	    DrawPolygonProc(markerPtr, drawable);
+	}
+    }
+    newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (LineIsDashed(pmPtr->dashes)) {
+	Blt_SetDashes(graphPtr->display, newGC, &pmPtr->dashes);
+    }
+    if (pmPtr->outlineGC != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, pmPtr->outlineGC);
+    }
+    pmPtr->outlineGC = newGC;
+
+    gcMask = 0;
+    if (pmPtr->fill.fgColor != NULL) {
+	gcMask |= GCForeground;
+	gcValues.foreground = pmPtr->fill.fgColor->pixel;
+    }
+    if (pmPtr->fill.bgColor != NULL) {
+	gcMask |= GCBackground;
+	gcValues.background = pmPtr->fill.bgColor->pixel;
+    }
+    if (pmPtr->stipple != None) {
+	gcValues.stipple = pmPtr->stipple;
+	gcValues.fill_style = (pmPtr->fill.bgColor != NULL)
+	    ? FillOpaqueStippled : FillStippled;
+	gcMask |= (GCStipple | GCFillStyle);
+    }
+    newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (pmPtr->fillGC != NULL) {
+	Tk_FreeGC(graphPtr->display, pmPtr->fillGC);
+    }
+    pmPtr->fillGC = newGC;
+
+    if ((gcMask == 0) && !(graphPtr->flags & RESET_AXES) && (pmPtr->xor)) {
+	if (drawable != None) {
+	    MapPolygonProc(markerPtr);
+	    DrawPolygonProc(markerPtr, drawable);
+	}
+	return TCL_OK;
+    }
+    markerPtr->flags |= MAP_ITEM;
+    if (markerPtr->drawUnder) {
+	graphPtr->flags |= CACHE_DIRTY;
+    }
+    graphPtr->flags |= RESET_WORLD;
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FreePolygonProc --
+ *
+ *	Release memory and resources allocated for the polygon element.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Everything associated with the polygon element is freed up.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+FreePolygonProc(Marker *markerPtr)
+{
+    PolygonMarker *pmPtr = (PolygonMarker *)markerPtr;
+    Graph *graphPtr = markerPtr->obj.graphPtr;
+
+    if (pmPtr->fillGC != NULL) {
+	Tk_FreeGC(graphPtr->display, pmPtr->fillGC);
+    }
+    if (pmPtr->outlineGC != NULL) {
+	Blt_FreePrivateGC(graphPtr->display, pmPtr->outlineGC);
+    }
+    if (pmPtr->fillPts != NULL) {
+	free(pmPtr->fillPts);
+    }
+    if (pmPtr->outlinePts != NULL) {
+	free(pmPtr->outlinePts);
+    }
+    if (pmPtr->screenPts != NULL) {
+	free(pmPtr->screenPts);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreatePolygonProc --
+ *
+ *	Allocate memory and initialize methods for the new polygon marker.
+ *
+ * Results:
+ *	The pointer to the newly allocated marker structure is returned.
+ *
+ * Side effects:
+ *	Memory is allocated for the polygon marker structure.
+ *
+ * -------------------------------------------------------------------------- 
+ */
+static Marker *
+CreatePolygonProc(void)
+{
+    PolygonMarker *pmPtr;
+
+    pmPtr = calloc(1, sizeof(PolygonMarker));
+    pmPtr->classPtr = &polygonMarkerClass;
+    pmPtr->capStyle = CapButt;
+    pmPtr->joinStyle = JoinMiter;
+    return (Marker *)pmPtr;
+}
+
+static int
+GetMarkerFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
+		 Marker **markerPtrPtr)
+{
+    Blt_HashEntry *hPtr;
+    const char *string;
+
+    string = Tcl_GetString(objPtr);
+    hPtr = Blt_FindHashEntry(&graphPtr->markers.table, string);
+    if (hPtr != NULL) {
+	*markerPtrPtr = Blt_GetHashValue(hPtr);
+	return TCL_OK;
+    }
+    if (interp != NULL) {
+	Tcl_AppendResult(interp, "can't find marker \"", string, 
+	     "\" in \"", Tk_PathName(graphPtr->tkwin), (char *)NULL);
+    }
+    return TCL_ERROR;
+}
+
+
+static int
+RenameMarker(Graph *graphPtr, Marker *markerPtr, const char *oldName, 
+	     const char *newName)
+{
+    int isNew;
+    Blt_HashEntry *hPtr;
+
+    /* Rename the marker only if no marker already exists by that name */
+    hPtr = Blt_CreateHashEntry(&graphPtr->markers.table, newName, &isNew);
+    if (!isNew) {
+	Tcl_AppendResult(graphPtr->interp, "can't rename marker: \"", newName,
+	    "\" already exists", (char *)NULL);
+	return TCL_ERROR;
+    }
+    markerPtr->obj.name = Blt_Strdup(newName);
+    markerPtr->hashPtr = hPtr;
+    Blt_SetHashValue(hPtr, (char *)markerPtr);
+
+    /* Delete the old hash entry */
+    hPtr = Blt_FindHashEntry(&graphPtr->markers.table, oldName);
+    Blt_DeleteHashEntry(&graphPtr->markers.table, hPtr);
+    if (oldName != NULL) {
+      free((void*)oldName);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NamesOp --
+ *
+ *	Returns a list of marker identifiers in interp->result;
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+NamesOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if (objc == 3) {
+	Blt_ChainLink link;
+
+	for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    Marker *markerPtr;
+
+	    markerPtr = Blt_Chain_GetValue(link);
+	    Tcl_ListObjAppendElement(interp, listObjPtr,
+		Tcl_NewStringObj(markerPtr->obj.name, -1));
+	}
+    } else {
+	Blt_ChainLink link;
+
+	for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); 
+	     link != NULL; link = Blt_Chain_NextLink(link)) {
+	    Marker *markerPtr;
+	    int i;
+
+	    markerPtr = Blt_Chain_GetValue(link);
+	    for (i = 3; i < objc; i++) {
+		const char *pattern;
+
+		pattern = Tcl_GetString(objv[i]);
+		if (Tcl_StringMatch(markerPtr->obj.name, pattern)) {
+		    Tcl_ListObjAppendElement(interp, listObjPtr,
+			Tcl_NewStringObj(markerPtr->obj.name, -1));
+		    break;
+		}
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BindOp --
+ *
+ *	.g element bind elemName sequence command
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+BindOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    if (objc == 3) {
+	Blt_HashEntry *hp;
+	Blt_HashSearch iter;
+	Tcl_Obj *listObjPtr;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	for (hp = Blt_FirstHashEntry(&graphPtr->markers.tagTable, &iter);
+	    hp != NULL; hp = Blt_NextHashEntry(&iter)) {
+	    const char *tag;
+	    Tcl_Obj *objPtr;
+
+	    tag = Blt_GetHashKey(&graphPtr->markers.tagTable, hp);
+	    objPtr = Tcl_NewStringObj(tag, -1);
+	    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+	return TCL_OK;
+    }
+    return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable,
+	Blt_MakeMarkerTag(graphPtr, Tcl_GetString(objv[3])),
+	objc - 4, objv + 4);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CgetOp --
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+CgetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Marker *markerPtr;
+
+    if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, 
+	markerPtr->classPtr->configSpecs, (char *)markerPtr, objv[4], 0) 
+	!= TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureOp --
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ * Side Effects:
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ConfigureOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Marker *markerPtr;
+    Tcl_Obj *const *options;
+    const char *oldName;
+    const char *string;
+    int flags = BLT_CONFIG_OBJV_ONLY;
+    int nNames, nOpts;
+    int i;
+    int under;
+
+    markerPtr = NULL;			/* Suppress compiler warning. */
+
+    /* Figure out where the option value pairs begin */
+    objc -= 3;
+    objv += 3;
+    for (i = 0; i < objc; i++) {
+	string = Tcl_GetString(objv[i]);
+	if (string[0] == '-') {
+	    break;
+	}
+	if (GetMarkerFromObj(interp, graphPtr, objv[i], &markerPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    nNames = i;				/* # of element names specified */
+    nOpts = objc - i;			/* # of options specified */
+    options = objv + nNames;		/* Start of options in objv  */
+    
+    for (i = 0; i < nNames; i++) {
+	GetMarkerFromObj(interp, graphPtr, objv[i], &markerPtr);
+	if (nOpts == 0) {
+	    return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, 
+		markerPtr->classPtr->configSpecs, (char *)markerPtr, 
+		(Tcl_Obj *)NULL, flags);
+	} else if (nOpts == 1) {
+	    return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin,
+		markerPtr->classPtr->configSpecs, (char *)markerPtr, 
+		options[0], flags);
+	}
+	/* Save the old marker name. */
+	oldName = markerPtr->obj.name;
+	under = markerPtr->drawUnder;
+	if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, 
+		markerPtr->classPtr->configSpecs, nOpts, options, 
+		(char *)markerPtr, flags) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (oldName != markerPtr->obj.name) {
+	    if (RenameMarker(graphPtr, markerPtr, oldName, markerPtr->obj.name)
+		!= TCL_OK) {
+		markerPtr->obj.name = oldName;
+		return TCL_ERROR;
+	    }
+	}
+	if ((*markerPtr->classPtr->configProc) (markerPtr) != TCL_OK) {
+
+	    return TCL_ERROR;
+	}
+	if (markerPtr->drawUnder != under) {
+	    graphPtr->flags |= CACHE_DIRTY;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateOp --
+ *
+ *	This procedure creates and initializes a new marker.
+ *
+ * Results:
+ *	The return value is a pointer to a structure describing the new
+ *	element.  If an error occurred, then the return value is NULL and an
+ *	error message is left in interp->result.
+ *
+ * Side effects:
+ *	Memory is allocated, etc.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+CreateOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Marker *markerPtr;
+    Blt_HashEntry *hPtr;
+    int isNew;
+    ClassId classId;
+    int i;
+    const char *name;
+    char ident[200];
+    const char *string;
+    char c;
+
+    string = Tcl_GetString(objv[3]);
+    c = string[0];
+    /* Create the new marker based upon the given type */
+    if ((c == 't') && (strcmp(string, "text") == 0)) {
+	classId = CID_MARKER_TEXT;
+    } else if ((c == 'l') && (strcmp(string, "line") == 0)) {
+	classId = CID_MARKER_LINE;
+    } else if ((c == 'p') && (strcmp(string, "polygon") == 0)) {
+	classId = CID_MARKER_POLYGON;
+    } else if ((c == 'i') && (strcmp(string, "image") == 0)) {
+	classId = CID_MARKER_IMAGE;
+    } else if ((c == 'b') && (strcmp(string, "bitmap") == 0)) {
+	classId = CID_MARKER_BITMAP;
+    } else if ((c == 'w') && (strcmp(string, "window") == 0)) {
+	classId = CID_MARKER_WINDOW;
+    } else {
+	Tcl_AppendResult(interp, "unknown marker type \"", string,
+    "\": should be \"text\", \"line\", \"polygon\", \"bitmap\", \"image\", or \
+\"window\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    /* Scan for "-name" option. We need it for the component name */
+    name = NULL;
+    for (i = 4; i < objc; i += 2) {
+	int length;
+
+	string = Tcl_GetStringFromObj(objv[i], &length);
+	if ((length > 1) && (strncmp(string, "-name", length) == 0)) {
+	    name = Tcl_GetString(objv[i + 1]);
+	    break;
+	}
+    }
+    /* If no name was given for the marker, make up one. */
+    if (name == NULL) {
+	sprintf_s(ident, 200, "marker%d", graphPtr->nextMarkerId++);
+	name = ident;
+    } else if (name[0] == '-') {
+	Tcl_AppendResult(interp, "name of marker \"", name, 
+		"\" can't start with a '-'", (char *)NULL);
+	return TCL_ERROR;
+    }
+    markerPtr = CreateMarker(graphPtr, name, classId);
+    if (Blt_ConfigureComponentFromObj(interp, graphPtr->tkwin, name, 
+		markerPtr->obj.className, markerPtr->classPtr->configSpecs, 
+		objc - 4, objv + 4, (char *)markerPtr, 0) != TCL_OK) {
+	DestroyMarker(markerPtr);
+	return TCL_ERROR;
+    }
+    if ((*markerPtr->classPtr->configProc) (markerPtr) != TCL_OK) {
+	DestroyMarker(markerPtr);
+	return TCL_ERROR;
+    }
+    hPtr = Blt_CreateHashEntry(&graphPtr->markers.table, name, &isNew);
+    if (!isNew) {
+	Marker *oldPtr;
+	/*
+	 * Marker by the same name already exists.  Delete the old marker and
+	 * it's list entry.  But save the hash entry.
+	 */
+	oldPtr = Blt_GetHashValue(hPtr);
+	oldPtr->hashPtr = NULL;
+	DestroyMarker(oldPtr);
+    }
+    Blt_SetHashValue(hPtr, markerPtr);
+    markerPtr->hashPtr = hPtr;
+    /* Unlike elements, new markers are drawn on top of old markers. */
+    markerPtr->link = Blt_Chain_Prepend(graphPtr->markers.displayList,markerPtr);
+    if (markerPtr->drawUnder) {
+	graphPtr->flags |= CACHE_DIRTY;
+    }
+    Blt_EventuallyRedrawGraph(graphPtr);
+    Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DeleteOp --
+ *
+ *	Deletes the marker given by markerId.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new display list.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+DeleteOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int i;
+
+    for (i = 3; i < objc; i++) {
+	Marker *markerPtr;
+
+	if (GetMarkerFromObj(NULL, graphPtr, objv[i], &markerPtr) == TCL_OK) {
+	    markerPtr->flags |= DELETE_PENDING;
+	    Tcl_EventuallyFree(markerPtr, FreeMarker);
+	}
+    }
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetOp --
+ *
+ * 	Find the legend entry from the given argument.  The argument can be
+ * 	either a screen position "@x,y" or the name of an element.
+ *
+ *	I don't know how useful it is to test with the name of an element.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new legend attributes.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+GetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Marker *markerPtr;
+    const char *string;
+
+    string = Tcl_GetString(objv[3]);
+    if ((string[0] == 'c') && (strcmp(string, "current") == 0)) {
+	markerPtr = (Marker *)Blt_GetCurrentItem(graphPtr->bindTable);
+	if (markerPtr == NULL) {
+	    return TCL_OK;		/* Report only on markers. */
+
+	}
+	if ((markerPtr->obj.classId >= CID_MARKER_BITMAP) &&
+	    (markerPtr->obj.classId <= CID_MARKER_WINDOW))	    {
+	    Tcl_SetStringObj(Tcl_GetObjResult(interp), 
+		markerPtr->obj.name, -1);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RelinkOp --
+ *
+ *	Reorders the marker (given by the first name) before/after the another
+ *	marker (given by the second name) in the marker display list.  If no
+ *	second name is given, the marker is placed at the beginning/end of the
+ *	list.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side Effects:
+ *	Graph will be redrawn to reflect the new display list.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+RelinkOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Blt_ChainLink link, place;
+    Marker *markerPtr;
+    const char *string;
+
+    /* Find the marker to be raised or lowered. */
+    if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    /* Right now it's assumed that all markers are always in the display
+       list. */
+    link = markerPtr->link;
+    Blt_Chain_UnlinkLink(graphPtr->markers.displayList, markerPtr->link);
+
+    place = NULL;
+    if (objc == 5) {
+	if (GetMarkerFromObj(interp, graphPtr, objv[4], &markerPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	place = markerPtr->link;
+    }
+
+    /* Link the marker at its new position. */
+    string = Tcl_GetString(objv[2]);
+    if (string[0] == 'l') {
+	Blt_Chain_LinkAfter(graphPtr->markers.displayList, link, place);
+    } else {
+	Blt_Chain_LinkBefore(graphPtr->markers.displayList, link, place);
+    }
+    if (markerPtr->drawUnder) {
+	graphPtr->flags |= CACHE_DIRTY;
+    }
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FindOp --
+ *
+ *	Returns if marker by a given ID currently exists.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+FindOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Blt_ChainLink link;
+    Region2d extents;
+    const char *string;
+    int enclosed;
+    int left, right, top, bottom;
+    int mode;
+
+#define FIND_ENCLOSED	 (1<<0)
+#define FIND_OVERLAPPING (1<<1)
+    string = Tcl_GetString(objv[3]);
+    if (strcmp(string, "enclosed") == 0) {
+	mode = FIND_ENCLOSED;
+    } else if (strcmp(string, "overlapping") == 0) {
+	mode = FIND_OVERLAPPING;
+    } else {
+	Tcl_AppendResult(interp, "bad search type \"", string, 
+		": should be \"enclosed\", or \"overlapping\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+
+    if ((Tcl_GetIntFromObj(interp, objv[4], &left) != TCL_OK) ||
+	(Tcl_GetIntFromObj(interp, objv[5], &top) != TCL_OK) ||
+	(Tcl_GetIntFromObj(interp, objv[6], &right) != TCL_OK) ||
+	(Tcl_GetIntFromObj(interp, objv[7], &bottom) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    if (left < right) {
+	extents.left = (double)left;
+	extents.right = (double)right;
+    } else {
+	extents.left = (double)right;
+	extents.right = (double)left;
+    }
+    if (top < bottom) {
+	extents.top = (double)top;
+	extents.bottom = (double)bottom;
+    } else {
+	extents.top = (double)bottom;
+	extents.bottom = (double)top;
+    }
+    enclosed = (mode == FIND_ENCLOSED);
+    for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList);
+	 link != NULL; link = Blt_Chain_NextLink(link)) {
+	Marker *markerPtr;
+
+	markerPtr = Blt_Chain_GetValue(link);
+	if (markerPtr->flags & (HIDE|DELETE_PENDING)) {
+	    continue;
+	}
+	if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) {
+	    continue;
+	}
+	if ((*markerPtr->classPtr->regionProc)(markerPtr, &extents, enclosed)) {
+	    Tcl_Obj *objPtr;
+
+	    objPtr = Tcl_GetObjResult(interp);
+	    Tcl_SetStringObj(objPtr, markerPtr->obj.name, -1);
+	    return TCL_OK;
+	}
+    }
+    Tcl_SetStringObj(Tcl_GetObjResult(interp), "", -1);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ExistsOp --
+ *
+ *	Returns if marker by a given ID currently exists.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ExistsOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Blt_HashEntry *hPtr;
+
+    hPtr = Blt_FindHashEntry(&graphPtr->markers.table, Tcl_GetString(objv[3]));
+    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (hPtr != NULL));
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TypeOp --
+ *
+ *	Returns a symbolic name for the type of the marker whose ID is given.
+ *
+ * Results:
+ *	A standard TCL result. interp->result will contain the symbolic type
+ *	of the marker.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+TypeOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Marker *markerPtr;
+    const char *type;
+
+    if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    switch (markerPtr->obj.classId) {
+    case CID_MARKER_BITMAP:	type = "bitmap";	break;
+    case CID_MARKER_IMAGE:	type = "image";		break;
+    case CID_MARKER_LINE:	type = "line";		break;
+    case CID_MARKER_POLYGON:	type = "polygon";	break;
+    case CID_MARKER_TEXT:	type = "text";		break;
+    case CID_MARKER_WINDOW:	type = "window";	break;
+    default:			type = "???";		break;
+    }
+    Tcl_SetStringObj(Tcl_GetObjResult(interp), type, -1);
+    return TCL_OK;
+}
+
+/* Public routines */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_MarkerOp --
+ *
+ *	This procedure is invoked to process the TCL command that corresponds
+ *	to a widget managed by this module.  See the user documentation for
+ *	details on what it does.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Blt_OpSpec markerOps[] =
+{
+    {"bind",      1, BindOp,   3, 6, "marker sequence command",},
+    {"cget",      2, CgetOp,   5, 5, "marker option",},
+    {"configure", 2, ConfigureOp, 4, 0,"marker ?marker?... ?option value?...",},
+    {"create",    2, CreateOp, 4, 0, "type ?option value?...",},
+    {"delete",    1, DeleteOp, 3, 0, "?marker?...",},
+    {"exists",    1, ExistsOp, 4, 4, "marker",},
+    {"find",      1, FindOp,   8, 8, "enclosed|overlapping x1 y1 x2 y2",},
+    {"get",       1, GetOp,    4, 4, "name",},
+    {"lower",     1, RelinkOp, 4, 5, "marker ?afterMarker?",},
+    {"names",     1, NamesOp,  3, 0, "?pattern?...",},
+    {"raise",     1, RelinkOp, 4, 5, "marker ?beforeMarker?",},
+    {"type",      1, TypeOp,   4, 4, "marker",},
+};
+static int nMarkerOps = sizeof(markerOps) / sizeof(Blt_OpSpec);
+
+/*ARGSUSED*/
+int
+Blt_MarkerOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	     Tcl_Obj *const *objv)
+{
+    GraphMarkerProc *proc;
+    int result;
+
+    proc = Blt_GetOpFromObj(interp, nMarkerOps, markerOps, BLT_OP_ARG2, 
+	objc, objv,0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    result = (*proc) (graphPtr, interp, objc, objv);
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_MarkersToPostScript --
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_MarkersToPostScript(Graph *graphPtr, Blt_Ps ps, int under)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_LastLink(graphPtr->markers.displayList); 
+	 link != NULL; link = Blt_Chain_PrevLink(link)) {
+	Marker *markerPtr;
+
+	markerPtr = Blt_Chain_GetValue(link);
+	if ((markerPtr->classPtr->postscriptProc == NULL) || 
+	    (markerPtr->nWorldPts == 0)) {
+	    continue;
+	}
+	if (markerPtr->drawUnder != under) {
+	    continue;
+	}
+	if (markerPtr->flags & (HIDE|DELETE_PENDING)) {
+	    continue;
+	}
+	if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) {
+	    continue;
+	}
+	Blt_Ps_VarAppend(ps, "\n% Marker \"", markerPtr->obj.name, 
+		"\" is a ", markerPtr->obj.className, ".\n", (char *)NULL);
+	(*markerPtr->classPtr->postscriptProc) (markerPtr, ps);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DrawMarkers --
+ *
+ *	Calls the individual drawing routines (based on marker type) for each
+ *	marker in the display list.
+ *
+ *	A marker will not be drawn if
+ *
+ *	1) An element linked to the marker (indicated by elemName) is
+ *	   currently hidden.
+ *
+ *	2) No coordinates have been specified for the marker.
+ *
+ *	3) The marker is requesting to be drawn at a different level
+ *	   (above/below the elements) from the current mode.
+ *
+ *	4) The marker is configured as hidden (-hide option).
+ *
+ *	5) The marker isn't visible in the current viewport (i.e. clipped).
+ *
+ * Results:
+ *	None
+ *
+ * Side Effects:
+ *	Markers are drawn into the drawable (pixmap) which will eventually
+ *	be displayed in the graph window.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DrawMarkers(Graph *graphPtr, Drawable drawable, int under)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_LastLink(graphPtr->markers.displayList); 
+	 link != NULL; link = Blt_Chain_PrevLink(link)) {
+	Marker *markerPtr;
+
+	markerPtr = Blt_Chain_GetValue(link);
+
+	if ((markerPtr->nWorldPts == 0) || 
+	    (markerPtr->drawUnder != under) ||
+	    (markerPtr->clipped) ||
+	    (markerPtr->flags & (DELETE_PENDING|HIDE))) {
+	    continue;
+	}
+	if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) {
+	    continue;
+	}
+	(*markerPtr->classPtr->drawProc) (markerPtr, drawable);
+    }
+}
+
+void
+Blt_ConfigureMarkers(Graph *graphPtr)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); 
+	 link != NULL; link = Blt_Chain_NextLink(link)) {
+	Marker *markerPtr;
+
+	markerPtr = Blt_Chain_GetValue(link);
+	(*markerPtr->classPtr->configProc) (markerPtr);
+    }
+}
+
+void
+Blt_MapMarkers(Graph *graphPtr)
+{
+    Blt_ChainLink link;
+
+    for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); 
+	 link != NULL; link = Blt_Chain_NextLink(link)) {
+	Marker *markerPtr;
+
+	markerPtr = Blt_Chain_GetValue(link);
+	if (markerPtr->nWorldPts == 0) {
+	    continue;
+	}
+	if (markerPtr->flags & (HIDE|DELETE_PENDING)) {
+	    continue;
+	}
+	if ((graphPtr->flags & MAP_ALL) || (markerPtr->flags & MAP_ITEM)) {
+	    (*markerPtr->classPtr->mapProc) (markerPtr);
+	    markerPtr->flags &= ~MAP_ITEM;
+	}
+    }
+}
+
+void
+Blt_DestroyMarkers(Graph *graphPtr)
+{
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch iter;
+
+    for (hPtr = Blt_FirstHashEntry(&graphPtr->markers.table, &iter); 
+	 hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	Marker *markerPtr;
+
+	markerPtr = Blt_GetHashValue(hPtr);
+	/*
+	 * Dereferencing the pointer to the hash table prevents the hash table
+	 * entry from being automatically deleted.
+	 */
+	markerPtr->hashPtr = NULL;
+	DestroyMarker(markerPtr);
+    }
+    Blt_DeleteHashTable(&graphPtr->markers.table);
+    Blt_DeleteHashTable(&graphPtr->markers.tagTable);
+    Blt_Chain_Destroy(graphPtr->markers.displayList);
+}
+
+Marker *
+Blt_NearestMarker(
+    Graph *graphPtr,
+    int x, int y,			/* Screen coordinates */
+    int under)
+{
+    Blt_ChainLink link;
+    Point2d point;
+
+    point.x = (double)x;
+    point.y = (double)y;
+    for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList);
+	link != NULL; link = Blt_Chain_NextLink(link)) {
+	Marker *markerPtr;
+
+	markerPtr = Blt_Chain_GetValue(link);
+	if ((markerPtr->nWorldPts == 0) ||
+	    (markerPtr->flags & (HIDE|DELETE_PENDING|MAP_ITEM))) {
+	    continue;			/* Don't consider markers that are
+					 * pending to be mapped. Even if the
+					 * marker has already been mapped, the
+					 * coordinates could be invalid now.
+					 * Better to pick no marker than the
+					 * wrong marker. */
+
+	}
+	if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) {
+	    continue;
+	}
+	if ((markerPtr->drawUnder == under) && 
+	    (markerPtr->state == STATE_NORMAL)) {
+	    if ((*markerPtr->classPtr->pointProc) (markerPtr, &point)) {
+		return markerPtr;
+	    }
+	}
+    }
+    return NULL;
+}
+
+ClientData
+Blt_MakeMarkerTag(Graph *graphPtr, const char *tagName)
+{
+    Blt_HashEntry *hPtr;
+    int isNew;
+
+    assert(tagName != NULL);
+    hPtr = Blt_CreateHashEntry(&graphPtr->markers.tagTable, tagName, &isNew);
+    return Blt_GetHashKey(&graphPtr->markers.tagTable, hPtr);
+}
+
+
diff --git a/tlt3.0/bltGrMisc.c b/tlt3.0/bltGrMisc.c
new file mode 100644
index 0000000..db4b178
--- /dev/null
+++ b/tlt3.0/bltGrMisc.c
@@ -0,0 +1,1005 @@
+
+
+/*
+ * bltGrMisc.c --
+ *
+ * This module implements miscellaneous routines for the BLT graph widget.
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+#include <X11/Xutil.h>
+
+#include "bltInt.h"
+#include "bltGraph.h"
+
+#define ARROW_LEFT		(0)
+#define ARROW_UP		(1)
+#define ARROW_RIGHT		(2)
+#define ARROW_DOWN		(3)
+#define ARROW_OFFSET		4
+#define STD_ARROW_HEIGHT	3
+#define STD_ARROW_WIDTH		((2 * (ARROW_OFFSET - 1)) + 1)
+
+#define BLT_SCROLL_MODE_CANVAS	(1<<0)
+#define BLT_SCROLL_MODE_LISTBOX	(1<<1)
+#define BLT_SCROLL_MODE_HIERBOX	(1<<2)
+
+static Blt_OptionParseProc ObjToPoint;
+static Blt_OptionPrintProc PointToObj;
+Blt_CustomOption bltPointOption =
+{
+    ObjToPoint, PointToObj, NULL, (ClientData)0
+};
+
+static Blt_OptionParseProc ObjToLimitsProc;
+static Blt_OptionPrintProc LimitsToObjProc;
+Blt_CustomOption bltLimitsOption =
+{
+    ObjToLimitsProc, LimitsToObjProc, NULL, (ClientData)0
+};
+
+
+/*
+ *---------------------------------------------------------------------------
+ * Custom option parse and print procedures
+ *---------------------------------------------------------------------------
+ */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetXY --
+ *
+ *	Converts a string in the form "@x,y" into an XPoint structure of the x
+ *	and y coordinates.
+ *
+ * Results:
+ *	A standard TCL result. If the string represents a valid position
+ *	*pointPtr* will contain the converted x and y coordinates and TCL_OK
+ *	is returned.  Otherwise, TCL_ERROR is returned and interp->result will
+ *	contain an error message.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_GetXY(Tcl_Interp *interp, Tk_Window tkwin, const char *string, 
+	  int *xPtr, int *yPtr)
+{
+    char *comma;
+    int result;
+    int x, y;
+
+    if ((string == NULL) || (*string == '\0')) {
+	*xPtr = *yPtr = -SHRT_MAX;
+	return TCL_OK;
+    }
+    if (*string != '@') {
+	goto badFormat;
+    }
+    comma = strchr(string + 1, ',');
+    if (comma == NULL) {
+	goto badFormat;
+    }
+    *comma = '\0';
+    result = ((Tk_GetPixels(interp, tkwin, string + 1, &x) == TCL_OK) &&
+	      (Tk_GetPixels(interp, tkwin, comma + 1, &y) == TCL_OK));
+    *comma = ',';
+    if (!result) {
+	Tcl_AppendResult(interp, ": can't parse position \"", string, "\"",
+	    (char *)NULL);
+	return TCL_ERROR;
+    }
+    *xPtr = x, *yPtr = y;
+    return TCL_OK;
+
+  badFormat:
+    Tcl_AppendResult(interp, "bad position \"", string, 
+	     "\": should be \"@x,y\"", (char *)NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToPoint --
+ *
+ *	Convert the string representation of a legend XY position into window
+ *	coordinates.  The form of the string must be "@x,y" or none.
+ *
+ * Results:
+ *	A standard TCL result.  The symbol type is written into the
+ *	widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToPoint(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tk_Window tkwin,		/* Not used. */
+    Tcl_Obj *objPtr,		/* New legend position string */
+    char *widgRec,		/* Widget record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    XPoint *pointPtr = (XPoint *)(widgRec + offset);
+    int x, y;
+
+    if (Blt_GetXY(interp, tkwin, Tcl_GetString(objPtr), &x, &y) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    pointPtr->x = x, pointPtr->y = y;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PointToObj --
+ *
+ *	Convert the window coordinates into a string.
+ *
+ * Results:
+ *	The string representing the coordinate position is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+PointToObj(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Not used. */
+    Tk_Window tkwin,		/* Not used. */
+    char *widgRec,		/* Widget record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    XPoint *pointPtr = (XPoint *)(widgRec + offset);
+    Tcl_Obj *objPtr;
+
+    if ((pointPtr->x != -SHRT_MAX) && (pointPtr->y != -SHRT_MAX)) {
+	char string[200];
+
+	sprintf_s(string, 200, "@%d,%d", pointPtr->x, pointPtr->y);
+	objPtr = Tcl_NewStringObj(string, -1);
+    } else { 
+	objPtr = Tcl_NewStringObj("", -1);
+    }
+    return objPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToLimitsProc --
+ *
+ *	Converts the list of elements into zero or more pixel values which
+ *	determine the range of pixel values possible.  An element can be in any
+ *	form accepted by Tk_GetPixels. The list has a different meaning based
+ *	upon the number of elements.
+ *
+ *	    # of elements:
+ *
+ *	    0 - the limits are reset to the defaults.
+ *	    1 - the minimum and maximum values are set to this
+ *		value, freezing the range at a single value.
+ *	    2 - first element is the minimum, the second is the
+ *		maximum.
+ *	    3 - first element is the minimum, the second is the
+ *		maximum, and the third is the nominal value.
+ *
+ *	Any element may be the empty string which indicates the default.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The min and max fields
+ *	of the range are set.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToLimitsProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,		        /* Interpreter to send results back
+					 * to */
+    Tk_Window tkwin,			/* Widget of paneset */
+    Tcl_Obj *objPtr,			/* New width list */
+    char *widgRec,			/* Widget record */
+    int offset,				/* Offset to field in structure */
+    int flags)	
+{
+    Blt_Limits *limitsPtr = (Blt_Limits *)(widgRec + offset);
+
+    if (Blt_GetLimitsFromObj(interp, tkwin, objPtr, limitsPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LimitsToObjProc --
+ *
+ *	Convert the limits of the pixel values allowed into a list.
+ *
+ * Results:
+ *	The string representation of the limits is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+LimitsToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Not used. */
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* Row/column structure record */
+    int offset,				/* Offset to field in structure */
+    int flags)	
+{
+    Blt_Limits *limitsPtr = (Blt_Limits *)(widgRec + offset);
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if (limitsPtr->flags & LIMITS_MIN_SET) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+				 Tcl_NewIntObj(limitsPtr->min));
+    } else {
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1));
+    }
+    if (limitsPtr->flags & LIMITS_MAX_SET) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+				 Tcl_NewIntObj(limitsPtr->max));
+    } else {
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1));
+    }
+    if (limitsPtr->flags & LIMITS_NOM_SET) {
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+				 Tcl_NewIntObj(limitsPtr->nom));
+    } else {
+	Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1));
+    }
+    return listObjPtr;
+}
+
+int
+Blt_PointInSegments(
+    Point2d *samplePtr,
+    Segment2d *segments,
+    int nSegments,
+    double halo)
+{
+    Segment2d *sp, *send;
+    double minDist;
+
+    minDist = DBL_MAX;
+    for (sp = segments, send = sp + nSegments; sp < send; sp++) {
+	double dist;
+	double left, right, top, bottom;
+	Point2d p, t;
+
+	t = Blt_GetProjection((int)samplePtr->x, (int)samplePtr->y, 
+			      &sp->p, &sp->q);
+	if (sp->p.x > sp->q.x) {
+	    right = sp->p.x, left = sp->q.x;
+	} else {
+	    right = sp->q.x, left = sp->p.x;
+	}
+	if (sp->p.y > sp->q.y) {
+	    bottom = sp->p.y, top = sp->q.y;
+	} else {
+	    bottom = sp->q.y, top = sp->p.y;
+	}
+	p.x = BOUND(t.x, left, right);
+	p.y = BOUND(t.y, top, bottom);
+	dist = hypot(p.x - samplePtr->x, p.y - samplePtr->y);
+	if (dist < minDist) {
+	    minDist = dist;
+	}
+    }
+    return (minDist < halo);
+}
+
+int
+Blt_PointInPolygon(
+    Point2d *s,			/* Sample point. */
+    Point2d *points,		/* Points representing the polygon. */
+    int nPoints)		/* # of points in above array. */
+{
+    Point2d *p, *q, *qend;
+    int count;
+
+    count = 0;
+    for (p = points, q = p + 1, qend = p + nPoints; q < qend; p++, q++) {
+	if (((p->y <= s->y) && (s->y < q->y)) || 
+	    ((q->y <= s->y) && (s->y < p->y))) {
+	    double b;
+
+	    b = (q->x - p->x) * (s->y - p->y) / (q->y - p->y) + p->x;
+	    if (s->x < b) {
+		count++;	/* Count the number of intersections. */
+	    }
+	}
+    }
+    return (count & 0x01);
+}
+
+int
+Blt_RegionInPolygon(
+    Region2d *regionPtr,
+    Point2d *points,
+    int nPoints,
+    int enclosed)
+{
+    Point2d *pp, *pend;
+
+    if (enclosed) {
+	/*  
+	 * All points of the polygon must be inside the rectangle.
+	 */
+	for (pp = points, pend = pp + nPoints; pp < pend; pp++) {
+	    if ((pp->x < regionPtr->left) || (pp->x > regionPtr->right) ||
+		(pp->y < regionPtr->top) || (pp->y > regionPtr->bottom)) {
+		return FALSE;	/* One point is exterior. */
+	    }
+	}
+	return TRUE;
+    } else {
+	Point2d r;
+	/*
+	 * If any segment of the polygon clips the bounding region, the
+	 * polygon overlaps the rectangle.
+	 */
+	points[nPoints] = points[0];
+	for (pp = points, pend = pp + nPoints; pp < pend; pp++) {
+	    Point2d p, q;
+
+	    p = *pp;
+	    q = *(pp + 1);
+	    if (Blt_LineRectClip(regionPtr, &p, &q)) {
+		return TRUE;
+	    }
+	}
+	/* 
+	 * Otherwise the polygon and rectangle are either disjoint or
+	 * enclosed.  Check if one corner of the rectangle is inside the
+	 * polygon.
+	 */
+	r.x = regionPtr->left;
+	r.y = regionPtr->top;
+	return Blt_PointInPolygon(&r, points, nPoints);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GraphExtents --
+ *
+ *	Generates a bounding box representing the plotting area of the
+ *	graph. This data structure is used to clip the points and line
+ *	segments of the line element.
+ *
+ *	The clip region is the plotting area plus such arbitrary extra space.
+ *	The reason we clip with a bounding box larger than the plot area is so
+ *	that symbols will be drawn even if their center point isn't in the
+ *	plotting area.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	The bounding box is filled with the dimensions of the plotting area.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_GraphExtents(Graph *graphPtr, Region2d *regionPtr)
+{
+    regionPtr->left = (double)(graphPtr->hOffset - graphPtr->xPad.side1);
+    regionPtr->top = (double)(graphPtr->vOffset - graphPtr->yPad.side1);
+    regionPtr->right = (double)(graphPtr->hOffset + graphPtr->hRange + 
+	graphPtr->xPad.side2);
+    regionPtr->bottom = (double)(graphPtr->vOffset + graphPtr->vRange + 
+	graphPtr->yPad.side2);
+}
+
+static int 
+ClipTest (double ds, double dr, double *t1, double *t2)
+{
+  double t;
+
+  if (ds < 0.0) {
+      t = dr / ds;
+      if (t > *t2) {
+	  return FALSE;
+      } 
+      if (t > *t1) {
+	  *t1 = t;
+      }
+  } else if (ds > 0.0) {
+      t = dr / ds;
+      if (t < *t1) {
+	  return FALSE;
+      } 
+      if (t < *t2) {
+	  *t2 = t;
+      }
+  } else {
+      /* d = 0, so line is parallel to this clipping edge */
+      if (dr < 0.0) {		/* Line is outside clipping edge */
+	  return FALSE;
+      }
+  }
+  return TRUE;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_LineRectClip --
+ *
+ *	Clips the given line segment to a rectangular region.  The coordinates
+ *	of the clipped line segment are returned.  The original coordinates
+ *	are overwritten.
+ *
+ *	Reference: 
+ *	  Liang, Y-D., and B. Barsky, A new concept and method for
+ *	  Line Clipping, ACM, TOG,3(1), 1984, pp.1-22.
+ *
+ * Results:
+ *	Returns if line segment is visible within the region. The coordinates
+ *	of the original line segment are overwritten by the clipped
+ *	coordinates.
+ *
+ *---------------------------------------------------------------------------
+ */
+int 
+Blt_LineRectClip(
+    Region2d *regionPtr,	/* Rectangular region to clip. */
+    Point2d *p, Point2d *q)	/* (in/out) Coordinates of original and
+				 * clipped line segment. */
+{
+    double t1, t2;
+    double dx, dy;
+
+    t1 = 0.0, t2 = 1.0;
+    dx = q->x - p->x;
+    if ((ClipTest (-dx, p->x - regionPtr->left, &t1, &t2)) &&
+	(ClipTest (dx, regionPtr->right - p->x, &t1, &t2))) {
+	dy = q->y - p->y;
+	if ((ClipTest (-dy, p->y - regionPtr->top, &t1, &t2)) && 
+	    (ClipTest (dy, regionPtr->bottom - p->y, &t1, &t2))) {
+	    if (t2 < 1.0) {
+		q->x = p->x + t2 * dx;
+		q->y = p->y + t2 * dy;
+	    }
+	    if (t1 > 0.0) {
+		p->x += t1 * dx;
+		p->y += t1 * dy;
+	    }
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_PolyRectClip --
+ *
+ *	Clips the given polygon to a rectangular region.  The resulting
+ *	polygon is returned. Note that the resulting polyon may be complex,
+ *	connected by zero width/height segments.  The drawing routine (such as
+ *	XFillPolygon) will not draw a connecting segment.
+ *
+ *	Reference:  
+ *	  Liang Y. D. and Brian A. Barsky, "Analysis and Algorithm for
+ *	  Polygon Clipping", Communications of ACM, Vol. 26,
+ *	  p.868-877, 1983
+ *
+ * Results:
+ *	Returns the number of points in the clipped polygon. The points of the
+ *	clipped polygon are stored in *outputPts*.
+ *
+ *---------------------------------------------------------------------------
+ */
+#define EPSILON  FLT_EPSILON
+#define AddVertex(vx, vy)	    r->x=(vx), r->y=(vy), r++, count++ 
+#define LastVertex(vx, vy)	    r->x=(vx), r->y=(vy), count++ 
+
+int 
+Blt_PolyRectClip(
+    Region2d *regionPtr,	/* Rectangular region clipping the polygon. */
+    Point2d *points,		/* Points of polygon to be clipped. */
+    int nPoints,		/* # of points in polygon. */
+    Point2d *clipPts)		/* (out) Points of clipped polygon. */
+{
+    Point2d *p;			/* First vertex of input polygon edge. */
+    Point2d *pend;
+    Point2d *q;			/* Last vertex of input polygon edge. */
+    Point2d *r;
+    int count;
+
+    r = clipPts;
+    count = 0;			/* Counts # of vertices in output polygon. */
+
+    points[nPoints] = points[0];
+    for (p = points, q = p + 1, pend = p + nPoints; p < pend; p++, q++) {
+	double dx, dy;
+	double tin1, tin2, tinx, tiny;
+	double xin, yin, xout, yout;
+
+	dx = q->x - p->x;	/* X-direction */
+	dy = q->y - p->y;	/* Y-direction */
+
+	if (fabs(dx) < EPSILON) { 
+	    dx = (p->x > regionPtr->left) ? -EPSILON : EPSILON ;
+	}
+	if (fabs(dy) < EPSILON) { 
+	    dy = (p->y > regionPtr->top) ? -EPSILON : EPSILON ;
+	}
+
+	if (dx > 0.0) {		/* Left */
+	    xin = regionPtr->left;
+	    xout = regionPtr->right + 1.0;
+	} else {		/* Right */
+	    xin = regionPtr->right + 1.0;
+	    xout = regionPtr->left;
+	}
+	if (dy > 0.0) {		/* Top */
+	    yin = regionPtr->top;
+	    yout = regionPtr->bottom + 1.0;
+	} else {		/* Bottom */
+	    yin = regionPtr->bottom + 1.0;
+	    yout = regionPtr->top;
+	}
+	
+	tinx = (xin - p->x) / dx;
+	tiny = (yin - p->y) / dy;
+	
+	if (tinx < tiny) {	/* Hits x first */
+	    tin1 = tinx;
+	    tin2 = tiny;
+	} else {		/* Hits y first */
+	    tin1 = tiny;
+	    tin2 = tinx;
+	}
+	
+	if (tin1 <= 1.0) {
+	    if (tin1 > 0.0) {
+		AddVertex(xin, yin);
+            }
+	    if (tin2 <= 1.0) {
+		double toutx, touty, tout1;
+
+		toutx = (xout - p->x) / dx;
+		touty = (yout - p->y) / dy;
+		tout1 = MIN(toutx, touty);
+		
+		if ((tin2 > 0.0) || (tout1 > 0.0)) {
+		    if (tin2 <= tout1) {
+			if (tin2 > 0.0) {
+			    if (tinx > tiny) {
+				AddVertex(xin, p->y + tinx * dy);
+			    } else {
+				AddVertex(p->x + tiny * dx, yin);
+			    }
+			}
+			if (tout1 < 1.0) {
+			    if (toutx < touty) {
+				AddVertex(xout, p->y + toutx * dy);
+			    } else {
+				AddVertex(p->x + touty * dx, yout);
+			    }
+			} else {
+			    AddVertex(q->x, q->y);
+			}
+		    } else {
+			if (tinx > tiny) {
+			    AddVertex(xin, yout);
+			} else {
+			    AddVertex(xout, yin);
+			}
+
+		    }
+		}
+            }
+	}
+    }
+    if (count > 0) {
+	LastVertex(clipPts[0].x, clipPts[0].y);
+    }
+    return count;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetProjection --
+ *
+ *	Computes the projection of a point on a line.  The line (given by two
+ *	points), is assumed the be infinite.
+ *
+ *	Compute the slope (angle) of the line and rotate it 90 degrees.  Using
+ *	the slope-intercept method (we know the second line from the sample
+ *	test point and the computed slope), then find the intersection of both
+ *	lines. This will be the projection of the sample point on the first
+ *	line.
+ *
+ * Results:
+ *	Returns the coordinates of the projection on the line.
+ *
+ *---------------------------------------------------------------------------
+ */
+Point2d
+Blt_GetProjection(
+    int x, int y,		/* Screen coordinates of the sample point. */
+    Point2d *p, Point2d *q)	/* Line segment to project point onto */
+{
+    double dx, dy;
+    Point2d t;
+
+    dx = p->x - q->x;
+    dy = p->y - q->y;
+
+    /* Test for horizontal and vertical lines */
+    if (fabs(dx) < DBL_EPSILON) {
+	t.x = p->x, t.y = (double)y;
+    } else if (fabs(dy) < DBL_EPSILON) {
+	t.x = (double)x, t.y = p->y;
+    } else {
+	double m1, m2;		/* Slope of both lines */
+	double b1, b2;		/* y-intercepts */
+	double midX, midY;	/* Midpoint of line segment. */
+	double ax, ay, bx, by;
+
+	/* Compute the slope and intercept of PQ. */
+	m1 = (dy / dx);
+	b1 = p->y - (p->x * m1);
+
+	/* 
+	 * Compute the slope and intercept of a second line segment: one that
+	 * intersects through sample X-Y coordinate with a slope perpendicular
+	 * to original line.
+	 */
+
+	/* Find midpoint of PQ. */
+	midX = (p->x + q->x) * 0.5;
+	midY = (p->y + q->y) * 0.5;
+
+	/* Rotate the line 90 degrees */
+	ax = midX - (0.5 * dy);
+	ay = midY - (0.5 * -dx);
+	bx = midX + (0.5 * dy);
+	by = midY + (0.5 * -dx);
+
+	m2 = (ay - by) / (ax - bx);
+	b2 = y - (x * m2);
+
+	/*
+	 * Given the equations of two lines which contain the same point,
+	 *
+	 *    y = m1 * x + b1
+	 *    y = m2 * x + b2
+	 *
+	 * solve for the intersection.
+	 *
+	 *    x = (b2 - b1) / (m1 - m2)
+	 *    y = m1 * x + b1
+	 *
+	 */
+
+	t.x = (b2 - b1) / (m1 - m2);
+	t.y = m1 * t.x + b1;
+    }
+    return t;
+}
+
+#define SetColor(c,r,g,b) ((c)->red = (int)((r) * 65535.0), \
+			   (c)->green = (int)((g) * 65535.0), \
+			   (c)->blue = (int)((b) * 65535.0))
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_AdjustViewport --
+ *
+ *	Adjusts the offsets of the viewport according to the scroll mode.
+ *	This is to accommodate both "listbox" and "canvas" style scrolling.
+ *
+ *	"canvas"	The viewport scrolls within the range of world
+ *			coordinates.  This way the viewport always displays
+ *			a full page of the world.  If the world is smaller
+ *			than the viewport, then (bizarrely) the world and
+ *			viewport are inverted so that the world moves up
+ *			and down within the viewport.
+ *
+ *	"listbox"	The viewport can scroll beyond the range of world
+ *			coordinates.  Every entry can be displayed at the
+ *			top of the viewport.  This also means that the
+ *			scrollbar thumb weirdly shrinks as the last entry
+ *			is scrolled upward.
+ *
+ * Results:
+ *	The corrected offset is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_AdjustViewport(int offset, int worldSize, int windowSize, int scrollUnits, 
+		   int scrollMode)
+{
+    switch (scrollMode) {
+    case BLT_SCROLL_MODE_CANVAS:
+
+	/*
+	 * Canvas-style scrolling allows the world to be scrolled within the
+	 * window.
+	 */
+	if (worldSize < windowSize) {
+	    if ((worldSize - offset) > windowSize) {
+		offset = worldSize - windowSize;
+	    }
+	    if (offset > 0) {
+		offset = 0;
+	    }
+	} else {
+	    if ((offset + windowSize) > worldSize) {
+		offset = worldSize - windowSize;
+	    }
+	    if (offset < 0) {
+		offset = 0;
+	    }
+	}
+	break;
+
+    case BLT_SCROLL_MODE_LISTBOX:
+	if (offset < 0) {
+	    offset = 0;
+	}
+	if (offset >= worldSize) {
+	    offset = worldSize - scrollUnits;
+	}
+	break;
+
+    case BLT_SCROLL_MODE_HIERBOX:
+
+	/*
+	 * Hierbox-style scrolling allows the world to be scrolled within the
+	 * window.
+	 */
+	if ((offset + windowSize) > worldSize) {
+	    offset = worldSize - windowSize;
+	}
+	if (offset < 0) {
+	    offset = 0;
+	}
+	break;
+    }
+    return offset;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_UpdateScrollbar --
+ *
+ * 	Invoke a TCL command to the scrollbar, defining the new position and
+ * 	length of the scroll. See the Tk documentation for further information
+ * 	on the scrollbar.  It is assumed the scrollbar command prefix is
+ * 	valid.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Scrollbar is commanded to change position and/or size.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_UpdateScrollbar(
+    Tcl_Interp *interp,
+    Tcl_Obj *scrollCmdObjPtr,		/* Scrollbar command prefix. May be
+					 * several words */
+    int first, int last, int width)
+{
+    Tcl_Obj *cmdObjPtr;
+    double firstFract, lastFract;
+
+    firstFract = 0.0, lastFract = 1.0;
+    if (width > 0) {
+	firstFract = (double)first / (double)width;
+	lastFract = (double)last / (double)width;
+    }
+    cmdObjPtr = Tcl_DuplicateObj(scrollCmdObjPtr);
+    Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewDoubleObj(firstFract));
+    Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewDoubleObj(lastFract));
+    Tcl_IncrRefCount(cmdObjPtr);
+    if (Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL) != TCL_OK) {
+	Tcl_BackgroundError(interp);
+    }
+    Tcl_DecrRefCount(cmdObjPtr);
+
+}
+
+/* -------------------------------------------------------------------------- */
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetPrivateGCFromDrawable --
+ *
+ *      Like Tk_GetGC, but doesn't share the GC with any other widget.  This
+ *      is needed because the certain GC parameters (like dashes) can not be
+ *      set via XCreateGC, therefore there is no way for Tk's hashing
+ *      mechanism to recognize that two such GCs differ.
+ *
+ * Results:
+ *      A new GC is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+GC
+Blt_GetPrivateGCFromDrawable(
+    Display *display,
+    Drawable drawable,
+    unsigned long gcMask,
+    XGCValues *valuePtr)
+{
+    GC newGC;
+
+    newGC = XCreateGC(display, drawable, gcMask, valuePtr);
+    return newGC;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetPrivateGC --
+ *
+ *      Like Tk_GetGC, but doesn't share the GC with any other widget.  This
+ *      is needed because the certain GC parameters (like dashes) can not be
+ *      set via XCreateGC, therefore there is no way for Tk's hashing
+ *      mechanism to recognize that two such GCs differ.
+ *
+ * Results:
+ *      A new GC is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+GC
+Blt_GetPrivateGC(
+    Tk_Window tkwin,
+    unsigned long gcMask,
+    XGCValues *valuePtr)
+{
+    GC gc;
+    Pixmap pixmap;
+    Drawable drawable;
+    Display *display;
+
+    pixmap = None;
+    drawable = Tk_WindowId(tkwin);
+    display = Tk_Display(tkwin);
+    if (drawable == None) {
+	Drawable root;
+	int depth;
+
+	root = Tk_RootWindow(tkwin);
+	depth = Tk_Depth(tkwin);
+
+	if (depth == DefaultDepth(display, Tk_ScreenNumber(tkwin))) {
+	    drawable = root;
+	} else {
+	    pixmap = Tk_GetPixmap(display, root, 1, 1, depth);
+	    drawable = pixmap;
+	    Blt_SetDrawableAttribs(display, drawable, 1, 1, depth, 
+		Tk_Colormap(tkwin), Tk_Visual(tkwin));
+	}
+    }
+    gc = Blt_GetPrivateGCFromDrawable(display, drawable, gcMask, valuePtr);
+    if (pixmap != None) {
+	Tk_FreePixmap(display, pixmap);
+    }
+    return gc;
+}
+
+void
+Blt_FreePrivateGC(Display *display, GC gc)
+{
+    Tk_FreeXId(display, (XID) XGContextFromGC(gc));
+    XFreeGC(display, gc);
+}
+
+void
+Blt_SetDashes(Display *display, GC gc, Blt_Dashes *dashesPtr)
+{
+    XSetDashes(display, gc, dashesPtr->offset, (const char *)dashesPtr->values,
+	(int)strlen((char *)dashesPtr->values));
+}
+
+void
+Blt_ScreenDPI(Tk_Window tkwin, unsigned int *xPtr, unsigned int *yPtr) 
+{
+    Screen *screen;
+
+#define MM_INCH		25.4
+    screen = Tk_Screen(tkwin);
+    *xPtr = (unsigned int)((WidthOfScreen(screen) * MM_INCH) / 
+			   WidthMMOfScreen(screen));
+    *yPtr = (unsigned int)((HeightOfScreen(screen) * MM_INCH) / 
+			   HeightMMOfScreen(screen));
+}
+
+void
+Blt_Draw2DSegments(
+    Display *display,
+    Drawable drawable,
+    GC gc,
+    Segment2d *segments,
+    int nSegments)
+{
+    XSegment *dp, *xsegments;
+    Segment2d *sp, *send;
+
+    xsegments = malloc(nSegments * sizeof(XSegment));
+    if (xsegments == NULL) {
+	return;
+    }
+    dp = xsegments;
+    for (sp = segments, send = sp + nSegments; sp < send; sp++) {
+	dp->x1 = (short int)sp->p.x;
+	dp->y1 = (short int)sp->p.y;
+	dp->x2 = (short int)sp->q.x;
+	dp->y2 = (short int)sp->q.y;
+	dp++;
+    }
+    XDrawSegments(display, drawable, gc, xsegments, nSegments);
+    free(xsegments);
+}
+
+long 
+Blt_MaxRequestSize(Display *display, size_t elemSize) 
+{
+    static long maxSizeBytes = 0L;
+
+    if (maxSizeBytes == 0L) {
+	long size;
+	size = XExtendedMaxRequestSize(display);
+	if (size == 0) {
+	    size = XMaxRequestSize(display);
+	}
+	size -= (4 * elemSize);
+	/*	maxSizeBytes = (size * 4); */
+	maxSizeBytes = size;
+    }
+    return (maxSizeBytes / elemSize);
+}
+
diff --git a/tlt3.0/bltGrPen.c b/tlt3.0/bltGrPen.c
new file mode 100644
index 0000000..79973a5
--- /dev/null
+++ b/tlt3.0/bltGrPen.c
@@ -0,0 +1,760 @@
+
+/*
+ * bltGrPen.c --
+ *
+ * This module implements pens for the BLT graph widget.
+ *
+ *	Copyright 1996-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <X11/Xutil.h>
+
+#include "bltInt.h"
+#include "bltGraph.h"
+#include "bltOp.h"
+
+typedef int (GraphPenProc)(Tcl_Interp *interp, Graph *graphPtr, int objc, 
+	Tcl_Obj *const *objv);
+
+static Blt_OptionFreeProc FreeColor;
+static Blt_OptionParseProc ObjToColor;
+static Blt_OptionPrintProc ColorToObj;
+Blt_CustomOption bltColorOption = {
+    ObjToColor, ColorToObj, FreeColor, (ClientData)0
+};
+
+static Blt_OptionFreeProc FreePen;
+static Blt_OptionParseProc ObjToPen;
+static Blt_OptionPrintProc PenToObj;
+Blt_CustomOption bltBarPenOption = {
+    ObjToPen, PenToObj, FreePen, (ClientData)CID_ELEM_BAR
+};
+Blt_CustomOption bltLinePenOption = {
+    ObjToPen, PenToObj, FreePen, (ClientData)CID_ELEM_LINE
+};
+
+/*ARGSUSED*/
+static void
+FreeColor(
+    ClientData clientData,	/* Not used. */
+    Display *display,		/* Not used. */
+    char *widgRec,
+    int offset)
+{
+    XColor *colorPtr = *(XColor **)(widgRec + offset);
+
+    if ((colorPtr != NULL) && (colorPtr != COLOR_DEFAULT)) {
+	Tk_FreeColor(colorPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+
+ * ObjToColor --
+ *
+ *	Convert the string representation of a color into a XColor pointer.
+ *
+ * Results:
+ *	The return value is a standard TCL result.  The color pointer is
+ *	written into the widget record.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToColor(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tk_Window tkwin,		/* Not used. */
+    Tcl_Obj *objPtr,		/* String representing color */
+    char *widgRec,		/* Widget record */
+    int offset,			/* Offset to field in structure */
+    int flags)	
+{
+    XColor **colorPtrPtr = (XColor **)(widgRec + offset);
+    XColor *colorPtr;
+    const char *string;
+    char c;
+    int length;
+
+    string = Tcl_GetStringFromObj(objPtr, &length);
+    c = string[0];
+
+    if ((c == '\0') && (flags & BLT_CONFIG_NULL_OK)) {
+	if ((*colorPtrPtr != NULL) && (*colorPtrPtr != COLOR_DEFAULT)) {
+	    Tk_FreeColor(*colorPtrPtr);
+	}
+	*colorPtrPtr = NULL;
+	return TCL_OK;
+    } 
+    if ((c == 'd') && (strncmp(string, "defcolor", length) == 0)) {
+	if ((*colorPtrPtr != NULL) && (*colorPtrPtr != COLOR_DEFAULT)) {
+	    Tk_FreeColor(*colorPtrPtr);
+	}
+	*colorPtrPtr = COLOR_DEFAULT;
+	return TCL_OK;
+    } 
+    colorPtr = Tk_AllocColorFromObj(interp, tkwin, objPtr);
+    if (colorPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if ((*colorPtrPtr != NULL) && (*colorPtrPtr != COLOR_DEFAULT)) {
+	Tk_FreeColor(*colorPtrPtr);
+    }
+    *colorPtrPtr = colorPtr;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ColorToObj --
+ *
+ *	Convert the color value into a string.
+ *
+ * Results:
+ *	The string representing the symbol color is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+ColorToObj(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Not used. */
+    Tk_Window tkwin,		/* Not used. */
+    char *widgRec,		/* Widget information record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    XColor *colorPtr = *(XColor **)(widgRec + offset);
+    Tcl_Obj *objPtr;
+
+    if (colorPtr == NULL) {
+	objPtr = Tcl_NewStringObj("", -1);
+    } else if (colorPtr == COLOR_DEFAULT) {
+	objPtr = Tcl_NewStringObj("defcolor", -1);
+    } else {
+	objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1);
+    }
+    return objPtr;
+}
+
+/*ARGSUSED*/
+static void
+FreePen(
+    ClientData clientData,	/* Not used. */
+    Display *display,		/* Not used. */
+    char *widgRec,
+    int offset)
+{
+    Pen **penPtrPtr = (Pen **)(widgRec + offset);
+
+    if (*penPtrPtr != NULL) {
+	Blt_FreePen(*penPtrPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToPen --
+ *
+ *	Convert the color value into a string.
+ *
+ * Results:
+ *	The string representing the symbol color is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToPen(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    Tk_Window tkwin,		/* Not used. */
+    Tcl_Obj *objPtr,		/* String representing pen */
+    char *widgRec,		/* Widget record */
+    int offset,			/* Offset to field in structure */
+    int flags)	
+{
+    Pen **penPtrPtr = (Pen **)(widgRec + offset);
+    const char *string;
+
+    string = Tcl_GetString(objPtr);
+    if ((string[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) {
+	Blt_FreePen(*penPtrPtr);
+	*penPtrPtr = NULL;
+    } else {
+	Pen *penPtr;
+	Graph *graphPtr;
+	ClassId classId = (ClassId)clientData; /* Element type. */
+
+	graphPtr = Blt_GetGraphFromWindowData(tkwin);
+	assert(graphPtr);
+
+	if (classId == CID_NONE) {	
+	    classId = graphPtr->classId;
+	}
+	if (Blt_GetPenFromObj(interp, graphPtr, objPtr, classId, &penPtr) 
+	    != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	Blt_FreePen(*penPtrPtr);
+	*penPtrPtr = penPtr;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PenToObj --
+ *
+ *	Parse the name of the name.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+PenToObj(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Not used. */
+    Tk_Window tkwin,		/* Not used. */
+    char *widgRec,		/* Widget information record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    Pen *penPtr = *(Pen **)(widgRec + offset);
+
+    if (penPtr == NULL) {
+	return Tcl_NewStringObj("", -1);
+    } else {
+	return Tcl_NewStringObj(penPtr->name, -1);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetPenFromObj --
+ *
+ *	Find and return the pen style from a given name.
+ *
+ * Results:
+ *     	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, 
+	      Pen **penPtrPtr)
+{
+    Blt_HashEntry *hPtr;
+    Pen *penPtr;
+    const char *name;
+
+    penPtr = NULL;
+    name = Tcl_GetString(objPtr);
+    hPtr = Blt_FindHashEntry(&graphPtr->penTable, name);
+    if (hPtr != NULL) {
+	penPtr = Blt_GetHashValue(hPtr);
+	if (penPtr->flags & DELETE_PENDING) {
+	    penPtr = NULL;
+	}
+    }
+    if (penPtr == NULL) {
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "can't find pen \"", name, "\" in \"", 
+		Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
+	}
+	return TCL_ERROR;
+    }
+    *penPtrPtr = penPtr;
+    return TCL_OK;
+}
+
+static void
+DestroyPen(Pen *penPtr)
+{
+    Graph *graphPtr = penPtr->graphPtr;
+
+    Blt_FreeOptions(penPtr->configSpecs, (char *)penPtr, graphPtr->display, 0);
+    (*penPtr->destroyProc) (graphPtr, penPtr);
+    if ((penPtr->name != NULL) && (penPtr->name[0] != '\0')) {
+      free((void*)(penPtr->name));
+    }
+    if (penPtr->hashPtr != NULL) {
+	Blt_DeleteHashEntry(&graphPtr->penTable, penPtr->hashPtr);
+    }
+    free(penPtr);
+}
+
+void
+Blt_FreePen(Pen *penPtr)
+{
+    if (penPtr != NULL) {
+	penPtr->refCount--;
+	if ((penPtr->refCount == 0) && (penPtr->flags & DELETE_PENDING)) {
+	    DestroyPen(penPtr);
+	}
+    }
+}
+
+Pen *
+Blt_CreatePen(Graph *graphPtr, const char *penName, ClassId classId,
+	      int objc, Tcl_Obj *const *objv)
+{
+    Pen *penPtr;
+    Blt_HashEntry *hPtr;
+    unsigned int configFlags;
+    int isNew;
+    int i;
+
+    /*
+     * Scan the option list for a "-type" entry.  This will indicate what type
+     * of pen we are creating. Otherwise we'll default to the suggested type.
+     * Last -type option wins.
+     */
+    for (i = 0; i < objc; i += 2) {
+	char *string;
+	int length;
+
+	string = Tcl_GetStringFromObj(objv[i],  &length);
+	if ((length > 2) && (strncmp(string, "-type", length) == 0)) {
+	    char *arg;
+
+	    arg = Tcl_GetString(objv[i + 1]);
+	    if (strcmp(arg, "bar") == 0) {
+		classId = CID_ELEM_BAR;
+	    } else if (strcmp(arg, "line") == 0) {
+		classId = CID_ELEM_LINE;
+	    } else {
+		Tcl_AppendResult(graphPtr->interp, "unknown pen type \"",
+		    arg, "\" specified", (char *)NULL);
+		return NULL;
+	    }
+	}
+    }
+    classId = CID_ELEM_LINE;
+    hPtr = Blt_CreateHashEntry(&graphPtr->penTable, penName, &isNew);
+    if (!isNew) {
+	penPtr = Blt_GetHashValue(hPtr);
+	if ((penPtr->flags & DELETE_PENDING) == 0) {
+	    Tcl_AppendResult(graphPtr->interp, "pen \"", penName,
+		"\" already exists in \"", Tk_PathName(graphPtr->tkwin), "\"",
+		(char *)NULL);
+	    return NULL;
+	}
+	if (penPtr->classId != classId) {
+	    Tcl_AppendResult(graphPtr->interp, "pen \"", penName,
+		"\" in-use: can't change pen type from \"", 
+		Blt_GraphClassName(penPtr->classId), "\" to \"", 
+		Blt_GraphClassName(classId), "\"", (char *)NULL);
+	    return NULL;
+	}
+	penPtr->flags &= ~DELETE_PENDING; /* Undelete the pen. */
+    } else {
+	if (classId == CID_ELEM_BAR) {
+	    penPtr = Blt_BarPen(penName);
+	} else {
+	    penPtr = Blt_LinePen(penName);
+	}
+	penPtr->classId = classId;
+	penPtr->hashPtr = hPtr;
+	penPtr->graphPtr = graphPtr;
+	Blt_SetHashValue(hPtr, penPtr);
+    }
+    configFlags = (penPtr->flags & (ACTIVE_PEN | NORMAL_PEN));
+    if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin,
+	    penPtr->name, "Pen", penPtr->configSpecs, objc, objv,
+	    (char *)penPtr, configFlags) != TCL_OK) {
+	if (isNew) {
+	    DestroyPen(penPtr);
+	}
+	return NULL;
+    }
+    (*penPtr->configProc) (graphPtr, penPtr);
+    return penPtr;
+}
+
+int
+Blt_GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
+		  ClassId classId, Pen **penPtrPtr)
+{
+    Blt_HashEntry *hPtr;
+    Pen *penPtr;
+    const char *name;
+    
+    penPtr = NULL;
+    name = Tcl_GetString(objPtr);
+    hPtr = Blt_FindHashEntry(&graphPtr->penTable, name);
+    if (hPtr != NULL) {
+	penPtr = Blt_GetHashValue(hPtr);
+	if (penPtr->flags & DELETE_PENDING) {
+	    penPtr = NULL;
+	}
+    }
+    if (penPtr == NULL) {
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "can't find pen \"", name, "\" in \"", 
+		Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
+	}
+	return TCL_ERROR;
+    }
+    classId = CID_ELEM_LINE;
+    if (penPtr->classId != classId) {
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "pen \"", name, 
+		"\" is the wrong type (is \"", 
+		Blt_GraphClassName(penPtr->classId), "\"", ", wanted \"", 
+		Blt_GraphClassName(classId), "\")", (char *)NULL);
+	}
+	return TCL_ERROR;
+    }
+    penPtr->refCount++;
+    *penPtrPtr = penPtr;
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DestroyPens --
+ *
+ *	Release memory and resources allocated for the style.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Everything associated with the pen style is freed up.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DestroyPens(Graph *graphPtr)
+{
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch iter;
+
+    for (hPtr = Blt_FirstHashEntry(&graphPtr->penTable, &iter);
+	hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	Pen *penPtr;
+
+	penPtr = Blt_GetHashValue(hPtr);
+	penPtr->hashPtr = NULL;
+	DestroyPen(penPtr);
+    }
+    Blt_DeleteHashTable(&graphPtr->penTable);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CgetOp --
+ *
+ *	Queries axis attributes (font, line width, label, etc).
+ *
+ * Results:
+ *	A standard TCL result.  If querying configuration values,
+ *	interp->result will contain the results.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static int
+CgetOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    Pen *penPtr;
+    unsigned int configFlags;
+
+    if (GetPenFromObj(interp, graphPtr, objv[3], &penPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    configFlags = (penPtr->flags & (ACTIVE_PEN | NORMAL_PEN));
+    return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, 
+	penPtr->configSpecs, (char *)penPtr, objv[4], configFlags);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureOp --
+ *
+ *	Queries or resets pen attributes (font, line width, color, etc).
+ *
+ * Results:
+ *	A standard TCL result.  If querying configuration values,
+ *	interp->result will contain the results.
+ *
+ * Side Effects:
+ *	Pen resources are possibly allocated (GC, font).
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ConfigureOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    Pen *penPtr;
+    int nNames, nOpts;
+    int redraw;
+    Tcl_Obj *const *options;
+    int i;
+
+    /* Figure out where the option value pairs begin */
+    objc -= 3;
+    objv += 3;
+    for (i = 0; i < objc; i++) {
+	char *string;
+
+	string = Tcl_GetString(objv[i]);
+	if (string[0] == '-') {
+	    break;
+	}
+	if (GetPenFromObj(interp, graphPtr, objv[i], &penPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    nNames = i;			/* Number of pen names specified */
+    nOpts = objc - i;		/* Number of options specified */
+    options = objv + i;		/* Start of options in objv  */
+
+    redraw = 0;
+    for (i = 0; i < nNames; i++) {
+    int flags;
+
+	if (GetPenFromObj(interp, graphPtr, objv[i], &penPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flags = BLT_CONFIG_OBJV_ONLY | (penPtr->flags&(ACTIVE_PEN|NORMAL_PEN));
+	if (nOpts == 0) {
+	    return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, 
+		penPtr->configSpecs, (char *)penPtr, (Tcl_Obj *)NULL, flags);
+	} else if (nOpts == 1) {
+	    return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, 
+		    penPtr->configSpecs, (char *)penPtr, options[0], flags);
+	}
+	if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, 
+		penPtr->configSpecs, nOpts, options, (char *)penPtr, flags) 
+		!= TCL_OK) {
+	    break;
+	}
+	(*penPtr->configProc) (graphPtr, penPtr);
+	if (penPtr->refCount > 0) {
+	    redraw++;
+	}
+    }
+    if (redraw) {
+	graphPtr->flags |= CACHE_DIRTY;
+	Blt_EventuallyRedrawGraph(graphPtr);
+    }
+    if (i < nNames) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateOp --
+ *
+ *	Adds a new penstyle to the graph.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+CreateOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    Pen *penPtr;
+
+    penPtr = Blt_CreatePen(graphPtr, Tcl_GetString(objv[3]), graphPtr->classId,
+	objc - 4, objv + 4);
+    if (penPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, objv[3]);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DeleteOp --
+ *
+ *	Delete the given pen.
+ *
+ * Results:
+ *	Always returns TCL_OK.  The interp->result field is a list of the
+ *	graph axis limits.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+/*ARGSUSED*/
+static int
+DeleteOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    int i;
+
+    for (i = 3; i < objc; i++) {
+	Pen *penPtr;
+
+	if (GetPenFromObj(interp, graphPtr, objv[i], &penPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (penPtr->flags & DELETE_PENDING) {
+	    Tcl_AppendResult(interp, "can't find pen \"", 
+		Tcl_GetString(objv[i]), "\" in \"", 
+		Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	penPtr->flags |= DELETE_PENDING;
+	if (penPtr->refCount == 0) {
+	    DestroyPen(penPtr);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NamesOp --
+ *
+ *	Return a list of the names of all the axes.
+ *
+ * Results:
+ *	Returns a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+NamesOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if (objc == 3) {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch iter;
+
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->penTable, &iter);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	    Pen *penPtr;
+
+	    penPtr = Blt_GetHashValue(hPtr);
+	    if ((penPtr->flags & DELETE_PENDING) == 0) {
+		Tcl_ListObjAppendElement(interp, listObjPtr, 
+			Tcl_NewStringObj(penPtr->name, -1));
+	    }
+	}
+    } else {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch iter;
+
+	for (hPtr = Blt_FirstHashEntry(&graphPtr->penTable, &iter);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) {
+	    Pen *penPtr;
+
+	    penPtr = Blt_GetHashValue(hPtr);
+	    if ((penPtr->flags & DELETE_PENDING) == 0) {
+		int i;
+
+		for (i = 3; i < objc; i++) {
+		    char *pattern;
+
+		    pattern = Tcl_GetString(objv[i]);
+		    if (Tcl_StringMatch(penPtr->name, pattern)) {
+			Tcl_ListObjAppendElement(interp, listObjPtr, 
+				Tcl_NewStringObj(penPtr->name, -1));
+			break;
+		    }
+		}
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TypeOp --
+ *
+ *	Return the type of pen.
+ *
+ * Results:
+ *	Returns a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+TypeOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv)
+{
+    Pen *penPtr;
+
+    if (GetPenFromObj(interp, graphPtr, objv[3], &penPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Tcl_SetStringObj(Tcl_GetObjResult(interp), 
+		     Blt_GraphClassName(penPtr->classId), -1);
+    return TCL_OK;
+}
+
+static Blt_OpSpec penOps[] =
+{
+    {"cget", 2, CgetOp, 5, 5, "penName option",},
+    {"configure", 2, ConfigureOp, 4, 0,
+	"penName ?penName?... ?option value?...",},
+    {"create", 2, CreateOp, 4, 0, "penName ?option value?...",},
+    {"delete", 2, DeleteOp, 3, 0, "?penName?...",},
+    {"names", 1, NamesOp, 3, 0, "?pattern?...",},
+    {"type", 1, TypeOp, 4, 4, "penName",},
+};
+static int nPenOps = sizeof(penOps) / sizeof(Blt_OpSpec);
+
+int
+Blt_PenOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    GraphPenProc *proc;
+
+    proc = Blt_GetOpFromObj(interp, nPenOps, penOps, BLT_OP_ARG2, 
+	objc, objv, 0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    return (*proc) (interp, graphPtr, objc, objv);
+}
diff --git a/tlt3.0/bltGrPs.c b/tlt3.0/bltGrPs.c
new file mode 100644
index 0000000..eae049b
--- /dev/null
+++ b/tlt3.0/bltGrPs.c
@@ -0,0 +1,709 @@
+
+/*
+ * bltGrPs.c --
+ *
+ * This module implements the "postscript" operation for BLT graph widget.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PostScript routines to print a graph
+ *
+ *---------------------------------------------------------------------------
+ */
+#include <stdarg.h>
+#include <time.h>
+#include <X11/Xutil.h>
+
+#include "bltInt.h"
+#include "bltGraph.h"
+#include "bltOp.h"
+#include "bltPsInt.h"
+
+#define MM_INCH		25.4
+#define PICA_INCH	72.0
+
+typedef int (GraphPsProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+static Blt_OptionParseProc ObjToPicaProc;
+static Blt_OptionPrintProc PicaToObjProc;
+static Blt_CustomOption picaOption =
+{
+    ObjToPicaProc, PicaToObjProc, NULL, (ClientData)0,
+};
+
+static Blt_OptionParseProc ObjToPad;
+static Blt_OptionPrintProc PadToObj;
+static Blt_CustomOption padOption =
+{
+    ObjToPad, PadToObj, NULL, (ClientData)0,
+};
+
+#define DEF_PS_CENTER		"yes"
+#define DEF_PS_COLOR_MAP	(char *)NULL
+#define DEF_PS_GREYSCALE	"no"
+#define DEF_PS_DECORATIONS	"no"
+#define DEF_PS_FONT_MAP		(char *)NULL
+#define DEF_PS_FOOTER		"no"
+#define DEF_PS_LEVEL		"2"
+#define DEF_PS_HEIGHT		"0"
+#define DEF_PS_LANDSCAPE	"no"
+#define DEF_PS_PADX		"1.0i"
+#define DEF_PS_PADY		"1.0i"
+#define DEF_PS_PAPERHEIGHT	"11.0i"
+#define DEF_PS_PAPERWIDTH	"8.5i"
+#define DEF_PS_WIDTH		"0"
+#define DEF_PS_COMMENTS		""
+
+static Blt_ConfigSpec configSpecs[] =
+{
+    {BLT_CONFIG_BITMASK, "-center", "center", "Center", DEF_PS_CENTER, 
+	Blt_Offset(PageSetup, flags), BLT_CONFIG_DONT_SET_DEFAULT, 
+        (Blt_CustomOption *)PS_CENTER},
+    {BLT_CONFIG_STRING, "-colormap", "colorMap", "ColorMap",
+	DEF_PS_COLOR_MAP, Blt_Offset(PageSetup, colorVarName),
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_LIST,    "-comments", "comments", "Comments",
+	DEF_PS_COMMENTS, Blt_Offset(PageSetup, comments), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_BITMASK, "-decorations", "decorations", "Decorations",
+	DEF_PS_DECORATIONS, Blt_Offset(PageSetup, flags),
+	BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)PS_DECORATIONS},
+    {BLT_CONFIG_STRING, "-fontmap", "fontMap", "FontMap",
+	DEF_PS_FONT_MAP, Blt_Offset(PageSetup, fontVarName),
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_BITMASK, "-footer", "footer", "Footer", DEF_PS_FOOTER, 
+        Blt_Offset(PageSetup, flags), BLT_CONFIG_DONT_SET_DEFAULT,
+        (Blt_CustomOption *)PS_FOOTER},
+    {BLT_CONFIG_BITMASK, "-greyscale", "greyscale", "Greyscale",
+	DEF_PS_GREYSCALE, Blt_Offset(PageSetup, flags),
+	BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)PS_GREYSCALE},
+    {BLT_CONFIG_CUSTOM, "-height", "height", "Height", DEF_PS_HEIGHT, 
+	Blt_Offset(PageSetup, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT,
+	&picaOption},
+    {BLT_CONFIG_BITMASK, "-landscape", "landscape", "Landscape",
+	DEF_PS_LANDSCAPE, Blt_Offset(PageSetup, flags),
+	BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)PS_LANDSCAPE},
+    {BLT_CONFIG_INT_POS, "-level", "level", "Level", DEF_PS_LEVEL, 
+	Blt_Offset(PageSetup, level), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_CUSTOM, "-padx", "padX", "PadX", DEF_PS_PADX, 
+	Blt_Offset(PageSetup, xPad), 0, &padOption},
+    {BLT_CONFIG_CUSTOM, "-pady", "padY", "PadY", DEF_PS_PADY, 
+	Blt_Offset(PageSetup, yPad), 0, &padOption},
+    {BLT_CONFIG_CUSTOM, "-paperheight", "paperHeight", "PaperHeight",
+	DEF_PS_PAPERHEIGHT, Blt_Offset(PageSetup, reqPaperHeight), 0,
+	&picaOption},
+    {BLT_CONFIG_CUSTOM, "-paperwidth", "paperWidth", "PaperWidth",
+	DEF_PS_PAPERWIDTH, Blt_Offset(PageSetup, reqPaperWidth), 0,
+	&picaOption},
+    {BLT_CONFIG_CUSTOM, "-width", "width", "Width", DEF_PS_WIDTH, 
+        Blt_Offset(PageSetup, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT, 
+	&picaOption},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToPicaProc --
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToPicaProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Interpreter to send results back
+					 * to */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* New value. */
+    char *widgRec,			/* Widget record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    int *picaPtr = (int *)(widgRec + offset);
+
+    return Blt_Ps_GetPicaFromObj(interp, objPtr, picaPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PicaToObj --
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+PicaToObjProc(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Not used. */
+    Tk_Window tkwin,			/* Not used. */
+    char *widgRec,			/* PostScript structure record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    int pica = *(int *)(widgRec + offset);
+
+    return Tcl_NewIntObj(pica);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToPad --
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToPad(
+    ClientData clientData,		/* Not used. */
+    Tcl_Interp *interp,			/* Interpreter to send results back
+					 * to */
+    Tk_Window tkwin,			/* Not used. */
+    Tcl_Obj *objPtr,			/* New value. */
+    char *widgRec,			/* Widget record */
+    int offset,				/* Offset to field in structure */
+    int flags)				/* Not used. */
+{
+    Blt_Pad *padPtr = (Blt_Pad *) (widgRec + offset);
+
+    return Blt_Ps_GetPadFromObj(interp, objPtr, padPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PadToObj --
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Tcl_Obj *
+PadToObj(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,
+    Tk_Window tkwin,		/* Not used. */
+    char *widgRec,		/* PostScript structure record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    Blt_Pad *padPtr = (Blt_Pad *)(widgRec + offset);
+    Tcl_Obj *objPtr, *listObjPtr;
+	    
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    objPtr = Tcl_NewIntObj(padPtr->side1);
+    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+    objPtr = Tcl_NewIntObj(padPtr->side2);
+    Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+    return listObjPtr;
+}
+
+static void
+AddComments(Blt_Ps ps, const char **comments)
+{
+    const char **p;
+
+    for (p = comments; *p != NULL; p += 2) {
+	if (*(p+1) == NULL) {
+	    break;
+	}
+	Blt_Ps_Format(ps, "%% %s: %s\n", *p, *(p+1));
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PostScriptPreamble
+ *
+ *    	The PostScript preamble calculates the needed translation and scaling
+ *    	to make X11 coordinates compatible with PostScript.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+PostScriptPreamble(Graph *graphPtr, const char *fileName, Blt_Ps ps)
+{
+    PageSetup *setupPtr = graphPtr->pageSetup;
+    time_t ticks;
+    char date[200];			/* Holds the date string from ctime() */
+    char *newline;
+
+    if (fileName == NULL) {
+	fileName = Tk_PathName(graphPtr->tkwin);
+    }
+    Blt_Ps_Append(ps, "%!PS-Adobe-3.0 EPSF-3.0\n");
+
+    /*
+     * The "BoundingBox" comment is required for EPS files. The box
+     * coordinates are integers, so we need round away from the center of the
+     * box.
+     */
+    Blt_Ps_Format(ps, "%%%%BoundingBox: %d %d %d %d\n",
+	setupPtr->left, setupPtr->paperHeight - setupPtr->top,
+	setupPtr->right, setupPtr->paperHeight - setupPtr->bottom);
+	
+    Blt_Ps_Append(ps, "%%Pages: 0\n");
+
+    Blt_Ps_Format(ps, "%%%%Creator: (%s %s %s)\n", 
+		  PACKAGE_NAME, PACKAGE_VERSION, Tk_Class(graphPtr->tkwin));
+
+    ticks = time((time_t *) NULL);
+    strcpy(date, ctime(&ticks));
+    newline = date + strlen(date) - 1;
+    if (*newline == '\n') {
+	*newline = '\0';
+    }
+    Blt_Ps_Format(ps, "%%%%CreationDate: (%s)\n", date);
+    Blt_Ps_Format(ps, "%%%%Title: (%s)\n", fileName);
+    Blt_Ps_Append(ps, "%%DocumentData: Clean7Bit\n");
+    if (setupPtr->flags & PS_LANDSCAPE) {
+	Blt_Ps_Append(ps, "%%Orientation: Landscape\n");
+    } else {
+	Blt_Ps_Append(ps, "%%Orientation: Portrait\n");
+    }
+    Blt_Ps_Append(ps, "%%DocumentNeededResources: font Helvetica Courier\n");
+    AddComments(ps, setupPtr->comments);
+    Blt_Ps_Append(ps, "%%EndComments\n\n");
+    if (Blt_Ps_IncludeFile(graphPtr->interp, ps, "bltGraph.pro") != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (setupPtr->flags & PS_FOOTER) {
+	const char *who;
+
+	who = getenv("LOGNAME");
+	if (who == NULL) {
+	    who = "???";
+	}
+	Blt_Ps_VarAppend(ps,
+	    "8 /Helvetica SetFont\n",
+	    "10 30 moveto\n",
+	    "(Date: ", date, ") show\n",
+	    "10 20 moveto\n",
+	    "(File: ", fileName, ") show\n",
+	    "10 10 moveto\n",
+	    "(Created by: ", who, "@", Tcl_GetHostName(), ") show\n",
+	    "0 0 moveto\n",
+	    (char *)NULL);
+    }
+    /*
+     * Set the conversion from PostScript to X11 coordinates.  Scale pica to
+     * pixels and flip the y-axis (the origin is the upperleft corner).
+     */
+    Blt_Ps_VarAppend(ps,
+	"% Transform coordinate system to use X11 coordinates\n\n",
+	"% 1. Flip y-axis over by reversing the scale,\n",
+	"% 2. Translate the origin to the other side of the page,\n",
+	"%    making the origin the upper left corner\n", (char *)NULL);
+    Blt_Ps_Format(ps, "1 -1 scale\n");
+    /* Papersize is in pixels.  Translate the new origin *after* changing the
+     * scale. */
+    Blt_Ps_Format(ps, "0 %d translate\n\n", -setupPtr->paperHeight);
+    Blt_Ps_VarAppend(ps, "% User defined page layout\n\n",
+		     "% Set color level\n", (char *)NULL);
+    Blt_Ps_Format(ps, "%% Set origin\n%d %d translate\n\n",
+	setupPtr->left, setupPtr->bottom);
+    if (setupPtr->flags & PS_LANDSCAPE) {
+	Blt_Ps_Format(ps,
+	    "%% Landscape orientation\n0 %g translate\n-90 rotate\n",
+	    ((double)graphPtr->width * setupPtr->scale));
+    }
+    Blt_Ps_Append(ps, "\n%%EndSetup\n\n");
+    return TCL_OK;
+}
+
+
+static void
+MarginsToPostScript(Graph *graphPtr, Blt_Ps ps)
+{
+    PageSetup *setupPtr = graphPtr->pageSetup;
+    XRectangle margin[4];
+
+    margin[0].x = margin[0].y = margin[3].x = margin[1].x = 0;
+    margin[0].width = margin[3].width = graphPtr->width;
+    margin[0].height = graphPtr->top;
+    margin[3].y = graphPtr->bottom;
+    margin[3].height = graphPtr->height - graphPtr->bottom;
+    margin[2].y = margin[1].y = graphPtr->top;
+    margin[1].width = graphPtr->left;
+    margin[2].height = margin[1].height = graphPtr->bottom - graphPtr->top;
+    margin[2].x = graphPtr->right;
+    margin[2].width = graphPtr->width - graphPtr->right;
+
+    /* Clear the surrounding margins and clip the plotting surface */
+    if (setupPtr->flags & PS_DECORATIONS) {
+	Blt_Ps_XSetBackground(ps,Blt_BackgroundBorderColor(graphPtr->normalBg));
+    } else {
+	Blt_Ps_SetClearBackground(ps);
+    }
+    Blt_Ps_Append(ps, "% Margins\n");
+    Blt_Ps_XFillRectangles(ps, margin, 4);
+    
+    Blt_Ps_Append(ps, "% Interior 3D border\n");
+    /* Interior 3D border */
+    if (graphPtr->plotBW > 0) {
+	Tk_3DBorder border;
+	int x, y, w, h;
+
+	x = graphPtr->left - graphPtr->plotBW;
+	y = graphPtr->top - graphPtr->plotBW;
+	w = (graphPtr->right - graphPtr->left) + (2*graphPtr->plotBW);
+	h = (graphPtr->bottom - graphPtr->top) + (2*graphPtr->plotBW);
+	border = Blt_BackgroundBorder(graphPtr->normalBg);
+	Blt_Ps_Draw3DRectangle(ps, border, (double)x, (double)y, w, h,
+		graphPtr->plotBW, graphPtr->plotRelief);
+    }
+    if (Blt_Legend_Site(graphPtr) & LEGEND_MARGIN_MASK) {
+	/*
+	 * Print the legend if we're using a site which lies in one of the
+	 * margins (left, right, top, or bottom) of the graph.
+	 */
+	Blt_LegendToPostScript(graphPtr, ps);
+    }
+    if (graphPtr->title != NULL) {
+	Blt_Ps_Append(ps, "% Graph title\n");
+	Blt_Ps_DrawText(ps, graphPtr->title, &graphPtr->titleTextStyle, 
+		(double)graphPtr->titleX, (double)graphPtr->titleY);
+    }
+    Blt_AxesToPostScript(graphPtr, ps);
+}
+
+
+static int
+GraphToPostScript(Graph *graphPtr, const char *ident, Blt_Ps ps)
+{
+    int x, y, w, h;
+    int result;
+    PageSetup *setupPtr = graphPtr->pageSetup;
+
+    /*   
+     * We need to know how big a graph to print.  If the graph hasn't been drawn
+     * yet, the width and height will be 1.  Instead use the requested size of
+     * the widget.  The user can still override this with the -width and -height
+     * postscript options.
+     */
+    if (setupPtr->reqWidth > 0) {
+	graphPtr->width = setupPtr->reqWidth;
+    } else if (graphPtr->width < 2) {
+	graphPtr->width = Tk_ReqWidth(graphPtr->tkwin);
+    }
+    if (setupPtr->reqHeight > 0) {
+	graphPtr->height = setupPtr->reqHeight;
+    } else if (graphPtr->height < 2) {
+	graphPtr->height = Tk_ReqHeight(graphPtr->tkwin);
+    }
+    Blt_Ps_ComputeBoundingBox(setupPtr, graphPtr->width, graphPtr->height);
+    graphPtr->flags |= LAYOUT_NEEDED | RESET_WORLD;
+
+    /* Turn on PostScript measurements when computing the graph's layout. */
+    Blt_Ps_SetPrinting(ps, TRUE);
+    Blt_ReconfigureGraph(graphPtr);
+    Blt_MapGraph(graphPtr);
+
+    result = PostScriptPreamble(graphPtr, ident, ps);
+    if (result != TCL_OK) {
+	goto error;
+    }
+    /* Determine rectangle of the plotting area for the graph window */
+    x = graphPtr->left - graphPtr->plotBW;
+    y = graphPtr->top - graphPtr->plotBW;
+
+    w = (graphPtr->right - graphPtr->left + 1) + (2*graphPtr->plotBW);
+    h = (graphPtr->bottom - graphPtr->top + 1) + (2*graphPtr->plotBW);
+
+    Blt_Ps_XSetFont(ps, Blt_Ts_GetFont(graphPtr->titleTextStyle));
+    if (graphPtr->pageSetup->flags & PS_DECORATIONS) {
+	Blt_Ps_XSetBackground(ps, Blt_BackgroundBorderColor(graphPtr->plotBg));
+    } else {
+	Blt_Ps_SetClearBackground(ps);
+    }
+    Blt_Ps_XFillRectangle(ps, x, y, w, h);
+    Blt_Ps_Rectangle(ps, x, y, w, h);
+    Blt_Ps_Append(ps, "gsave clip\n\n");
+    /* Draw the grid, elements, and markers in the plotting area. */
+    Blt_GridsToPostScript(graphPtr, ps);
+    Blt_MarkersToPostScript(graphPtr, ps, TRUE);
+    if ((Blt_Legend_Site(graphPtr) & LEGEND_PLOTAREA_MASK) && 
+	(!Blt_Legend_IsRaised(graphPtr))) {
+	/* Print legend underneath elements and markers */
+	Blt_LegendToPostScript(graphPtr, ps);
+    }
+    Blt_AxisLimitsToPostScript(graphPtr, ps);
+    Blt_ElementsToPostScript(graphPtr, ps);
+    if ((Blt_Legend_Site(graphPtr) & LEGEND_PLOTAREA_MASK) && 
+	(Blt_Legend_IsRaised(graphPtr))) {
+	/* Print legend above elements (but not markers) */
+	Blt_LegendToPostScript(graphPtr, ps);
+    }
+    Blt_MarkersToPostScript(graphPtr, ps, FALSE);
+    Blt_ActiveElementsToPostScript(graphPtr, ps);
+    Blt_Ps_VarAppend(ps, "\n",
+	"% Unset clipping\n",
+	"grestore\n\n", (char *)NULL);
+    MarginsToPostScript(graphPtr, ps);
+    Blt_Ps_VarAppend(ps,
+	"showpage\n",
+	"%Trailer\n",
+	"grestore\n",
+	"end\n",
+	"%EOF\n", (char *)NULL);
+  error:
+    /* Reset height and width of graph window */
+    graphPtr->width = Tk_Width(graphPtr->tkwin);
+    graphPtr->height = Tk_Height(graphPtr->tkwin);
+    graphPtr->flags |= MAP_WORLD;
+    Blt_Ps_SetPrinting(ps, FALSE);
+    Blt_ReconfigureGraph(graphPtr);
+    Blt_MapGraph(graphPtr);
+    /*
+     * Redraw the graph in order to re-calculate the layout as soon as
+     * possible. This is in the case the crosshairs are active.
+     */
+    Blt_EventuallyRedrawGraph(graphPtr);
+    return result;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CgetOp --
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+CgetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    PageSetup *setupPtr = graphPtr->pageSetup;
+
+    if (Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs, 
+	(char *)setupPtr, objv[3], 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureOp --
+ *
+ *      This procedure is invoked to print the graph in a file.
+ *
+ * Results:
+ *      A standard TCL result.
+ *
+ * Side effects:
+ *      A new PostScript file is created.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ConfigureOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int flags = BLT_CONFIG_OBJV_ONLY;
+    PageSetup *setupPtr = graphPtr->pageSetup;
+
+    if (objc == 3) {
+	return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs,
+		(char *)setupPtr, (Tcl_Obj *)NULL, flags);
+    } else if (objc == 4) {
+	return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs,
+		(char *)setupPtr, objv[3], flags);
+    }
+    if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, 
+	    objc - 3, objv + 3, (char *)setupPtr, flags) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * OutputOp --
+ *
+ *      This procedure is invoked to print the graph in a file.
+ *
+ * Results:
+ *      Standard TCL result.  TCL_OK if plot was successfully printed, 
+ *      TCL_ERROR otherwise.
+ *
+ * Side effects:
+ *      A new PostScript file is created.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+OutputOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    const char *buffer;
+    PostScript *psPtr;
+    Tcl_Channel channel;
+    const char *fileName;		/* Name of file to write PostScript
+					 * output If NULL, output is returned
+					 * via interp->result. */
+    int length;
+
+    fileName = NULL;			/* Used to identify the output sink. */
+    channel = NULL;
+    if (objc > 3) {
+	fileName = Tcl_GetString(objv[3]);
+	if (fileName[0] != '-') {
+	    objv++, objc--;		/* First argument is the file name. */
+	    channel = Tcl_OpenFileChannel(interp, fileName, "w", 0666);
+	    if (channel == NULL) {
+		return TCL_ERROR;
+	    }
+	    if (Tcl_SetChannelOption(interp, channel, "-translation", "binary") 
+		!= TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+    }
+
+    psPtr = Blt_Ps_Create(graphPtr->interp, graphPtr->pageSetup);
+    if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, 
+	objc - 3, objv + 3, (char *)graphPtr->pageSetup, BLT_CONFIG_OBJV_ONLY) 
+	!= TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (GraphToPostScript(graphPtr, fileName, psPtr) != TCL_OK) {
+	goto error;
+    }
+    buffer = Blt_Ps_GetValue(psPtr, &length);
+    if (channel != NULL) {
+	int nBytes;
+	/*
+	 * If a file name was given, write the results to that file
+	 */
+	nBytes = Tcl_Write(channel, buffer, length);
+	if (nBytes < 0) {
+	    Tcl_AppendResult(interp, "error writing file \"", fileName, "\": ",
+		Tcl_PosixError(interp), (char *)NULL);
+	    goto error;
+	}
+        Tcl_Close(interp, channel);
+    } else {
+	Tcl_SetStringObj(Tcl_GetObjResult(interp), buffer, length);
+    }
+    Blt_Ps_Free(psPtr);
+    return TCL_OK;
+
+  error:
+    if (channel != NULL) {
+        Tcl_Close(interp, channel);
+    }
+    Blt_Ps_Free(psPtr);
+    return TCL_ERROR;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_CreatePostScript --
+ *
+ *      Creates a postscript structure.
+ *
+ * Results:
+ *      Always TCL_OK.
+ *
+ * Side effects:
+ *      A new PostScript structure is created.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_CreatePageSetup(Graph *graphPtr)
+{
+    PageSetup *setupPtr;
+
+    setupPtr = calloc(1, sizeof(PostScript));
+    setupPtr->flags = PS_CENTER;
+    setupPtr->level = 2;
+    graphPtr->pageSetup = setupPtr;
+
+    if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin,
+	    "postscript", "Postscript", configSpecs, 0, (Tcl_Obj **)NULL,
+	    (char *)setupPtr, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_PostScriptOp --
+ *
+ *	This procedure is invoked to process the TCL command that corresponds
+ *	to a widget managed by this module.  See the user documentation for
+ *	details on what it does.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_OpSpec psOps[] =
+{
+    {"cget",      2, CgetOp,      4, 4, "option",},
+    {"configure", 2, ConfigureOp, 3, 0, "?option value?...",},
+    {"output",    1, OutputOp,    3, 0, "?fileName? ?option value?...",},
+};
+
+static int nPsOps = sizeof(psOps) / sizeof(Blt_OpSpec);
+
+int
+Blt_PostScriptOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv)
+{
+    GraphPsProc *proc;
+    int result;
+
+    proc = Blt_GetOpFromObj(interp, nPsOps, psOps, BLT_OP_ARG2, objc, objv, 0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    result = (*proc) (graphPtr, interp, objc, objv);
+    return result;
+}
+
+void
+Blt_DestroyPageSetup(Graph *graphPtr)
+{
+    if (graphPtr->pageSetup != NULL) {
+	Blt_FreeOptions(configSpecs, (char *)graphPtr->pageSetup, 
+		graphPtr->display, 0);
+	free(graphPtr->pageSetup);
+    }
+}
diff --git a/tlt3.0/bltGraph.c b/tlt3.0/bltGraph.c
new file mode 100644
index 0000000..4959b79
--- /dev/null
+++ b/tlt3.0/bltGraph.c
@@ -0,0 +1,1762 @@
+
+/*
+ * bltGraph.c --
+ *
+ * This module implements a graph widget for the BLT toolkit.
+ *
+ * The graph widget was created by Sani Nassif and George Howlett.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * To do:
+ *
+ * 2) Update manual pages.
+ *
+ * 3) Update comments.
+ *
+ * 5) Surface, contour, and flow graphs
+ *
+ * 7) Arrows for line markers
+ *
+ */
+
+#include <assert.h>
+#include <X11/Xutil.h>
+
+#include "bltInt.h"
+#include "bltMath.h"
+#include "bltGraph.h"
+#include "bltOp.h"
+#include "bltGrElem.h"
+#include "bltSwitch.h"
+
+typedef int (GraphCmdProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+/* 
+ * Objects in the graph have their own class names.  These class names are
+ * used for the resource database and bindings.  Example.
+ *
+ *	option add *X.title "X Axis Title" widgetDefault
+ *	.g marker bind BitmapMarker <Enter> { ... }
+ *
+ * The option database trick is performed by creating a temporary window when
+ * an object is initially configured.  The class name of the temporary window
+ * will be from the list below.
+ */
+static const char *objectClassNames[] = {
+    "unknown",
+    "XAxis", 
+    "YAxis",
+    "BarElement", 
+    "ContourElement",
+    "LineElement", 
+    "StripElement", 
+    "BitmapMarker", 
+    "ImageMarker", 
+    "LineMarker", 
+    "PolygonMarker",
+    "TextMarker", 
+    "WindowMarker",
+};
+
+extern Blt_CustomOption bltLinePenOption;
+extern Blt_CustomOption bltBarPenOption;
+extern Blt_CustomOption bltBarModeOption;
+
+#define DEF_GRAPH_ASPECT_RATIO		"0.0"
+#define DEF_GRAPH_BAR_BASELINE		"0.0"
+#define DEF_GRAPH_BAR_MODE		"normal"
+#define DEF_GRAPH_BAR_WIDTH		"0.9"
+#define DEF_GRAPH_BACKGROUND		STD_NORMAL_BACKGROUND
+#define DEF_GRAPH_BORDERWIDTH		STD_BORDERWIDTH
+#define DEF_GRAPH_BUFFER_ELEMENTS	"yes"
+#define DEF_GRAPH_BUFFER_GRAPH		"1"
+#define DEF_GRAPH_CURSOR		"crosshair"
+#define DEF_GRAPH_FONT			"{Sans Serif} 12"
+#define DEF_GRAPH_HALO			"2m"
+#define DEF_GRAPH_HALO_BAR		"0.1i"
+#define DEF_GRAPH_HEIGHT		"4i"
+#define DEF_GRAPH_HIGHLIGHT_BACKGROUND	STD_NORMAL_BACKGROUND
+#define DEF_GRAPH_HIGHLIGHT_COLOR	RGB_BLACK
+#define DEF_GRAPH_HIGHLIGHT_WIDTH	"2"
+#define DEF_GRAPH_INVERT_XY		"0"
+#define DEF_GRAPH_JUSTIFY		"center"
+#define DEF_GRAPH_MARGIN		"0"
+#define DEF_GRAPH_MARGIN_VAR		(char *)NULL
+#define DEF_GRAPH_PLOT_BACKGROUND	RGB_WHITE
+#define DEF_GRAPH_PLOT_BORDERWIDTH	"1"
+#define DEF_GRAPH_PLOT_PADX		"0"
+#define DEF_GRAPH_PLOT_PADY		"0"
+#define DEF_GRAPH_PLOT_RELIEF		"solid"
+#define DEF_GRAPH_RELIEF		"flat"
+#define DEF_GRAPH_SHOW_VALUES		"no"
+#define DEF_GRAPH_STACK_AXES		"no"
+#define DEF_GRAPH_TAKE_FOCUS		""
+#define DEF_GRAPH_TITLE			(char *)NULL
+#define DEF_GRAPH_TITLE_COLOR		STD_NORMAL_FOREGROUND
+#define DEF_GRAPH_WIDTH			"5i"
+#define DEF_GRAPH_DATA			(char *)NULL
+#define DEF_GRAPH_DATA_COMMAND		(char *)NULL
+#define DEF_GRAPH_UNMAP_HIDDEN_ELEMENTS	"0"
+
+static Blt_ConfigSpec configSpecs[] =
+{
+    {BLT_CONFIG_FLOAT, "-aspect", "aspect", "Aspect", DEF_GRAPH_ASPECT_RATIO, 
+	Blt_Offset(Graph, aspect), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BACKGROUND, "-background", "background", "Background",
+	DEF_GRAPH_BACKGROUND, Blt_Offset(Graph, normalBg), 0},
+    {BLT_CONFIG_CUSTOM, "-barmode", "barMode", "BarMode", DEF_GRAPH_BAR_MODE, 
+	Blt_Offset(Graph, mode), BLT_CONFIG_DONT_SET_DEFAULT, 
+	&bltBarModeOption},
+    {BLT_CONFIG_FLOAT, "-barwidth", "barWidth", "BarWidth", 
+	DEF_GRAPH_BAR_WIDTH, Blt_Offset(Graph, barWidth), 0},
+    {BLT_CONFIG_FLOAT, "-baseline", "baseline", "Baseline",
+	DEF_GRAPH_BAR_BASELINE, Blt_Offset(Graph, baseline), 0},
+    {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL,0, 0},
+    {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_SYNONYM, "-bm", "bottomMargin", (char *)NULL, (char *)NULL, 
+	0, 0},
+    {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth",
+	DEF_GRAPH_BORDERWIDTH, Blt_Offset(Graph, borderWidth),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-bottommargin", "bottomMargin", "Margin",
+	DEF_GRAPH_MARGIN, Blt_Offset(Graph, bottomMargin.reqSize), 0},
+    {BLT_CONFIG_STRING, "-bottomvariable", "bottomVariable", "BottomVariable",
+	DEF_GRAPH_MARGIN_VAR, Blt_Offset(Graph, bottomMargin.varName), 
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_BOOLEAN, "-bufferelements", "bufferElements", "BufferElements",
+	DEF_GRAPH_BUFFER_ELEMENTS, Blt_Offset(Graph, backingStore),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BOOLEAN, "-buffergraph", "bufferGraph", "BufferGraph",
+	DEF_GRAPH_BUFFER_GRAPH, Blt_Offset(Graph, doubleBuffer),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
+	DEF_GRAPH_CURSOR, Blt_Offset(Graph, cursor), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_STRING, "-data", "data", "Data", 
+        (char *)NULL, Blt_Offset(Graph, data), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-datacommand", "dataCommand", "DataCommand", 
+        (char *)NULL, Blt_Offset(Graph, dataCmd), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_FONT, "-font", "font", "Font",
+	DEF_GRAPH_FONT, Blt_Offset(Graph, titleTextStyle.font), 0},
+    {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
+	DEF_GRAPH_TITLE_COLOR, Blt_Offset(Graph, titleTextStyle.color), 0},
+    {BLT_CONFIG_PIXELS_NNEG, "-halo", "halo", "Halo", DEF_GRAPH_HALO, 
+	Blt_Offset(Graph, halo), 0},
+    {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_GRAPH_HEIGHT, 
+	Blt_Offset(Graph, reqHeight), 0},
+    {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
+	"HighlightBackground", DEF_GRAPH_HIGHLIGHT_BACKGROUND, 
+	Blt_Offset(Graph, highlightBgColor), 0},
+    {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
+	DEF_GRAPH_HIGHLIGHT_COLOR, Blt_Offset(Graph, highlightColor), 0},
+    {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness",
+	"HighlightThickness", DEF_GRAPH_HIGHLIGHT_WIDTH, 
+	Blt_Offset(Graph, highlightWidth), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_BITMASK, "-unmaphiddenelements", "unmapHiddenElements", 
+	"UnmapHiddenElements", DEF_GRAPH_UNMAP_HIDDEN_ELEMENTS, 
+	Blt_Offset(Graph, flags), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT, 
+	(Blt_CustomOption *)UNMAP_HIDDEN},
+    {BLT_CONFIG_BOOLEAN, "-invertxy", "invertXY", "InvertXY", 
+	DEF_GRAPH_INVERT_XY, Blt_Offset(Graph, inverted),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify", DEF_GRAPH_JUSTIFY, 
+	Blt_Offset(Graph, titleTextStyle.justify), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-leftmargin", "leftMargin", "Margin", 
+	DEF_GRAPH_MARGIN, Blt_Offset(Graph, leftMargin.reqSize), 
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-leftvariable", "leftVariable", "LeftVariable",
+	DEF_GRAPH_MARGIN_VAR, Blt_Offset(Graph, leftMargin.varName), 
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-lm", "leftMargin", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_BACKGROUND, "-plotbackground", "plotBackground", "Background",
+	DEF_GRAPH_PLOT_BACKGROUND, Blt_Offset(Graph, plotBg), 0},
+    {BLT_CONFIG_PIXELS_NNEG, "-plotborderwidth", "plotBorderWidth", 
+        "PlotBorderWidth", DEF_GRAPH_PLOT_BORDERWIDTH, 
+	Blt_Offset(Graph, plotBW), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PAD, "-plotpadx", "plotPadX", "PlotPad", DEF_GRAPH_PLOT_PADX, 
+	Blt_Offset(Graph, xPad), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PAD, "-plotpady", "plotPadY", "PlotPad", DEF_GRAPH_PLOT_PADY, 
+	Blt_Offset(Graph, yPad), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_RELIEF, "-plotrelief", "plotRelief", "Relief", 
+	DEF_GRAPH_PLOT_RELIEF, Blt_Offset(Graph, plotRelief),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_GRAPH_RELIEF, 
+	Blt_Offset(Graph, relief), BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-rightmargin", "rightMargin", "Margin",
+	DEF_GRAPH_MARGIN, Blt_Offset(Graph, rightMargin.reqSize),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-rightvariable", "rightVariable", "RightVariable",
+	DEF_GRAPH_MARGIN_VAR, Blt_Offset(Graph, rightMargin.varName), 
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-rm", "rightMargin", (char *)NULL, (char *)NULL, 0,0},
+    {BLT_CONFIG_BOOLEAN, "-stackaxes", "stackAxes", "StackAxes", 
+	DEF_GRAPH_STACK_AXES, Blt_Offset(Graph, stackAxes),
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
+	DEF_GRAPH_TAKE_FOCUS, Blt_Offset(Graph, takeFocus), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_STRING, "-title", "title", "Title", DEF_GRAPH_TITLE, 
+	Blt_Offset(Graph, title), BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_SYNONYM, "-tm", "topMargin", (char *)NULL, (char *)NULL, 0, 0},
+    {BLT_CONFIG_PIXELS_NNEG, "-topmargin", "topMargin", "Margin", 
+	DEF_GRAPH_MARGIN, Blt_Offset(Graph, topMargin.reqSize), 
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_STRING, "-topvariable", "topVariable", "TopVariable",
+	DEF_GRAPH_MARGIN_VAR, Blt_Offset(Graph, topMargin.varName), 
+	BLT_CONFIG_NULL_OK},
+    {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_GRAPH_WIDTH, 
+	Blt_Offset(Graph, reqWidth), 0},
+    {BLT_CONFIG_PIXELS_NNEG, "-plotwidth", "plotWidth", "PlotWidth", 
+	(char *)NULL, Blt_Offset(Graph, reqPlotWidth), 
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_PIXELS_NNEG, "-plotheight", "plotHeight", "PlotHeight", 
+	(char *)NULL, Blt_Offset(Graph, reqPlotHeight), 
+	BLT_CONFIG_DONT_SET_DEFAULT},
+    {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+static Tcl_IdleProc DisplayGraph;
+static Tcl_FreeProc DestroyGraph;
+static Tk_EventProc GraphEventProc;
+Tcl_ObjCmdProc Blt_GraphInstCmdProc;
+
+static Blt_BindPickProc PickEntry;
+static Tcl_ObjCmdProc BarchartCmd;
+static Tcl_ObjCmdProc GraphCmd;
+static Tcl_CmdDeleteProc GraphInstCmdDeleteProc;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_UpdateGraph --
+ *
+ *	Tells the Tk dispatcher to call the graph display routine at the next
+ *	idle point.  This request is made only if the window is displayed and
+ *	no other redraw request is pending.
+ *
+ * Results: None.
+ *
+ * Side effects:
+ *	The window is eventually redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_UpdateGraph(ClientData clientData)
+{
+    Graph *graphPtr = clientData;
+
+    graphPtr->flags |= REDRAW_WORLD;
+    if ((graphPtr->tkwin != NULL) && !(graphPtr->flags & REDRAW_PENDING)) {
+	Tcl_DoWhenIdle(DisplayGraph, graphPtr);
+	graphPtr->flags |= REDRAW_PENDING;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_EventuallyRedrawGraph --
+ *
+ *	Tells the Tk dispatcher to call the graph display routine at the next
+ *	idle point.  This request is made only if the window is displayed and
+ *	no other redraw request is pending.
+ *
+ * Results: None.
+ *
+ * Side effects:
+ *	The window is eventually redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_EventuallyRedrawGraph(Graph *graphPtr) 
+{
+    if ((graphPtr->tkwin != NULL) && !(graphPtr->flags & REDRAW_PENDING)) {
+	Tcl_DoWhenIdle(DisplayGraph, graphPtr);
+	graphPtr->flags |= REDRAW_PENDING;
+    }
+}
+
+const char *
+Blt_GraphClassName(ClassId classId) 
+{
+    if ((classId >= CID_NONE) && (classId <= CID_MARKER_WINDOW)) {
+	return objectClassNames[classId];
+    }
+    return NULL;
+}
+
+void
+Blt_GraphSetObjectClass(GraphObj *graphObjPtr, ClassId classId)
+{
+    graphObjPtr->classId = classId;
+    graphObjPtr->className = Blt_GraphClassName(classId);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GraphEventProc --
+ *
+ *	This procedure is invoked by the Tk dispatcher for various events on
+ *	graphs.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	When the window gets deleted, internal structures get cleaned up.
+ *	When it gets exposed, the graph is eventually redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+GraphEventProc(ClientData clientData, XEvent *eventPtr)
+{
+    Graph *graphPtr = clientData;
+
+    if (eventPtr->type == Expose) {
+	if (eventPtr->xexpose.count == 0) {
+	    graphPtr->flags |= REDRAW_WORLD;
+	    Blt_EventuallyRedrawGraph(graphPtr);
+	}
+    } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) {
+	if (eventPtr->xfocus.detail != NotifyInferior) {
+	    if (eventPtr->type == FocusIn) {
+		graphPtr->flags |= FOCUS;
+	    } else {
+		graphPtr->flags &= ~FOCUS;
+	    }
+	    graphPtr->flags |= REDRAW_WORLD;
+	    Blt_EventuallyRedrawGraph(graphPtr);
+	}
+    } else if (eventPtr->type == DestroyNotify) {
+	if (graphPtr->tkwin != NULL) {
+	    graphPtr->tkwin = NULL;
+	    Tcl_DeleteCommandFromToken(graphPtr->interp, graphPtr->cmdToken);
+	}
+	if (graphPtr->flags & REDRAW_PENDING) {
+	    Tcl_CancelIdleCall(DisplayGraph, graphPtr);
+	}
+	Tcl_EventuallyFree(graphPtr, DestroyGraph);
+    } else if (eventPtr->type == ConfigureNotify) {
+	graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD);
+	Blt_EventuallyRedrawGraph(graphPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GraphInstCmdDeleteProc --
+ *
+ *	This procedure is invoked when a widget command is deleted.  If the
+ *	widget isn't already in the process of being destroyed, this command
+ *	destroys it.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The widget is destroyed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+GraphInstCmdDeleteProc(ClientData clientData) /* Pointer to widget record. */
+{
+    Graph *graphPtr = clientData;
+
+    if (graphPtr->tkwin != NULL) {	/* NULL indicates window has already
+					 * been destroyed. */
+	Tk_Window tkwin;
+
+	tkwin = graphPtr->tkwin;
+	graphPtr->tkwin = NULL;
+	Tk_DestroyWindow(tkwin);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AdjustAxisPointers --
+ *
+ *	Sets the axis pointers according to whether the axis is inverted on
+ *	not.  The axis sites are also reset.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+AdjustAxisPointers(Graph *graphPtr) 
+{
+    if (graphPtr->inverted) {
+	graphPtr->leftMargin.axes   = graphPtr->axisChain[0];
+	graphPtr->bottomMargin.axes = graphPtr->axisChain[1];
+	graphPtr->rightMargin.axes  = graphPtr->axisChain[2];
+	graphPtr->topMargin.axes    = graphPtr->axisChain[3];
+    } else {
+	graphPtr->leftMargin.axes   = graphPtr->axisChain[1];
+	graphPtr->bottomMargin.axes = graphPtr->axisChain[0];
+	graphPtr->rightMargin.axes  = graphPtr->axisChain[3];
+	graphPtr->topMargin.axes    = graphPtr->axisChain[2];
+    }
+}
+
+static int
+InitPens(Graph *graphPtr)
+{
+    Blt_InitHashTable(&graphPtr->penTable, BLT_STRING_KEYS);
+    if (Blt_CreatePen(graphPtr, "activeLine", CID_ELEM_LINE, 0, NULL) == NULL) {
+  	return TCL_ERROR;
+    }
+    if (Blt_CreatePen(graphPtr, "activeBar", CID_ELEM_BAR, 0, NULL) == NULL) {
+  	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GraphTags --
+ *
+ *	Sets the binding tags for a graph obj. This routine is called by Tk
+ *	when an event occurs in the graph.  It fills an array of pointers with
+ *	bind tag addresses.
+ *
+ *	The object addresses are strings hashed in one of two tag tables: one
+ *	for elements and the another for markers.  Note that there's only one
+ *	binding table for elements and markers.  [We don't want to trigger
+ *	both a marker and element bind command for the same event.]  But we
+ *	don't want a marker and element with the same tag name to activate the
+ *	others bindings. A tag "all" for markers should mean all markers, not
+ *	all markers and elements.  As a result, element and marker tags are
+ *	stored in separate hash tables, which means we can't generate the same
+ *	tag address for both an elements and marker, even if they have the
+ *	same name.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	This information will be used by the binding code in bltUtil.c to
+ *	determine what graph objects match the current event.  The tags are
+ *	placed in tagArr and *nTagsPtr is set with the number of tags found.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+void
+Blt_GraphTags(
+    Blt_BindTable table,
+    ClientData object,
+    ClientData context,		/* Not used. */
+    Blt_List list)
+{
+    GraphObj *graphObjPtr;
+    MakeTagProc *tagProc;
+    Graph *graphPtr;
+
+    graphPtr = (Graph *)Blt_GetBindingData(table);
+
+    /* 
+     * All graph objects (markers, elements, axes, etc) have the same starting
+     * fields in their structures, such as "classId", "name", "className", and
+     * "tags".
+     */
+    graphObjPtr = (GraphObj *)object;
+
+    switch (graphObjPtr->classId) {
+    case CID_ELEM_BAR:		
+    case CID_ELEM_LINE: 
+	tagProc = Blt_MakeElementTag;
+	break;
+    case CID_AXIS_X:
+    case CID_AXIS_Y:
+	tagProc = Blt_MakeAxisTag;
+	break;
+    case CID_MARKER_BITMAP:
+    case CID_MARKER_IMAGE:
+    case CID_MARKER_LINE:
+    case CID_MARKER_POLYGON:
+    case CID_MARKER_TEXT:
+    case CID_MARKER_WINDOW:
+	tagProc = Blt_MakeMarkerTag;
+	break;
+    case CID_NONE:
+	Blt_Panic("unknown object type");
+	tagProc = NULL;
+	break;
+    default:
+	Blt_Panic("bogus object type");
+	tagProc = NULL;
+	break;
+    }
+    assert(graphObjPtr->name != NULL);
+
+    /* Always add the name of the object to the tag array. */
+    Blt_List_Append(list, (*tagProc)(graphPtr, graphObjPtr->name), 0);
+    Blt_List_Append(list, (*tagProc)(graphPtr, graphObjPtr->className), 0);
+    if (graphObjPtr->tags != NULL) {
+	const char **p;
+
+	for (p = graphObjPtr->tags; *p != NULL; p++) {
+	    Blt_List_Append(list, (*tagProc) (graphPtr, *p), 0);
+	}
+    }
+}
+
+/*
+ *	Find the closest point from the set of displayed elements, searching
+ *	the display list from back to front.  That way, if the points from
+ *	two different elements overlay each other exactly, the one that's on
+ *	top (visible) is picked.
+ */
+/*ARGSUSED*/
+static ClientData
+PickEntry(ClientData clientData, int x, int y, ClientData *contextPtr)
+{
+    Graph *graphPtr = clientData;
+    Blt_ChainLink link;
+    Element *elemPtr;
+    Marker *markerPtr;
+    Region2d exts;
+
+    if (graphPtr->flags & MAP_ALL) {
+	return NULL;			/* Don't pick anything until the next
+					 * redraw occurs. */
+    }
+    Blt_GraphExtents(graphPtr, &exts);
+
+    if ((x >= exts.right) || (x < exts.left) || 
+	(y >= exts.bottom) || (y < exts.top)) {
+	/* 
+	 * Sample coordinate is in one of the graph margins.  Can only pick an
+	 * axis.
+	 */
+	return Blt_NearestAxis(graphPtr, x, y);
+    }
+    /* 
+     * From top-to-bottom check:
+     *	1. markers drawn on top (-under false).
+     *	2. elements using its display list back to front.
+     *  3. markers drawn under element (-under true).
+     */
+    markerPtr = Blt_NearestMarker(graphPtr, x, y, FALSE);
+    if (markerPtr != NULL) {
+	return markerPtr;		/* Found a marker (-under false). */
+    }
+    {
+	ClosestSearch search;
+
+	search.along = SEARCH_BOTH;
+	search.halo = graphPtr->halo;
+	search.index = -1;
+	search.x = x;
+	search.y = y;
+	search.dist = (double)(search.halo + 1);
+	search.mode = SEARCH_AUTO;
+	
+	for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
+	     link != NULL; link = Blt_Chain_PrevLink(link)) {
+	    elemPtr = Blt_Chain_GetValue(link);
+	    if (elemPtr->flags & (HIDE|MAP_ITEM)) {
+		continue;
+	    }
+	    if (elemPtr->state == STATE_NORMAL) {
+		(*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search);
+	    }
+	}
+	if (search.dist <= (double)search.halo) {
+	    return search.elemPtr;	/* Found an element within the minimum
+					 * halo distance. */
+	}
+    }
+    markerPtr = Blt_NearestMarker(graphPtr, x, y, TRUE);
+    if (markerPtr != NULL) {
+	return markerPtr;		/* Found a marker (-under true) */
+    }
+    return NULL;			/* Nothing found. */
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ConfigureGraph --
+ *
+ *	Allocates resources for the graph.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Configuration information, such as text string, colors, font, etc. get
+ *	set for graphPtr; old resources get freed, if there were any.  The
+ *	graph is redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+ConfigureGraph(Graph *graphPtr)	
+{
+    XColor *colorPtr;
+    GC newGC;
+    XGCValues gcValues;
+    unsigned long gcMask;
+
+    /* Don't allow negative bar widths. Reset to an arbitrary value (0.1) */
+    if (graphPtr->barWidth <= 0.0f) {
+	graphPtr->barWidth = 0.8f;
+    }
+    graphPtr->inset = graphPtr->borderWidth + graphPtr->highlightWidth;
+    if ((graphPtr->reqHeight != Tk_ReqHeight(graphPtr->tkwin)) ||
+	(graphPtr->reqWidth != Tk_ReqWidth(graphPtr->tkwin))) {
+	Tk_GeometryRequest(graphPtr->tkwin, graphPtr->reqWidth,
+	    graphPtr->reqHeight);
+    }
+    Tk_SetInternalBorder(graphPtr->tkwin, graphPtr->borderWidth);
+    colorPtr = Blt_BackgroundBorderColor(graphPtr->normalBg);
+
+    graphPtr->titleWidth = graphPtr->titleHeight = 0;
+    if (graphPtr->title != NULL) {
+	unsigned int w, h;
+
+	Blt_Ts_GetExtents(&graphPtr->titleTextStyle, graphPtr->title, &w, &h);
+	graphPtr->titleHeight = h;
+    }
+
+    /*
+     * Create GCs for interior and exterior regions, and a background GC for
+     * clearing the margins with XFillRectangle
+     */
+
+    /* Margin GC */
+
+    gcValues.foreground = 
+	Blt_Ts_GetForeground(graphPtr->titleTextStyle)->pixel;
+    gcValues.background = colorPtr->pixel;
+    gcMask = (GCForeground | GCBackground);
+    newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+    if (graphPtr->drawGC != NULL) {
+	Tk_FreeGC(graphPtr->display, graphPtr->drawGC);
+    }
+    graphPtr->drawGC = newGC;
+
+    if (graphPtr->plotBg != NULL) {
+	Blt_SetBackgroundChangedProc(graphPtr->plotBg, Blt_UpdateGraph, 
+		graphPtr);
+    }
+    if (graphPtr->normalBg != NULL) {
+	Blt_SetBackgroundChangedProc(graphPtr->normalBg, Blt_UpdateGraph, 
+		graphPtr);
+    }
+    if (Blt_ConfigModified(configSpecs, "-invertxy", (char *)NULL)) {
+
+	/*
+	 * If the -inverted option changed, we need to readjust the pointers
+	 * to the axes and recompute the their scales.
+	 */
+
+	AdjustAxisPointers(graphPtr);
+	graphPtr->flags |= RESET_AXES;
+    }
+    if ((!graphPtr->backingStore) && (graphPtr->cache != None)) {
+	/*
+	 * Free the pixmap if we're not buffering the display of elements
+	 * anymore.
+	 */
+	Tk_FreePixmap(graphPtr->display, graphPtr->cache);
+	graphPtr->cache = None;
+    }
+    /*
+     * Reconfigure the crosshairs, just in case the background color of the
+     * plotarea has been changed.
+     */
+    Blt_ConfigureCrosshairs(graphPtr);
+
+    /*
+     *  Update the layout of the graph (and redraw the elements) if any of the
+     *  following graph options which affect the size of * the plotting area
+     *  has changed.
+     *
+     *	    -aspect
+     *      -borderwidth, -plotborderwidth
+     *	    -font, -title
+     *	    -width, -height
+     *	    -invertxy
+     *	    -bottommargin, -leftmargin, -rightmargin, -topmargin,
+     *	    -barmode, -barwidth
+     */
+    if (Blt_ConfigModified(configSpecs, "-invertxy", "-title", "-font",
+		"-*margin", "-*width", "-height", "-barmode", "-*pad*", 
+		"-aspect", "-*borderwidth", "-plot*", "-*width", "-*height",
+		"-unmaphiddenelements", (char *)NULL)) {
+	graphPtr->flags |= RESET_WORLD | CACHE_DIRTY;
+    }
+    if (Blt_ConfigModified(configSpecs, "-plot*", "-*background",
+			   (char *)NULL)) {
+	graphPtr->flags |= CACHE_DIRTY;
+    }
+    graphPtr->flags |= REDRAW_WORLD;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DestroyGraph --
+ *
+ *	This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to
+ *	clean up the internal structure of a graph at a safe time (when no-one
+ *	is using it anymore).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Everything associated with the widget is freed up.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void DestroyGraph(char* dataPtr)
+{
+    Graph *graphPtr = (Graph *)dataPtr;
+
+    Blt_FreeOptions(configSpecs, (char *)graphPtr, graphPtr->display, 0);
+    /*
+     * Destroy the individual components of the graph: elements, markers,
+     * axes, legend, display lists etc.  Be careful to remove them in
+     * order. For example, axes are used by elements and markers, so they have
+     * to be removed after the markers and elements. Same it true with the
+     * legend and pens (they use elements), so can't be removed until the
+     * elements are destroyed.
+     */
+    Blt_DestroyMarkers(graphPtr);
+    Blt_DestroyElements(graphPtr);
+    Blt_DestroyLegend(graphPtr);
+    Blt_DestroyAxes(graphPtr);
+    Blt_DestroyPens(graphPtr);
+    Blt_DestroyCrosshairs(graphPtr);
+    Blt_DestroyPageSetup(graphPtr);
+    Blt_DestroyBarSets(graphPtr);
+    if (graphPtr->bindTable != NULL) {
+	Blt_DestroyBindingTable(graphPtr->bindTable);
+    }
+
+    /* Release allocated X resources and memory. */
+    if (graphPtr->drawGC != NULL) {
+	Tk_FreeGC(graphPtr->display, graphPtr->drawGC);
+    }
+    Blt_Ts_FreeStyle(graphPtr->display, &graphPtr->titleTextStyle);
+    if (graphPtr->cache != None) {
+	Tk_FreePixmap(graphPtr->display, graphPtr->cache);
+    }
+    free(graphPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateGraph --
+ *
+ *	This procedure creates and initializes a new widget.
+ *
+ * Results:
+ *	The return value is a pointer to a structure describing the new
+ *	widget.  If an error occurred, then the return value is NULL and an
+ *	error message is left in interp->result.
+ *
+ * Side effects:
+ *	Memory is allocated, a Tk_Window is created, etc.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Graph *
+CreateGraph(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ClassId classId)
+{
+    Graph *graphPtr;
+    Tk_Window tkwin;
+
+    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), 
+	Tcl_GetString(objv[1]), (char *)NULL);
+    if (tkwin == NULL) {
+	return NULL;
+    }
+    graphPtr = calloc(1, sizeof(Graph));
+
+    /* Initialize the graph data structure. */
+
+    graphPtr->tkwin = tkwin;
+    graphPtr->display = Tk_Display(tkwin);
+    graphPtr->interp = interp;
+    graphPtr->classId = classId;
+    graphPtr->backingStore = TRUE;
+    graphPtr->doubleBuffer = TRUE;
+    graphPtr->borderWidth = 2;
+    graphPtr->plotBW = 1;
+    graphPtr->highlightWidth = 2;
+    graphPtr->plotRelief = TK_RELIEF_SOLID;
+    graphPtr->relief = TK_RELIEF_FLAT;
+    graphPtr->flags = RESET_WORLD;
+    graphPtr->nextMarkerId = 1;
+    graphPtr->padLeft = graphPtr->padRight = 0;
+    graphPtr->padTop = graphPtr->padBottom = 0;
+    graphPtr->bottomMargin.site = MARGIN_BOTTOM;
+    graphPtr->leftMargin.site = MARGIN_LEFT;
+    graphPtr->topMargin.site = MARGIN_TOP;
+    graphPtr->rightMargin.site = MARGIN_RIGHT;
+    Blt_Ts_InitStyle(graphPtr->titleTextStyle);
+    Blt_Ts_SetAnchor(graphPtr->titleTextStyle, TK_ANCHOR_N);
+
+    Blt_InitHashTable(&graphPtr->axes.table, BLT_STRING_KEYS);
+    Blt_InitHashTable(&graphPtr->axes.tagTable, BLT_STRING_KEYS);
+    Blt_InitHashTable(&graphPtr->elements.table, BLT_STRING_KEYS);
+    Blt_InitHashTable(&graphPtr->elements.tagTable, BLT_STRING_KEYS);
+    Blt_InitHashTable(&graphPtr->markers.table, BLT_STRING_KEYS);
+    Blt_InitHashTable(&graphPtr->markers.tagTable, BLT_STRING_KEYS);
+    Blt_InitHashTable(&graphPtr->dataTables, BLT_STRING_KEYS);
+    graphPtr->elements.displayList = Blt_Chain_Create();
+    graphPtr->markers.displayList = Blt_Chain_Create();
+    graphPtr->axes.displayList = Blt_Chain_Create();
+
+    switch (classId) {
+    case CID_ELEM_LINE:
+	Tk_SetClass(tkwin, "Graph");
+	break;
+    case CID_ELEM_BAR:
+	Tk_SetClass(tkwin, "Barchart");
+	break;
+    default:
+	Tk_SetClass(tkwin, "???");
+	break;
+    }
+    Blt_SetWindowInstanceData(tkwin, graphPtr);
+
+    if (InitPens(graphPtr) != TCL_OK) {
+	goto error;
+    }
+    if (Blt_ConfigureWidgetFromObj(interp, tkwin, configSpecs, objc - 2, 
+		objv + 2, (char *)graphPtr, 0) != TCL_OK) {
+	goto error;
+    }
+    if (Blt_DefaultAxes(graphPtr) != TCL_OK) {
+	goto error;
+    }
+    AdjustAxisPointers(graphPtr);
+
+    if (Blt_CreatePageSetup(graphPtr) != TCL_OK) {
+	goto error;
+    }
+    if (Blt_CreateCrosshairs(graphPtr) != TCL_OK) {
+	goto error;
+    }
+    if (Blt_CreateLegend(graphPtr) != TCL_OK) {
+	goto error;
+    }
+    Tk_CreateEventHandler(graphPtr->tkwin, 
+	ExposureMask | StructureNotifyMask | FocusChangeMask, GraphEventProc, 
+	graphPtr);
+
+    graphPtr->cmdToken = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[1]), 
+	Blt_GraphInstCmdProc, graphPtr, GraphInstCmdDeleteProc);
+    ConfigureGraph(graphPtr);
+    graphPtr->bindTable = Blt_CreateBindingTable(interp, tkwin, graphPtr, 
+	PickEntry, Blt_GraphTags);
+
+    Tcl_SetObjResult(interp, objv[1]);
+    return graphPtr;
+
+ error:
+    DestroyGraph((char*)graphPtr);
+    return NULL;
+}
+
+/* Widget sub-commands */
+
+/*ARGSUSED*/
+static int
+XAxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int margin;
+
+    margin = (graphPtr->inverted) ? MARGIN_LEFT : MARGIN_BOTTOM;
+    return Blt_AxisOp(interp, graphPtr, margin, objc, objv);
+}
+
+static int
+X2AxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int margin;
+
+    margin = (graphPtr->inverted) ? MARGIN_RIGHT : MARGIN_TOP;
+    return Blt_AxisOp(interp, graphPtr, margin, objc, objv);
+}
+
+static int
+YAxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int margin;
+
+    margin = (graphPtr->inverted) ? MARGIN_BOTTOM : MARGIN_LEFT;
+    return Blt_AxisOp(interp, graphPtr, margin, objc, objv);
+}
+
+static int
+Y2AxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int margin;
+
+    margin = (graphPtr->inverted) ? MARGIN_TOP : MARGIN_RIGHT;
+    return Blt_AxisOp(interp, graphPtr, margin, objc, objv);
+}
+
+static int
+BarOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    return Blt_ElementOp(graphPtr, interp, objc, objv, CID_ELEM_BAR);
+}
+
+/*ARGSUSED*/
+static int
+LineOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    return Blt_ElementOp(graphPtr, interp, objc, objv, CID_ELEM_LINE);
+}
+
+static int
+ElementOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    return Blt_ElementOp(graphPtr, interp, objc, objv, graphPtr->classId);
+}
+
+static int
+ConfigureOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int flags;
+
+    flags = BLT_CONFIG_OBJV_ONLY;
+    if (objc == 2) {
+	return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs,
+	    (char *)graphPtr, (Tcl_Obj *)NULL, flags);
+    } else if (objc == 3) {
+	return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs,
+	    (char *)graphPtr, objv[2], flags);
+    } else {
+	if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, 
+		objc - 2, objv + 2, (char *)graphPtr, flags) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	ConfigureGraph(graphPtr);
+	Blt_EventuallyRedrawGraph(graphPtr);
+	return TCL_OK;
+    }
+}
+
+/* ARGSUSED*/
+static int
+CgetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs,
+	(char *)graphPtr, objv[2], 0);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ExtentsOp --
+ *
+ *	Reports the size of one of several items within the graph.  The
+ *	following are valid items:
+ *
+ *	  "bottommargin"	Height of the bottom margin
+ *	  "leftmargin"		Width of the left margin
+ *	  "legend"		x y w h of the legend
+ *	  "plotarea"		x y w h of the plotarea
+ *	  "plotheight"		Height of the plot area
+ *	  "rightmargin"		Width of the right margin
+ *	  "topmargin"		Height of the top margin
+ *        "plotwidth"		Width of the plot area
+ *
+ * Results:
+ *	Always returns TCL_OK.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED*/
+static int
+ExtentsOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    const char *string;
+    char c;
+    int length;
+
+    string = Tcl_GetStringFromObj(objv[2], &length);
+    c = string[0];
+    if ((c == 'p') && (length > 4) && 
+	(strncmp("plotheight", string, length) == 0)) {
+	int height;
+
+	height = graphPtr->bottom - graphPtr->top + 1;
+	Tcl_SetIntObj(Tcl_GetObjResult(interp), height);
+    } else if ((c == 'p') && (length > 4) &&
+	(strncmp("plotwidth", string, length) == 0)) {
+	int width;
+
+	width = graphPtr->right - graphPtr->left + 1;
+	Tcl_SetIntObj(Tcl_GetObjResult(interp), width);
+    } else if ((c == 'p') && (length > 4) &&
+	(strncmp("plotarea", string, length) == 0)) {
+	Tcl_Obj *listObjPtr;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewIntObj(graphPtr->left));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewIntObj(graphPtr->top));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewIntObj(graphPtr->right - graphPtr->left + 1));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewIntObj(graphPtr->bottom - graphPtr->top + 1));
+	Tcl_SetObjResult(interp, listObjPtr);
+    } else if ((c == 'l') && (length > 2) &&
+	(strncmp("legend", string, length) == 0)) {
+	Tcl_Obj *listObjPtr;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewIntObj(Blt_Legend_X(graphPtr)));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewIntObj(Blt_Legend_Y(graphPtr)));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewIntObj(Blt_Legend_Width(graphPtr)));
+	Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewIntObj(Blt_Legend_Height(graphPtr)));
+	Tcl_SetObjResult(interp, listObjPtr);
+    } else if ((c == 'l') && (length > 2) &&
+	(strncmp("leftmargin", string, length) == 0)) {
+	Tcl_SetIntObj(Tcl_GetObjResult(interp), graphPtr->leftMargin.width);
+    } else if ((c == 'r') && (length > 1) &&
+	(strncmp("rightmargin", string, length) == 0)) {
+	Tcl_SetIntObj(Tcl_GetObjResult(interp), graphPtr->rightMargin.width);
+    } else if ((c == 't') && (length > 1) &&
+	(strncmp("topmargin", string, length) == 0)) {
+	Tcl_SetIntObj(Tcl_GetObjResult(interp), graphPtr->topMargin.height);
+    } else if ((c == 'b') && (length > 1) &&
+	(strncmp("bottommargin", string, length) == 0)) {
+	Tcl_SetIntObj(Tcl_GetObjResult(interp), graphPtr->bottomMargin.height);
+    } else {
+	Tcl_AppendResult(interp, "bad extent item \"", objv[2],
+	    "\": should be plotheight, plotwidth, leftmargin, rightmargin, \
+topmargin, bottommargin, plotarea, or legend", (char *)NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * InsideOp --
+ *
+ *	Returns true of false whether the given point is inside the plotting
+ *	area (defined by left,bottom right, top).
+ *
+ * Results:
+ *	Always returns TCL_OK.  interp->result will contain the boolean string
+ *	representation.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED*/
+static int
+InsideOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int x, y;
+    Region2d exts;
+    int result;
+
+    if (Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Blt_GraphExtents(graphPtr, &exts);
+    result = PointInRegion(&exts, x, y);
+    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), result);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * InvtransformOp --
+ *
+ *	This procedure returns a list of the graph coordinate values
+ *	corresponding with the given window X and Y coordinate positions.
+ *
+ * Results:
+ *	Returns a standard TCL result.  If an error occurred while parsing the
+ *	window positions, TCL_ERROR is returned, and interp->result will
+ *	contain the error message.  Otherwise interp->result will contain a
+ *	Tcl list of the x and y coordinates.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+InvtransformOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	       Tcl_Obj *const *objv)
+{
+    double x, y;
+    Point2d point;
+    Axis2d axes;
+    Tcl_Obj *listObjPtr;
+
+    if ((Blt_ExprDoubleFromObj(interp, objv[2], &x) != TCL_OK) ||
+	(Blt_ExprDoubleFromObj(interp, objv[3], &y) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    if (graphPtr->flags & RESET_AXES) {
+	Blt_ResetAxes(graphPtr);
+    }
+    /* Perform the reverse transformation, converting from window coordinates
+     * to graph data coordinates.  Note that the point is always mapped to the
+     * bottom and left axes (which may not be what the user wants).  */
+
+    /*  Pick the first pair of axes */
+    axes.x = Blt_GetFirstAxis(graphPtr->axisChain[0]);
+    axes.y = Blt_GetFirstAxis(graphPtr->axisChain[1]);
+    point = Blt_InvMap2D(graphPtr, x, y, &axes);
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(point.x));
+    Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(point.y));
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TransformOp --
+ *
+ *	This procedure returns a list of the window coordinates corresponding
+ *	with the given graph x and y coordinates.
+ *
+ * Results:
+ *	Returns a standard TCL result.  interp->result contains the list of
+ *	the graph coordinates. If an error occurred while parsing the window
+ *	positions, TCL_ERROR is returned, then interp->result will contain an
+ *	error message.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+TransformOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    double x, y;
+    Point2d point;
+    Axis2d axes;
+    Tcl_Obj *listObjPtr;
+
+    if ((Blt_ExprDoubleFromObj(interp, objv[2], &x) != TCL_OK) ||
+	(Blt_ExprDoubleFromObj(interp, objv[3], &y) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    if (graphPtr->flags & RESET_AXES) {
+	Blt_ResetAxes(graphPtr);
+    }
+    /*
+     * Perform the transformation from window to graph coordinates.  Note that
+     * the points are always mapped onto the bottom and left axes (which may
+     * not be the what the user wants).
+     */
+    axes.x = Blt_GetFirstAxis(graphPtr->axisChain[0]);
+    axes.y = Blt_GetFirstAxis(graphPtr->axisChain[1]);
+
+    point = Blt_Map2D(graphPtr, x, y, &axes);
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(ROUND(point.x)));
+    Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(ROUND(point.y)));
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GraphWidgetCmd --
+ *
+ *	This procedure is invoked to process the TCL command that
+ *	corresponds to a widget managed by this module.  See the user
+ *	documentation for details on what it does.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_OpSpec graphOps[] =
+{
+    {"axis",         1, Blt_VirtualAxisOp, 2, 0, "oper ?args?",},
+    {"bar",          2, BarOp,             2, 0, "oper ?args?",},
+    {"cget",         2, CgetOp,            3, 3, "option",},
+    {"configure",    2, ConfigureOp,       2, 0, "?option value?...",},
+    {"crosshairs",   2, Blt_CrosshairsOp,  2, 0, "oper ?args?",},
+    {"element",      2, ElementOp,         2, 0, "oper ?args?",},
+    {"extents",      2, ExtentsOp,         3, 3, "item",},
+    {"inside",       3, InsideOp,          4, 4, "winX winY",},
+    {"invtransform", 3, InvtransformOp,    4, 4, "winX winY",},
+    {"legend",       2, Blt_LegendOp,      2, 0, "oper ?args?",},
+    {"line",         2, LineOp,            2, 0, "oper ?args?",},
+    {"marker",       2, Blt_MarkerOp,      2, 0, "oper ?args?",},
+    {"pen",          2, Blt_PenOp,         2, 0, "oper ?args?",},
+    {"postscript",   2, Blt_PostScriptOp,  2, 0, "oper ?args?",},
+    {"transform",    1, TransformOp,       4, 4, "x y",},
+    {"x2axis",       2, X2AxisOp,          2, 0, "oper ?args?",},
+    {"xaxis",        2, XAxisOp,           2, 0, "oper ?args?",},
+    {"y2axis",       2, Y2AxisOp,          2, 0, "oper ?args?",},
+    {"yaxis",        2, YAxisOp,           2, 0, "oper ?args?",},
+};
+static int nGraphOps = sizeof(graphOps) / sizeof(Blt_OpSpec);
+
+int
+Blt_GraphInstCmdProc(ClientData clientData, Tcl_Interp *interp, int objc,
+		     Tcl_Obj *const *objv)
+{
+    GraphCmdProc *proc;
+    int result;
+    Graph *graphPtr = clientData;
+
+    proc = Blt_GetOpFromObj(interp, nGraphOps, graphOps, BLT_OP_ARG1, 
+	objc, objv, 0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_Preserve(graphPtr);
+    result = (*proc) (graphPtr, interp, objc, objv);
+    Tcl_Release(graphPtr);
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NewGraph --
+ *
+ *	Creates a new window and TCL command representing an instance of a
+ *	graph widget.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+NewGraph(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ClassId classId)
+{
+    Graph *graphPtr;
+
+    if (objc < 2) {
+	Tcl_AppendResult(interp, "wrong # args: should be \"", 
+		Tcl_GetString(objv[0]), " pathName ?option value?...\"", 
+		(char *)NULL);
+	return TCL_ERROR;
+    }
+    graphPtr = CreateGraph(interp, objc, objv, classId);
+    if (graphPtr == NULL) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GraphCmd --
+ *
+ *	Creates a new window and TCL command representing an instance of a
+ *	graph widget.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+GraphCmd(ClientData clientData, Tcl_Interp *interp, int objc, 
+	 Tcl_Obj *const *objv)
+{
+    return NewGraph(interp, objc, objv, CID_ELEM_LINE);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BarchartCmd --
+ *
+ *	Creates a new window and TCL command representing an instance of a
+ *	barchart widget.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+BarchartCmd(ClientData clientData, Tcl_Interp *interp, int objc, 
+	    Tcl_Obj *const *objv)
+{
+    return NewGraph(interp, objc, objv, CID_ELEM_BAR);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawMargins --
+ *
+ * 	Draws the exterior region of the graph (axes, ticks, titles, etc) 
+ * 	onto a pixmap. The interior region is defined by the given rectangle
+ * 	structure.
+ *
+ *	---------------------------------
+ *      |                               |
+ *      |           rectArr[0]          |
+ *      |                               |
+ *	---------------------------------
+ *      |     |top           right|     |
+ *      |     |                   |     |
+ *      |     |                   |     |
+ *      | [1] |                   | [2] |
+ *      |     |                   |     |
+ *      |     |                   |     |
+ *      |     |                   |     |
+ *      |     |                   |     |
+ *      |     |                   |     |
+ *      |     |left         bottom|     |
+ *	---------------------------------
+ *      |                               |
+ *      |          rectArr[3]           |
+ *      |                               |
+ *	---------------------------------
+ *
+ *		X coordinate axis
+ *		Y coordinate axis
+ *		legend
+ *		interior border
+ *		exterior border
+ *		titles (X and Y axis, graph)
+ *
+ * Returns:
+ *	None.
+ *
+ * Side Effects:
+ *	Exterior of graph is displayed in its window.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawMargins(Graph *graphPtr, Drawable drawable)
+{
+    XRectangle rects[4];
+    int site;
+
+    /*
+     * Draw the four outer rectangles which encompass the plotting
+     * surface. This clears the surrounding area and clips the plot.
+     */
+    rects[0].x = rects[0].y = rects[3].x = rects[1].x = 0;
+    rects[0].width = rects[3].width = (short int)graphPtr->width;
+    rects[0].height = (short int)graphPtr->top;
+    rects[3].y = graphPtr->bottom;
+    rects[3].height = graphPtr->height - graphPtr->bottom;
+    rects[2].y = rects[1].y = graphPtr->top;
+    rects[1].width = graphPtr->left;
+    rects[2].height = rects[1].height = graphPtr->bottom - graphPtr->top;
+    rects[2].x = graphPtr->right;
+    rects[2].width = graphPtr->width - graphPtr->right;
+
+    Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, 
+	rects[0].x, rects[0].y, rects[0].width, rects[0].height, 
+	0, TK_RELIEF_FLAT);
+    Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, 
+	rects[1].x, rects[1].y, rects[1].width, rects[1].height, 
+	0, TK_RELIEF_FLAT);
+    Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, 
+	rects[2].x, rects[2].y, rects[2].width, rects[2].height, 
+	0, TK_RELIEF_FLAT);
+    Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, 
+	rects[3].x, rects[3].y, rects[3].width, rects[3].height, 
+	0, TK_RELIEF_FLAT);
+
+    /* Draw 3D border around the plotting area */
+
+    if (graphPtr->plotBW > 0) {
+	int x, y, w, h;
+
+	x = graphPtr->left - graphPtr->plotBW;
+	y = graphPtr->top - graphPtr->plotBW;
+	w = (graphPtr->right - graphPtr->left) + (2*graphPtr->plotBW);
+	h = (graphPtr->bottom - graphPtr->top) + (2*graphPtr->plotBW);
+	Blt_DrawBackgroundRectangle(graphPtr->tkwin, drawable, 
+		graphPtr->normalBg, x, y, w, h, graphPtr->plotBW, 
+		graphPtr->plotRelief);
+    }
+    site = Blt_Legend_Site(graphPtr);
+    if (site & LEGEND_MARGIN_MASK) {
+	/* Legend is drawn on one of the graph margins */
+	Blt_DrawLegend(graphPtr, drawable);
+    } else if (site == LEGEND_WINDOW) {
+	Blt_Legend_EventuallyRedraw(graphPtr);
+    }
+    if (graphPtr->title != NULL) {
+	Blt_DrawText(graphPtr->tkwin, drawable, graphPtr->title,
+	    &graphPtr->titleTextStyle, graphPtr->titleX, graphPtr->titleY);
+    }
+    Blt_DrawAxes(graphPtr, drawable);
+    graphPtr->flags &= ~DRAW_MARGINS;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DrawPlot --
+ *
+ *	Draws the contents of the plotting area.  This consists of the
+ *	elements, markers (draw under elements), axis limits, and possibly the
+ *	legend.  Typically, the output will be cached into a backing store
+ *	pixmap, so that redraws can occur quickly.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DrawPlot(Graph *graphPtr, Drawable drawable)
+{
+    int site;
+
+    DrawMargins(graphPtr, drawable);
+
+    /* Draw the background of the plotting area with 3D border. */
+    Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->plotBg,
+	graphPtr->left   - graphPtr->plotBW, 
+	graphPtr->top    - graphPtr->plotBW, 
+	graphPtr->right  - graphPtr->left + 1 + 2 * graphPtr->plotBW,
+	graphPtr->bottom - graphPtr->top  + 1 + 2 * graphPtr->plotBW, 
+	graphPtr->plotBW, graphPtr->plotRelief);
+
+    /* Draw the elements, markers, legend, and axis limits. */
+    Blt_DrawAxes(graphPtr, drawable);
+    Blt_DrawGrids(graphPtr, drawable);
+    Blt_DrawMarkers(graphPtr, drawable, MARKER_UNDER);
+
+    site = Blt_Legend_Site(graphPtr);
+    if ((site & LEGEND_PLOTAREA_MASK) && (!Blt_Legend_IsRaised(graphPtr))) {
+	Blt_DrawLegend(graphPtr, drawable);
+    } else if (site == LEGEND_WINDOW) {
+	Blt_Legend_EventuallyRedraw(graphPtr);
+    }
+    Blt_DrawAxisLimits(graphPtr, drawable);
+    Blt_DrawElements(graphPtr, drawable);
+    /* Blt_DrawAxes(graphPtr, drawable); */
+}
+
+void
+Blt_MapGraph(Graph *graphPtr)
+{
+    if (graphPtr->flags & RESET_AXES) {
+	Blt_ResetAxes(graphPtr);
+    }
+    if (graphPtr->flags & LAYOUT_NEEDED) {
+	Blt_LayoutGraph(graphPtr);
+	graphPtr->flags &= ~LAYOUT_NEEDED;
+    }
+    /* Compute coordinate transformations for graph components */
+    if ((graphPtr->vRange > 1) && (graphPtr->hRange > 1)) {
+	if (graphPtr->flags & MAP_WORLD) {
+	    Blt_MapAxes(graphPtr);
+	}
+	Blt_MapElements(graphPtr);
+	Blt_MapMarkers(graphPtr);
+	graphPtr->flags &= ~(MAP_ALL);
+    }
+}
+
+void
+Blt_DrawGraph(Graph *graphPtr, Drawable drawable)
+{
+    DrawPlot(graphPtr, drawable);
+    /* Draw markers above elements */
+    Blt_DrawMarkers(graphPtr, drawable, MARKER_ABOVE);
+    Blt_DrawActiveElements(graphPtr, drawable);
+
+    /* Don't draw legend in the plot area. */
+    if ((Blt_Legend_Site(graphPtr) & LEGEND_PLOTAREA_MASK) && 
+	(Blt_Legend_IsRaised(graphPtr))) {
+	Blt_DrawLegend(graphPtr, drawable);
+    }
+    /* Draw 3D border just inside of the focus highlight ring. */
+    if ((graphPtr->borderWidth > 0) && (graphPtr->relief != TK_RELIEF_FLAT)) {
+	Blt_DrawBackgroundRectangle(graphPtr->tkwin, drawable, 
+		graphPtr->normalBg, graphPtr->highlightWidth, 
+		graphPtr->highlightWidth, 
+	 	graphPtr->width  - 2 * graphPtr->highlightWidth, 
+		graphPtr->height - 2 * graphPtr->highlightWidth, 
+		graphPtr->borderWidth, graphPtr->relief);
+    }
+    /* Draw focus highlight ring. */
+    if ((graphPtr->highlightWidth > 0) && (graphPtr->flags & FOCUS)) {
+	GC gc;
+
+	gc = Tk_GCForColor(graphPtr->highlightColor, drawable);
+	Tk_DrawFocusHighlight(graphPtr->tkwin, gc, graphPtr->highlightWidth,
+	    drawable);
+    }
+}
+
+static void
+UpdateMarginTraces(Graph *graphPtr)
+{
+    Margin *marginPtr, *endPtr;
+
+    for (marginPtr = graphPtr->margins, endPtr = marginPtr + 4; 
+	 marginPtr < endPtr; marginPtr++) {
+	if (marginPtr->varName != NULL) { /* Trigger variable traces */
+	    int size;
+
+	    if ((marginPtr->site == MARGIN_LEFT) || 
+		(marginPtr->site == MARGIN_RIGHT)) {
+		size = marginPtr->width;
+	    } else {
+		size = marginPtr->height;
+	    }
+	    Tcl_SetVar(graphPtr->interp, marginPtr->varName, Blt_Itoa(size), 
+		TCL_GLOBAL_ONLY);
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DisplayGraph --
+ *
+ *	This procedure is invoked to display a graph widget.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Commands are output to X to display the graph in its current mode.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DisplayGraph(ClientData clientData)
+{
+    Graph *graphPtr = clientData;
+    Pixmap drawable;
+    Tk_Window tkwin;
+    int site;
+
+    graphPtr->flags &= ~REDRAW_PENDING;
+    if (graphPtr->tkwin == NULL) {
+	return;				/* Window has been destroyed (we
+					 * should not get here) */
+    }
+    tkwin = graphPtr->tkwin;
+    if ((Tk_Width(tkwin) <= 1) || (Tk_Height(tkwin) <= 1)) {
+	/* Don't bother computing the layout until the size of the window is
+	 * something reasonable. */
+	return;
+    }
+    graphPtr->width = Tk_Width(tkwin);
+    graphPtr->height = Tk_Height(tkwin);
+    Blt_MapGraph(graphPtr);
+    if (!Tk_IsMapped(tkwin)) {
+	/* The graph's window isn't displayed, so don't bother drawing
+	 * anything.  By getting this far, we've at least computed the
+	 * coordinates of the graph's new layout.  */
+	return;
+    }
+    /* Create a pixmap the size of the window for double buffering. */
+    if (graphPtr->doubleBuffer) {
+	drawable = Tk_GetPixmap(graphPtr->display, Tk_WindowId(tkwin), 
+		graphPtr->width, graphPtr->height, Tk_Depth(tkwin));
+    } else {
+	drawable = Tk_WindowId(tkwin);
+    }
+    if (graphPtr->backingStore) {
+	if ((graphPtr->cache == None) || 
+	    (graphPtr->cacheWidth != graphPtr->width) ||
+	    (graphPtr->cacheHeight != graphPtr->height)) {
+	    if (graphPtr->cache != None) {
+		Tk_FreePixmap(graphPtr->display, graphPtr->cache);
+	    }
+
+
+	    graphPtr->cache = Tk_GetPixmap(graphPtr->display, 
+		Tk_WindowId(tkwin), graphPtr->width, graphPtr->height, 
+		Tk_Depth(tkwin));
+	    graphPtr->cacheWidth  = graphPtr->width;
+	    graphPtr->cacheHeight = graphPtr->height;
+	    graphPtr->flags |= CACHE_DIRTY;
+	}
+    }
+    if (graphPtr->backingStore) {
+	if (graphPtr->flags & CACHE_DIRTY) {
+	    /* The backing store is new or out-of-date. */
+	    DrawPlot(graphPtr, graphPtr->cache);
+	    graphPtr->flags &= ~CACHE_DIRTY;
+	}
+	/* Copy the pixmap to the one used for drawing the entire graph. */
+	XCopyArea(graphPtr->display, graphPtr->cache, drawable,
+		graphPtr->drawGC, 0, 0, Tk_Width(graphPtr->tkwin),
+		Tk_Height(graphPtr->tkwin), 0, 0);
+    } else {
+	DrawPlot(graphPtr, drawable);
+    }
+    /* Draw markers above elements */
+    Blt_DrawMarkers(graphPtr, drawable, MARKER_ABOVE);
+    Blt_DrawActiveElements(graphPtr, drawable);
+    /* Don't draw legend in the plot area. */
+    site = Blt_Legend_Site(graphPtr);
+    if ((site & LEGEND_PLOTAREA_MASK) && (Blt_Legend_IsRaised(graphPtr))) {
+	Blt_DrawLegend(graphPtr, drawable);
+    }
+    if (site == LEGEND_WINDOW) {
+	Blt_Legend_EventuallyRedraw(graphPtr);
+    }
+    /* Draw 3D border just inside of the focus highlight ring. */
+    if ((graphPtr->borderWidth > 0) && (graphPtr->relief != TK_RELIEF_FLAT)) {
+	Blt_DrawBackgroundRectangle(graphPtr->tkwin, drawable, 
+		graphPtr->normalBg, graphPtr->highlightWidth, 
+		graphPtr->highlightWidth, 
+	 	graphPtr->width - 2 * graphPtr->highlightWidth, 
+		graphPtr->height - 2 * graphPtr->highlightWidth, 
+		graphPtr->borderWidth, graphPtr->relief);
+    }
+    /* Draw focus highlight ring. */
+    if ((graphPtr->highlightWidth > 0) && (graphPtr->flags & FOCUS)) {
+	GC gc;
+
+	gc = Tk_GCForColor(graphPtr->highlightColor, drawable);
+	Tk_DrawFocusHighlight(graphPtr->tkwin, gc, graphPtr->highlightWidth,
+	    drawable);
+    }
+    /* Disable crosshairs before redisplaying to the screen */
+    Blt_DisableCrosshairs(graphPtr);
+    XCopyArea(graphPtr->display, drawable, Tk_WindowId(tkwin),
+	graphPtr->drawGC, 0, 0, graphPtr->width, graphPtr->height, 0, 0);
+    Blt_EnableCrosshairs(graphPtr);
+    if (graphPtr->doubleBuffer) {
+	Tk_FreePixmap(graphPtr->display, drawable);
+    }
+    graphPtr->flags &= ~RESET_WORLD;
+    UpdateMarginTraces(graphPtr);
+}
+
+/*LINTLIBRARY*/
+int
+Blt_GraphCmdInitProc(Tcl_Interp *interp)
+{
+    static Blt_InitCmdSpec cmdSpecs[] = {
+	{"graph", GraphCmd,},
+	{"barchart", BarchartCmd,},
+    };
+    return Blt_InitCmds(interp, "::blt", cmdSpecs, 2);
+}
+
+Graph *
+Blt_GetGraphFromWindowData(Tk_Window tkwin)
+{
+    Graph *graphPtr;
+
+    while (tkwin != NULL) {
+	graphPtr = (Graph *)Blt_GetWindowInstanceData(tkwin);
+	if (graphPtr != NULL) {
+	    return graphPtr;
+	}
+	tkwin = Tk_Parent(tkwin);
+    }
+    return NULL;
+}
+
+int
+Blt_GraphType(Graph *graphPtr)
+{
+    switch (graphPtr->classId) {
+    case CID_ELEM_LINE:
+	return GRAPH;
+    case CID_ELEM_BAR:
+	return BARCHART;
+    default:
+	return 0;
+    }
+    return 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ReconfigureGraph --
+ *
+ *	Allocates resources for the graph.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_ReconfigureGraph(Graph *graphPtr)	
+{
+    ConfigureGraph(graphPtr);
+    Blt_ConfigureLegend(graphPtr);
+    Blt_ConfigureElements(graphPtr);
+    Blt_ConfigureAxes(graphPtr);
+    Blt_ConfigureMarkers(graphPtr);
+}
diff --git a/tlt3.0/bltGraph.h b/tlt3.0/bltGraph.h
new file mode 100644
index 0000000..84688cf
--- /dev/null
+++ b/tlt3.0/bltGraph.h
@@ -0,0 +1,698 @@
+
+/*
+ * bltGraph.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_GRAPH_H
+#define _BLT_GRAPH_H
+
+#include "bltInt.h"
+#include "bltWindow.h"
+#include "bltHash.h"
+#include "bltBind.h"
+#include "bltChain.h"
+#include "bltPs.h"
+#include "bltBgStyle.h"
+
+typedef struct _Graph Graph;
+typedef struct _Element Element;
+typedef struct _Legend Legend;
+
+typedef enum {
+    CID_NONE, 
+    CID_AXIS_X,
+    CID_AXIS_Y,
+    CID_ELEM_BAR,
+    CID_ELEM_LINE,
+    CID_MARKER_BITMAP,
+    CID_MARKER_IMAGE,
+    CID_MARKER_LINE,
+    CID_MARKER_POLYGON,
+    CID_MARKER_TEXT,
+    CID_MARKER_WINDOW,
+    CID_LEGEND_ENTRY,
+} ClassId;
+
+typedef struct {
+    /* Generic fields common to all graph objects. */
+    ClassId classId;		/* Class type of object. */
+    const char *name;		/* Identifier to refer the object. */
+    const char *className;	/* Class name of object. */
+
+    Graph *graphPtr;		/* Graph containing of the object. */
+
+    const char **tags;		/* Binding tags for the object. */
+} GraphObj;
+
+#include "bltGrAxis.h"
+#include "bltGrLegd.h"
+
+#define MARKER_UNDER	1	/* Draw markers designated to lie underneath
+				 * elements, grids, legend, etc. */
+#define MARKER_ABOVE	0	/* Draw markers designated to rest above
+				 * elements, grids, legend, etc. */
+
+#define PADX		2	/* Padding between labels/titles */
+#define PADY    	2	/* Padding between labels */
+
+#define MINIMUM_MARGIN	20	/* Minimum margin size */
+
+
+#define BOUND(x, lo, hi)	 \
+	(((x) > (hi)) ? (hi) : ((x) < (lo)) ? (lo) : (x))
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * 	Graph component structure definitions
+ *
+ *---------------------------------------------------------------------------
+ */
+#define PointInGraph(g,x,y) \
+	(((x) <= (g)->right) && ((x) >= (g)->left) && \
+	 ((y) <= (g)->bottom) && ((y) >= (g)->top))
+
+/*
+ * Mask values used to selectively enable GRAPH or BARCHART entries in the
+ * various configuration specs.
+ */
+#define GRAPH			(BLT_CONFIG_USER_BIT << 1)
+#define STRIPCHART		(BLT_CONFIG_USER_BIT << 2)
+#define BARCHART		(BLT_CONFIG_USER_BIT << 3)
+#define LINE_GRAPHS		(GRAPH | STRIPCHART)
+#define ALL_GRAPHS		(GRAPH | BARCHART | STRIPCHART)
+
+#define ACTIVE_PEN		(BLT_CONFIG_USER_BIT << 16)
+#define NORMAL_PEN		(BLT_CONFIG_USER_BIT << 17)
+#define ALL_PENS		(NORMAL_PEN | ACTIVE_PEN)
+
+typedef struct {
+    Segment2d *segments;
+    int length;
+    int *map;
+} GraphSegments;
+
+typedef struct {
+    Point2d *points;
+    int length;
+    int *map;
+} GraphPoints;
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BarGroup --
+ *
+ *	Represents a sets of bars with the same abscissa. This structure is
+ *	used to track the display of the bars in the group.  
+ *
+ *	Each unique abscissa has at least one group.  Groups can be
+ *	defined by the bar element's -group option.  Multiple groups are
+ *	needed when you are displaying/comparing similar sets of data (same
+ *	abscissas) but belong to a separate group.
+ *	
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    int nSegments;			/* Number of occurrences of
+					 * x-coordinate */
+    Axis2d axes;			/* The axes associated with this
+					 * group. (mapped to the x-value) */
+    float sum;				/* Sum of the ordinates (y-coorinate) of
+					 * each duplicate abscissa. Used to
+					 * determine height of stacked bars. */
+    int count;				/* Current number of bars seen.  Used to
+					 * position of the next bar in the
+					 * group. */
+    float lastY;			/* y-cooridinate position of the
+					 * last bar seen. */
+    size_t index;			/* Order of group in set (an unique
+					 * abscissa may have more than one
+					 * group). */
+} BarGroup;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BarSetKey --
+ *
+ *	Key for hash table of set of bars.  The bar set is defined by
+ *	coordinates with the same abscissa (x-coordinate).
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    float value;			/* Duplicated abscissa */
+    Axis2d axes;			/* Axis mapping of element */
+} BarSetKey;
+
+/*
+ * BarModes --
+ *
+ *	Bar elements are displayed according to their x-y coordinates.  If two
+ *	bars have the same abscissa (x-coordinate), the bar segments will be
+ *	drawn according to one of the following modes:
+ */
+
+typedef enum BarModes {
+    BARS_INFRONT,			/* Each successive bar in a group is
+					 * drawn in front of the previous. */
+    BARS_STACKED,			/* Each successive bar in a group is
+					 * drawn stacked on top of the previous
+					 * bar. */
+    BARS_ALIGNED,			/* Each successive bar in a group is
+					 * drawn aligned side-by-side to the
+					 * previous from right-to-left. */
+    BARS_OVERLAP			/* Like "aligned", each successive bar
+					 * in a group is drawn from
+					 * right-to-left. The bars will overlap
+					 * each other by ~50%. */
+} BarMode;
+
+typedef struct _Pen Pen;
+typedef struct _Marker Marker;
+
+typedef Pen *(PenCreateProc)(void);
+typedef int (PenConfigureProc)(Graph *graphPtr, Pen *penPtr);
+typedef void (PenDestroyProc)(Graph *graphPtr, Pen *penPtr);
+
+struct _Pen {
+    const char *name;			/* Pen style identifier.  If NULL pen
+					 * was statically allocated. */
+    ClassId classId;			/* Type element using this pen. */
+    const char *typeId;			/* String token identifying the type of
+					 * pen. */
+    unsigned int flags;			/* Indicates if the pen element is
+					 * active or normal. */
+    int refCount;			/* Reference count for elements using
+					 * this pen. */
+    Blt_HashEntry *hashPtr;
+
+    Blt_ConfigSpec *configSpecs;	/* Configuration specifications */
+
+    PenConfigureProc *configProc;
+    PenDestroyProc *destroyProc;
+    Graph *graphPtr;			/* Graph that the pen is associated
+					 * with. */
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Crosshairs
+ *
+ *	Contains the line segments positions and graphics context used to
+ *	simulate crosshairs (by XOR-ing) on the graph.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct _Crosshairs Crosshairs;
+
+typedef struct {
+    short int width, height;		/* Dimensions of the margin */
+    short int axesOffset;
+    short int axesTitleLength;		/* Width of the widest title to be
+					 * shown.  Multiple titles are displayed
+					 * in another margin. This is the
+					 * minimum space requirement. */
+    short int maxTickWidth;
+    short int maxTickHeight;
+    unsigned int nAxes;			/* # of axes to be displayed */
+    Blt_Chain axes;			/* Axes associated with this margin */
+    const char *varName;		/* If non-NULL, name of variable to be
+					 * updated when the margin size
+					 * changes */
+    int reqSize;			/* Requested size of margin */
+    int site;				/* Indicates where margin is located:
+					 * left, right, top, or bottom. */
+} Margin;
+
+#define MARGIN_NONE	-1
+#define MARGIN_BOTTOM	0		/* x */
+#define MARGIN_LEFT	1 		/* y */
+#define MARGIN_TOP	2		/* x2 */
+#define MARGIN_RIGHT	3		/* y2 */
+
+#define rightMargin	margins[MARGIN_RIGHT]
+#define leftMargin	margins[MARGIN_LEFT]
+#define topMargin	margins[MARGIN_TOP]
+#define bottomMargin	margins[MARGIN_BOTTOM]
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Graph --
+ *
+ *	Top level structure containing everything pertaining to the graph.
+ *
+ *---------------------------------------------------------------------------
+ */
+struct _Graph {
+    unsigned int flags;			/* Flags;  see below for definitions. */
+    Tcl_Interp *interp;			/* Interpreter associated with graph */
+    Tk_Window tkwin;			/* Window that embodies the graph.
+					 * NULL means that the window has been
+					 * destroyed but the data structures
+					 * haven't yet been cleaned up. */
+    Display *display;			/* Display containing widget; used to
+					 * release resources after tkwin has
+					 * already gone away. */
+    Tcl_Command cmdToken;		/* Token for graph's widget command. */
+    const char *data;			/* This value isn't used in C code.
+					 * It may be used in TCL bindings to
+					 * associate extra data. */
+    Tk_Cursor cursor;
+    int inset;				/* Sum of focus highlight and 3-D
+					 * border.  Indicates how far to
+					 * offset the graph from outside edge
+					 * of the window. */
+    int borderWidth;			/* Width of the exterior border */
+    int relief;				/* Relief of the exterior border. */
+    Blt_Background normalBg;		/* 3-D border used to delineate the
+					 * plot surface and outer edge of
+					 * window. */
+    int highlightWidth;			/* Width in pixels of highlight to
+					 * draw around widget when it has the
+					 * focus.  <= 0 means don't draw a
+					 * highlight. */
+    XColor *highlightBgColor;		/* Color for drawing traversal
+					 * highlight area when highlight is
+					 * off. */
+    XColor *highlightColor;		/* Color for drawing traversal
+					 * highlight. */
+    const char *title;			/* Graph title */
+    short int titleX, titleY;		/* Position of title on graph. */
+    short int titleWidth, titleHeight;	/* Dimensions of title. */
+    TextStyle titleTextStyle;		/* Title attributes: font, color,
+					 * etc.*/
+    
+    const char *takeFocus;		/* Not used in C code, indicates if
+					 * widget should be included in focus
+					 * traversal. */
+    Axis *focusPtr;			/* The axis that currently has focus. */
+    
+    int reqWidth, reqHeight;		/* Requested size of graph window */
+    int reqPlotWidth, reqPlotHeight;	/* Requested size of plot area. Zero
+					 * means to adjust the dimension
+					 * according to the available space
+					 * left in the window. */
+    int width, height;			/* Actual size (in pixels) of graph
+					 * window or PostScript page. */
+    Blt_HashTable penTable;		/* Table of pens */
+    struct Component {
+	Blt_HashTable table;		/* Hash table of ids. */
+	Blt_Chain displayList;		/* Display list. */
+	Blt_HashTable tagTable;		/* Table of bind tags. */
+    } elements, markers, axes;
+
+    Blt_HashTable dataTables;		/* Hash table of datatable clients. */
+    ClassId classId;			/* Default element type */
+    Blt_BindTable bindTable;
+    int nextMarkerId;			/* Tracks next marker identifier
+					 * available */
+    Blt_Chain axisChain[4];		/* Chain of axes for each of the
+					 * margins.  They're separate from the
+					 * margin structures to make it easier
+					 * to invert the X-Y axes by simply
+					 * switching chain pointers. */
+    Margin margins[4];
+    PageSetup *pageSetup;		/* Page layout options: see bltGrPS.c */
+    Legend *legend;			/* Legend information: see
+					 * bltGrLegd.c */
+    Crosshairs *crosshairs;		/* Crosshairs information: see
+					 * bltGrHairs.c */
+    int halo;				/* Maximum distance allowed between
+					 * points when searching for a point */
+    int inverted;			/* If non-zero, indicates the x and y
+					 * axis positions should be inverted. */
+    int stackAxes;			/* If non-zero, indicates to stack
+					 * mulitple axes in a margin, rather
+					 * than layering them one on top of
+					 * another. */
+    GC drawGC;				/* GC for drawing on the margins. This
+					 * includes the axis lines */  
+    int plotBW;				/* Width of interior 3-D border. */
+    int plotRelief;			/* 3-d effect: TK_RELIEF_RAISED etc. */
+    Blt_Background plotBg;		/* Color of plotting surface */
+
+    /* If non-zero, force plot to conform to aspect ratio W/H */
+    float aspect;
+
+    short int left, right;		/* Coordinates of plot bbox */
+    short int top, bottom;	
+
+    Blt_Pad xPad;			/* Vertical padding for plotarea */
+    int vRange, vOffset;		/* Vertical axis range and offset from
+					 * the left side of the graph
+					 * window. Used to transform coordinates
+					 * to vertical axes. */
+    Blt_Pad yPad;			/* Horizontal padding for plotarea */
+    int hRange, hOffset;		/* Horizontal axis range and offset from
+					 * the top of the graph window. Used to
+					 * transform horizontal axes */
+    float vScale, hScale;
+
+    int doubleBuffer;			/* If non-zero, draw the graph into a
+					 * pixmap first to reduce flashing. */
+    int backingStore;			/* If non-zero, cache elements by
+					 * drawing them into a pixmap */
+    Pixmap cache;			/* Pixmap used to cache elements
+					 * displayed.  If *backingStore* is
+					 * non-zero, each element is drawn into
+					 * this pixmap before it is copied onto
+					 * the screen.  The pixmap then acts as
+					 * a cache (only the pixmap is
+					 * redisplayed if the none of elements
+					 * have changed). This is done so that
+					 * markers can be redrawn quickly over
+					 * elements without redrawing each
+					 * element. */
+    short int cacheWidth, cacheHeight;	/* Size of element backing store
+					 * pixmap. */
+
+    /*
+     * barchart specific information
+     */
+    float baseline;			/* Baseline from bar chart.  */
+    float barWidth;			/* Default width of each bar in graph
+					 * units.  The default width is 1.0
+					 * units. */
+    BarMode mode;			/* Mode describing how to display bars
+					 * with the same x-coordinates. Mode can
+					 * be "stacked", "aligned", "overlap",
+					 * or "infront" */
+    BarGroup *barGroups;		/* Contains information about duplicate
+					 * x-values in bar elements (malloc-ed).
+					 * This information can also be accessed
+					 * by the group hash table */
+    int nBarGroups;			/* # of entries in barGroups array.  If 
+					 * zero, indicates nothing special
+					 * needs to be * done for "stack" or
+					 * "align" modes */
+    Blt_HashTable setTable;		/* Table managing sets of bars with
+					 * the same abscissas. The bars in a
+					 * set may be displayed is various
+					 * ways: aligned, overlap, infront, or
+					 * stacked. */
+    int maxBarSetSize;
+    const char *dataCmd;		/* New data callback? */
+
+};
+
+/*
+ * Bit flags definitions:
+ *
+ * 	All kinds of state information kept here.  All these things happen
+ * 	when the window is available to draw into (DisplayGraph). Need the
+ * 	window width and height before we can calculate graph layout (i.e. the
+ * 	screen coordinates of the axes, elements, titles, etc). But we want to
+ * 	do this only when we have to, not every time the graph is redrawn.
+ *
+ *	Same goes for maintaining a pixmap to double buffer graph elements.
+ *	Need to mark when the pixmap needs to updated.
+ *
+ *
+ *	MAP_ITEM		Indicates that the element/marker/axis
+ *				configuration has changed such that
+ *				its layout of the item (i.e. its
+ *				position in the graph window) needs
+ *				to be recalculated.
+ *
+ *	MAP_ALL			Indicates that the layout of the axes and 
+ *				all elements and markers and the graph need 
+ *				to be recalculated. Otherwise, the layout
+ *				of only those markers and elements that
+ *				have changed will be reset. 
+ *
+ *	GET_AXIS_GEOMETRY	Indicates that the size of the axes needs 
+ *				to be recalculated. 
+ *
+ *	RESET_AXES		Flag to call to Blt_ResetAxes routine.  
+ *				This routine recalculates the scale offset
+ *				(used for mapping coordinates) of each axis.
+ *				If an axis limit has changed, then it sets 
+ *				flags to re-layout and redraw the entire 
+ *				graph.  This needs to happend before the axis
+ *				can compute transformations between graph and 
+ *				screen coordinates. 
+ *
+ *	LAYOUT_NEEDED		
+ *
+ *	CACHE_DIRTY		If set, redraw all elements into the pixmap 
+ *				used for buffering elements. 
+ *
+ *	REDRAW_PENDING		Non-zero means a DoWhenIdle handler has 
+ *				already been queued to redraw this window. 
+ *
+ *	DRAW_LEGEND		Non-zero means redraw the legend. If this is 
+ *				the only DRAW_* flag, the legend display 
+ *				routine is called instead of the graph 
+ *				display routine. 
+ *
+ *	DRAW_MARGINS		Indicates that the margins bordering 
+ *				the plotting area need to be redrawn. 
+ *				The possible reasons are:
+ *
+ *				1) an axis configuration changed
+ *				2) an axis limit changed
+ *				3) titles have changed
+ *				4) window was resized. 
+ *
+ *	GRAPH_FOCUS	
+ */
+
+#define HIDE			(1<<0) /* 0x0001 */
+#define DELETE_PENDING		(1<<1) /* 0x0002 */
+#define REDRAW_PENDING		(1<<2) /* 0x0004 */
+#define	ACTIVE_PENDING		(1<<3) /* 0x0008 */
+#define	MAP_ITEM		(1<<4) /* 0x0010 */
+#define DIRTY			(1<<5) /* 0x0020 */
+#define ACTIVE			(1<<6) /* 0x0040 */
+#define FOCUS			(1<<7) /* 0x0080 */
+
+#define	MAP_ALL			(1<<8) /* 0x0100 */
+#define LAYOUT_NEEDED		(1<<9) /* 0x0200 */
+#define RESET_AXES		(1<<10)/* 0x0400 */
+#define	GET_AXIS_GEOMETRY	(1<<11)/* 0x0800 */
+
+#define DRAW_LEGEND		(1<<12)/* 0x1000 */
+#define DRAW_MARGINS		(1<<13)/* 0x2000 */
+#define	CACHE_DIRTY		(1<<14)/* 0x4000 */
+#define REQ_BACKING_STORE	(1<<15)/* 0x8000 */
+#define UNMAP_HIDDEN		(1<<16)
+
+#define	MAP_WORLD		(MAP_ALL|RESET_AXES|GET_AXIS_GEOMETRY)
+#define REDRAW_WORLD		(DRAW_LEGEND)
+#define RESET_WORLD		(REDRAW_WORLD | MAP_WORLD)
+
+/*
+ * ---------------------- Forward declarations ------------------------
+ */
+
+extern int Blt_CreatePageSetup(Graph *graphPtr);
+
+extern int Blt_CreateCrosshairs(Graph *graphPtr);
+
+extern double Blt_InvHMap(Axis *axisPtr, double x);
+
+extern double Blt_InvVMap(Axis *axisPtr, double x);
+
+extern double Blt_HMap(Axis *axisPtr, double x);
+
+extern double Blt_VMap(Axis *axisPtr, double y);
+
+extern Point2d Blt_InvMap2D(Graph *graphPtr, double x, double y, 
+	Axis2d *pairPtr);
+
+extern Point2d Blt_Map2D(Graph *graphPtr, double x, double y, 
+	Axis2d *pairPtr);
+
+extern Graph *Blt_GetGraphFromWindowData(Tk_Window tkwin);
+
+extern void Blt_AdjustAxisPointers(Graph *graphPtr);
+
+extern int Blt_PolyRectClip(Region2d *extsPtr, Point2d *inputPts,
+	int nInputPts, Point2d *outputPts);
+
+extern void Blt_ComputeBarStacks(Graph *graphPtr);
+
+extern void Blt_ConfigureCrosshairs(Graph *graphPtr);
+extern void Blt_ConfigureLegend(Graph *graphPtr);
+extern void Blt_ConfigureElements(Graph *graphPtr);
+extern void Blt_ConfigureAxes(Graph *graphPtr);
+extern void Blt_ConfigureMarkers(Graph *graphPtr);
+extern void Blt_ReconfigureGraph(Graph *graphPtr);
+
+extern void Blt_DestroyAxes(Graph *graphPtr);
+
+extern void Blt_DestroyCrosshairs(Graph *graphPtr);
+
+extern void Blt_DestroyElements(Graph *graphPtr);
+
+extern void Blt_DestroyMarkers(Graph *graphPtr);
+
+extern void Blt_DestroyPageSetup(Graph *graphPtr);
+
+extern void Blt_DrawAxes(Graph *graphPtr, Drawable drawable);
+
+extern void Blt_DrawAxisLimits(Graph *graphPtr, Drawable drawable);
+
+extern void Blt_DrawElements(Graph *graphPtr, Drawable drawable);
+
+extern void Blt_DrawActiveElements(Graph *graphPtr, Drawable drawable);
+
+extern void Blt_DrawGraph(Graph *graphPtr, Drawable drawable);
+
+extern void Blt_DrawMarkers(Graph *graphPtr, Drawable drawable, int under);
+
+extern void Blt_Draw2DSegments(Display *display, Drawable drawable, GC gc, 
+	Segment2d *segments, int nSegments);
+
+extern int Blt_GetCoordinate(Tcl_Interp *interp, const char *string, 
+	double *valuePtr);
+
+extern void Blt_InitBarSetTable(Graph *graphPtr);
+
+extern void Blt_LayoutGraph(Graph *graphPtr);
+
+extern void Blt_EventuallyRedrawGraph(Graph *graphPtr);
+
+extern void Blt_ResetAxes(Graph *graphPtr);
+
+extern void Blt_ResetBarGroups(Graph *graphPtr);
+
+extern void Blt_GraphExtents(Graph *graphPtr, Region2d *extsPtr);
+
+extern void Blt_DisableCrosshairs(Graph *graphPtr);
+
+extern void Blt_EnableCrosshairs(Graph *graphPtr);
+
+extern void Blt_MapGraph(Graph *graphPtr);
+
+extern void Blt_MapAxes(Graph *graphPtr);
+
+extern void Blt_MapElements(Graph *graphPtr);
+
+extern void Blt_MapMarkers(Graph *graphPtr);
+
+extern void Blt_UpdateCrosshairs(Graph *graphPtr);
+
+extern void Blt_DestroyPens(Graph *graphPtr);
+
+extern int Blt_GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, 
+	Tcl_Obj *objPtr, ClassId classId, Pen **penPtrPtr);
+
+extern Pen *Blt_BarPen(const char *penName);
+
+extern Pen *Blt_LinePen(const char *penName);
+
+extern Pen *Blt_CreatePen(Graph *graphPtr, const char *penName, 
+	ClassId classId, int objc, Tcl_Obj *const *objv);
+
+extern int Blt_InitLinePens(Graph *graphPtr);
+
+extern int Blt_InitBarPens(Graph *graphPtr);
+
+extern void Blt_FreePen(Pen *penPtr);
+
+extern int Blt_VirtualAxisOp(Graph *graphPtr, Tcl_Interp *interp, 
+	int objc, Tcl_Obj *const *objv);
+
+extern int Blt_AxisOp(Tcl_Interp *interp, Graph *graphPtr, int margin, 
+	int objc, Tcl_Obj *const *objv);
+
+extern int Blt_ElementOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv, ClassId classId);
+
+extern int Blt_CrosshairsOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+extern int Blt_MarkerOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+extern int Blt_PenOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+extern int Blt_PointInPolygon(Point2d *samplePtr, Point2d *screenPts, 
+	int nScreenPts);
+
+extern int Blt_RegionInPolygon(Region2d *extsPtr, Point2d *points, 
+	int nPoints, int enclosed);
+
+extern int Blt_PointInSegments(Point2d *samplePtr, Segment2d *segments, 
+	int nSegments, double halo);
+
+extern int Blt_PostScriptOp(Graph *graphPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+extern int Blt_GraphUpdateNeeded(Graph *graphPtr);
+
+extern int Blt_DefaultAxes(Graph *graphPtr);
+
+extern Axis *Blt_GetFirstAxis(Blt_Chain chain);
+
+extern void Blt_UpdateAxisBackgrounds(Graph *graphPtr);
+
+extern Marker *Blt_NearestMarker(Graph *graphPtr, int x, int y, int under);
+
+extern Axis *Blt_NearestAxis(Graph *graphPtr, int x, int y);
+
+typedef ClientData (MakeTagProc)(Graph *graphPtr, const char *tagName);
+
+extern MakeTagProc Blt_MakeElementTag;
+extern MakeTagProc Blt_MakeMarkerTag;
+extern MakeTagProc Blt_MakeAxisTag;
+extern Blt_BindTagProc Blt_GraphTags;
+extern Blt_BindTagProc Blt_AxisTags;
+
+extern int Blt_GraphType(Graph *graphPtr);
+
+extern void Blt_UpdateGraph(ClientData clientData);
+
+extern void Blt_GraphSetObjectClass(GraphObj *graphObjPtr,ClassId classId);
+
+extern void Blt_MarkersToPostScript(Graph *graphPtr, Blt_Ps ps, int under);
+extern void Blt_ElementsToPostScript(Graph *graphPtr, Blt_Ps ps);
+extern void Blt_ActiveElementsToPostScript(Graph *graphPtr, Blt_Ps ps);
+extern void Blt_LegendToPostScript(Graph *graphPtr, Blt_Ps ps);
+extern void Blt_AxesToPostScript(Graph *graphPtr, Blt_Ps ps);
+extern void Blt_AxisLimitsToPostScript(Graph *graphPtr, Blt_Ps ps);
+
+extern Element *Blt_LineElement(Graph *graphPtr, const char *name, 
+	ClassId classId);
+extern Element *Blt_BarElement(Graph *graphPtr, const char *name, 
+	ClassId classId);
+
+extern void Blt_DrawGrids(Graph *graphPtr, Drawable drawable);
+
+extern void Blt_GridsToPostScript(Graph *graphPtr, Blt_Ps ps);
+extern void Blt_InitBarSetTable(Graph *graphPtr);
+extern void Blt_DestroyBarSets(Graph *graphPtr);
+
+/* ---------------------- Global declarations ------------------------ */
+
+extern const char *Blt_GraphClassName(ClassId classId);
+
+#endif /* _BLT_GRAPH_H */
diff --git a/tlt3.0/bltHash.c b/tlt3.0/bltHash.c
new file mode 100644
index 0000000..2d4cf72
--- /dev/null
+++ b/tlt3.0/bltHash.c
@@ -0,0 +1,1266 @@
+
+/* 
+ * bltHash.c --
+ *
+ * This module implements an in-memory hash table for the BLT toolkit.  Built
+ * upon the TCL hash table, it adds pool allocation 64-bit address handling,
+ * improved array hash function.
+ *
+ *	Copyright 2001 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Both the MIX32 and MIX64 routine are from Bob Jenkins.
+ *
+ *	Bob Jenkins, 1996.  hash.c.  Public Domain.
+ *	Bob Jenkins, 1997.  lookup8.c.  Public Domain.
+ *
+ * The hash table implementation is base upon the one in the Tcl distribution.
+ *
+ *	Copyright (c) 1991-1993 The Regents of the University of
+ *	California.  
+ *
+ *	Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ *	See the file "license.terms" for information on usage and
+ *	redistribution of this file, and for a DISCLAIMER OF ALL
+ *	WARRANTIES.
+ *
+ */
+
+#include <bltInt.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "bltHash.h"
+
+/*
+ * When there are this many entries per bucket, on average, rebuild the hash
+ * table to make it larger.
+ */
+
+#define REBUILD_MULTIPLIER	3
+
+/*
+ * Procedure prototypes for static procedures in this file:
+ */
+static Blt_Hash HashArray(const void *key, size_t length);
+static Blt_HashEntry *ArrayFind(Blt_HashTable *tablePtr, const void *key);
+static Blt_HashEntry *ArrayCreate(Blt_HashTable *tablePtr, const void *key, 
+	int *isNewPtr);
+static Blt_HashEntry *BogusFind(Blt_HashTable *tablePtr, const void *key);
+static Blt_HashEntry *BogusCreate(Blt_HashTable *tablePtr, const void *key, 
+	int *isNewPtr);
+static Blt_Hash HashString(const char *string);
+static void RebuildTable(Blt_HashTable *tablePtr);
+static Blt_HashEntry *StringFind(Blt_HashTable *tablePtr, const void *key);
+static Blt_HashEntry *StringCreate(Blt_HashTable *tablePtr, const void *key, 
+	int *isNewPtr);
+static Blt_HashEntry *OneWordFind(Blt_HashTable *tablePtr, const void *key);
+static Blt_HashEntry *OneWordCreate(Blt_HashTable *tablePtr, const void *key, 
+	int *isNewPtr);
+
+static Blt_Hash RandomIndex(Blt_HashTable *tablePtr, const void *key);
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * HashString --
+ *
+ *	Compute a one-word summary of a text string, which can be used to
+ *	generate a hash index.
+ *
+ * Results:
+ *	The return value is a one-word summary of the information in string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_Hash
+HashString(const char *string)		/* String from which to compute hash
+					 * value. */
+{
+    Blt_Hash result;
+    Blt_Hash c;
+
+    /*
+     * I tried a zillion different hash functions and asked many other
+     * people for advice.  Many people had their own favorite functions,
+     * all different, but no-one had much idea why they were good ones.
+     * I chose the one below (multiply by 9 and add new character)
+     * because of the following reasons:
+     *
+     * 1. Multiplying by 10 is perfect for keys that are decimal strings,
+     *    and multiplying by 9 is just about as good.
+     * 2. Times-9 is (shift-left-3) plus (old).  This means that each
+     *    character's bits hang around in the low-order bits of the
+     *    hash value for ever, plus they spread fairly rapidly up to
+     *    the high-order bits to fill out the hash value.  This seems
+     *    to work well both for decimal and non-decimal strings.
+     */
+
+    result = 0;
+    while ((c = *string++) != 0) {
+	result += (result << 3) + c;
+    }
+    return (Blt_Hash)result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * StringFind --
+ *
+ *	Given a hash table with string keys, and a string key, find the entry
+ *	with a matching key.
+ *
+ * Results:
+ *	The return value is a token for the matching entry in the hash table,
+ *	or NULL if there was no matching entry.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_HashEntry *
+StringFind(
+    Blt_HashTable *tablePtr,		/* Table in which to lookup entry. */
+    const void *key)			/* Key to find matching entry. */
+{
+    Blt_Hash hval;
+    Blt_HashEntry *hPtr;
+    size_t hindex;
+
+    hval = HashString((const char *)key);
+    hindex = hval & tablePtr->mask;
+
+    /*
+     * Search all of the entries in the appropriate bucket.
+     */
+    for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL; hPtr = hPtr->nextPtr) {
+	if (hPtr->hval == hval) {
+	    const char *p1, *p2;
+
+	    for (p1 = key, p2 = hPtr->key.string; ; p1++, p2++) {
+		if (*p1 != *p2) {
+		    break;
+		}
+		if (*p1 == '\0') {
+		    return hPtr;
+		}
+	    }
+	}
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * StringCreate --
+ *
+ *	Given a hash table with string keys, and a string key, find the entry
+ *	with a matching key.  If there is no matching entry, then create a new
+ *	entry that does match.
+ *
+ * Results:
+ *	The return value is a pointer to the matching entry.  If this is a
+ *	newly-created entry, then *isNewPtr will be set to a non-zero value;
+ *	otherwise *isNewPtr will be set to 0.  If this is a new entry the
+ *	value stored in the entry will initially be 0.
+ *
+ * Side effects:
+ *	A new entry may be added to the hash table.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_HashEntry *
+StringCreate(
+    Blt_HashTable *tablePtr,		/* Table in which to lookup entry. */
+    const void *key,			/* Key to use to find or create
+					 * matching entry. */
+    int *isNewPtr)			/* Store info here telling whether a
+					 * new entry was created. */
+{
+    Blt_Hash hval;
+    Blt_HashEntry **bucketPtr;
+    Blt_HashEntry *hPtr;
+    size_t size, hindex;
+
+    hval = HashString(key);
+    hindex = hval & tablePtr->mask;
+
+    /* Search all of the entries in this bucket. */
+
+    for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL;
+	    hPtr = hPtr->nextPtr) {
+	if (hPtr->hval == hval) {
+	    const char *p1, *p2;
+
+	    for (p1 = key, p2 = hPtr->key.string; ; p1++, p2++) {
+		if (*p1 != *p2) {
+		    break;
+		}
+		if (*p1 == '\0') {
+		    *isNewPtr = FALSE;
+		    return hPtr;
+		}
+	    }
+	}
+    }
+
+    /* Entry not found.  Add a new one to the bucket. */
+
+    *isNewPtr = TRUE;
+    size = sizeof(Blt_HashEntry) + strlen(key) - sizeof(Blt_HashKey) + 1;
+    if (tablePtr->hPool != NULL) {
+	hPtr = Blt_PoolAllocItem(tablePtr->hPool, size);
+    } else {
+	hPtr = malloc(size);
+    }
+    bucketPtr = tablePtr->buckets + hindex;
+    hPtr->nextPtr = *bucketPtr;
+    hPtr->hval = hval;
+    hPtr->clientData = 0;
+    strcpy(hPtr->key.string, key);
+    *bucketPtr = hPtr;
+    tablePtr->numEntries++;
+
+    /*
+     * If the table has exceeded a decent size, rebuild it with many more
+     * buckets.
+     */
+
+    if (tablePtr->numEntries >= tablePtr->rebuildSize) {
+	RebuildTable(tablePtr);
+    }
+    return hPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * HashOneWord --
+ *
+ *	Compute a one-word hash value of a 64-bit word, which then can be used
+ *	to generate a hash index.
+ *
+ *	From Knuth, it's a multiplicative hash.  Multiplies an unsigned 64-bit
+ *	value with the golden ratio (sqrt(5) - 1) / 2.  The downshift value is
+ *	64 - n, where n is the log2 of the size of the hash table.
+ *		
+ * Results:
+ *	The return value is a one-word summary of the information in 64 bit
+ *	word.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_Hash RandomIndex(Blt_HashTable *tablePtr, const void *key)
+{
+  if (sizeof(void*) == 8) {
+    uint64_t a0, a1;
+    uint64_t y0, y1;
+    uint64_t y2, y3; 
+    uint64_t p1, p2;
+    uint64_t result;
+    /* Compute key * GOLDEN_RATIO in 128-bit arithmetic */
+    a0 = (uint64_t)key & 0x00000000FFFFFFFF; 
+    a1 = (uint64_t)key >> 32;
+    
+    y0 = a0 * 0x000000007f4a7c13;
+    y1 = a0 * 0x000000009e3779b9; 
+    y2 = a1 * 0x000000007f4a7c13;
+    y3 = a1 * 0x000000009e3779b9; 
+    y1 += y0 >> 32;			/* Can't carry */ 
+    y1 += y2;				/* Might carry */
+    if (y1 < y2) {
+	y3 += (1LL << 32);		/* Propagate */ 
+    }
+
+    /* 128-bit product: p1 = loword, p2 = hiword */
+    p1 = ((y1 & 0x00000000FFFFFFFF) << 32) + (y0 & 0x00000000FFFFFFFF);
+    p2 = y3 + (y1 >> 32);
+    
+    /* Left shift the value downward by the size of the table */
+    if (tablePtr->downShift > 0) { 
+	if (tablePtr->downShift < 64) { 
+	    result = ((p2 << (64 - tablePtr->downShift)) | 
+		      (p1 >> (tablePtr->downShift & 63))); 
+	} else { 
+	    result = p2 >> (tablePtr->downShift & 63); 
+	} 
+    } else { 
+	result = p1;
+    } 
+    /* Finally mask off the high bits */
+    return (Blt_Hash)(result & tablePtr->mask);
+  }
+  else {
+    return (((((long) (key))*1103515245) >> (tablePtr)->downShift) & (tablePtr)->mask);
+  }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * OneWordFind --
+ *
+ *	Given a hash table with one-word keys, and a one-word key, find the
+ *	entry with a matching key.
+ *
+ * Results:
+ *	The return value is a token for the matching entry in the hash table,
+ *	or NULL if there was no matching entry.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_HashEntry *
+OneWordFind(
+    Blt_HashTable *tablePtr,		/* Table where to lookup entry. */
+    const void *key)			/* Key that we're searching for. */
+{
+    Blt_HashEntry *hPtr;
+    size_t hindex;
+
+    hindex = RandomIndex(tablePtr, key);
+
+    /* Search all of the entries in the appropriate bucket. */
+    for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL;
+	    hPtr = hPtr->nextPtr) {
+	if (hPtr->key.oneWordValue == key) {
+	    return hPtr;
+	}
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * OneWordCreate --
+ *
+ *	Given a hash table with one-word keys, and a one-word key, find the
+ *	entry with a matching key.  If there is no matching entry, then create
+ *	a new entry that does match.
+ *
+ * Results:
+ *	The return value is a pointer to the matching entry.  If this is a
+ *	newly-created entry, then *isNewPtr will be set to a non-zero value;
+ *	otherwise *isNewPtr will be set to 0.  If this is a new entry the value
+ *	stored in the entry will initially be 0.
+ *
+ * Side effects:
+ *	A new entry may be added to the hash table.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_HashEntry *
+OneWordCreate(
+    Blt_HashTable *tablePtr,		/* Table in which to lookup entry. */
+    const void *key,			/* Key to use to find or create
+					 * matching entry. */
+    int *isNewPtr)			/* Store info here telling whether a
+					 * new entry was created. */
+{
+    Blt_HashEntry **bucketPtr;
+    Blt_HashEntry *hPtr;
+    size_t hindex;
+
+    hindex = RandomIndex(tablePtr, key);
+
+    /* Search all of the entries in this bucket. */
+
+    for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL; hPtr = hPtr->nextPtr) {
+	if (hPtr->key.oneWordValue == key) {
+	    *isNewPtr = FALSE;
+	    return hPtr;
+	}
+    }
+
+    /* Entry not found.  Add a new one to the bucket. */
+
+    *isNewPtr = TRUE;
+    if (tablePtr->hPool != NULL) {
+	hPtr = Blt_PoolAllocItem(tablePtr->hPool, sizeof(Blt_HashEntry));
+    } else {
+	hPtr = malloc(sizeof(Blt_HashEntry));
+    }	
+    bucketPtr = tablePtr->buckets + hindex;
+    hPtr->nextPtr = *bucketPtr;
+    hPtr->hval = (Blt_Hash)key;
+    hPtr->clientData = 0;
+    hPtr->key.oneWordValue = (void *)key; /* const XXXX */
+    *bucketPtr = hPtr;
+    tablePtr->numEntries++;
+
+    /*
+     * If the table has exceeded a decent size, rebuild it with many more
+     * buckets.
+     */
+
+    if (tablePtr->numEntries >= tablePtr->rebuildSize) {
+	RebuildTable(tablePtr);
+    }
+    return hPtr;
+}
+
+
+#if (INTPTR_MAX	== INT32_MAX) 
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MIX32 -- 
+ *
+ *      Bob Jenkins, 1996.  Public Domain.
+ *
+ *	Mix 3 32/64-bit values reversibly.  For every delta with one or two
+ *	bit set, and the deltas of all three high bits or all three low bits,
+ *	whether the original value of a,b,c is almost all zero or is uniformly
+ *	distributed, If mix() is run forward or backward, at least 32 bits in
+ *	a,b,c have at least 1/4 probability of changing.  * If mix() is run
+ *	forward, every bit of c will change between 1/3 and 2/3 of the time.
+ *	(Well, 22/100 and 78/100 for some 2-bit deltas.)  mix() was built out
+ *	of 36 single-cycle latency instructions in a structure that could
+ *	supported 2x parallelism, like so:
+ *
+ *		a -= b; 
+ *		a -= c; x = (c>>13);
+ *		b -= c; a ^= x;
+ *		b -= a; x = (a<<8);
+ *		c -= a; b ^= x;
+ *		c -= b; x = (b>>13);
+ *		...
+ *
+ *	 Unfortunately, superscalar Pentiums and Sparcs can't take advantage
+ *	 of that parallelism.  They've also turned some of those single-cycle
+ *	 latency instructions into multi-cycle latency instructions.  Still,
+ *	 this is the fastest good hash I could find.  There were about 2^^68
+ *	 to choose from.  I only looked at a billion or so.
+ *
+ * -------------------------------------------------------------------------- 
+ */
+#define MIX32(a,b,c) \
+	a -= b, a -= c, a ^= (c >> 13), \
+	b -= c, b -= a, b ^= (a <<  8), \
+	c -= a, c -= b, c ^= (b >> 13), \
+	a -= b, a -= c, a ^= (c >> 12), \
+	b -= c, b -= a, b ^= (a << 16), \
+	c -= a, c -= b, c ^= (b >>  5), \
+	a -= b, a -= c, a ^= (c >>  3), \
+	b -= c, b -= a, b ^= (a << 10), \
+	c -= a, c -= b, c ^= (b >> 15)
+
+#define GOLDEN_RATIO32	0x9e3779b9	/* An arbitrary value */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * HashArray --
+ *
+ *      Bob Jenkins, 1996.  Public Domain.
+ *
+ *	This works on all machines.  Length has to be measured in unsigned
+ *	longs instead of bytes.  It requires that
+ *
+ *	  o The key be an array of unsigned ints.
+ *	  o All your machines have the same endianness
+ *	  o The length be the number of unsigned ints in the key.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_Hash
+HashArray(const void *key, size_t length)
+{
+    uint32_t a, b, c, len;
+    uint32_t *arrayPtr = (uint32_t *)key;
+    /* Set up the internal state */
+    len = length;
+    a = b = GOLDEN_RATIO32;		/* An arbitrary value */
+    c = 0;				/* Previous hash value */
+
+    while (len >= 3) {			/* Handle most of the key */
+	a += arrayPtr[0];
+	b += arrayPtr[1];
+	c += arrayPtr[2];
+	MIX32(a, b, c);
+	arrayPtr += 3; len -= 3;
+    }
+    c += length;		
+    /* And now the last 2 words */
+    /* Note that all the case statements fall through */
+    switch(len) {
+	/* c is reserved for the length */
+    case 2 : b += arrayPtr[1];
+    case 1 : a += arrayPtr[0];
+	/* case 0: nothing left to add */
+    }
+    MIX32(a, b, c);
+    return (Blt_Hash)c;
+}
+#endif
+
+#if (INTPTR_MAX	== INT64_MAX) 
+/* 
+ *---------------------------------------------------------------------------
+ *
+ * MIX64 --
+ *
+ *	Bob Jenkins, January 4 1997, Public Domain.  You can use this free for
+ *	any purpose.  It has no warranty.
+ *
+ *	Returns a 64-bit value.  Every bit of the key affects every bit of the
+ *	return value.  No funnels.  Every 1-bit and 2-bit delta achieves
+ *	avalanche.  About 41+5len instructions.
+ *
+ *	The best hash table sizes are powers of 2.  There is no need to do mod
+ *	a prime (mod is sooo slow!).  If you need less than 64 bits, use a
+ *	bitmask.  For example, if you need only 10 bits, do h = (h &
+ *	hashmask(10)); In which case, the hash table should have hashsize(10)
+ *	elements.
+ *
+ *	By Bob Jenkins, Jan 4 1997.  bob_jenkins at burtleburtle.net.  You may
+ *	use this code any way you wish, private, educational, or commercial,
+ *	as long as this whole comment accompanies it.
+ * 
+ *	See http://burtleburtle.net/bob/hash/evahash.html Use for hash table
+ *	lookup, or anything where one collision in 2^^64 * is acceptable.  Do
+ *	NOT use for cryptographic purposes.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+#define MIX64(a,b,c) \
+	a -= b, a -= c, a ^= (c >> 43), \
+	b -= c, b -= a, b ^= (a <<  9), \
+	c -= a, c -= b, c ^= (b >>  8), \
+	a -= b, a -= c, a ^= (c >> 38), \
+	b -= c, b -= a, b ^= (a << 23), \
+	c -= a, c -= b, c ^= (b >>  5), \
+	a -= b, a -= c, a ^= (c >> 35), \
+	b -= c, b -= a, b ^= (a << 49), \
+	c -= a, c -= b, c ^= (b >> 11), \
+	a -= b, a -= c, a ^= (c >> 12), \
+	b -= c, b -= a, b ^= (a << 18), \
+	c -= a, c -= b, c ^= (b >> 22)
+
+#define GOLDEN_RATIO64	0x9e3779b97f4a7c13LL
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * HashArray --
+ *
+ *	Bob Jenkins, January 4 1997, Public Domain.  You can use this free for
+ *	any purpose.  It has no warranty.
+ *
+ *	This works on all machines.  The length has to be measured in 64 bit
+ *	words, instead of bytes.  It requires that
+ *
+ *	  o The key be an array of 64 bit words (unsigned longs).
+ *	  o All your machines have the same endianness.
+ *	  o The length be the number of 64 bit words in the key.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_Hash
+HashArray(const void *key, size_t length)
+{
+    uint64_t a, b, c, len;
+    uint32_t *ip = (uint32_t *)key;
+
+#ifdef WORDS_BIGENDIAN
+#define PACK(a,b)	((uint64_t)(b) | ((uint64_t)(a) << 32))
+#else
+#define PACK(a,b)	((uint64_t)(a) | ((uint64_t)(b) << 32))
+#endif
+    /* Set up the internal state */
+    len = length;			/* Length is the number of 64-bit
+					 * words. */
+    a = b = GOLDEN_RATIO64;		/* An arbitrary value */
+    c = 0;				/* Previous hash value */
+
+    while (len >= 6) {			/* Handle most of the key */
+	a += PACK(ip[0], ip[1]);
+	b += PACK(ip[2], ip[3]);
+	c += PACK(ip[4], ip[5]);
+	MIX64(a,b,c);
+	ip += 6; len -= 6;
+    }
+    c += length;		
+    /* And now the last 2 words */
+    /* Note that all the case statements fall through */
+    switch(len) {
+	/* c is reserved for the length */
+    case 5 : 
+    case 4 : 
+	a += PACK(ip[0], ip[1]);
+	b += PACK(ip[2], ip[3]);
+	ip += 4; len -= 4;
+	break;
+    case 3 : 
+    case 2 : 
+	a += PACK(ip[0], ip[1]);
+	ip += 2; len -= 2;
+ /* case 0: nothing left to add */
+    }
+    if (len > 0) {		
+	b += ip[0];
+    }
+    MIX64(a,b,c);
+    return (Blt_Hash)c;
+}
+#endif
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ArrayFind --
+ *
+ *	Given a hash table with array-of-int keys, and a key, find the entry
+ *	with a matching key.
+ *
+ * Results:
+ *	The return value is a token for the matching entry in the hash table,
+ *	or NULL if there was no matching entry.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_HashEntry *
+ArrayFind(
+    Blt_HashTable *tablePtr,		/* Table in which to lookup entry. */
+    const void *key)			/* Key to use to find matching entry. */
+{
+    Blt_Hash hval;
+    Blt_HashEntry *hPtr;
+    size_t hindex;
+
+    hval = HashArray(key, tablePtr->keyType);
+    hindex = hval & tablePtr->mask;
+
+    /* Search all of the entries in the appropriate bucket. */
+    for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL;
+	    hPtr = hPtr->nextPtr) {
+	if (hPtr->hval == hval) {
+	    uint32_t *ip1, *ip2;
+	    size_t count;
+
+	    for (ip1 = (uint32_t *)key, ip2 = (uint32_t *)hPtr->key.words,
+		     count = tablePtr->keyType; ; count--, ip1++, ip2++) {
+		if (count == 0) {
+		    return hPtr;
+		}
+		if (*ip1 != *ip2) {
+		    break;
+		}
+	    }
+	}
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ArrayCreate --
+ *
+ *	Given a hash table with one-word keys, and a one-word key, find the
+ *	entry with a matching key.  If there is no matching entry, then create a
+ *	new entry that does match.
+ *
+ * Results:
+ *	The return value is a pointer to the matching entry.  If this is a
+ *	newly-created entry, then *isNewPtr will be set to a non-zero value;
+ *	otherwise *isNewPtr will be set to 0.  If this is a new entry the value
+ *	stored in the entry will initially be 0.
+ *
+ * Side effects:
+ *	A new entry may be added to the hash table.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_HashEntry *
+ArrayCreate(
+    Blt_HashTable *tablePtr,		/* Table in which to lookup entry. */
+    const void *key,			/* Key to use to find or create
+					 * matching entry. */
+    int *isNewPtr)			/* Store info here telling whether a
+					 * new entry was created. */
+{
+    Blt_Hash hval;
+    Blt_HashEntry **bucketPtr;
+    size_t count;
+    Blt_HashEntry *hPtr;
+    uint32_t *ip1, *ip2;
+    size_t size, hindex;
+
+    hval = HashArray(key, tablePtr->keyType);
+    hindex = hval & tablePtr->mask;
+
+    /* Search all of the entries in the appropriate bucket. */
+
+    for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL;
+	    hPtr = hPtr->nextPtr) {
+	if (hPtr->hval == hval) {
+	    for (ip1 = (uint32_t *)key, ip2 = (uint32_t *)hPtr->key.words,
+		     count = tablePtr->keyType; ; count--, ip1++, ip2++) {
+		if (count == 0) {
+		    *isNewPtr = FALSE;
+		    return hPtr;
+		}
+		if (*ip1 != *ip2) {
+		    break;
+		}
+	    }
+	}
+    }
+
+    /* Entry not found.  Add a new one to the bucket. */
+
+    *isNewPtr = TRUE;
+    /* We assume here that the size of the key is at least 2 words */
+    size = sizeof(Blt_HashEntry) + tablePtr->keyType * sizeof(uint32_t) - 
+	sizeof(Blt_HashKey);
+    if (tablePtr->hPool != NULL) {
+	hPtr = Blt_PoolAllocItem(tablePtr->hPool, size);
+    } else {
+	hPtr = malloc(size);
+    }
+    bucketPtr = tablePtr->buckets + hindex;
+    hPtr->nextPtr = *bucketPtr;
+    hPtr->hval = hval;
+    hPtr->clientData = 0;
+    count = tablePtr->keyType;
+    for (ip1 = (uint32_t *)key, ip2 = (uint32_t *)hPtr->key.words; 
+	 count > 0; count--, ip1++, ip2++) {
+	*ip2 = *ip1;
+    }
+    *bucketPtr = hPtr;
+    tablePtr->numEntries++;
+
+    /*
+     * If the table has exceeded a decent size, rebuild it with many more
+     * buckets.
+     */
+    if (tablePtr->numEntries >= tablePtr->rebuildSize) {
+	RebuildTable(tablePtr);
+    }
+    return hPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BogusFind --
+ *
+ *	This procedure is invoked when an Blt_FindHashEntry is called on a
+ *	table that has been deleted.
+ *
+ * Results:
+ *	If panic returns (which it shouldn't) this procedure returns NULL.
+ *
+ * Side effects:
+ *	Generates a panic.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static Blt_HashEntry *
+BogusFind(
+    Blt_HashTable *tablePtr,		/* Not used. */
+    const void *key)			/* Not used.*/
+{
+    Blt_Panic("called Blt_FindHashEntry on deleted table");
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BogusCreate --
+ *
+ *	This procedure is invoked when an Blt_CreateHashEntry is called on a
+ *	table that has been deleted.
+ *
+ * Results:
+ *	If panic returns (which it shouldn't) this procedure returns NULL.
+ *
+ * Side effects:
+ *	Generates a panic.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static Blt_HashEntry *
+BogusCreate(
+    Blt_HashTable *tablePtr,		/* Not used. */
+    const void *key,			/* Not used. */
+    int *isNewPtr)			/* Not used. */
+{
+    Blt_Panic("called Blt_CreateHashEntry on deleted table");
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RebuildTable --
+ *
+ *	This procedure is invoked when the ratio of entries to hash buckets
+ *	becomes too large.  It creates a new table with a larger bucket array
+ *	and moves all of the entries into the new table.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory gets reallocated and entries get re-hashed to new buckets.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+RebuildTable(Blt_HashTable *tablePtr)	/* Table to enlarge. */
+{
+    Blt_HashEntry **oldBuckets;
+    int oldNumBuckets;
+
+    oldBuckets = tablePtr->buckets;
+    oldNumBuckets = tablePtr->numBuckets;
+    /*
+     * Allocate and initialize the new bucket array, and set up hashing
+     * constants for new array size.
+     */
+    tablePtr->numBuckets <<= 2;
+    tablePtr->buckets = calloc(tablePtr->numBuckets, sizeof(Blt_HashEntry *));
+    tablePtr->rebuildSize <<= 2;
+    tablePtr->downShift -= 2;
+    tablePtr->mask = tablePtr->numBuckets - 1;
+
+    /*
+     * Move all of the existing entries into the new bucket array, based on
+     * their hash values.
+     */
+    if (tablePtr->keyType == BLT_ONE_WORD_KEYS) {
+	Blt_HashEntry **hpp, **hend;
+
+	/* 
+	 * BLT_ONE_WORD_KEYS are handled slightly differently because they use
+	 * the current table size (number of buckets) to distribute the entries.
+	 */
+	for (hpp = oldBuckets, hend = hpp + oldNumBuckets; hpp < hend; hpp++) {
+	    Blt_HashEntry *hPtr, *nextPtr;
+
+	    for (hPtr = *hpp; hPtr != NULL; hPtr = nextPtr) {
+		Blt_HashEntry **bucketPtr;
+		size_t hindex;
+
+		nextPtr = hPtr->nextPtr;
+		hindex = RandomIndex(tablePtr, hPtr->key.oneWordValue);
+		bucketPtr = tablePtr->buckets + hindex;
+		hPtr->nextPtr = *bucketPtr;
+		*bucketPtr = hPtr;
+	    }
+	}
+    } else {
+	Blt_HashEntry **hpp, **hend;
+
+	for (hpp = oldBuckets, hend = hpp + oldNumBuckets; hpp < hend; hpp++) {
+	    Blt_HashEntry *hPtr, *nextPtr;
+
+	    for (hPtr = *hpp; hPtr != NULL; hPtr = nextPtr) {
+		Blt_HashEntry **bucketPtr;
+		size_t hindex;
+
+		nextPtr = hPtr->nextPtr;
+		hindex = hPtr->hval & tablePtr->mask;
+		bucketPtr = tablePtr->buckets + hindex;
+		hPtr->nextPtr = *bucketPtr;
+		*bucketPtr = hPtr;
+	    }
+	}
+    }
+
+    /*
+     * Free up the old bucket array, if it was dynamically allocated.
+     */
+    if (oldBuckets != tablePtr->staticBuckets) {
+	free(oldBuckets);
+    }
+}
+
+
+/* Public hash table routines */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_InitHashTable --
+ *
+ *	Given storage for a hash table, set up the fields to prepare the hash
+ *	table for use.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	TablePtr is now ready to be passed to Blt_FindHashEntry and
+ *	Blt_CreateHashEntry.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_InitHashTable(Blt_HashTable *tablePtr, size_t keyType)
+{
+#if (BLT_SMALL_HASH_TABLE != 4) 
+    Blt_Panic("Blt_InitHashTable: BLT_SMALL_HASH_TABLE is %d, not 4\n",
+	    BLT_SMALL_HASH_TABLE);
+#endif
+    tablePtr->buckets = tablePtr->staticBuckets;
+    tablePtr->numBuckets = BLT_SMALL_HASH_TABLE;
+    tablePtr->staticBuckets[0] = tablePtr->staticBuckets[1] = 0;
+    tablePtr->staticBuckets[2] = tablePtr->staticBuckets[3] = 0;
+    tablePtr->numEntries = 0;
+    tablePtr->rebuildSize = BLT_SMALL_HASH_TABLE * REBUILD_MULTIPLIER;
+
+    if (sizeof(void*) == 8) 
+      tablePtr->downShift = 62;
+    else
+      tablePtr->downShift = 28;
+
+    /* The number of buckets is always a power of 2, so we can generate the mask
+     * by simply subtracting 1 from the number of buckets. */
+    tablePtr->mask = (Blt_Hash)(tablePtr->numBuckets - 1);
+    tablePtr->keyType = keyType;
+
+    switch (keyType) {
+    case BLT_STRING_KEYS:		/* NUL terminated string keys. */
+	tablePtr->findProc = StringFind;
+	tablePtr->createProc = StringCreate;
+	break;
+
+    case BLT_ONE_WORD_KEYS:		/* 32 or 64-bit atomic keys. */
+	tablePtr->findProc = OneWordFind;
+	tablePtr->createProc = OneWordCreate;
+	break;
+
+    default:				/* Structures/arrays. */
+	if (keyType == 0) {
+	    Blt_Panic("Blt_InitHashTable: Key size can't be %d, must be > 0\n",
+		  keyType);
+	}
+	tablePtr->findProc = ArrayFind;
+	tablePtr->createProc = ArrayCreate;
+	break;
+    }
+    tablePtr->hPool = NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_InitHashTableWithPool --
+ *
+ *	Given storage for a hash table, set up the fields to prepare the hash
+ *	table for use.  The only difference between this routine and
+ *	Blt_InitHashTable is that is uses a pool allocator to allocate memory
+ *	for hash table entries.  The type of pool is either fixed or variable
+ *	size (string) keys.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	TablePtr is now ready to be passed to Blt_FindHashEntry and
+ *	Blt_CreateHashEntry.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_InitHashTableWithPool(Blt_HashTable *tablePtr, size_t keyType)
+{
+    Blt_InitHashTable(tablePtr, keyType);
+    if (keyType == BLT_STRING_KEYS) {
+	tablePtr->hPool = Blt_PoolCreate(BLT_VARIABLE_SIZE_ITEMS);
+    } else {
+	tablePtr->hPool = Blt_PoolCreate(BLT_FIXED_SIZE_ITEMS);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DeleteHashEntry --
+ *
+ *	Remove a single entry from a hash table.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The entry given by entryPtr is deleted from its table and should never
+ *	again be used by the caller.  It is up to the caller to free the
+ *	clientData field of the entry, if that is relevant.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DeleteHashEntry(Blt_HashTable *tablePtr, Blt_HashEntry *entryPtr)
+{
+    Blt_HashEntry **bucketPtr;
+    size_t hindex;
+
+    if (tablePtr->keyType == BLT_ONE_WORD_KEYS) {
+	hindex = RandomIndex(tablePtr, (const void *)entryPtr->hval);
+    } else {
+	hindex = (entryPtr->hval & tablePtr->mask);
+    }	
+    bucketPtr = tablePtr->buckets + hindex;
+    if (*bucketPtr == entryPtr) {
+	*bucketPtr = entryPtr->nextPtr;
+    } else {
+	Blt_HashEntry *prevPtr;
+
+	for (prevPtr = *bucketPtr; /*empty*/; prevPtr = prevPtr->nextPtr) {
+	    if (prevPtr == NULL) {
+		Blt_Panic("malformed bucket chain in Blt_DeleteHashEntry");
+	    }
+	    if (prevPtr->nextPtr == entryPtr) {
+		prevPtr->nextPtr = entryPtr->nextPtr;
+		break;
+	    }
+	}
+    }
+    tablePtr->numEntries--;
+    if (tablePtr->hPool != NULL) {
+	Blt_PoolFreeItem(tablePtr->hPool, entryPtr);
+    } else {
+	free(entryPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DeleteHashTable --
+ *
+ *	Free up everything associated with a hash table except for the record
+ *	for the table itself.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The hash table is no longer useable.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DeleteHashTable(Blt_HashTable *tablePtr)	/* Table to delete. */
+{
+    /* Free up all the entries in the table. */
+    if (tablePtr->hPool != NULL) {
+	Blt_PoolDestroy(tablePtr->hPool);
+	tablePtr->hPool = NULL;
+    } else {
+	size_t i;
+
+	for (i = 0; i < tablePtr->numBuckets; i++) {
+	    Blt_HashEntry *hPtr;
+
+	    hPtr = tablePtr->buckets[i];
+	    while (hPtr != NULL) {
+		Blt_HashEntry *nextPtr;
+
+		nextPtr = hPtr->nextPtr;
+		free(hPtr);
+		hPtr = nextPtr;
+	    }
+	}
+    }
+    
+    /* Free up the bucket array, if it was dynamically allocated. */
+    if (tablePtr->buckets != tablePtr->staticBuckets) {
+	free(tablePtr->buckets);
+    }
+
+    /*
+     * Arrange for panics if the table is used again without re-initialization.
+     */
+    tablePtr->findProc = BogusFind;
+    tablePtr->createProc = BogusCreate;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FirstHashEntry --
+ *
+ *	Locate the first entry in a hash table and set up a record that can be
+ *	used to step through all the remaining entries of the table.
+ *
+ * Results:
+ *	The return value is a pointer to the first entry in tablePtr, or NULL
+ *	if tablePtr has no entries in it.  The memory at *searchPtr is
+ *	initialized so that subsequent calls to Blt_NextHashEntry will return
+ *	all of the entries in the table, one at a time.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_HashEntry *
+Blt_FirstHashEntry(
+    Blt_HashTable *tablePtr,		/* Table to search. */
+    Blt_HashSearch *searchPtr)		/* Place to store information about
+					 * progress through the table. */
+{
+    searchPtr->tablePtr = tablePtr;
+    searchPtr->nextIndex = 0;
+    searchPtr->nextEntryPtr = NULL;
+    return Blt_NextHashEntry(searchPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_NextHashEntry --
+ *
+ *	Once a hash table enumeration has been initiated by calling
+ *	Blt_FirstHashEntry, this procedure may be called to return successive
+ *	elements of the table.
+ *
+ * Results:
+ *	The return value is the next entry in the hash table being enumerated,
+ *	or NULL if the end of the table is reached.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_HashEntry *
+Blt_NextHashEntry(Blt_HashSearch *searchPtr)
+{
+    Blt_HashEntry *hPtr;
+
+    while (searchPtr->nextEntryPtr == NULL) {
+	if (searchPtr->nextIndex >= searchPtr->tablePtr->numBuckets) {
+	    return NULL;
+	}
+	searchPtr->nextEntryPtr =
+		searchPtr->tablePtr->buckets[searchPtr->nextIndex];
+	searchPtr->nextIndex++;
+    }
+    hPtr = searchPtr->nextEntryPtr;
+    searchPtr->nextEntryPtr = hPtr->nextPtr;
+    return hPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_HashStats --
+ *
+ *	Return statistics describing the layout of the hash table in its hash
+ *	buckets.
+ *
+ * Results:
+ *	The return value is a malloc-ed string containing information about
+ *	tablePtr.  It is the caller's responsibility to free this string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+const char *
+Blt_HashStats(Blt_HashTable *tablePtr) /* Table for which to produce stats. */
+{
+    Blt_HashEntry **bp, **bend;
+    char *result, *p;
+    double average, tmp;
+#define NUM_COUNTERS 10
+    size_t count[NUM_COUNTERS], overflow, i, max;
+
+    /* Compute a histogram of bucket usage. */
+    for (i = 0; i < NUM_COUNTERS; i++) {
+	count[i] = 0;
+    }
+    overflow = 0;
+    average = 0.0;
+    max = 0;
+
+    for (bp = tablePtr->buckets, bend = bp + tablePtr->numBuckets; bp < bend; 
+	 bp++) {
+	Blt_HashEntry *hPtr;
+	size_t j;
+
+	j = 0;
+	for (hPtr = *bp; hPtr != NULL; hPtr = hPtr->nextPtr) {
+	    j++;
+	}
+	if (j > max) {
+	    max = j;
+	}
+	if (j < NUM_COUNTERS) {
+	    count[j]++;
+	} else {
+	    overflow++;
+	}
+	tmp = j;
+	average += (tmp+1.0)*(tmp/tablePtr->numEntries)/2.0;
+    }
+
+    /* Print out the histogram and a few other pieces of information. */
+    result = malloc((unsigned) ((NUM_COUNTERS*60) + 300));
+    sprintf(result, "%lu entries in table, %lu buckets\n",
+	    (unsigned long)tablePtr->numEntries, 
+	    (unsigned long)tablePtr->numBuckets);
+    p = result + strlen(result);
+    for (i = 0; i < NUM_COUNTERS; i++) {
+	sprintf(p, "number of buckets with %lu entries: %lu\n",
+		(unsigned long)i, (unsigned long)count[i]);
+	p += strlen(p);
+    }
+    sprintf(p, "number of buckets with %d or more entries: %lu\n",
+	    NUM_COUNTERS, (unsigned long)overflow);
+    p += strlen(p);
+    sprintf(p, "average search distance for entry: %.2f\n", average);
+    p += strlen(p);
+    sprintf(p, "maximum search distance for entry: %lu", (unsigned long)max);
+    return result;
+}
diff --git a/tlt3.0/bltHash.h b/tlt3.0/bltHash.h
new file mode 100644
index 0000000..dfbf7ce
--- /dev/null
+++ b/tlt3.0/bltHash.h
@@ -0,0 +1,180 @@
+
+/* 
+ * bltHash.h --
+ *
+ *	Copyright 2000-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The hash table data structures are based upon the ones in the public header
+ * file tcl.h in the Tcl library distribution.
+ *
+ *	Copyright (c) 1991-1993 The Regents of the University of California.
+ *
+ *	Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ *	See the file "license.terms" for information on usage and
+ *	redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef BLT_HASH_H
+#define BLT_HASH_H 1
+
+#include <stdint.h>
+
+#if (INTPTR_MAX	== INT64_MAX) 
+typedef uint64_t Blt_Hash;
+#else
+typedef uint32_t Blt_Hash;
+#endif
+
+#include "bltPool.h"
+
+/*
+ * Acceptable key types for hash tables:
+ */
+#ifndef BLT_STRING_KEYS
+#  define BLT_STRING_KEYS		0L
+#endif
+#ifndef BLT_ONE_WORD_KEYS
+#  define BLT_ONE_WORD_KEYS	((size_t)-1L)
+#endif
+/*
+ * Forward declaration of Blt_HashTable.  Needed by some C++ compilers to
+ * prevent errors when the forward reference to Blt_HashTable is encountered
+ * in the Blt_HashEntry structure.
+ */
+
+#ifdef __cplusplus
+struct Blt_HashTable;
+#endif
+
+typedef union {			/* Key has one of these forms: */
+    void *oneWordValue;		/* One-word value for key. */
+    unsigned long words[1];	/* Multiple integer words for key.  The actual
+				 * size will be as large as necessary for this
+				 * table's keys. */
+    char string[4];		/* String for key.  The actual size will be as
+				 * large as needed to hold the key. */
+} Blt_HashKey;
+
+/*
+ * Structure definition for an entry in a hash table.  No one outside BLT
+ * should access any of these fields directly; use the macros defined below.
+ */
+typedef struct Blt_HashEntry {
+    struct Blt_HashEntry *nextPtr; /* Pointer to next entry in this hash
+				    * bucket, or NULL for end of chain.*/
+    Blt_Hash hval;
+
+    ClientData clientData;	/* Application stores something here with
+				 * Blt_SetHashValue. */
+    Blt_HashKey key;		/* MUST BE LAST FIELD IN RECORD!! */
+} Blt_HashEntry;
+
+/*
+ * Structure definition for a hash table.  Must be in blt.h so clients can
+ * allocate space for these structures, but clients should never access any
+ * fields in this structure.
+ */
+#define BLT_SMALL_HASH_TABLE 4
+typedef struct Blt_HashTable {
+    Blt_HashEntry **buckets;	/* Pointer to bucket array.  Each element
+				 * points to first entry in bucket's hash
+				 * chain, or NULL. */
+    Blt_HashEntry *staticBuckets[BLT_SMALL_HASH_TABLE];
+				/* Bucket array used for small tables (to
+				 * avoid mallocs and frees). */
+    size_t numBuckets;		/* Total number of buckets allocated at
+				 * buckets. */
+    size_t numEntries;		/* Total # of entries present in table. */
+    size_t rebuildSize;		/* Enlarge table when numEntries gets to be
+				 * this large. */
+    Blt_Hash mask;		/* Mask value used in hashing function. */	
+    unsigned int downShift;	/* Shift count used in hashing function.
+				 * Designed to use high- order bits of
+				 * randomized keys. */
+    size_t keyType;		/* Type of keys used in this table.  It's
+				 * either BLT_STRING_KEYS, BLT_ONE_WORD_KEYS,
+				 * or an integer giving the number of ints
+				 * that is the size of the key. */
+    Blt_HashEntry *(*findProc) _ANSI_ARGS_((struct Blt_HashTable *tablePtr,
+	    CONST void *key));
+    Blt_HashEntry *(*createProc) _ANSI_ARGS_((struct Blt_HashTable *tablePtr,
+	    CONST void *key, int *newPtr));
+
+    Blt_Pool hPool;		/* Pointer to the pool allocator used for
+				 * entries in this hash table. If NULL, the
+				 * standard Tcl_Alloc, Tcl_Free routines will
+				 * be used instead. */
+} Blt_HashTable;
+
+/*
+ * Structure definition for information used to keep track of searches through
+ * hash tables:
+ */
+
+typedef struct {
+    Blt_HashTable *tablePtr;	/* Table being searched. */
+    unsigned long nextIndex;	/* Index of next bucket to be enumerated after
+				 * present one. */
+    Blt_HashEntry *nextEntryPtr; /* Next entry to be enumerated in the current
+				  * bucket. */
+} Blt_HashSearch;
+
+/*
+ * Macros for clients to use to access fields of hash entries:
+ */
+
+#define Blt_GetHashValue(h) ((h)->clientData)
+#define Blt_SetHashValue(h, value) ((h)->clientData = (ClientData)(value))
+#define Blt_GetHashKey(tablePtr, h) \
+    ((void *) (((tablePtr)->keyType == BLT_ONE_WORD_KEYS) ? \
+     (void *)(h)->key.oneWordValue : (h)->key.string))
+
+/*
+ * Macros to use for clients to use to invoke find and create procedures for
+ * hash tables:
+ */
+#define Blt_FindHashEntry(tablePtr, key) \
+	(*((tablePtr)->findProc))(tablePtr, key)
+#define Blt_CreateHashEntry(tablePtr, key, newPtr) \
+	(*((tablePtr)->createProc))(tablePtr, key, newPtr)
+
+extern void Blt_InitHashTable _ANSI_ARGS_((Blt_HashTable *tablePtr, 
+	size_t keyType));
+
+extern void Blt_InitHashTableWithPool _ANSI_ARGS_((Blt_HashTable *tablePtr, 
+	size_t keyType));
+
+extern void Blt_DeleteHashTable _ANSI_ARGS_((Blt_HashTable *tablePtr));
+
+extern void Blt_DeleteHashEntry _ANSI_ARGS_((Blt_HashTable *tablePtr,
+	Blt_HashEntry *entryPtr));
+
+extern Blt_HashEntry *Blt_FirstHashEntry _ANSI_ARGS_((
+	Blt_HashTable *tablePtr, Blt_HashSearch *searchPtr));
+
+extern Blt_HashEntry *Blt_NextHashEntry _ANSI_ARGS_((
+	Blt_HashSearch *srchPtr));
+
+extern const char *Blt_HashStats _ANSI_ARGS_((Blt_HashTable *tablePtr));
+
+#endif /* BLT_HASH_H */
diff --git a/tlt3.0/bltImage.c b/tlt3.0/bltImage.c
new file mode 100644
index 0000000..32f14a0
--- /dev/null
+++ b/tlt3.0/bltImage.c
@@ -0,0 +1,156 @@
+
+/*
+ * bltImage.c --
+ *
+ * This module implements image processing procedures for the BLT toolkit.
+ *
+ *	Copyright 1997-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining a
+ *	copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be included
+ *	in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ *	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <X11/Xutil.h>
+
+#include "bltInt.h"
+#include "bltImage.h"
+
+/*
+ * Each call to Tk_GetImage returns a pointer to one of the following
+ * structures, which is used as a token by clients (widgets) that display
+ * images.
+ */
+typedef struct _TkImage {
+    Tk_Window tkwin;			/* Window passed to Tk_GetImage (needed
+					 * to "re-get" the image later if the *
+					 * manager changes). */
+    Display *display;			/* Display for tkwin.  Needed because
+					 * when the image is eventually freed
+					 * tkwin may not exist anymore. */
+    struct _TkImageMaster *masterPtr;	/* Master for this image (identifiers
+					 * image manager, for example). */
+    ClientData instanceData;		/* One word argument to pass to image
+					 * manager when dealing with this image
+					 * instance. */
+    Tk_ImageChangedProc *changeProc;	/* Code in widget to call when image
+					 * changes in a way that affects
+					 * redisplay. */
+    ClientData widgetClientData;	/* Argument to pass to changeProc. */
+    struct _TkImage *nextPtr;		/* Next in list of all image instances
+					 * associated with the same name. */
+} TkImage;
+
+/*
+ * For each image master there is one of the following structures, which
+ * represents a name in the image table and all of the images instantiated from
+ * it.  Entries in mainPtr->imageTable point to these structures.
+ */
+typedef struct _TkImageMaster {
+    Tk_ImageType *typePtr;		/* Information about image type.  NULL
+					 * means that no image manager owns this
+					 * image: the image was deleted. */
+    ClientData masterData;		/* One-word argument to pass to image
+					 * mgr when dealing with the master, as
+					 * opposed to instances. */
+    int width, height;			/* Last known dimensions for image. */
+    void *tablePtr;			/* Pointer to hash table containing
+					 * image (the imageTable field in some
+					 * TkMainInfo structure). */
+    void *hPtr;				/* Hash entry in mainPtr->imageTable for
+					 * this structure (used to delete the
+					 * hash entry). */
+    void *instancePtr;			/* Pointer to first in list of instances
+					 * derived from this name. */
+    int deleted;			/* Flag set when image is being 
+					 * deleted. */
+    Tk_Window tkwin;			/* Main window of interpreter (used to
+					 * detect when the world is falling
+					 * apart.) */
+} TkImageMaster;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Image_IsDeleted --
+ *
+ *	Is there any other way to determine if an image has been deleted?
+ *
+ * Results:
+ *	Returns 1 if the image has been deleted, 0 otherwise.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+int
+Blt_Image_IsDeleted(Tk_Image tkImage)	/* Token for image. */
+{
+    TkImage *imagePtr = (TkImage *) tkImage;
+
+    if (imagePtr->masterPtr == NULL) {
+	return TRUE;
+    }
+    return (imagePtr->masterPtr->typePtr == NULL);
+}
+
+/*LINTLIBRARY*/
+Tk_ImageMaster
+Blt_Image_GetMaster(Tk_Image tkImage)	/* Token for image. */
+{
+    TkImage *imagePtr = (TkImage *)tkImage;
+
+    return (Tk_ImageMaster)imagePtr->masterPtr;
+}
+
+/*LINTLIBRARY*/
+ClientData
+Blt_Image_GetInstanceData(Tk_Image tkImage) /* Token for image. */
+{
+    TkImage *imagePtr = (TkImage *)tkImage;
+
+    return imagePtr->instanceData;
+}
+
+/*LINTLIBRARY*/
+Tk_ImageType *
+Blt_Image_GetType(Tk_Image tkImage)	/* Token for image. */
+{
+    TkImageMaster *masterPtr;
+
+    masterPtr = (TkImageMaster *)Blt_Image_GetMaster(tkImage);
+    return masterPtr->typePtr;
+}
+
+const char *
+Blt_Image_Name(Tk_Image tkImage)
+{
+    Tk_ImageMaster master;
+
+    master = Blt_Image_GetMaster(tkImage);
+    return Tk_NameOfImage(master);
+}
+
+const char *
+Blt_Image_NameOfType(Tk_Image tkImage)
+{
+    TkImageMaster *masterPtr;
+
+    masterPtr = (TkImageMaster *)Blt_Image_GetMaster(tkImage);
+    return masterPtr->typePtr->name;
+}
+
diff --git a/tlt3.0/bltImage.h b/tlt3.0/bltImage.h
new file mode 100644
index 0000000..2dd8eec
--- /dev/null
+++ b/tlt3.0/bltImage.h
@@ -0,0 +1,51 @@
+
+/*
+ * bltImage.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_IMAGE_H
+#define _BLT_IMAGE_H
+
+#define ROTATE_0	0
+#define ROTATE_90	1
+#define ROTATE_180	2
+#define ROTATE_270	3
+
+/* Routines that really should be in the Tk image C API. */
+
+extern int Blt_Image_IsDeleted(Tk_Image tkImage);
+
+extern Tk_ImageMaster Blt_Image_GetMaster(Tk_Image tkImage);
+
+extern Tk_ImageType *Blt_Image_GetType(Tk_Image tkImage);
+
+extern ClientData Blt_Image_GetInstanceData(Tk_Image tkImage);
+
+extern const char *Blt_Image_Name(Tk_Image tkImage);
+extern const char *Blt_Image_NameOfType(Tk_Image tkImage);
+
+#endif /*_BLT_IMAGE_H*/
diff --git a/tlt3.0/bltInit.c b/tlt3.0/bltInit.c
new file mode 100644
index 0000000..036e9e5
--- /dev/null
+++ b/tlt3.0/bltInit.c
@@ -0,0 +1,123 @@
+
+/*
+ * bltInit.c --
+ *
+ * This module initials the BLT toolkit, registering its commands with the
+ * Tcl/Tk interpreter.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "bltInt.h"
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_InitCmd --
+ *
+ *      Given the name of a command, return a pointer to the clientData field
+ *      of the command.
+ *
+ * Results:
+ *      A standard TCL result. If the command is found, TCL_OK is returned
+ *      and clientDataPtr points to the clientData field of the command (if
+ *      the clientDataPtr in not NULL).
+ *
+ * Side effects:
+ *      If the command is found, clientDataPtr is set to the address of the
+ *      clientData of the command.  If not found, an error message is left
+ *      in interp->result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+int
+Blt_InitCmd(Tcl_Interp *interp, const char *nsName, Blt_InitCmdSpec *specPtr)
+{
+    const char *cmdPath;
+    Tcl_DString dString;
+    Tcl_Command cmdToken;
+    Tcl_Namespace *nsPtr;
+
+    Tcl_DStringInit(&dString);
+    if (nsName != NULL) {
+	Tcl_DStringAppend(&dString, nsName, -1);
+    } 
+    Tcl_DStringAppend(&dString, "::", -1);
+    Tcl_DStringAppend(&dString, specPtr->name, -1);
+
+    cmdPath = Tcl_DStringValue(&dString);
+    cmdToken = Tcl_FindCommand(interp, cmdPath, (Tcl_Namespace *)NULL, 0);
+    if (cmdToken != NULL) {
+	Tcl_DStringFree(&dString);
+	return TCL_OK;		/* Assume command was already initialized */
+    }
+    cmdToken = Tcl_CreateObjCommand(interp, cmdPath, specPtr->cmdProc, 
+	specPtr->clientData, specPtr->cmdDeleteProc);
+    Tcl_DStringFree(&dString);
+    nsPtr = Tcl_FindNamespace(interp, nsName, (Tcl_Namespace *)NULL,
+	TCL_LEAVE_ERR_MSG);
+    if (nsPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (Tcl_Export(interp, nsPtr, specPtr->name, FALSE) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_InitCmds --
+ *
+ *      Given the name of a command, return a pointer to the clientData field
+ *      of the command.
+ *
+ * Results:
+ *      A standard TCL result. If the command is found, TCL_OK is returned and
+ *      clientDataPtr points to the clientData field of the command (if the
+ *      clientDataPtr in not NULL).
+ *
+ * Side effects:
+ *      If the command is found, clientDataPtr is set to the address of the
+ *      clientData of the command.  If not found, an error message is left in
+ *      interp->result.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_InitCmds(
+    Tcl_Interp *interp, 
+    const char *nsName, 
+    Blt_InitCmdSpec *specs, 
+    int nCmds)
+{
+    Blt_InitCmdSpec *sp, *endPtr;
+
+    for (sp = specs, endPtr = specs + nCmds; sp < endPtr; sp++) {
+	if (Blt_InitCmd(interp, nsName, sp) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
diff --git a/tlt3.0/bltInt.c b/tlt3.0/bltInt.c
new file mode 100644
index 0000000..41ad000
--- /dev/null
+++ b/tlt3.0/bltInt.c
@@ -0,0 +1,83 @@
+/*
+ * bltCoreInit.c --
+ *
+ * This module initials the non-Tk command of the BLT toolkit, registering the
+ * commands with the TCL interpreter.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "bltInt.h"
+
+Tcl_AppInitProc Tlt_Init;
+Tcl_AppInitProc Tlt_SafeInit;
+
+int Tlt_Init(Tcl_Interp *interp)
+{
+  Tcl_Namespace *nsPtr;
+
+  if(
+#ifdef USE_TCL_STUBS
+     Tcl_InitStubs(interp, TCL_PATCH_LEVEL, 0)
+#else
+     Tcl_PkgRequire(interp, "Tcl", TCL_PATCH_LEVEL, 0)
+#endif
+     == NULL) {
+    return TCL_ERROR;
+  }
+
+  if(
+#ifdef USE_TK_STUBS
+     Tk_InitStubs(interp, TK_PATCH_LEVEL, 0)
+#else
+     Tcl_PkgRequire(interp, "Tk", TK_PATCH_LEVEL, 0)
+#endif
+     == NULL) {
+    return TCL_ERROR;
+  }
+
+  nsPtr = Tcl_FindNamespace(interp, "::blt", (Tcl_Namespace *)NULL, 0);
+  if (nsPtr == NULL) {
+    nsPtr = Tcl_CreateNamespace(interp, "::blt", NULL, NULL);
+    if (nsPtr == NULL) {
+      return TCL_ERROR;
+    }
+  }
+
+  if (Blt_VectorCmdInitProc(interp) != TCL_OK)
+    return TCL_ERROR;
+  if (Blt_GraphCmdInitProc(interp) != TCL_OK)
+    return TCL_ERROR;
+
+  if (Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION) != TCL_OK) {
+    return TCL_ERROR;
+  }
+
+  return TCL_OK;
+}
+
+int Tlt_SafeInit(Tcl_Interp *interp)
+{
+  return Tlt_Init(interp);
+}
+
+
diff --git a/tlt3.0/bltInt.h b/tlt3.0/bltInt.h
new file mode 100644
index 0000000..8e6cd51
--- /dev/null
+++ b/tlt3.0/bltInt.h
@@ -0,0 +1,331 @@
+/*
+ * bltInt.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_INT_H
+#define _BLT_INT_H
+
+#include <tcl.h>
+#ifdef USE_TCL_STUBS
+#include <tclInt.h>
+#endif
+
+#include <tk.h>
+#ifdef USE_TK_STUBS
+#include <tkInt.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+#include <ctype.h>
+#include <memory.h>
+
+#define TRUE 	1
+#define FALSE 	0
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_InitCmdSpec --
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    const char *name;			/* Name of command */
+    Tcl_ObjCmdProc *cmdProc;
+    Tcl_CmdDeleteProc *cmdDeleteProc;
+    ClientData clientData;
+} Blt_InitCmdSpec;
+
+extern int Blt_DictionaryCompare (const char *s1, const char *s2);
+
+/* ---------------------------------------------------------------- */
+
+#define COUNT_NNEG		0
+#define COUNT_POS		1
+#define COUNT_ANY		2
+
+#define RGB_ANTIQUEWHITE1	"#ffefdb"
+#define RGB_BISQUE1		"#ffe4c4"
+#define RGB_BISQUE2		"#eed5b7"
+#define RGB_BISQUE3		"#cdb79e"
+#define RGB_BLACK		"#000000"
+#define RGB_BLUE		"#0000ff"
+#define RGB_GREEN		"#00ff00"
+#define RGB_GREY		"#b0b0b0"
+#define RGB_GREY15		"#262626"
+#define RGB_GREY20		"#333333"
+#define RGB_GREY25		"#404040"
+#define RGB_GREY30		"#4d4d4d"
+#define RGB_GREY35		"#595959"
+#define RGB_GREY40		"#666666"
+#define RGB_GREY50		"#7f7f7f"
+#define RGB_GREY64		"#a3a3a3"
+#define RGB_GREY70		"#b3b3b3"
+#define RGB_GREY75		"#bfbfbf"
+#define RGB_GREY77		"#c3c3c3"
+#define RGB_GREY82		"#d1d1d1"
+#define RGB_GREY85		"#d9d9d9"
+#define RGB_GREY90		"#e5e5e5"
+#define RGB_GREY93		"#ececec"
+#define RGB_GREY95		"#f2f2f2"
+#define RGB_GREY97		"#f7f7f7"
+#define RGB_LIGHTBLUE0		"#e4f7ff"
+#define RGB_LIGHTBLUE00		"#D9F5FF"
+#define RGB_LIGHTBLUE1		"#bfefff"
+#define RGB_LIGHTBLUE2		"#b2dfee"
+#define RGB_LIGHTSKYBLUE1	"#b0e2ff"
+#define RGB_MAROON		"#b03060"
+#define RGB_NAVYBLUE		"#000080"
+#define RGB_PINK		"#ffc0cb"
+#define RGB_BISQUE1		"#ffe4c4"
+#define RGB_RED			"#ff0000"
+#define RGB_RED3		"#cd0000"
+#define RGB_WHITE		"#ffffff"
+#define RGB_YELLOW		"#ffff00"
+#define RGB_SKYBLUE4		"#4a708b"
+
+#define STD_NORMAL_BACKGROUND	RGB_GREY85
+#define STD_ACTIVE_BACKGROUND	RGB_GREY90
+#define STD_SELECT_BACKGROUND	RGB_SKYBLUE4
+#define STD_SELECT_FOREGROUND	RGB_WHITE
+
+#define STD_ACTIVE_BG_MONO	RGB_BLACK
+#define STD_ACTIVE_FOREGROUND	RGB_BLACK
+#define STD_ACTIVE_FG_MONO	RGB_WHITE
+#define STD_BORDERWIDTH 	"2"
+#define STD_FONT_HUGE		"{Sans Serif} 18"
+#define STD_FONT_LARGE		"{Sans Serif} 14"
+#define STD_FONT_MEDIUM		"{Sans Serif} 11"
+#define STD_FONT_NORMAL		"{Sans Serif} 9"
+#define STD_FONT_SMALL		"{Sans Serif} 8"
+#define	STD_FONT_NUMBERS	"Math 8"
+#define STD_FONT		STD_FONT_NORMAL
+#define STD_INDICATOR_COLOR	RGB_RED3
+#define STD_NORMAL_BG_MONO	RGB_WHITE
+#define STD_NORMAL_FOREGROUND	RGB_BLACK
+#define STD_NORMAL_FG_MONO	RGB_BLACK
+#define STD_SELECT_BG_MONO	RGB_BLACK
+#define STD_SELECT_BORDERWIDTH	"2"
+#define STD_SELECT_FG_MONO	RGB_WHITE
+#define STD_SHADOW_MONO		RGB_BLACK
+#define STD_SELECT_FONT_HUGE	"{Sans Serif} 18 Bold"
+#define STD_SELECT_FONT_LARGE	"{Sans Serif} 14 Bold"
+#define STD_SELECT_FONT_MEDIUM	"{Sans Serif} 11 Bold"
+#define STD_SELECT_FONT_NORMAL	"{Sans Serif} 9 Bold"
+#define STD_SELECT_FONT_SMALL	"{Sans Serif} 8 Bold"
+#define STD_SELECT_FONT		STD_SELECT_FONT_NORMAL
+#define STD_DISABLED_FOREGROUND	RGB_GREY70
+#define STD_DISABLED_BACKGROUND	RGB_GREY90
+
+#define LineWidth(w)	(((w) > 1) ? (w) : 0)
+
+#ifdef TCL_UTF_MAX
+#  define HAVE_UTF	1
+#else
+#  define HAVE_UTF	0
+#endif /* TCL_UTF_MAX */
+
+#ifndef TK_RELIEF_SOLID
+#  define TK_RELIEF_SOLID		TK_RELIEF_FLAT
+#endif
+
+typedef int (QSortCompareProc) (const void *, const void *);
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Point2 --
+ *
+ *	2-D coordinate.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    double x, y;
+} Point2d;
+
+typedef struct {
+    float x, y;
+} Point2f;
+
+typedef struct {
+    int x, y;
+} Point2i;
+
+typedef struct {
+    size_t nValues; 
+    void *values;
+} Array;
+
+typedef struct {
+    Point2d p, q;		/* The two end points of the segment. */
+} Segment2d;
+
+typedef struct {
+    short int width, height;
+} Dim2D;
+
+typedef struct {
+    float left, right, top, bottom;
+} Region2f;
+
+typedef struct {
+    double left, right, top, bottom;
+} Region2d;
+
+#define PointInRegion(e,x,y) \
+	(((x) <= (e)->right) && ((x) >= (e)->left) && \
+	 ((y) <= (e)->bottom) && ((y) >= (e)->top))
+
+#define PointInRectangle(r,x0,y0) \
+	(((x0) <= (int)((r)->x + (r)->width - 1)) && ((x0) >= (int)(r)->x) && \
+	 ((y0) <= (int)((r)->y + (r)->height - 1)) && ((y0) >= (int)(r)->y))
+
+/*-------------------------------------------------------------------------------
+ *
+ * ColorPair --
+ *
+ *	Holds a pair of foreground, background colors.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    XColor *fgColor, *bgColor;
+} ColorPair;
+
+#define COLOR_NONE		(XColor *)0
+#define COLOR_DEFAULT		(XColor *)1
+#define COLOR_ALLOW_DEFAULTS	1
+
+extern void strtolower(char*);
+
+extern void Blt_FreeColorPair (ColorPair *pairPtr);
+
+extern int Blt_ExprDoubleFromObj (Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	double *valuePtr);
+
+extern int Blt_ExprIntFromObj (Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	int *valuePtr);
+
+extern const char *Blt_Itoa(int value);
+
+extern const char *Blt_Ltoa(long value);
+
+extern const char *Blt_Utoa(unsigned int value);
+
+extern const char *Blt_Dtoa(Tcl_Interp *interp, double value);
+
+extern int Blt_InitCmd (Tcl_Interp *interp, const char *namespace, 
+	Blt_InitCmdSpec *specPtr);
+
+extern int Blt_InitCmds (Tcl_Interp *interp, const char *namespace, 
+	Blt_InitCmdSpec *specPtr, int nCmds);
+
+extern int Blt_GlobalEvalObjv(Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+extern int Blt_GetDoubleFromString(Tcl_Interp *interp, const char *s, 
+	double *valuePtr);
+extern int Blt_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	double *valuePtr);
+
+extern int Blt_LineRectClip(Region2d *regionPtr, Point2d *p, Point2d *q);
+
+extern int Blt_SimplifyLine (Point2d *origPts, int low, int high, 
+	double tolerance, int *indices);
+
+extern GC Blt_GetPrivateGC(Tk_Window tkwin, unsigned long gcMask,
+	XGCValues *valuePtr);
+
+extern GC Blt_GetPrivateGCFromDrawable(Display *display, Drawable drawable, 
+	unsigned long gcMask, XGCValues *valuePtr);
+
+extern void Blt_FreePrivateGC(Display *display, GC gc);
+
+extern int Blt_GetWindowFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	Window *windowPtr);
+
+extern Window Blt_GetParentWindow(Display *display, Window window);
+
+extern int Blt_GetCountFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	int check, long *valuePtr);
+
+extern const char *Blt_NameOfFill(int fill);
+
+extern int Blt_GetXY (Tcl_Interp *interp, Tk_Window tkwin, 
+	const char *string, int *xPtr, int *yPtr);
+
+extern Point2d Blt_GetProjection (int x, int y, Point2d *p, Point2d *q);
+
+extern Window Blt_GetParent (Display *display, Window tkwin);
+
+extern void Blt_GetBoundingBox (int width, int height, float angle, 
+	double *widthPtr, double *heightPtr, Point2d *points);
+
+extern void Blt_TranslateAnchor (int x, int y, int width, int height, 
+	Tk_Anchor anchor, int *transXPtr, int *transYPtr);
+
+extern Point2d Blt_AnchorPoint (double x, double y, double width, 
+	double height, Tk_Anchor anchor);
+
+extern long Blt_MaxRequestSize (Display *display, size_t elemSize);
+
+extern Window Blt_GetWindowId (Tk_Window tkwin);
+
+extern void Blt_InitXRandrConfig(Tcl_Interp *interp);
+
+extern int Blt_GetWindowRegion(Display *display, Window window, int *xPtr,
+	int *yPtr, int *widthPtr, int *heightPtr);
+
+extern int Blt_AdjustViewport (int offset, int worldSize, int windowSize, 
+	int scrollUnits, int scrollMode);
+
+extern void Blt_UpdateScrollbar(Tcl_Interp *interp, 
+	Tcl_Obj *scrollCmdObjPtr, int first, int last, int width);
+
+extern GC Blt_GetBitmapGC(Tk_Window tkwin);
+
+#define Tk_RootWindow(tkwin) \
+  RootWindow(Tk_Display(tkwin),Tk_ScreenNumber(tkwin))
+
+#include "bltConfig.h"
+
+extern Tcl_AppInitProc Blt_GraphCmdInitProc;
+extern Tcl_AppInitProc Blt_VectorCmdInitProc;
+
+extern int TclGetLong(Tcl_Interp *interp, const char *s, long *longPtr);
+
+extern int sprintf_s(char *s, size_t size, const char *fmt, /*args*/ ...);
+
+extern void Blt_Panic TCL_VARARGS(const char *, args);
+
+extern void Blt_ScreenDPI(Tk_Window tkwin, unsigned int *xPtr, 
+	unsigned int *yPtr);
+
+extern char *Blt_Strdup(const char *string);
+
+#endif /*_BLT_INT_H*/
diff --git a/tlt3.0/bltList.c b/tlt3.0/bltList.c
new file mode 100644
index 0000000..e77b88a
--- /dev/null
+++ b/tlt3.0/bltList.c
@@ -0,0 +1,558 @@
+
+/*
+ * bltList.c --
+ *
+ * The module implements generic linked lists for the BLT toolkit.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "bltInt.h"
+#include "bltList.h"
+
+typedef struct _Blt_ListNode Node;
+typedef struct _Blt_List bltList;
+
+static Node *
+FindString(bltList *listPtr, const char *key)	
+{
+    Node *np;
+    char c;
+
+    c = key[0];
+    for (np = listPtr->head; np != NULL; np = np->next) {
+	if ((c == np->key.string[0]) && (strcmp(key, np->key.string) == 0)) {
+	    return np;
+	}
+    }
+    return NULL;
+}
+
+static Blt_ListNode
+FindOneWord(bltList *listPtr, const char *key)
+{
+    Node *np;
+
+    for (np = listPtr->head; np != NULL; np = np->next) {
+	if (key == np->key.oneWordValue) {
+	    return np;
+	}
+    }
+    return NULL;
+}
+
+static Blt_ListNode
+FindArray(bltList *listPtr, const char *key)
+{
+    Node *np;
+    size_t nBytes;
+
+    nBytes = sizeof(uint32_t) * listPtr->type;
+    for (np = listPtr->head; np != NULL; np = np->next) {
+	if (memcmp(key, np->key.words, nBytes) == 0) {
+	    return np;
+	}
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FreeNode --
+ *
+ *	Free the memory allocated for the node.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+FreeNode(Blt_ListNode node)
+{
+    free(node);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_Create --
+ *
+ *	Creates a new linked list structure and initializes its pointers
+ *
+ * Results:
+ *	Returns a pointer to the newly created list structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+Blt_List 
+Blt_List_Create(size_t type)
+{
+    bltList *listPtr;
+
+    listPtr = malloc(sizeof(bltList));
+    if (listPtr != NULL) {
+	Blt_List_Init(listPtr, type);
+    }
+    return listPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_CreateNode --
+ *
+ *	Creates a list node holder.  This routine does not insert the node
+ *	into the list, nor does it no attempt to maintain consistency of the
+ *	keys.  For example, more than one node may use the same key.
+ *
+ * Results:
+ *	The return value is the pointer to the newly created node.
+ *
+ * Side Effects:
+ *	The key is not copied, only the Uid is kept.  It is assumed this key
+ *	will not change in the life of the node.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+Blt_ListNode
+Blt_List_CreateNode(bltList *listPtr, const char *key)
+{
+    Node *np;
+    size_t keySize;
+
+    if (listPtr->type == BLT_STRING_KEYS) {
+	keySize = strlen(key) + 1;
+    } else if (listPtr->type == BLT_ONE_WORD_KEYS) {
+	keySize = sizeof(void *);
+    } else {
+	keySize = sizeof(uint32_t) * listPtr->type;
+    }
+    np = calloc(1, sizeof(Node) + keySize - 4);
+    np->clientData = NULL;
+    np->next = np->prev = NULL;
+    np->list = listPtr;
+    switch (listPtr->type) {
+    case BLT_STRING_KEYS:
+	strcpy(np->key.string, key);
+	break;
+    case BLT_ONE_WORD_KEYS:
+	np->key.oneWordValue = key;
+	break;
+    default:
+	memcpy(np->key.words, key, keySize);
+	break;
+    }
+    return np;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_Reset --
+ *
+ *	Removes all the entries from a list, removing pointers to the objects
+ *	and keys (not the objects or keys themselves).  The node counter is
+ *	reset to zero.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+void
+Blt_List_Reset(bltList *listPtr)		/* List to clear */
+{
+    if (listPtr != NULL) {
+	Node *nextPtr, *np;
+
+	for (np = listPtr->head; np != NULL; np = nextPtr) {
+	    nextPtr = np->next;
+	    FreeNode(np);
+	}
+	Blt_List_Init(listPtr, listPtr->type);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_Destroy
+ *
+ *     Frees the list structure.
+ *
+ * Results:
+ *	Returns a pointer to the newly created list structure.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+void
+Blt_List_Destroy(Blt_List list)
+{
+    if (list != NULL) {
+	Blt_List_Reset(list);
+	free(list);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_Init --
+ *
+ *	Initializes a linked list.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+void
+Blt_List_Init(bltList *listPtr, size_t type)
+{
+    listPtr->nNodes = 0;
+    listPtr->head = listPtr->tail = NULL;
+    listPtr->type = type;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_LinkAfter --
+ *
+ *	Inserts an node following a given node.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+void
+Blt_List_LinkAfter(bltList *listPtr, Node *np, Node *afterPtr)
+{
+    if (listPtr->head == NULL) {
+	listPtr->tail = listPtr->head = np;
+    } else {
+	if (afterPtr == NULL) {
+	    /* Prepend to the front of the list */
+	    np->next = listPtr->head;
+	    np->prev = NULL;
+	    listPtr->head->prev = np;
+	    listPtr->head = np;
+	} else {
+	    np->next = afterPtr->next;
+	    np->prev = afterPtr;
+	    if (afterPtr == listPtr->tail) {
+		listPtr->tail = np;
+	    } else {
+		afterPtr->next->prev = np;
+	    }
+	    afterPtr->next = np;
+	}
+    }
+    np->list = listPtr;
+    listPtr->nNodes++;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_LinkBefore --
+ *
+ *	Inserts an node preceding a given node.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+void
+Blt_List_LinkBefore(bltList *listPtr, Node *np, Node *beforePtr)
+{
+    if (listPtr->head == NULL) {
+	listPtr->tail = listPtr->head = np;
+    } else {
+	if (beforePtr == NULL) {
+	    /* Append onto the end of the list */
+	    np->next = NULL;
+	    np->prev = listPtr->tail;
+	    listPtr->tail->next = np;
+	    listPtr->tail = np;
+	} else {
+	    np->prev = beforePtr->prev;
+	    np->next = beforePtr;
+	    if (beforePtr == listPtr->head) {
+		listPtr->head = np;
+	    } else {
+		beforePtr->prev->next = np;
+	    }
+	    beforePtr->prev = np;
+	}
+    }
+    np->list = listPtr;
+    listPtr->nNodes++;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_UnlinkNode --
+ *
+ *	Unlinks an node from the given list. The node itself is not
+ *	deallocated, but only removed from the list.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+void
+Blt_List_UnlinkNode(Node *np)
+{
+    bltList *listPtr;
+
+    listPtr = np->list;
+    if (listPtr != NULL) {
+	int unlinked = 0;
+
+	if (listPtr->head == np) {
+	    listPtr->head = np->next;
+	    unlinked++;
+	}
+	if (listPtr->tail == np) {
+	    listPtr->tail = np->prev;
+	    unlinked++;
+	}
+	if (np->next != NULL) {
+	    np->next->prev = np->prev;
+	    unlinked++;
+	}
+	if (np->prev != NULL) {
+	    np->prev->next = np->next;
+	    unlinked++;
+	}
+	np->list = NULL;
+	if (unlinked) {
+	    assert(listPtr->nNodes > 0);
+	    listPtr->nNodes--;
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_GetNode --
+ *
+ *	Find the first node matching the key given.
+ *
+ * Results:
+ *	Returns the pointer to the node.  If no node matching the key given is
+ *	found, then NULL is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+/*LINTLIBRARY*/
+Blt_ListNode
+Blt_List_GetNode(bltList *listPtr, const char *key)
+{
+    if (listPtr != NULL) {
+	switch (listPtr->type) {
+	case BLT_STRING_KEYS:
+	    return FindString(listPtr, key);
+	case BLT_ONE_WORD_KEYS:
+	    return FindOneWord(listPtr, key);
+	default:
+	    return FindArray(listPtr, key);
+	}
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_DeleteNode --
+ *
+ *	Unlinks and deletes the given node.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+void
+Blt_List_DeleteNode(Blt_ListNode node)
+{
+    Blt_List_UnlinkNode(node);
+    FreeNode(node);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_DeleteNodeByKey --
+ *
+ *	Find the node and free the memory allocated for the node.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+void
+Blt_List_DeleteNodeByKey(Blt_List list, const char *key)
+{
+    Blt_ListNode node;
+
+    node = Blt_List_GetNode(list, key);
+    if (node != NULL) {
+	Blt_List_DeleteNode(node);
+    }
+}
+
+/*LINTLIBRARY*/
+Blt_ListNode
+Blt_List_Append(Blt_List list, const char *key, ClientData clientData)
+{
+    Blt_ListNode node;
+
+    node = Blt_List_CreateNode(list, key);
+    Blt_List_SetValue(node, clientData);
+    Blt_List_AppendNode(list, node);
+    return node;
+}
+
+/*LINTLIBRARY*/
+Blt_ListNode
+Blt_List_Prepend(Blt_List list, const char *key, ClientData clientData)
+{
+    Blt_ListNode node;
+
+    node = Blt_List_CreateNode(list, key);
+    Blt_List_SetValue(node, clientData);
+    Blt_List_PrependNode(list, node);
+    return node;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_GetNthNode --
+ *
+ *	Find the node based upon a given position in list.
+ *
+ * Results:
+ *	Returns the pointer to the node, if that numbered element
+ *	exists. Otherwise NULL.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+Blt_ListNode
+Blt_List_GetNthNode(bltList *listPtr, long position, int direction)
+{
+    if (listPtr == NULL) {
+	return NULL;
+    }
+    if (direction > 0) {
+	Node *np;
+	
+	for (np = listPtr->head; np != NULL; np = np->next) {
+	    if (position == 0) {
+		return np;
+	    }
+	    position--;
+	}
+    } else {
+	Node *np;
+	
+	for (np = listPtr->tail; np != NULL; np = np->prev) {
+	    if (position == 0) {
+		return np;
+	    }
+	    position--;
+	}
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_List_Sort --
+ *
+ *	Find the node based upon a given position in list.
+ *
+ * Results:
+ *	Returns the pointer to the node, if that numbered element
+ *	exists. Otherwise NULL.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+void
+Blt_List_Sort(bltList *listPtr, Blt_ListCompareProc *proc)
+{
+    Node **nodes;
+    Node *np;
+    size_t i;
+
+    if (listPtr->nNodes < 2) {
+	return;
+    }
+    nodes = malloc(sizeof(Node *) * (listPtr->nNodes + 1));
+    if (nodes == NULL) {
+	return;			/* Out of memory. */
+    }
+    for (i = 0, np = listPtr->head; np != NULL; np = np->next) {
+	nodes[i++] = np;
+    }
+    qsort(nodes, listPtr->nNodes, sizeof(Node *), (QSortCompareProc *)proc);
+
+    /* Rethread the list. */
+    np = nodes[0];
+    listPtr->head = np;
+    np->prev = NULL;
+    for (i = 1; i < listPtr->nNodes; i++) {
+	np->next = nodes[i];
+	np->next->prev = np;
+	np = np->next;
+    }
+    listPtr->tail = np;
+    np->next = NULL;
+    free(nodes);
+}
diff --git a/tlt3.0/bltList.h b/tlt3.0/bltList.h
new file mode 100644
index 0000000..ab53626
--- /dev/null
+++ b/tlt3.0/bltList.h
@@ -0,0 +1,116 @@
+
+/*
+ * bltList.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _BLT_LIST_H
+#define _BLT_LIST_H
+
+/*
+ * Acceptable key types for hash tables:
+ */
+#ifndef BLT_STRING_KEYS
+#define BLT_STRING_KEYS		0
+#endif
+#ifndef BLT_ONE_WORD_KEYS
+#define BLT_ONE_WORD_KEYS	((size_t)-1)
+#endif
+
+typedef struct _Blt_List *Blt_List;
+typedef struct _Blt_ListNode *Blt_ListNode;
+
+typedef union {			/* Key has one of these forms: */
+    const void *oneWordValue;	/* One-word value for key. */
+    unsigned int words[1];	/* Multiple integer words for key.  The actual
+				 * size will be as large as necessary for this
+				 * table's keys. */
+    char string[4];		/* String for key.  The actual size will be as
+				 * large as needed to hold the key. */
+} Blt_ListKey;
+
+/*
+ * A Blt_ListNode is the container structure for the Blt_List.
+ */
+struct _Blt_ListNode {
+    Blt_ListNode prev;		/* Link to the previous node */
+    Blt_ListNode next;		/* Link to the next node */
+    Blt_List list;		/* List to eventually insert node */
+    ClientData clientData;	/* Pointer to the data object */
+    Blt_ListKey key;		/* MUST BE LAST FIELD IN RECORD!! */
+};
+
+typedef int (Blt_ListCompareProc)(Blt_ListNode *node1Ptr, 
+	Blt_ListNode *node2Ptr);
+
+/*
+ * A Blt_List is a doubly chained list structure.
+ */
+struct _Blt_List {
+    Blt_ListNode head;		/* Pointer to first element in list */
+    Blt_ListNode tail;		/* Pointer to last element in list */
+    size_t nNodes;		/* Number of node currently in the list. */
+    size_t type;		/* Type of keys in list. */
+};
+
+extern void Blt_List_Init(Blt_List list, size_t type);
+extern void Blt_List_Reset(Blt_List list);
+extern Blt_List Blt_List_Create(size_t type);
+extern void Blt_List_Destroy(Blt_List list);
+extern Blt_ListNode Blt_List_CreateNode(Blt_List list, const char *key);
+extern void Blt_List_DeleteNode(Blt_ListNode node);
+
+extern Blt_ListNode Blt_List_Append(Blt_List list, const char *key, 
+	ClientData clientData);
+extern Blt_ListNode Blt_List_Prepend(Blt_List list, const char *key, 
+	ClientData clientData);
+extern void Blt_List_LinkAfter(Blt_List list, Blt_ListNode node, 
+	Blt_ListNode afterNode);
+extern void Blt_List_LinkBefore(Blt_List list, Blt_ListNode node, 
+	Blt_ListNode beforeNode);
+extern void Blt_List_UnlinkNode(Blt_ListNode node);
+extern Blt_ListNode Blt_List_GetNode(Blt_List list, const char *key);
+extern void Blt_List_DeleteNodeByKey(Blt_List list, const char *key);
+extern Blt_ListNode Blt_List_GetNthNode(Blt_List list, long position, 
+	int direction);
+extern void Blt_List_Sort(Blt_List list, Blt_ListCompareProc *proc);
+
+#define Blt_List_GetLength(list) \
+	(((list) == NULL) ? 0 : ((struct _Blt_List *)list)->nNodes)
+#define Blt_List_FirstNode(list) \
+	(((list) == NULL) ? NULL : ((struct _Blt_List *)list)->head)
+#define Blt_List_LastNode(list)	\
+	(((list) == NULL) ? NULL : ((struct _Blt_List *)list)->tail)
+#define Blt_List_PrevNode(node)	((node)->prev)
+#define Blt_List_NextNode(node) 	((node)->next)
+#define Blt_List_GetKey(node)	\
+	(((node)->list->type == BLT_STRING_KEYS) \
+		 ? (node)->key.string : (node)->key.oneWordValue)
+#define Blt_List_GetValue(node)  	((node)->clientData)
+#define Blt_List_SetValue(node, value) \
+	((node)->clientData = (ClientData)(value))
+#define Blt_List_AppendNode(list, node) \
+	(Blt_List_LinkBefore((list), (node), (Blt_ListNode)NULL))
+#define Blt_List_PrependNode(list, node) \
+	(Blt_List_LinkAfter((list), (node), (Blt_ListNode)NULL))
+
+#endif /* _BLT_LIST_H */
diff --git a/tlt3.0/bltMath.h b/tlt3.0/bltMath.h
new file mode 100644
index 0000000..54814c0
--- /dev/null
+++ b/tlt3.0/bltMath.h
@@ -0,0 +1,45 @@
+
+/*
+ * bltMath.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_MATH_H
+#define _BLT_MATH_H
+
+#include <math.h>
+#include <float.h>
+#include <limits.h>
+
+#define MIN(a,b)	(((a)<(b))?(a):(b))
+#define MAX(a,b)	(((a)>(b))?(a):(b))
+#define MIN3(a,b,c)	(((a)<(b))?(((a)<(c))?(a):(c)):(((b)<(c))?(b):(c)))
+#define MAX3(a,b,c)	(((a)>(b))?(((a)>(c))?(a):(c)):(((b)>(c))?(b):(c)))
+#define EXP10(x)	(pow(10.0,(x)))
+#define ROUND(x) 	((int)((x) + (((x)<0.0) ? -0.5 : 0.5)))
+
+#endif /* BLT_MATH_H */
+
diff --git a/tlt3.0/bltNsUtil.c b/tlt3.0/bltNsUtil.c
new file mode 100644
index 0000000..3598e82
--- /dev/null
+++ b/tlt3.0/bltNsUtil.c
@@ -0,0 +1,146 @@
+/*
+ * bltNsUtil.c --
+ *
+ * This module implements utility namespace procedures for the BLT toolkit.
+ *
+ *	Copyright 1997-2008 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <tclPort.h>
+#include <tclInt.h>
+
+#include "bltInt.h"
+#include "bltNsUtil.h"
+
+/*ARGSUSED*/
+Tcl_Namespace *
+Blt_GetCommandNamespace(Tcl_Command cmdToken)
+{
+  Command *cmdPtr = (Command *)cmdToken;
+
+  return (Tcl_Namespace *)cmdPtr->nsPtr;
+}
+
+int
+Blt_ParseObjectName(Tcl_Interp *interp, const char *path, 
+		    Blt_ObjectName *namePtr, unsigned int flags)
+{
+  char *last, *colon;
+
+  namePtr->nsPtr = NULL;
+  namePtr->name = NULL;
+  colon = NULL;
+
+  /* Find the last namespace separator in the qualified name. */
+  last = (char *)(path + strlen(path));
+  while (--last > path) {
+    if ((*last == ':') && (*(last - 1) == ':')) {
+      last++;		/* just after the last "::" */
+      colon = last - 2;
+      break;
+    }
+  }
+  if (colon == NULL) {
+    namePtr->name = path;
+    if ((flags & BLT_NO_DEFAULT_NS) == 0) {
+      namePtr->nsPtr = Tcl_GetCurrentNamespace(interp);
+    }
+    return TRUE;		/* No namespace designated in name. */
+  }
+
+  /* Separate the namespace and the object name. */
+  *colon = '\0';
+  if (path[0] == '\0') {
+    namePtr->nsPtr = Tcl_GetGlobalNamespace(interp);
+  } else {
+    namePtr->nsPtr = Tcl_FindNamespace(interp, (char *)path, NULL, 
+				       (flags & BLT_NO_ERROR_MSG) ? 0 : TCL_LEAVE_ERR_MSG);
+  }
+  /* Repair the string. */    *colon = ':';
+
+  if (namePtr->nsPtr == NULL) {
+    return FALSE;		/* Namespace doesn't exist. */
+  }
+  namePtr->name =last;
+  return TRUE;
+}
+
+char *
+Blt_MakeQualifiedName(Blt_ObjectName *namePtr, Tcl_DString *resultPtr)
+{
+  Tcl_DStringInit(resultPtr);
+  if ((namePtr->nsPtr->fullName[0] != ':') || 
+      (namePtr->nsPtr->fullName[1] != ':') ||
+      (namePtr->nsPtr->fullName[2] != '\0')) {
+    Tcl_DStringAppend(resultPtr, namePtr->nsPtr->fullName, -1);
+  }
+  Tcl_DStringAppend(resultPtr, "::", -1);
+  Tcl_DStringAppend(resultPtr, (char *)namePtr->name, -1);
+  return Tcl_DStringValue(resultPtr);
+}
+
+static Tcl_Namespace* NamespaceOfVariable(Var *varPtr)
+{
+  if (varPtr->flags & VAR_IN_HASHTABLE) {
+    VarInHash *vhashPtr = (VarInHash *)varPtr;
+    TclVarHashTable *vtablePtr;
+
+    vtablePtr = (TclVarHashTable *)vhashPtr->entry.tablePtr;
+    return (Tcl_Namespace*)(vtablePtr->nsPtr);
+  }
+  return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetVariableNamespace --
+ *
+ *	Returns the namespace context of the variable.  If NULL, this
+ *	indicates that the variable is local to the call frame.
+ *
+ * Results:
+ *	Returns the context of the namespace in an opaque type.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Namespace *
+Blt_GetVariableNamespace(Tcl_Interp *interp, const char *path)
+{
+  Blt_ObjectName objName;
+
+  if (!Blt_ParseObjectName(interp, path, &objName, BLT_NO_DEFAULT_NS)) {
+    return NULL;
+  }
+  if (objName.nsPtr == NULL) {
+    Var *varPtr;
+
+    varPtr = (Var *)Tcl_FindNamespaceVar(interp, (char *)path, 
+					 (Tcl_Namespace *)NULL, 
+					 TCL_GLOBAL_ONLY);
+    if (varPtr != NULL) {
+      return NamespaceOfVariable(varPtr);
+    }
+  }
+  return objName.nsPtr;    
+}
diff --git a/tlt3.0/bltNsUtil.h b/tlt3.0/bltNsUtil.h
new file mode 100644
index 0000000..63f8ae3
--- /dev/null
+++ b/tlt3.0/bltNsUtil.h
@@ -0,0 +1,59 @@
+/*
+ * bltNsUtil.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef BLT_NS_UTIL_H
+#define BLT_NS_UTIL_H 1
+
+#define NS_SEARCH_NONE		(0)
+#define NS_SEARCH_CURRENT	(1<<0)
+#define NS_SEARCH_GLOBAL	(1<<1)
+#define NS_SEARCH_BOTH		(NS_SEARCH_GLOBAL | NS_SEARCH_CURRENT)
+
+typedef struct {
+    const char *name;
+    Tcl_Namespace *nsPtr;
+} Blt_ObjectName;
+
+#define BLT_NO_DEFAULT_NS	(1<<0)
+#define BLT_NO_ERROR_MSG	(1<<1)
+
+/* 
+ * Auxillary procedures 
+ */
+extern Tcl_Namespace *Blt_GetVariableNamespace(Tcl_Interp *interp, 
+	const char *varName);
+
+extern Tcl_Namespace *Blt_GetCommandNamespace(Tcl_Command cmdToken);
+
+extern int Blt_ParseObjectName(Tcl_Interp *interp, const char *name, 
+	Blt_ObjectName *objNamePtr, unsigned int flags);
+
+extern char *Blt_MakeQualifiedName(Blt_ObjectName *objNamePtr, 
+	Tcl_DString *resultPtr);
+
+#endif /* BLT_NS_UTIL_H */
diff --git a/tlt3.0/bltOp.h b/tlt3.0/bltOp.h
new file mode 100644
index 0000000..ef4c712
--- /dev/null
+++ b/tlt3.0/bltOp.h
@@ -0,0 +1,37 @@
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_OpSpec --
+ *
+ * 	Structure to specify a set of operations for a TCL command.
+ *      This is passed to the Blt_GetOp procedure to look
+ *      for a function pointer associated with the operation name.
+ *
+ *---------------------------------------------------------------------------
+ */
+typedef struct {
+    const char *name;		/* Name of operation */
+    int minChars;		/* Minimum # characters to disambiguate */
+    void *proc;
+    int minArgs;		/* Minimum # args required */
+    int maxArgs;		/* Maximum # args required */
+    const char *usage;		/* Usage message */
+} Blt_OpSpec;
+
+typedef enum {
+    BLT_OP_ARG0,		/* Op is the first argument. */
+    BLT_OP_ARG1,		/* Op is the second argument. */
+    BLT_OP_ARG2,		/* Op is the third argument. */
+    BLT_OP_ARG3,		/* Op is the fourth argument. */
+    BLT_OP_ARG4			/* Op is the fifth argument. */
+
+} Blt_OpIndex;
+
+#define BLT_OP_BINARY_SEARCH	0
+#define BLT_OP_LINEAR_SEARCH	1
+
+extern void *Blt_GetOpFromObj(Tcl_Interp *interp, int nSpecs, 
+	Blt_OpSpec *specs, int operPos, int objc, Tcl_Obj *const *objv, 
+	int flags);
+
diff --git a/tlt3.0/bltParse.c b/tlt3.0/bltParse.c
new file mode 100644
index 0000000..7c188e2
--- /dev/null
+++ b/tlt3.0/bltParse.c
@@ -0,0 +1,511 @@
+/*
+ * bltParse.c --
+ *
+ * Contains a collection of procedures that are used to parse Tcl
+ * commands or parts of commands (like quoted strings or nested 
+ * sub-commands).
+ *
+ * This file is copied from tclParse.c in the TCL library distribution.
+ *
+ *	Copyright (c) 1987-1993 The Regents of the University of
+ *	California.
+ *
+ *	Copyright (c) 1994-1998 Sun Microsystems, Inc.
+ * 
+ */
+
+/*
+ * Since TCL 8.1.0 these routines have been replaced by ones that
+ * generate byte-codes.  But since these routines are used in vector
+ * expressions, where no such byte-compilation is necessary, I now
+ * include them.  In fact, the byte-compiled versions would be slower
+ * since the compiled code typically runs only one time.
+ */
+
+#include "bltInt.h"
+#include "bltParse.h"
+
+/*
+ * A table used to classify input characters to assist in parsing
+ * TCL commands.  The table should be indexed with a signed character
+ * using the CHAR_TYPE macro.  The character may have a negative
+ * value.  The CHAR_TYPE macro takes a pointer to a signed character
+ * and a pointer to the last character in the source string.  If the
+ * src pointer is pointing at the terminating null of the string,
+ * CHAR_TYPE returns TCL_COMMAND_END.
+ */
+
+#define STATIC_STRING_SPACE	150
+#define TCL_NORMAL		0x01
+#define TCL_SPACE		0x02
+#define TCL_COMMAND_END		0x04
+#define TCL_QUOTE		0x08
+#define TCL_OPEN_BRACKET	0x10
+#define TCL_OPEN_BRACE		0x20
+#define TCL_CLOSE_BRACE		0x40
+#define TCL_BACKSLASH		0x80
+#define TCL_DOLLAR		0x00
+
+/*
+ * The following table assigns a type to each character. Only types
+ * meaningful to TCL parsing are represented here. The table is
+ * designed to be referenced with either signed or unsigned characters,
+ * so it has 384 entries. The first 128 entries correspond to negative
+ * character values, the next 256 correspond to positive character
+ * values. The last 128 entries are identical to the first 128. The
+ * table is always indexed with a 128-byte offset (the 128th entry
+ * corresponds to a 0 character value).
+ */
+
+static unsigned char tclTypeTable[] =
+{
+ /*
+     * Negative character values, from -128 to -1:
+     */
+
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+
+    /*
+     * Positive character values, from 0-127:
+     */
+
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_SPACE, TCL_COMMAND_END, TCL_SPACE,
+    TCL_SPACE, TCL_SPACE, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_SPACE, TCL_NORMAL, TCL_QUOTE, TCL_NORMAL,
+    TCL_DOLLAR, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_COMMAND_END,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_OPEN_BRACKET,
+    TCL_BACKSLASH, TCL_COMMAND_END, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_OPEN_BRACE,
+    TCL_NORMAL, TCL_CLOSE_BRACE, TCL_NORMAL, TCL_NORMAL,
+
+    /*
+     * Large unsigned character values, from 128-255:
+     */
+
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+    TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL,
+};
+
+#define CHAR_TYPE(src,last) \
+	(((src)==(last))?TCL_COMMAND_END:(tclTypeTable+128)[(int)*(src)])
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ParseNestedCmd --
+ *
+ *	This procedure parses a nested TCL command between
+ *	brackets, returning the result of the command.
+ *
+ * Results:
+ *	The return value is a standard TCL result, which is
+ *	TCL_OK unless there was an error while executing the
+ *	nested command.  If an error occurs then interp->result
+ *	contains a standard error message.  *TermPtr is filled
+ *	in with the address of the character just after the
+ *	last one processed;  this is usually the character just
+ *	after the matching close-bracket, or the null character
+ *	at the end of the string if the close-bracket was missing
+ *	(a missing close bracket is an error).  The result returned
+ *	by the command is stored in standard fashion in *parsePtr,
+ *	null-terminated, with parsePtr->next pointing to the null
+ *	character.
+ *
+ * Side effects:
+ *	The storage space at *parsePtr may be expanded.
+ *
+ *---------------------------------------------------------------------------
+ */
+int Blt_ParseNestedCmd(
+    Tcl_Interp *interp,		/* Interpreter to use for nested command
+				 * evaluations and error messages. */
+    const char *string,		/* Character just after opening bracket. */
+    int flags,			/* Flags to pass to nested Tcl_Eval. */
+    const char **termPtr,	/* Store address of terminating character
+				 * here. */
+    ParseValue *parsePtr)	/* Information about where to place
+				 * result of command. */
+{
+  return TCL_ERROR;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ParseBraces --
+ *
+ *	This procedure scans the information between matching
+ *	curly braces.
+ *
+ * Results:
+ *	The return value is a standard TCL result, which is
+ *	TCL_OK unless there was an error while parsing string.
+ *	If an error occurs then interp->result contains a
+ *	standard error message.  *TermPtr is filled
+ *	in with the address of the character just after the
+ *	last one successfully processed;  this is usually the
+ *	character just after the matching close-brace.  The
+ *	information between curly braces is stored in standard
+ *	fashion in *parsePtr, null-terminated with parsePtr->next
+ *	pointing to the terminating null character.
+ *
+ * Side effects:
+ *	The storage space at *parsePtr may be expanded.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int Blt_ParseBraces(
+    Tcl_Interp *interp,		/* Interpreter to use for nested command
+				 * evaluations and error messages. */
+    const char *string,		/* Character just after opening bracket. */
+    const char **termPtr,	/* Store address of terminating character
+				 * here. */
+    ParseValue *parsePtr)	/* Information about where to place
+				 * result of command. */
+{
+    int level;
+    const char *src;
+    char *dest, *end;
+    char c;
+    const char *lastChar = string + strlen(string);
+
+    src = string;
+    dest = parsePtr->next;
+    end = parsePtr->end;
+    level = 1;
+
+    /*
+     * Copy the characters one at a time to the result area, stopping
+     * when the matching close-brace is found.
+     */
+
+    for (;;) {
+	c = *src;
+	src++;
+
+	if (dest == end) {
+	    parsePtr->next = dest;
+	    (*parsePtr->expandProc) (parsePtr, 20);
+	    dest = parsePtr->next;
+	    end = parsePtr->end;
+	}
+	*dest = c;
+	dest++;
+
+	if (CHAR_TYPE(src - 1, lastChar) == TCL_NORMAL) {
+	    continue;
+	} else if (c == '{') {
+	    level++;
+	} else if (c == '}') {
+	    level--;
+	    if (level == 0) {
+		dest--;		/* Don't copy the last close brace. */
+		break;
+	    }
+	} else if (c == '\\') {
+	    int count;
+
+	    /*
+	     * Must always squish out backslash-newlines, even when in
+	     * braces.  This is needed so that this sequence can appear
+	     * anywhere in a command, such as the middle of an expression.
+	     */
+
+	    if (*src == '\n') {
+		dest[-1] = Tcl_Backslash(src - 1, &count);
+		src += count - 1;
+	    } else {
+		Tcl_Backslash(src - 1, &count);
+		while (count > 1) {
+		    if (dest == end) {
+			parsePtr->next = dest;
+			(*parsePtr->expandProc) (parsePtr, 20);
+			dest = parsePtr->next;
+			end = parsePtr->end;
+		    }
+		    *dest = *src;
+		    dest++;
+		    src++;
+		    count--;
+		}
+	    }
+	} else if (c == '\0') {
+	    Tcl_AppendResult(interp, "missing close-brace", (char *)NULL);
+	    *termPtr = string - 1;
+	    return TCL_ERROR;
+	}
+    }
+
+    *dest = '\0';
+    parsePtr->next = dest;
+    *termPtr = src;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ExpandParseValue --
+ *
+ *	This procedure is commonly used as the value of the
+ *	expandProc in a ParseValue.  It uses malloc to allocate
+ *	more space for the result of a parse.
+ *
+ * Results:
+ *	The buffer space in *parsePtr is reallocated to something
+ *	larger, and if parsePtr->clientData is non-zero the old
+ *	buffer is freed.  Information is copied from the old
+ *	buffer to the new one.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+void Blt_ExpandParseValue(
+    ParseValue *parsePtr,	/* Information about buffer that
+				 * must be expanded.  If the clientData
+				 * in the structure is non-zero, it
+				 * means that the current buffer is
+				 * dynamically allocated. */
+    int needed)			/* Minimum amount of additional space
+				 * to allocate. */
+{
+    int size;
+    char *buffer;
+
+    /*
+     * Either double the size of the buffer or add enough new space
+     * to meet the demand, whichever produces a larger new buffer.
+     */
+    size = (parsePtr->end - parsePtr->buffer) + 1;
+    if (size < needed) {
+	size += needed;
+    } else {
+	size += size;
+    }
+    buffer = malloc((unsigned int)size);
+
+    /*
+     * Copy from old buffer to new, free old buffer if needed, and
+     * mark new buffer as malloc-ed.
+     */
+    memcpy((VOID *) buffer, (VOID *) parsePtr->buffer,
+	(size_t) (parsePtr->next - parsePtr->buffer));
+    parsePtr->next = buffer + (parsePtr->next - parsePtr->buffer);
+    if (parsePtr->clientData != 0) {
+	free(parsePtr->buffer);
+    }
+    parsePtr->buffer = buffer;
+    parsePtr->end = buffer + size - 1;
+    parsePtr->clientData = (ClientData)1;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ParseQuotes --
+ *
+ *	This procedure parses a double-quoted string such as a
+ *	quoted TCL command argument or a quoted value in a Tcl
+ *	expression.  This procedure is also used to parse array
+ *	element names within parentheses, or anything else that
+ *	needs all the substitutions that happen in quotes.
+ *
+ * Results:
+ *	The return value is a standard TCL result, which is
+ *	TCL_OK unless there was an error while parsing the
+ *	quoted string.  If an error occurs then interp->result
+ *	contains a standard error message.  *TermPtr is filled
+ *	in with the address of the character just after the
+ *	last one successfully processed;  this is usually the
+ *	character just after the matching close-quote.  The
+ *	fully-substituted contents of the quotes are stored in
+ *	standard fashion in *parsePtr, null-terminated with
+ *	parsePtr->next pointing to the terminating null character.
+ *
+ * Side effects:
+ *	The buffer space in parsePtr may be enlarged by calling its
+ *	expandProc.
+ *
+ *---------------------------------------------------------------------------
+ */
+int Blt_ParseQuotes(
+    Tcl_Interp *interp,		/* Interpreter to use for nested command
+				 * evaluations and error messages. */
+    const char *string,		/* Character just after opening double-
+				 * quote. */
+    int termChar,		/* Character that terminates "quoted" string
+				 * (usually double-quote, but sometimes
+				 * right-paren or something else). */
+    int flags,			/* Flags to pass to nested Tcl_Eval calls. */
+    const char **termPtr,	/* Store address of terminating character
+				 * here. */
+    ParseValue *parsePtr)	/* Information about where to place
+				 * fully-substituted result of parse. */
+{
+    const char *src;
+    char *dest, c;
+    const char *lastChar = string + strlen(string);
+
+    src = string;
+    dest = parsePtr->next;
+
+    for (;;) {
+	if (dest == parsePtr->end) {
+	    /*
+	     * Target buffer space is about to run out.  Make more space.
+	     */
+	    parsePtr->next = dest;
+	    (*parsePtr->expandProc) (parsePtr, 1);
+	    dest = parsePtr->next;
+	}
+	c = *src;
+	src++;
+	if (c == termChar) {
+	    *dest = '\0';
+	    parsePtr->next = dest;
+	    *termPtr = src;
+	    return TCL_OK;
+	} else if (CHAR_TYPE(src - 1, lastChar) == TCL_NORMAL) {
+	  copy:
+	    *dest = c;
+	    dest++;
+	    continue;
+	} else if (c == '$') {
+	    int length;
+	    const char *value;
+
+	    value = Tcl_ParseVar(interp, src - 1, termPtr);
+	    if (value == NULL) {
+		return TCL_ERROR;
+	    }
+	    src = *termPtr;
+	    length = strlen(value);
+	    if ((parsePtr->end - dest) <= length) {
+		parsePtr->next = dest;
+		(*parsePtr->expandProc) (parsePtr, length);
+		dest = parsePtr->next;
+	    }
+	    strcpy(dest, value);
+	    dest += length;
+	    continue;
+	} else if (c == '[') {
+	    int result;
+
+	    parsePtr->next = dest;
+	    result = Blt_ParseNestedCmd(interp, src, flags, termPtr, parsePtr);
+	    if (result != TCL_OK) {
+		return result;
+	    }
+	    src = *termPtr;
+	    dest = parsePtr->next;
+	    continue;
+	} else if (c == '\\') {
+	    int nRead;
+
+	    src--;
+	    *dest = Tcl_Backslash(src, &nRead);
+	    dest++;
+	    src += nRead;
+	    continue;
+	} else if (c == '\0') {
+	    char buf[10];
+
+	    Tcl_ResetResult(interp);
+	    sprintf_s(buf, 10, "missing %c", termChar);
+	    Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, 9);
+	    *termPtr = string - 1;
+	    return TCL_ERROR;
+	} else {
+	    goto copy;
+	}
+    }
+}
+
diff --git a/tlt3.0/bltParse.h b/tlt3.0/bltParse.h
new file mode 100644
index 0000000..c56f3d6
--- /dev/null
+++ b/tlt3.0/bltParse.h
@@ -0,0 +1,47 @@
+
+/*
+ * bltParse.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_PARSE_H
+#define _BLT_PARSE_H
+
+typedef struct _ParseValue ParseValue;
+struct _ParseValue {
+    char *buffer;
+    char *next;
+    char *end;
+    void (*expandProc)(ParseValue *pvPtr, int needed);
+    ClientData clientData;
+};
+
+extern int Blt_ParseBraces(Tcl_Interp *interp, const char *string, 
+	const char **termPtr, ParseValue *pvPtr);
+extern int Blt_ParseNestedCmd(Tcl_Interp *interp, const char *string, 
+	int flags, const char **termPtr, ParseValue *pvPtr);
+extern int Blt_ParseQuotes(Tcl_Interp *interp, const char *string, 
+	int termChar, int flags, const char **termPtr, ParseValue * pvPtr);
+extern void Blt_ExpandParseValue(ParseValue *pvPtr, int needed);
+
+#endif 
diff --git a/tlt3.0/bltPool.c b/tlt3.0/bltPool.c
new file mode 100644
index 0000000..8042a67
--- /dev/null
+++ b/tlt3.0/bltPool.c
@@ -0,0 +1,474 @@
+/*
+ * bltPool.c --
+ *
+ *	Copyright 2001-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "bltInt.h"
+#include "bltPool.h"
+
+/*
+ * Blt_Pool --
+ *
+ *	Implements a pool memory allocator. 
+ *
+ *	  + It's faster allocating memory since malloc/free are called
+ *	    only a fraction of the normal times.  Fixed size items can 
+ *	    be reused without deallocating/reallocating memory.
+ *	  + You don't have the extra 8-16 byte overhead per malloc. 
+ *	  - Memory is freed only when the entire pool is destroyed.
+ *	  - Memory is allocated in chunks. More memory is allocated 
+ *	    than used.  
+ *	  0 Depending upon allocation/deallocation patterns, locality
+ *	    may be improved or degraded.
+ *
+ *      The pool is a chain of malloc'ed blocks.
+ *
+ *             +---------+  +---------+  +---------+  
+ *       NULL<-| nextPtr |<-| nextPtr |<-| nextPtr |<- headPtr
+ *             |---------|  |---------|  |---------|  
+ *             | chunk1  |  | chunk2  |  | chunk3  |  
+ *             +---------+  |         |  |         |  
+ *                          +---------+  |         |  
+ *                                       |         |  
+ *                                       |         |  
+ *                                       +---------+  
+ *
+ *      Each chunk contains an integral number of fixed size items.
+ *	The number of items doubles until a maximum size is reached
+ *      (each subsequent new chunk will be the maximum).  Chunks
+ *	are allocated only when needed (no more space is available
+ *	in the last chunk).
+ *
+ *	The chain of blocks is only freed when the entire pool is
+ *	destroyed.  
+ *
+ *      A freelist of unused items also maintained. Each freed item
+ *	is prepended to a free list.  Before allocating new chunks
+ *	the freelist is examined to see if any unused items exist.
+ *
+ *               chunk1       chunk2       chunk3
+ *            +---------+  +---------+  +---------+  
+ *      NULL<-| unused  |  |         |  |         |
+ *            +----^----+  +---------+  +---------+  
+ *            | unused  |<-| unused  |<-| unused  |       
+ *            +---------+  +---------+  +----^----+  
+ *            |         |  |         |  | unused  |
+ *            +---------+  |         |  +----^----+
+ *                         |         |  |    |    |
+ *                         +---------+  +----|----+
+ *                                      | usused  |<- freePtr
+ *                                      +---------+  
+ */
+
+#define POOL_MAX_CHUNK_SIZE      ((1<<16) - sizeof(PoolChain))
+
+#ifndef ALIGN
+#define ALIGN(a) \
+	(((size_t)a + (sizeof(void *) - 1)) & (~(sizeof(void *) - 1)))
+#endif /* ALIGN */
+
+typedef struct _PoolChain {
+   struct _PoolChain *nextPtr;
+} PoolChain;
+
+typedef struct {
+    Blt_PoolAllocProc *allocProc;
+    Blt_PoolFreeProc *freeProc;
+
+    PoolChain *headPtr;		/* Chain of malloc'ed chunks. */
+    PoolChain *freePtr; 	/* List of deleted items. This is only used
+				 * for fixed size items. */
+    size_t poolSize;		/* Log2 of # of items in the current block. */
+    size_t itemSize;		/* Size of an item. */
+    size_t bytesLeft;		/* # of bytes left in the current chunk. */
+    size_t waste;
+} Pool;
+
+static Blt_PoolAllocProc VariablePoolAllocItem;
+static Blt_PoolFreeProc  VariablePoolFreeItem;
+static Blt_PoolAllocProc FixedPoolAllocItem;
+static Blt_PoolFreeProc  FixedPoolFreeItem;
+static Blt_PoolAllocProc StringPoolAllocItem;
+static Blt_PoolFreeProc  StringPoolFreeItem;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VariablePoolAllocItem --
+ *
+ *      Returns a new item.  First check if there is any more space 
+ *	left in the current chunk.  If there isn't then next check
+ *	the free list for unused items.  Finally allocate a new 
+ *	chunk and return its first item.
+ *
+ * Results:
+ *      Returns a new (possible reused) item.
+ *
+ * Side Effects:
+ *	A new memory chunk may be allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void *
+VariablePoolAllocItem(
+    Blt_Pool pool,		      
+    size_t size)		/* Number of bytes to allocate. */
+{
+    Pool *poolPtr = (Pool *)pool;
+    PoolChain *chainPtr;
+    void *memory;
+
+    size = ALIGN(size);
+    if (size >= POOL_MAX_CHUNK_SIZE) {
+	/* 
+	 * Handle oversized requests by allocating a chunk to hold the
+	 * single item and immediately placing it into the in-use list.
+	 */
+	chainPtr = malloc(sizeof(PoolChain) + size);
+        if (poolPtr->headPtr == NULL) {
+	    poolPtr->headPtr = chainPtr;
+	} else {
+	    chainPtr->nextPtr = poolPtr->headPtr->nextPtr;
+	    poolPtr->headPtr->nextPtr = chainPtr;
+	}
+	memory = (void *)chainPtr;
+    } else {
+	if (poolPtr->bytesLeft >= size) {
+	    poolPtr->bytesLeft -= size;
+	    memory = (char *)(poolPtr->headPtr + 1) + poolPtr->bytesLeft;
+	} else {
+	    poolPtr->waste += poolPtr->bytesLeft;
+	    /* Create a new block of items and prepend it to the in-use list */
+	    poolPtr->bytesLeft = POOL_MAX_CHUNK_SIZE;
+	    /* Allocate the requested chunk size, plus the header */
+	    chainPtr = malloc(sizeof(PoolChain) + poolPtr->bytesLeft);
+	    chainPtr->nextPtr = poolPtr->headPtr;
+	    poolPtr->headPtr = chainPtr;
+	    /* Peel off a new item. */
+	    poolPtr->bytesLeft -= size;
+	    memory = (char *)(chainPtr + 1) + poolPtr->bytesLeft;
+	}
+    }
+    return memory;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VariablePoolFreeItem --
+ *
+ *      Placeholder for freeProc routine.  The pool memory is 
+ *	not reclaimed or freed until the entire pool is released.
+ *
+ * Results:
+ *      None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static void
+VariablePoolFreeItem(Blt_Pool pool, void *item)
+{
+    /* Does nothing */
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * StringPoolAllocItem --
+ *
+ *      Returns a new item.  First check if there is any more space 
+ *	left in the current chunk.  If there isn't then next check
+ *	the free list for unused items.  Finally allocate a new 
+ *	chunk and return its first item.
+ *
+ * Results:
+ *      Returns a new (possible reused) item.
+ *
+ * Side Effects:
+ *	A new memory chunk may be allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void *
+StringPoolAllocItem(Blt_Pool pool, size_t size)
+{
+    Pool *poolPtr = (Pool *)pool;
+    PoolChain *chainPtr;
+    void *memory;
+
+    if (size >= POOL_MAX_CHUNK_SIZE) {
+	/* 
+	 * Handle oversized requests by allocating a chunk to hold the
+	 * single item and immediately placing it into the in-use list.
+	 */
+	chainPtr = malloc(sizeof(PoolChain) + size);
+        if (poolPtr->headPtr == NULL) {
+	    poolPtr->headPtr = chainPtr;
+	} else {
+	    chainPtr->nextPtr = poolPtr->headPtr->nextPtr;
+	    poolPtr->headPtr->nextPtr = chainPtr;
+	}
+	memory = (void *)chainPtr;
+    } else {
+	if (poolPtr->bytesLeft >= size) {
+	    poolPtr->bytesLeft -= size;
+	    memory = (char *)(poolPtr->headPtr + 1) + poolPtr->bytesLeft;
+	} else {
+	    poolPtr->waste += poolPtr->bytesLeft;
+	    /* Create a new block of items and prepend it to the
+	     * in-use list */
+	    poolPtr->bytesLeft = POOL_MAX_CHUNK_SIZE;
+	    /* Allocate the requested chunk size, plus the header */
+	    chainPtr = malloc(sizeof(PoolChain) + poolPtr->bytesLeft);
+	    chainPtr->nextPtr = poolPtr->headPtr;
+	    poolPtr->headPtr = chainPtr;
+	    /* Peel off a new item. */
+	    poolPtr->bytesLeft -= size;
+	    memory = (char *)(chainPtr + 1) + poolPtr->bytesLeft;
+	}
+    }
+    return memory;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * StringPoolFreeItem --
+ *
+ *      Placeholder for freeProc routine.  String pool memory is 
+ *	not reclaimed or freed until the entire pool is released.
+ *
+ * Results:
+ *      None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static void
+StringPoolFreeItem(Blt_Pool pool, void *item) 
+{
+    /* Does nothing */
+}
+
+/*
+ *       The fixed size pool is a chain of malloc'ed blocks.
+ *
+ *             +---------+  +---------+  +---------+  
+ *       NULL<-| nextPtr |<-| nextPtr |<-| nextPtr |<- headPtr
+ *             |---------|  |---------|  |---------|  
+ *             | chunk1  |  | chunk2  |  | chunk3  |  
+ *             +---------+  |         |  |         |  
+ *                          +---------+  |         |  
+ *                                       |         |  
+ *                                       |         |  
+ *                                       +---------+  
+ *
+ *      Each chunk contains an integral number of fixed size items.
+ *	The number of items doubles until a maximum size is reached
+ *      (each subsequent new chunk will be the maximum).  Chunks
+ *	are allocated only when needed (no more space is available
+ *	in the last chunk).
+ *
+ *	The chain of blocks is only freed when the entire pool is
+ *	destroyed.  
+ *
+ *      A freelist of unused items also maintained. Each freed item
+ *	is prepended to a free list.  Before allocating new chunks
+ *	the freelist is examined to see if an unused items exist.
+ *
+ *               chunk1       chunk2       chunk3
+ *            +---------+  +---------+  +---------+  
+ *      NULL<-| unused  |  |         |  |         |
+ *            +----^----+  +---------+  +---------+  
+ *            | unused  |<-| unused  |<-| unused  |       
+ *            +---------+  +---------+  +----^----+  
+ *            |         |  |         |  | unused  |
+ *            +---------+  |         |  +----^----+
+ *                         |         |  |    |    |
+ *                         +---------+  +----|----+
+ *                                      | usused  |<- freePtr
+ *                                      +---------+  
+ */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FixedPoolFreeItem --
+ *
+ *      Returns a new item.  First check if there is any more space 
+ *	left in the current chunk.  If there isn't then next check
+ *	the free list for unused items.  Finally allocate a new 
+ *	chunk and return its first item.
+ *
+ * Results:
+ *      Returns a new (possible reused) item.
+ *
+ * Side Effects:
+ *	A new memory chunk may be allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void *
+FixedPoolAllocItem(Blt_Pool pool, size_t size)
+{
+    Pool *poolPtr = (Pool *)pool;
+    PoolChain *chainPtr;
+    void *newPtr;
+
+    size = ALIGN(size);
+    if (poolPtr->itemSize == 0) {
+	poolPtr->itemSize = size;
+    }
+    assert(size == poolPtr->itemSize);
+
+    if (poolPtr->bytesLeft > 0) {
+	poolPtr->bytesLeft -= poolPtr->itemSize;
+	newPtr = (char *)(poolPtr->headPtr + 1) + poolPtr->bytesLeft;
+    } else if (poolPtr->freePtr != NULL) { /* Reuse from the free list. */
+	/* Reuse items on the free list */
+	chainPtr = poolPtr->freePtr;
+	poolPtr->freePtr = chainPtr->nextPtr;
+	newPtr = (void *)chainPtr;
+    } else {			/* Allocate another block. */
+	
+	/* Create a new block of items and prepend it to the in-use list */
+	poolPtr->bytesLeft = poolPtr->itemSize * (1 << poolPtr->poolSize);
+	if (poolPtr->bytesLeft < POOL_MAX_CHUNK_SIZE) {
+	    poolPtr->poolSize++; /* Keep doubling the size of the new 
+				  * chunk up to a maximum size. */
+	}
+	/* Allocate the requested chunk size, plus the header */
+	chainPtr = malloc(sizeof(PoolChain) + poolPtr->bytesLeft);
+	chainPtr->nextPtr = poolPtr->headPtr;
+	poolPtr->headPtr = chainPtr;
+
+	/* Peel off a new item. */
+	poolPtr->bytesLeft -= poolPtr->itemSize;
+	newPtr = (char *)(poolPtr->headPtr + 1) + poolPtr->bytesLeft;
+    }
+    return newPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FixedPoolFreeItem --
+ *
+ *      Frees an item.  The actual memory is not freed.  The item
+ *	instead is prepended to a freelist where it may be reclaimed
+ *	and used again.
+ *
+ * Results:
+ *      None.
+ *
+ * Side Effects:
+ *	Item is placed on the pool's free list.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+FixedPoolFreeItem(Blt_Pool pool, void *item) 
+{
+    Pool *poolPtr = (Pool *)pool;
+    PoolChain *chainPtr = (PoolChain *)item;
+    
+    /* Prepend the newly deallocated item to the free list. */
+    chainPtr->nextPtr = poolPtr->freePtr;
+    poolPtr->freePtr = chainPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_PoolCreate --
+ *
+ *      Creates a new memory pool for fixed-size/variable-size/string
+ *      items.  
+ *
+ * Results:
+ *      Returns a pointer to the newly allocated pool.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Blt_Pool
+Blt_PoolCreate(int type)
+{
+    Pool *poolPtr;
+
+    poolPtr = malloc(sizeof(Pool));
+    switch (type) {
+    case BLT_VARIABLE_SIZE_ITEMS:
+	poolPtr->allocProc = VariablePoolAllocItem;
+	poolPtr->freeProc = VariablePoolFreeItem;
+	break;
+    case BLT_FIXED_SIZE_ITEMS:
+	poolPtr->allocProc = FixedPoolAllocItem;
+	poolPtr->freeProc = FixedPoolFreeItem;
+	break;
+    case BLT_STRING_ITEMS:
+ 	poolPtr->allocProc = StringPoolAllocItem;
+	poolPtr->freeProc = StringPoolFreeItem;
+	break;
+    }
+    poolPtr->headPtr = poolPtr->freePtr = NULL;
+    poolPtr->waste = poolPtr->bytesLeft = 0;
+    poolPtr->poolSize = poolPtr->itemSize = 0;
+    return (Blt_Pool)poolPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_PoolDestroy --
+ *
+ *      Destroys the given memory pool.  The chain of allocated blocks
+ *	are freed.  The is the only time that memory is actually freed.
+ *
+ * Results:
+ *      None.
+ *
+ * Side Effects:
+ *	All memory used by the pool is freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+void  
+Blt_PoolDestroy(Blt_Pool pool)
+{
+    Pool *poolPtr = (Pool *)pool;
+    PoolChain *chainPtr, *nextPtr;
+    
+    for (chainPtr = poolPtr->headPtr; chainPtr != NULL; chainPtr = nextPtr) {
+	nextPtr = chainPtr->nextPtr;
+	free(chainPtr);
+    }
+    free(poolPtr);
+}
+
diff --git a/tlt3.0/bltPool.h b/tlt3.0/bltPool.h
new file mode 100644
index 0000000..5adf0a5
--- /dev/null
+++ b/tlt3.0/bltPool.h
@@ -0,0 +1,23 @@
+#ifndef BLT_POOL_H
+#define BLT_POOL_H
+
+#define BLT_STRING_ITEMS		0
+#define BLT_FIXED_SIZE_ITEMS		1
+#define BLT_VARIABLE_SIZE_ITEMS		2
+
+typedef struct _Blt_Pool *Blt_Pool;
+typedef void *(Blt_PoolAllocProc)(Blt_Pool pool, size_t size);
+typedef void (Blt_PoolFreeProc)(Blt_Pool pool, void *item);
+
+struct _Blt_Pool {
+    Blt_PoolAllocProc *allocProc;
+    Blt_PoolFreeProc *freeProc;
+};
+
+extern Blt_Pool Blt_PoolCreate(int type);
+extern void Blt_PoolDestroy(Blt_Pool pool);
+
+#define Blt_PoolAllocItem(pool, n) (*((pool)->allocProc))(pool, n)
+#define Blt_PoolFreeItem(pool, item) (*((pool)->freeProc))(pool, item)
+
+#endif /* BLT_POOL_H */
diff --git a/tlt3.0/bltPs.c b/tlt3.0/bltPs.c
new file mode 100644
index 0000000..b9f4c68
--- /dev/null
+++ b/tlt3.0/bltPs.c
@@ -0,0 +1,1328 @@
+/*
+ * bltPs.c --
+ *
+ * This module implements general PostScript conversion routines.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdarg.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#include <tkPort.h>
+#include <tkInt.h>
+#include <tk3d.h>
+
+#include "bltInt.h"
+#include "bltMath.h"
+#include "bltDBuffer.h"
+#include "bltPsInt.h"
+
+#define PS_MAXPATH	1500		/* Maximum number of components in a
+					 * PostScript (level 1) path. */
+
+#define PICA_MM		2.83464566929
+#define PICA_INCH	72.0
+#define PICA_CM		28.3464566929
+
+static Tcl_Interp *psInterp = NULL;
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Ps_GetPica --
+ *
+ *	Given a string, returns the number of pica corresponding to that
+ *	string.
+ *
+ * Results:
+ *	The return value is a standard TCL return result.  If TCL_OK is
+ *	returned, then everything went well and the pixel distance is stored
+ *	at *doublePtr; otherwise TCL_ERROR is returned and an error message is
+ *	left in interp->result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_Ps_GetPicaFromObj(
+    Tcl_Interp *interp,			/* Use this for error reporting. */
+    Tcl_Obj *objPtr,			/* String describing a number of
+					 * pixels. */
+    int *picaPtr)			/* Place to store converted result. */
+{
+    char *p;
+    double pica;
+    const char *string;
+    
+    string = Tcl_GetString(objPtr);
+    pica = strtod((char *)string, &p);
+    if (p == string) {
+	goto error;
+    }
+    if (pica < 0.0) {
+	goto error;
+    }
+    while ((*p != '\0') && isspace((unsigned char)(*p))) {
+	p++;
+    }
+    switch (*p) {
+	case '\0':			     break;
+	case 'c': pica *= PICA_CM;   p++;    break;
+	case 'i': pica *= PICA_INCH; p++;    break;
+	case 'm': pica *= PICA_MM;   p++;    break;
+	case 'p': p++;                       break;
+	default:  goto error;
+    }
+    while ((*p != '\0') && isspace((unsigned char)(*p))) {
+	p++;
+    }
+    if (*p == '\0') {
+	*picaPtr = ROUND(pica);
+	return TCL_OK;
+    }
+ error:
+    Tcl_AppendResult(interp, "bad screen distance \"", string, "\"", 
+	(char *) NULL);
+    return TCL_ERROR;
+}
+
+int
+Blt_Ps_GetPadFromObj(
+    Tcl_Interp *interp,			/* Interpreter to send results back
+					 * to */
+    Tcl_Obj *objPtr,			/* Pixel value string */
+    Blt_Pad *padPtr)
+{
+    int side1, side2;
+    int objc;
+    Tcl_Obj **objv;
+
+    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if ((objc < 1) || (objc > 2)) {
+	Tcl_AppendResult(interp, "wrong # elements in padding list",
+	    (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (Blt_Ps_GetPicaFromObj(interp, objv[0], &side1) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    side2 = side1;
+    if ((objc > 1) && 
+	(Blt_Ps_GetPicaFromObj(interp, objv[1], &side2) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    /* Don't update the pad structure until we know both values are okay. */
+    padPtr->side1 = side1;
+    padPtr->side2 = side2;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Ps_ComputeBoundingBox --
+ *
+ * 	Computes the bounding box for the PostScript plot.  First get the size
+ * 	of the plot (by default, it's the size of graph's X window).  If the
+ * 	plot plus the page border is bigger than the designated paper size, or
+ * 	if the "-maxpect" option is turned on, scale the plot to the page.
+ *
+ *	Note: All coordinates/sizes are in screen coordinates, not PostScript
+ *	      coordinates.  This includes the computed bounding box and paper
+ *	      size.  They will be scaled to printer points later.
+ *
+ * Results:
+ *	Returns the height of the paper in screen coordinates.
+ *
+ * Side Effects:
+ *	The graph dimensions (width and height) are changed to the requested
+ *	PostScript plot size.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_Ps_ComputeBoundingBox(PageSetup *setupPtr, int width, int height)
+{
+    int paperWidth, paperHeight;
+    int x, y, hSize, vSize, hBorder, vBorder;
+    float hScale, vScale, scale;
+
+    x = setupPtr->padLeft;
+    y = setupPtr->padTop;
+
+    hBorder = PADDING(setupPtr->xPad);
+    vBorder = PADDING(setupPtr->yPad);
+
+    if (setupPtr->flags & PS_LANDSCAPE) {
+	hSize = height;
+	vSize = width;
+    } else {
+	hSize = width;
+	vSize = height;
+    }
+    /*
+     * If the paper size wasn't specified, set it to the graph size plus the
+     * paper border.
+     */
+    paperWidth = (setupPtr->reqPaperWidth > 0) ? setupPtr->reqPaperWidth :
+	hSize + hBorder;
+    paperHeight = (setupPtr->reqPaperHeight > 0) ? setupPtr->reqPaperHeight :
+	vSize + vBorder;
+
+    /*
+     * Scale the plot size (the graph itself doesn't change size) if it's
+     * bigger than the paper or if -maxpect was set.
+     */
+    hScale = vScale = 1.0f;
+    if ((setupPtr->flags & PS_MAXPECT) || ((hSize + hBorder) > paperWidth)) {
+	hScale = (float)(paperWidth - hBorder) / (float)hSize;
+    }
+    if ((setupPtr->flags & PS_MAXPECT) || ((vSize + vBorder) > paperHeight)) {
+	vScale = (float)(paperHeight - vBorder) / (float)vSize;
+    }
+    scale = MIN(hScale, vScale);
+    if (scale != 1.0f) {
+	hSize = (int)((hSize * scale) + 0.5f);
+	vSize = (int)((vSize * scale) + 0.5f);
+    }
+    setupPtr->scale = scale;
+    if (setupPtr->flags & PS_CENTER) {
+	if (paperWidth > hSize) {
+	    x = (paperWidth - hSize) / 2;
+	}
+	if (paperHeight > vSize) {
+	    y = (paperHeight - vSize) / 2;
+	}
+    }
+    setupPtr->left = x;
+    setupPtr->bottom = y;
+    setupPtr->right = x + hSize - 1;
+    setupPtr->top = y + vSize - 1;
+    setupPtr->paperHeight = paperHeight;
+    setupPtr->paperWidth = paperWidth;
+    return paperHeight;
+}
+
+PostScript *
+Blt_Ps_Create(Tcl_Interp *interp, PageSetup *setupPtr)
+{
+    PostScript *psPtr;
+
+    psPtr = malloc(sizeof(PostScript));
+    psPtr->setupPtr = setupPtr;
+    psPtr->interp = interp;
+    Tcl_DStringInit(&psPtr->dString);
+    return psPtr;
+}
+
+void 
+Blt_Ps_SetPrinting(PostScript *psPtr, int state)
+{
+    psInterp = ((state) && (psPtr != NULL)) ? psPtr->interp : NULL;
+}
+
+int
+Blt_Ps_IsPrinting(void)
+{
+    return (psInterp != NULL);
+}
+
+void
+Blt_Ps_Free(PostScript *psPtr)
+{
+    Tcl_DStringFree(&psPtr->dString);
+    free(psPtr);
+}
+
+const char *
+Blt_Ps_GetValue(PostScript *psPtr, int *lengthPtr)
+{
+    *lengthPtr = strlen(Tcl_DStringValue(&psPtr->dString));
+    return Tcl_DStringValue(&psPtr->dString);
+}
+
+void
+Blt_Ps_SetInterp(PostScript *psPtr, Tcl_Interp *interp)
+{
+    Tcl_DStringResult(interp, &psPtr->dString);
+}
+
+char *
+Blt_Ps_GetScratchBuffer(PostScript *psPtr)
+{
+    return psPtr->scratchArr;
+}
+
+Tcl_Interp *
+Blt_Ps_GetInterp(PostScript *psPtr)
+{
+    return psPtr->interp;
+}
+
+Tcl_DString *
+Blt_Ps_GetDString(PostScript *psPtr)
+{
+    return &psPtr->dString;
+}
+
+int 
+Blt_Ps_SaveFile(Tcl_Interp *interp, PostScript *psPtr, const char *fileName)
+{
+    Tcl_Channel channel;
+    int nWritten, nBytes;
+    char *bytes;
+
+    channel = Tcl_OpenFileChannel(interp, fileName, "w", 0660);
+    if (channel == NULL) {
+	return TCL_ERROR;
+    }
+    nBytes = Tcl_DStringLength(&psPtr->dString);
+    bytes = Tcl_DStringValue(&psPtr->dString);
+    nWritten = Tcl_Write(channel, bytes, nBytes);
+    Tcl_Close(interp, channel);
+    if (nWritten != nBytes) {
+	Tcl_AppendResult(interp, "short file \"", fileName, (char *)NULL);
+	Tcl_AppendResult(interp, "\" : wrote ", Blt_Itoa(nWritten), " of ", 
+			 (char *)NULL);
+	Tcl_AppendResult(interp, Blt_Itoa(nBytes), " bytes.", (char *)NULL); 
+	return TCL_ERROR;
+    }	
+    return TCL_OK;
+}
+
+void
+Blt_Ps_VarAppend
+TCL_VARARGS_DEF(PostScript *, arg1)
+{
+    va_list argList;
+    PostScript *psPtr;
+    const char *string;
+
+    psPtr = TCL_VARARGS_START(PostScript, arg1, argList);
+    for (;;) {
+	string = va_arg(argList, char *);
+	if (string == NULL) {
+	    break;
+	}
+	Tcl_DStringAppend(&psPtr->dString, string, -1);
+    }
+}
+
+void
+Blt_Ps_AppendBytes(PostScript *psPtr, const char *bytes, int length)
+{
+    Tcl_DStringAppend(&psPtr->dString, bytes, length);
+}
+
+void
+Blt_Ps_Append(PostScript *psPtr, const char *string)
+{
+    Tcl_DStringAppend(&psPtr->dString, string, -1);
+}
+
+void
+Blt_Ps_Format
+TCL_VARARGS_DEF(PostScript *, arg1)
+{
+    va_list argList;
+    PostScript *psPtr;
+    char *fmt;
+
+    psPtr = TCL_VARARGS_START(PostScript, arg1, argList);
+    fmt = va_arg(argList, char *);
+    vsnprintf(psPtr->scratchArr, POSTSCRIPT_BUFSIZ, fmt, argList);
+    va_end(argList);
+    Tcl_DStringAppend(&psPtr->dString, psPtr->scratchArr, -1);
+}
+
+int
+Blt_Ps_IncludeFile(Tcl_Interp *interp, Blt_Ps ps, const char *fileName)
+{
+    Tcl_Channel channel;
+    Tcl_DString dString;
+    char *buf;
+    char *libDir;
+    int nBytes;
+
+    buf = Blt_Ps_GetScratchBuffer(ps);
+
+    /*
+     * Read in a standard prolog file from file and append it to the
+     * PostScript output stored in the Tcl_DString in psPtr.
+     */
+
+    libDir = (char *)Tcl_GetVar(interp, "tlt_library", TCL_GLOBAL_ONLY);
+    if (libDir == NULL) {
+	Tcl_AppendResult(interp, "couldn't find TLT script library:",
+	    "global variable \"tlt_library\" doesn't exist", (char *)NULL);
+	return TCL_ERROR;
+    }
+    Tcl_DStringInit(&dString);
+    Tcl_DStringAppend(&dString, libDir, -1);
+    Tcl_DStringAppend(&dString, "/", -1);
+    Tcl_DStringAppend(&dString, fileName, -1);
+    fileName = Tcl_DStringValue(&dString);
+    Blt_Ps_VarAppend(ps, "\n% including file \"", fileName, "\"\n\n", 
+	(char *)NULL);
+    channel = Tcl_OpenFileChannel(interp, fileName, "r", 0);
+    if (channel == NULL) {
+	Tcl_AppendResult(interp, "couldn't open prologue file \"", fileName,
+		 "\": ", Tcl_PosixError(interp), (char *)NULL);
+	return TCL_ERROR;
+    }
+    for(;;) {
+	nBytes = Tcl_Read(channel, buf, POSTSCRIPT_BUFSIZ);
+	if (nBytes < 0) {
+	    Tcl_AppendResult(interp, "error reading prologue file \"", 
+		     fileName, "\": ", Tcl_PosixError(interp), 
+		     (char *)NULL);
+	    Tcl_Close(interp, channel);
+	    Tcl_DStringFree(&dString);
+	    return TCL_ERROR;
+	}
+	if (nBytes == 0) {
+	    break;
+	}
+	buf[nBytes] = '\0';
+	Blt_Ps_Append(ps, buf);
+    }
+    Tcl_DStringFree(&dString);
+    Tcl_Close(interp, channel);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * XColorToPostScript --
+ *
+ *	Convert the a XColor (from its RGB values) to a PostScript command.
+ *	If a Tk color map variable exists, it will be consulted for a
+ *	PostScript translation based upon the color name.
+ *
+ *	Maps an X color intensity (0 to 2^16-1) to a floating point value
+ *	[0..1].  Many versions of Tk don't properly handle the the lower 8
+ *	bits of the color intensity, so we can only consider the upper 8 bits.
+ *
+ * Results:
+ *	The string representing the color mode is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+XColorToPostScript(Blt_Ps ps, XColor *colorPtr)
+{
+    /* 
+     * Shift off the lower byte before dividing because some versions of Tk
+     * don't fill the lower byte correctly.
+     */
+    Blt_Ps_Format(ps, "%g %g %g",
+	((double)(colorPtr->red >> 8) / 255.0),
+	((double)(colorPtr->green >> 8) / 255.0),
+	((double)(colorPtr->blue >> 8) / 255.0));
+}
+
+void
+Blt_Ps_XSetBackground(PostScript *psPtr, XColor *colorPtr)
+{
+    /* If the color name exists in TCL array variable, use that translation */
+    if ((psPtr->setupPtr != NULL) && (psPtr->setupPtr->colorVarName != NULL)) {
+	const char *psColor;
+
+	psColor = Tcl_GetVar2(psPtr->interp, psPtr->setupPtr->colorVarName,
+	    Tk_NameOfColor(colorPtr), 0);
+	if (psColor != NULL) {
+	    Blt_Ps_VarAppend(psPtr, " ", psColor, "\n", (char *)NULL);
+	    return;
+	}
+    }
+    XColorToPostScript(psPtr, colorPtr);
+    Blt_Ps_Append(psPtr, " setrgbcolor\n");
+    if (psPtr->setupPtr->flags & PS_GREYSCALE) {
+	Blt_Ps_Append(psPtr, " currentgray setgray\n");
+    }
+}
+
+void
+Blt_Ps_XSetForeground(PostScript *psPtr, XColor *colorPtr)
+{
+    /* If the color name exists in TCL array variable, use that translation */
+    if ((psPtr->setupPtr != NULL) && (psPtr->setupPtr->colorVarName != NULL)) {
+	const char *psColor;
+
+	psColor = Tcl_GetVar2(psPtr->interp, psPtr->setupPtr->colorVarName,
+	    Tk_NameOfColor(colorPtr), 0);
+	if (psColor != NULL) {
+	    Blt_Ps_VarAppend(psPtr, " ", psColor, "\n", (char *)NULL);
+	    return;
+	}
+    }
+    XColorToPostScript(psPtr, colorPtr);
+    Blt_Ps_Append(psPtr, " setrgbcolor\n");
+    if (psPtr->setupPtr->flags & PS_GREYSCALE) {
+	Blt_Ps_Append(psPtr, " currentgray setgray\n");
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ReverseBits --
+ *
+ *	Convert a byte from a X image into PostScript image order.  This
+ *	requires not only the nybbles to be reversed but also their bit
+ *	values.
+ *
+ * Results:
+ *	The converted byte is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+INLINE static unsigned char
+ReverseBits(unsigned char byte)
+{
+    byte = ((byte >> 1) & 0x55) | ((byte << 1) & 0xaa);
+    byte = ((byte >> 2) & 0x33) | ((byte << 2) & 0xcc);
+    byte = ((byte >> 4) & 0x0f) | ((byte << 4) & 0xf0);
+    return byte;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ByteToHex --
+ *
+ *	Convert a byte to its ASCII hexidecimal equivalent.
+ *
+ * Results:
+ *	The converted 2 ASCII character string is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+INLINE static void
+ByteToHex(unsigned char byte, char *string)
+{
+    static char hexDigits[] = "0123456789ABCDEF";
+
+    string[0] = hexDigits[byte >> 4];
+    string[1] = hexDigits[byte & 0x0F];
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Ps_XSetBitmapData --
+ *
+ *      Output a PostScript image string of the given bitmap image.  It is
+ *      assumed the image is one bit deep and a zero value indicates an
+ *      off-pixel.  To convert to PostScript, the bits need to be reversed
+ *      from the X11 image order.
+ *
+ * Results:
+ *      None.
+ *
+ * Side Effects:
+ *      The PostScript image string is appended to interp->result.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Ps_XSetBitmapData(Blt_Ps ps, Display *display, Pixmap bitmap, int w, int h)
+{
+    XImage *imagePtr;
+    int byteCount;
+    int y, bitPos;
+
+    imagePtr = XGetImage(display, bitmap, 0, 0, w, h, 1, ZPixmap);
+    Blt_Ps_Append(ps, "\t<");
+    byteCount = bitPos = 0;	/* Suppress compiler warning */
+    for (y = 0; y < h; y++) {
+	unsigned char byte;
+	char string[10];
+	int x;
+
+	byte = 0;
+	for (x = 0; x < w; x++) {
+	    unsigned long pixel;
+
+	    pixel = XGetPixel(imagePtr, x, y);
+	    bitPos = x % 8;
+	    byte |= (unsigned char)(pixel << bitPos);
+	    if (bitPos == 7) {
+		byte = ReverseBits(byte);
+		ByteToHex(byte, string);
+		string[2] = '\0';
+		byteCount++;
+		byte = 0;
+		if (byteCount >= 30) {
+		    string[2] = '\n';
+		    string[3] = '\t';
+		    string[4] = '\0';
+		    byteCount = 0;
+		}
+		Blt_Ps_Append(ps, string);
+	    }
+	}			/* x */
+	if (bitPos != 7) {
+	    byte = ReverseBits(byte);
+	    ByteToHex(byte, string);
+	    string[2] = '\0';
+	    Blt_Ps_Append(ps, string);
+	    byteCount++;
+	}
+    }				/* y */
+    Blt_Ps_Append(ps, ">\n");
+    XDestroyImage(imagePtr);
+}
+
+typedef struct {
+    const char *alias;
+    const char *fontName;
+} FamilyMap;
+
+static FamilyMap familyMap[] =
+{
+    { "Arial",		        "Helvetica"	   },
+    { "AvantGarde",             "AvantGarde"       },
+    { "Bookman",                "Bookman"          },
+    { "Courier New",            "Courier"          },
+    { "Courier",                "Courier"          },
+    { "Geneva",                 "Helvetica"        },
+    { "Helvetica",              "Helvetica"        },
+    { "Mathematica1",		"Helvetica"	   },
+    { "Monaco",                 "Courier"          },
+    { "New Century Schoolbook", "NewCenturySchlbk" },
+    { "New York",               "Times"            },
+    { "Nimbus Roman No9 L"	"Times"		   },
+    { "Nimbus Sans L Condensed","Helvetica"        },
+    { "Nimbus Sans L",		"Helvetica"        },
+    { "Palatino",               "Palatino"         },
+    { "Standard Symbols L",	"Symbol"           },
+    { "Swiss 721",              "Helvetica"        },
+    { "Symbol",                 "Symbol"           },
+    { "Times New Roman",        "Times"            },
+    { "Times Roman",            "Times"            },
+    { "Times",                  "Times"            },
+    { "ZapfChancery",           "ZapfChancery"     },
+    { "ZapfDingbats",           "ZapfDingbats"     }
+};
+
+static int nFamilyNames = (sizeof(familyMap) / sizeof(FamilyMap));
+
+static const char *
+FamilyToPsFamily(const char *family) 
+{
+    FamilyMap *fp, *fend;
+
+    if (strncasecmp(family, "itc ", 4) == 0) {
+	family += 4;
+    }
+    for (fp = familyMap, fend = fp + nFamilyNames; fp < fend; fp++) {
+	if (strcasecmp(fp->alias, family) == 0) {
+	    return fp->fontName;
+	}
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * Routines to convert X drawing functions to PostScript commands.
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Ps_SetClearBackground(Blt_Ps ps)
+{
+    Blt_Ps_Append(ps, "1 1 1 setrgbcolor\n");
+}
+
+void
+Blt_Ps_XSetCapStyle(Blt_Ps ps, int capStyle)
+{
+    /*
+     * X11:not last = 0, butt = 1, round = 2, projecting = 3
+     * PS: butt = 0, round = 1, projecting = 2
+     */
+    if (capStyle > 0) {
+	capStyle--;
+    }
+    Blt_Ps_Format(ps, "%d setlinecap\n", capStyle);
+}
+
+void
+Blt_Ps_XSetJoinStyle(Blt_Ps ps, int joinStyle)
+{
+    /*
+     * miter = 0, round = 1, bevel = 2
+     */
+    Blt_Ps_Format(ps, "%d setlinejoin\n", joinStyle);
+}
+
+void
+Blt_Ps_XSetLineWidth(Blt_Ps ps, int lineWidth)
+{
+    if (lineWidth < 1) {
+	lineWidth = 1;
+    }
+    Blt_Ps_Format(ps, "%d setlinewidth\n", lineWidth);
+}
+
+void
+Blt_Ps_XSetDashes(Blt_Ps ps, Blt_Dashes *dashesPtr)
+{
+
+    Blt_Ps_Append(ps, "[ ");
+    if (dashesPtr != NULL) {
+	unsigned char *vp;
+
+	for (vp = dashesPtr->values; *vp != 0; vp++) {
+	    Blt_Ps_Format(ps, " %d", *vp);
+	}
+    }
+    Blt_Ps_Append(ps, "] 0 setdash\n");
+}
+
+void
+Blt_Ps_XSetLineAttributes(
+    Blt_Ps ps,
+    XColor *colorPtr,
+    int lineWidth,
+    Blt_Dashes *dashesPtr,
+    int capStyle, 
+    int joinStyle)
+{
+    Blt_Ps_XSetJoinStyle(ps, joinStyle);
+    Blt_Ps_XSetCapStyle(ps, capStyle);
+    Blt_Ps_XSetForeground(ps, colorPtr);
+    Blt_Ps_XSetLineWidth(ps, lineWidth);
+    Blt_Ps_XSetDashes(ps, dashesPtr);
+    Blt_Ps_Append(ps, "/DashesProc {} def\n");
+}
+
+void
+Blt_Ps_Rectangle(Blt_Ps ps, int x, int y, int width, int height)
+{
+    Blt_Ps_Append(ps, "newpath\n");
+    Blt_Ps_Format(ps, "  %d %d moveto\n", x, y);
+    Blt_Ps_Format(ps, "  %d %d rlineto\n", width, 0);
+    Blt_Ps_Format(ps, "  %d %d rlineto\n", 0, height);
+    Blt_Ps_Format(ps, "  %d %d rlineto\n", -width, 0);
+    Blt_Ps_Append(ps, "closepath\n");
+}
+
+void
+Blt_Ps_XFillRectangle(Blt_Ps ps, double x, double y, int width, int height)
+{
+    Blt_Ps_Rectangle(ps, (int)x, (int)y, width, height);
+    Blt_Ps_Append(ps, "fill\n");
+}
+
+void
+Blt_Ps_PolylineFromXPoints(Blt_Ps ps, XPoint *points, int n)
+{
+    XPoint *pp, *pend;
+
+    pp = points;
+    Blt_Ps_Append(ps, "newpath\n");
+    Blt_Ps_Format(ps, "  %d %d moveto\n", pp->x, pp->y);
+    pp++;
+    for (pend = points + n; pp < pend; pp++) {
+	Blt_Ps_Format(ps, "  %d %d lineto\n", pp->x, pp->y);
+    }
+}
+
+void
+Blt_Ps_Polyline(Blt_Ps ps, Point2d *screenPts, int nScreenPts)
+{
+    Point2d *pp, *pend;
+
+    pp = screenPts;
+    Blt_Ps_Append(ps, "newpath\n");
+    Blt_Ps_Format(ps, "  %g %g moveto\n", pp->x, pp->y);
+    for (pp++, pend = screenPts + nScreenPts; pp < pend; pp++) {
+	Blt_Ps_Format(ps, "  %g %g lineto\n", pp->x, pp->y);
+    }
+}
+
+void
+Blt_Ps_Polygon(Blt_Ps ps, Point2d *screenPts, int nScreenPts)
+{
+    Point2d *pp, *pend;
+
+    pp = screenPts;
+    Blt_Ps_Append(ps, "newpath\n");
+    Blt_Ps_Format(ps, "  %g %g moveto\n", pp->x, pp->y);
+    for (pp++, pend = screenPts + nScreenPts; pp < pend; pp++) {
+	Blt_Ps_Format(ps, "  %g %g lineto\n", pp->x, pp->y);
+    }
+    Blt_Ps_Format(ps, "  %g %g lineto\n", screenPts[0].x, screenPts[0].y);
+    Blt_Ps_Append(ps, "closepath\n");
+}
+
+void
+Blt_Ps_XFillPolygon(Blt_Ps ps, Point2d *screenPts, int nScreenPts)
+{
+    Blt_Ps_Polygon(ps, screenPts, nScreenPts);
+    Blt_Ps_Append(ps, "fill\n");
+}
+
+void
+Blt_Ps_XDrawSegments(Blt_Ps ps, XSegment *segments, int nSegments)
+{
+    XSegment *sp, *send;
+
+    for (sp = segments, send = sp + nSegments; sp < send; sp++) {
+	Blt_Ps_Format(ps, "%d %d moveto %d %d lineto\n", sp->x1, sp->y1, 
+		      sp->x2, sp->y2);
+	Blt_Ps_Append(ps, "DashesProc stroke\n");
+    }
+}
+
+
+void
+Blt_Ps_XFillRectangles(Blt_Ps ps, XRectangle *rectangles, int nRectangles)
+{
+    XRectangle *rp, *rend;
+
+    for (rp = rectangles, rend = rp + nRectangles; rp < rend; rp++) {
+	Blt_Ps_XFillRectangle(ps, (double)rp->x, (double)rp->y, 
+		(int)rp->width, (int)rp->height);
+    }
+}
+
+#ifndef TK_RELIEF_SOLID
+#define TK_RELIEF_SOLID		-1	/* Set the an impossible value. */
+#endif /* TK_RELIEF_SOLID */
+
+void
+Blt_Ps_Draw3DRectangle(
+    Blt_Ps ps,
+    Tk_3DBorder border,		/* Token for border to draw. */
+    double x, double y,		/* Coordinates of rectangle */
+    int width, int height,	/* Region to be drawn. */
+    int borderWidth,		/* Desired width for border, in pixels. */
+    int relief)			/* Should be either TK_RELIEF_RAISED or
+                                 * TK_RELIEF_SUNKEN; indicates position of
+                                 * interior of window relative to exterior. */
+{
+    Point2d points[7];
+    TkBorder *borderPtr = (TkBorder *) border;
+    XColor *lightPtr, *darkPtr;
+    XColor *topPtr, *bottomPtr;
+    XColor light, dark;
+    int twiceWidth = (borderWidth * 2);
+
+    if ((width < twiceWidth) || (height < twiceWidth)) {
+	return;
+    }
+    if ((relief == TK_RELIEF_SOLID) ||
+	(borderPtr->lightColorPtr == NULL) || (borderPtr->darkColorPtr == NULL)) {
+	if (relief == TK_RELIEF_SOLID) {
+	    dark.red = dark.blue = dark.green = 0x00;
+	    light.red = light.blue = light.green = 0x00;
+	    relief = TK_RELIEF_SUNKEN;
+	} else {
+	    light = *borderPtr->bgColorPtr;
+	    dark.red = dark.blue = dark.green = 0xFF;
+	}
+	lightPtr = &light;
+	darkPtr = &dark;
+    } else {
+	lightPtr = borderPtr->lightColorPtr;
+	darkPtr = borderPtr->darkColorPtr;
+    }
+
+
+    /* Handle grooves and ridges with recursive calls. */
+
+    if ((relief == TK_RELIEF_GROOVE) || (relief == TK_RELIEF_RIDGE)) {
+	int halfWidth, insideOffset;
+
+	halfWidth = borderWidth / 2;
+	insideOffset = borderWidth - halfWidth;
+	Blt_Ps_Draw3DRectangle(ps, border, (double)x, (double)y,
+	    width, height, halfWidth, 
+	    (relief == TK_RELIEF_GROOVE) ? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED);
+	Blt_Ps_Draw3DRectangle(ps, border, 
+  	    (double)(x + insideOffset), (double)(y + insideOffset), 
+	    width - insideOffset * 2, height - insideOffset * 2, halfWidth,
+	    (relief == TK_RELIEF_GROOVE) ? TK_RELIEF_RAISED : TK_RELIEF_SUNKEN);
+	return;
+    }
+    if (relief == TK_RELIEF_RAISED) {
+	topPtr = lightPtr;
+	bottomPtr = darkPtr;
+    } else if (relief == TK_RELIEF_SUNKEN) {
+	topPtr = darkPtr;
+	bottomPtr = lightPtr;
+    } else {
+	topPtr = bottomPtr = borderPtr->bgColorPtr;
+    }
+    Blt_Ps_XSetBackground(ps, bottomPtr);
+    Blt_Ps_XFillRectangle(ps, x, y + height - borderWidth, width, borderWidth);
+    Blt_Ps_XFillRectangle(ps, x + width - borderWidth, y, borderWidth, height);
+    points[0].x = points[1].x = points[6].x = x;
+    points[0].y = points[6].y = y + height;
+    points[1].y = points[2].y = y;
+    points[2].x = x + width;
+    points[3].x = x + width - borderWidth;
+    points[3].y = points[4].y = y + borderWidth;
+    points[4].x = points[5].x = x + borderWidth;
+    points[5].y = y + height - borderWidth;
+    if (relief != TK_RELIEF_FLAT) {
+	Blt_Ps_XSetBackground(ps, topPtr);
+    }
+    Blt_Ps_XFillPolygon(ps, points, 7);
+}
+
+void
+Blt_Ps_Fill3DRectangle(
+    Blt_Ps ps,
+    Tk_3DBorder border,		/* Token for border to draw. */
+    double x, double y,		/* Coordinates of top-left of border area */
+    int width, int height,	/* Dimension of border to be drawn. */
+    int borderWidth,		/* Desired width for border, in pixels. */
+    int relief)			/* Should be either TK_RELIEF_RAISED or
+                                 * TK_RELIEF_SUNKEN;  indicates position of
+                                 * interior of window relative to exterior. */
+{
+    TkBorder *borderPtr = (TkBorder *) border;
+
+    Blt_Ps_XSetBackground(ps, borderPtr->bgColorPtr);
+    Blt_Ps_XFillRectangle(ps, x, y, width, height);
+    Blt_Ps_Draw3DRectangle(ps, border, x, y, width, height, borderWidth,
+	relief);
+}
+
+void
+Blt_Ps_XSetStipple(Blt_Ps ps, Display *display, Pixmap bitmap)
+{
+    int width, height;
+
+    Tk_SizeOfBitmap(display, bitmap, &width, &height);
+    Blt_Ps_Format(ps, 
+	"gsave\n"
+        "  clip\n"
+        "  %d %d\n", 
+	width, height);
+    Blt_Ps_XSetBitmapData(ps, display, bitmap, width, height);
+    Blt_Ps_VarAppend(ps, 
+        "  StippleFill\n"
+        "grestore\n", (char *)NULL);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Ps_XSetFont --
+ *
+ *      Map the Tk font to a PostScript font and point size.
+ *
+ *	If a TCL array variable was specified, each element should be indexed
+ *	by the X11 font name and contain a list of 1-2 elements; the
+ *	PostScript font name and the desired point size.  The point size may
+ *	be omitted and the X font point size will be used.
+ *
+ *	Otherwise, if the foundry is "Adobe", we try to do a plausible mapping
+ *	looking at the full name of the font and building a string in the form
+ *	of "Family-TypeFace".
+ *
+ * Returns:
+ *      None.
+ *
+ * Side Effects:
+ *      PostScript commands are output to change the type and the point size
+ *      of the current font.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+Blt_Ps_XSetFont(PostScript *psPtr, Blt_Font font) 
+{
+    Tcl_Interp *interp = psPtr->interp;
+    const char *family;
+
+    /* Use the font variable information if it exists. */
+    if ((psPtr->setupPtr != NULL) && (psPtr->setupPtr->fontVarName != NULL)) {
+	char *value;
+
+	value = (char *)Tcl_GetVar2(interp, psPtr->setupPtr->fontVarName, 
+		Blt_NameOfFont(font), 0);
+	if (value != NULL) {
+	    const char **argv = NULL;
+	    int argc;
+	    int newSize;
+	    double pointSize;
+	    const char *fontName;
+
+	    if (Tcl_SplitList(NULL, value, &argc, &argv) != TCL_OK) {
+		return;
+	    }
+	    fontName = argv[0];
+	    if ((argc != 2) || 
+		(Tcl_GetInt(interp, argv[1], &newSize) != TCL_OK)) {
+		free(argv);
+		return;
+	    }
+	    pointSize = (double)newSize;
+	    Blt_Ps_Format(psPtr, "%g /%s SetFont\n", pointSize, 
+		fontName);
+	    free(argv);
+	    return;
+	}
+	/*FallThru*/
+    }
+
+    /*
+     * Check to see if it's a PostScript font. Tk_PostScriptFontName silently
+     * generates a bogus PostScript font name, so we have to check to see if
+     * this is really a PostScript font first before we call it.
+     */
+    family = FamilyToPsFamily(Blt_FamilyOfFont(font));
+    if (family != NULL) {
+	Tcl_DString dString;
+	double pointSize;
+	
+	Tcl_DStringInit(&dString);
+	pointSize = (double)Blt_PostscriptFontName(font, &dString);
+	Blt_Ps_Format(psPtr, "%g /%s SetFont\n", pointSize, 
+		Tcl_DStringValue(&dString));
+	Tcl_DStringFree(&dString);
+	return;
+    }
+    Blt_Ps_Append(psPtr, "12.0 /Helvetica-Bold SetFont\n");
+}
+
+static void
+TextLayoutToPostScript(Blt_Ps ps, int x, int y, TextLayout *textPtr)
+{
+    char *bp, *dst;
+    int count;			/* Counts the # of bytes written to the
+				 * intermediate scratch buffer. */
+    const char *src, *end;
+    TextFragment *fragPtr;
+    int i;
+    unsigned char c;
+#if HAVE_UTF
+    Tcl_UniChar ch;
+#endif
+    int limit;
+
+    limit = POSTSCRIPT_BUFSIZ - 4; /* High water mark for scratch buffer. */
+    fragPtr = textPtr->fragments;
+    for (i = 0; i < textPtr->nFrags; i++, fragPtr++) {
+	if (fragPtr->count < 1) {
+	    continue;
+	}
+	Blt_Ps_Append(ps, "(");
+	count = 0;
+	dst = Blt_Ps_GetScratchBuffer(ps);
+	src = fragPtr->text;
+	end = fragPtr->text + fragPtr->count;
+	while (src < end) {
+	    if (count > limit) {
+		/* Don't let the scatch buffer overflow */
+		dst = Blt_Ps_GetScratchBuffer(ps);
+		dst[count] = '\0';
+		Blt_Ps_Append(ps, dst);
+		count = 0;
+	    }
+#if HAVE_UTF
+	    /*
+	     * INTL: For now we just treat the characters as binary data and
+	     * display the lower byte.  Eventually this should be revised to
+	     * handle international postscript fonts.
+	     */
+	    src += Tcl_UtfToUniChar(src, &ch);
+	    c = (unsigned char)(ch & 0xff);
+#else 
+	    c = *src++;
+#endif
+
+	    if ((c == '\\') || (c == '(') || (c == ')')) {
+		/*
+		 * If special PostScript characters characters "\", "(", and
+		 * ")" are contained in the text string, prepend backslashes
+		 * to them.
+		 */
+		*dst++ = '\\';
+		*dst++ = c;
+		count += 2;
+	    } else if ((c < ' ') || (c > '~')) {
+		/* Convert non-printable characters into octal. */
+		sprintf_s(dst, 5, "\\%03o", c);
+		dst += 4;
+		count += 4;
+	    } else {
+		*dst++ = c;
+		count++;
+	    }
+	}
+	bp = Blt_Ps_GetScratchBuffer(ps);
+	bp[count] = '\0';
+	Blt_Ps_Append(ps, bp);
+	Blt_Ps_Format(ps, ") %d %d %d DrawAdjText\n",
+	    fragPtr->width, x + fragPtr->x, y + fragPtr->y);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Ps_DrawText --
+ *
+ *      Output PostScript commands to print a text string. The string may be
+ *      rotated at any arbitrary angle, and placed according the anchor type
+ *      given. The anchor indicates how to interpret the window coordinates as
+ *      an anchor for the text bounding box.
+ *
+ * Results:
+ *      None.
+ *
+ * Side Effects:
+ *      Text string is drawn using the given font and GC on the graph window
+ *      at the given coordinates, anchor, and rotation
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Ps_DrawText(
+    Blt_Ps ps,
+    const char *string,		/* String to convert to PostScript */
+    TextStyle *tsPtr,		/* Text attribute information */
+    double x, double y)		/* Window coordinates where to print text */
+{
+    TextLayout *textPtr;
+    Point2d t;
+
+    if ((string == NULL) || (*string == '\0')) { /* Empty string, do nothing */
+	return;
+    }
+    textPtr = Blt_Ts_CreateLayout(string, -1, tsPtr);
+    {
+	float angle;
+	double rw, rh;
+	
+	angle = fmod(tsPtr->angle, (double)360.0);
+	Blt_GetBoundingBox(textPtr->width, textPtr->height, angle, &rw, &rh, 
+	(Point2d *)NULL);
+	/*
+	 * Find the center of the bounding box
+	 */
+	t = Blt_AnchorPoint(x, y, rw, rh, tsPtr->anchor); 
+	t.x += rw * 0.5;
+	t.y += rh * 0.5;
+    }
+
+    /* Initialize text (sets translation and rotation) */
+    Blt_Ps_Format(ps, "%d %d %g %g %g BeginText\n", textPtr->width, 
+	textPtr->height, tsPtr->angle, t.x, t.y);
+
+    Blt_Ps_XSetFont(ps, tsPtr->font);
+
+    Blt_Ps_XSetForeground(ps, tsPtr->color);
+    TextLayoutToPostScript(ps, 0, 0, textPtr);
+    free(textPtr);
+    Blt_Ps_Append(ps, "EndText\n");
+}
+
+void
+Blt_Ps_XDrawLines(Blt_Ps ps, XPoint *points, int n)
+{
+    int nLeft;
+
+    if (n <= 0) {
+	return;
+    }
+    for (nLeft = n; nLeft > 0; nLeft -= PS_MAXPATH) {
+	int length;
+
+	length = MIN(PS_MAXPATH, nLeft);
+	Blt_Ps_PolylineFromXPoints(ps, points, length);
+	Blt_Ps_Append(ps, "DashesProc stroke\n");
+	points += length;
+    }
+}
+
+void
+Blt_Ps_DrawPolyline(Blt_Ps ps, Point2d *points, int nPoints)
+{
+    int nLeft;
+
+    if (nPoints <= 0) {
+	return;
+    }
+    for (nLeft = nPoints; nLeft > 0; nLeft -= PS_MAXPATH) {
+	int length;
+
+	length = MIN(PS_MAXPATH, nLeft);
+	Blt_Ps_Polyline(ps, points, length);
+	Blt_Ps_Append(ps, "DashesProc stroke\n");
+	points += length;
+    }
+}
+
+void
+Blt_Ps_DrawBitmap(
+    Blt_Ps ps,
+    Display *display,
+    Pixmap bitmap,		/* Bitmap to be converted to PostScript */
+    double xScale, double yScale)
+{
+    int width, height;
+    double sw, sh;
+
+    Tk_SizeOfBitmap(display, bitmap, &width, &height);
+    sw = (double)width * xScale;
+    sh = (double)height * yScale;
+    Blt_Ps_Append(ps, "  gsave\n");
+    Blt_Ps_Format(ps, "    %g %g translate\n", sw * -0.5, sh * 0.5);
+    Blt_Ps_Format(ps, "    %g %g scale\n", sw, -sh);
+    Blt_Ps_Format(ps, "    %d %d true [%d 0 0 %d 0 %d] {", 
+	width, height, width, -height, height);
+    Blt_Ps_XSetBitmapData(ps, display, bitmap, width, height);
+    Blt_Ps_Append(ps, "    } imagemask\n  grestore\n");
+}
+
+void
+Blt_Ps_Draw2DSegments(Blt_Ps ps, Segment2d *segments, int nSegments)
+{
+    Segment2d *sp, *send;
+
+    Blt_Ps_Append(ps, "newpath\n");
+    for (sp = segments, send = sp + nSegments; sp < send; sp++) {
+	Blt_Ps_Format(ps, "  %g %g moveto %g %g lineto\n", 
+		sp->p.x, sp->p.y, sp->q.x, sp->q.y);
+	Blt_Ps_Append(ps, "DashesProc stroke\n");
+    }
+}
+
+void
+Blt_Ps_FontName(const char *family, int flags, Tcl_DString *resultPtr)
+{
+    const char *familyName, *weightName, *slantName;
+    int len;
+
+    len = Tcl_DStringLength(resultPtr);
+
+    familyName = FamilyToPsFamily(family);
+    if (familyName == NULL) {
+	Tcl_UniChar ch;
+	char *src, *dest;
+	int upper;
+
+	/*
+	 * Inline, capitalize the first letter of each word, lowercase the
+	 * rest of the letters in each word, and then take out the spaces
+	 * between the words.  This may make the DString shorter, which is
+	 * safe to do.
+	 */
+	Tcl_DStringAppend(resultPtr, family, -1);
+	src = dest = Tcl_DStringValue(resultPtr) + len;
+	upper = TRUE;
+	while (*src != '\0') {
+	    while (isspace(*src)) { /* INTL: ISO space */
+		src++;
+		upper = TRUE;
+	    }
+	    src += Tcl_UtfToUniChar(src, &ch);
+	    if (upper) {
+		ch = Tcl_UniCharToUpper(ch);
+		upper = FALSE;
+	    } else {
+	        ch = Tcl_UniCharToLower(ch);
+	    }
+	    dest += Tcl_UniCharToUtf(ch, dest);
+	}
+	*dest = '\0';
+	Tcl_DStringSetLength(resultPtr, dest - Tcl_DStringValue(resultPtr));
+	familyName = Tcl_DStringValue(resultPtr) + len;
+    }
+    if (familyName != Tcl_DStringValue(resultPtr) + len) {
+	Tcl_DStringAppend(resultPtr, familyName, -1);
+	familyName = Tcl_DStringValue(resultPtr) + len;
+    }
+    if (strcasecmp(familyName, "NewCenturySchoolbook") == 0) {
+	Tcl_DStringSetLength(resultPtr, len);
+	Tcl_DStringAppend(resultPtr, "NewCenturySchlbk", -1);
+	familyName = Tcl_DStringValue(resultPtr) + len;
+    }
+
+    /* Get the string to use for the weight. */
+    weightName = NULL;
+    if (flags & FONT_BOLD) {
+	if ((strcmp(familyName, "Bookman") == 0) || 
+	    (strcmp(familyName, "AvantGarde") == 0)) {
+	    weightName = "Demi";
+	} else {
+	    weightName = "Bold";
+	}
+    } else {
+	if (strcmp(familyName, "Bookman") == 0) {
+	    weightName = "Light";
+	} else if (strcmp(familyName, "AvantGarde") == 0) {
+	    weightName = "Book";
+	} else if (strcmp(familyName, "ZapfChancery") == 0) {
+	    weightName = "Medium";
+	}
+    }
+
+    /* Get the string to use for the slant. */
+    slantName = NULL;
+    if (flags & FONT_ITALIC) {
+	if ((strcmp(familyName, "Helvetica") == 0) || 
+	    (strcmp(familyName, "Courier") == 0) || 
+	    (strcmp(familyName, "AvantGarde") == 0)) {
+	    slantName = "Oblique";
+	} else {
+	    slantName = "Italic";
+	}
+    }
+
+    /*
+     * The string "Roman" needs to be added to some fonts that are not bold
+     * and not italic.
+     */
+    if ((slantName == NULL) && (weightName == NULL)) {
+	if ((strcmp(familyName, "Times") == 0) || 
+	    (strcmp(familyName, "NewCenturySchlbk") == 0) || 
+	    (strcmp(familyName, "Palatino") == 0)) {
+	    Tcl_DStringAppend(resultPtr, "-Roman", -1);
+	}
+    } else {
+	Tcl_DStringAppend(resultPtr, "-", -1);
+	if (weightName != NULL) {
+	    Tcl_DStringAppend(resultPtr, weightName, -1);
+	}
+	if (slantName != NULL) {
+	    Tcl_DStringAppend(resultPtr, slantName, -1);
+	}
+    }
+}
diff --git a/tlt3.0/bltPs.h b/tlt3.0/bltPs.h
new file mode 100644
index 0000000..93e73ec
--- /dev/null
+++ b/tlt3.0/bltPs.h
@@ -0,0 +1,210 @@
+
+/*
+ * bltPs.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_PS_H
+#define _BLT_PS_H
+
+/*
+ * PageSetup --
+ *
+ * 	Structure contains information specific to the layout of the page for
+ * 	printing the graph.
+ *
+ */
+typedef struct  {
+    /* User configurable fields */
+
+    int reqWidth, reqHeight;	/* If greater than zero, represents the
+				 * requested dimensions of the printed graph */
+    int reqPaperWidth;
+    int reqPaperHeight;		/* Requested dimensions for the PostScript
+				 * page. Can constrain the size of the graph
+				 * if the graph (plus padding) is larger than
+				 * the size of the page. */
+    Blt_Pad xPad, yPad;		/* Requested padding on the exterior of the
+				 * graph. This forms the bounding box for
+				 * the page. */
+    const char *colorVarName;	/* If non-NULL, is the name of a TCL array
+				 * variable containing X to output device color
+				 * translations */
+    const char *fontVarName;	/* If non-NULL, is the name of a TCL array
+				 * variable containing X to output device font
+				 * translations */
+    int level;			/* PostScript Language level 1-3 */
+    unsigned int flags;
+
+    const char **comments;	/* User supplied comments to be added. */
+
+    /* Computed fields */
+
+    short int left, bottom;	/* Bounding box of the plot in the page. */
+    short int right, top;
+
+    float scale;		/* Scale of page. Set if "-maxpect" option
+				 * is set, otherwise 1.0. */
+
+    int paperHeight;
+    int paperWidth;
+    
+} PageSetup;
+
+#define PS_GREYSCALE	(1<<0)
+#define PS_LANDSCAPE	(1<<2)
+#define PS_CENTER	(1<<3)
+#define PS_MAXPECT	(1<<4)
+#define PS_DECORATIONS	(1<<5)
+#define PS_FOOTER	(1<<6)
+#define PS_FMT_NONE	0
+#define PS_FMT_MASK	(PS_FMT_WMF|PS_FMT_EPSI|PS_FMT_TIFF)
+#define PS_FMT_WMF	(1<<8)
+#define PS_FMT_EPSI	(1<<9)
+#define PS_FMT_TIFF	(1<<10)
+
+typedef struct _Blt_Ps *Blt_Ps;
+
+extern Blt_Ps Blt_Ps_Create(Tcl_Interp *interp, PageSetup *setupPtr);
+
+extern void Blt_Ps_Free(Blt_Ps ps);
+
+extern const char *Blt_Ps_GetValue(Blt_Ps ps, int *lengthPtr);
+
+extern Tcl_Interp *Blt_Ps_GetInterp(Blt_Ps ps);
+
+extern Tcl_DString *Blt_Ps_GetDString(Blt_Ps ps);
+
+extern char *Blt_Ps_GetScratchBuffer(Blt_Ps ps);
+
+extern void Blt_Ps_SetInterp(Blt_Ps ps, Tcl_Interp *interp);
+
+extern void Blt_Ps_Append(Blt_Ps ps, const char *string);
+
+extern void Blt_Ps_AppendBytes(Blt_Ps ps, const char *string, int nBytes);
+
+extern void Blt_Ps_VarAppend TCL_VARARGS(Blt_Ps, ps);
+
+extern void Blt_Ps_Format TCL_VARARGS(Blt_Ps, ps);
+
+extern void Blt_Ps_SetClearBackground(Blt_Ps ps);
+
+extern int Blt_Ps_IncludeFile(Tcl_Interp *interp, Blt_Ps ps, 
+	const char *fileName);
+
+extern int Blt_Ps_GetPicaFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	int *picaPtr);
+
+extern int Blt_Ps_GetPadFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	Blt_Pad *padPtr);
+
+extern int Blt_Ps_ComputeBoundingBox(PageSetup *setupPtr, int w, int h);
+
+extern void Blt_Ps_Rectangle(Blt_Ps ps, int x, int y, int w, int h);
+
+
+extern int Blt_Ps_SaveFile(Tcl_Interp *interp, Blt_Ps ps, 
+	const char *fileName);
+
+#ifdef _TK
+
+#include "bltFont.h"
+#include "bltText.h"
+
+extern void Blt_Ps_XSetLineWidth(Blt_Ps ps, int lineWidth);
+
+extern void Blt_Ps_XSetBackground(Blt_Ps ps, XColor *colorPtr);
+
+extern void Blt_Ps_XSetBitmapData(Blt_Ps ps, Display *display, 
+	Pixmap bitmap, int width, int height);
+
+extern void Blt_Ps_XSetForeground(Blt_Ps ps, XColor *colorPtr);
+
+extern void Blt_Ps_XSetFont(Blt_Ps ps, Blt_Font font);
+
+extern void Blt_Ps_XSetDashes(Blt_Ps ps, Blt_Dashes *dashesPtr);
+
+extern void Blt_Ps_XSetLineAttributes(Blt_Ps ps, XColor *colorPtr,
+	int lineWidth, Blt_Dashes *dashesPtr, int capStyle, int joinStyle);
+
+extern void Blt_Ps_XSetStipple(Blt_Ps ps, Display *display, Pixmap bitmap);
+
+extern void Blt_Ps_Polyline(Blt_Ps ps, Point2d *screenPts, int nScreenPts);
+
+extern void Blt_Ps_XDrawLines(Blt_Ps ps, XPoint *points, int n);
+
+extern void Blt_Ps_XDrawSegments(Blt_Ps ps, XSegment *segments, 
+	int nSegments);
+
+extern void Blt_Ps_DrawPolyline(Blt_Ps ps, Point2d *points, int n);
+
+extern void Blt_Ps_Draw2DSegments(Blt_Ps ps, Segment2d *segments,
+	int nSegments);
+
+extern void Blt_Ps_Draw3DRectangle(Blt_Ps ps, Tk_3DBorder border, 
+	double x, double y, int width, int height, int borderWidth, int relief);
+
+extern void Blt_Ps_Fill3DRectangle(Blt_Ps ps, Tk_3DBorder border, double x,
+	 double y, int width, int height, int borderWidth, int relief);
+
+extern void Blt_Ps_XFillRectangle(Blt_Ps ps, double x, double y, 
+	int width, int height);
+
+extern void Blt_Ps_XFillRectangles(Blt_Ps ps, XRectangle *rects, int n);
+
+extern void Blt_Ps_XFillPolygon(Blt_Ps ps, Point2d *screenPts, 
+	int nScreenPts);
+
+extern void Blt_Ps_DrawPhoto(Blt_Ps ps, Tk_PhotoHandle photoToken,
+	double x, double y);
+
+extern void Blt_Ps_XDrawWindow(Blt_Ps ps, Tk_Window tkwin, 
+	double x, double y);
+
+extern void Blt_Ps_DrawText(Blt_Ps ps, const char *string, 
+	TextStyle *attrPtr, double x, double y);
+
+extern void Blt_Ps_DrawBitmap(Blt_Ps ps, Display *display, Pixmap bitmap, 
+	double scaleX, double scaleY);
+
+extern void Blt_Ps_XSetCapStyle(Blt_Ps ps, int capStyle);
+
+extern void Blt_Ps_XSetJoinStyle(Blt_Ps ps, int joinStyle);
+
+extern void Blt_Ps_PolylineFromXPoints(Blt_Ps ps, XPoint *points, int n);
+
+extern void Blt_Ps_Polygon(Blt_Ps ps, Point2d *screenPts, int nScreenPts);
+
+extern void Blt_Ps_SetPrinting(Blt_Ps ps, int value);
+extern int Blt_Ps_IsPrinting(void);
+
+extern int Blt_Ps_TextWidth(Blt_Font font, const char *string, int nBytes);
+
+extern int Blt_Ps_GetFontMetrics(Blt_Font font, Blt_FontMetrics *fmPtr);
+
+extern void Blt_Ps_FontName(const char *family, int flags, 
+	Tcl_DString *resultPtr);
+
+#endif /* _TK */
+
+#endif /* BLT_PS_H */
diff --git a/tlt3.0/bltPsAfm.c b/tlt3.0/bltPsAfm.c
new file mode 100644
index 0000000..59f38b4
--- /dev/null
+++ b/tlt3.0/bltPsAfm.c
@@ -0,0 +1,1557 @@
+/*
+ * bltPsAfm.c --
+ *
+ * This module implements an Adobe Font Metric File parser for the purpose of
+ * determining font metrics when generating PostScript.
+ *
+ *	Copyright 2009 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <assert.h>
+#include <math.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+
+#include "bltInt.h"
+#include "bltHash.h"
+#include "bltPs.h"
+#include "bltOp.h"
+#include "bltText.h"
+#include "bltFont.h"
+
+#define AFM_MAXSTATES	50
+#define AFM_MAXLINE	512
+#define FM(x)		Blt_Offset(AdobeFontMetrics, x)
+#define CM(x)		Blt_Offset(CharMetrics, x)
+#define FTOA(x)		Blt_Dtoa(interp, (double)x)
+    
+typedef struct {
+    const char *name;
+    short int code;
+} Symbol;
+
+static Symbol isoLatin1Symbols[] = {
+    { "A", 65 },
+    { "AE", 198 },
+    { "Aacute", 193 },
+    { "Acircumflex", 194 },
+    { "Adieresis", 196 },
+    { "Agrave", 192 },
+    { "Aring", 197 },
+    { "Atilde", 195 },
+    { "B", 66 },
+    { "C", 67 },
+    { "Ccedilla", 199 },
+    { "D", 68 },
+    { "E", 69 },
+    { "Eacute", 201 },
+    { "Ecircumflex", 202 },
+    { "Edieresis", 203 },
+    { "Egrave", 200 },
+    { "Eth", 208 },
+    { "F", 70 },
+    { "G", 71 },
+    { "H", 72 },
+    { "I", 73 },
+    { "Iacute", 205 },
+    { "Icircumflex", 206 },
+    { "Idieresis", 207 },
+    { "Igrave", 204 },
+    { "J", 74 },
+    { "K", 75 },
+    { "L", 76 },
+    { "M", 77 },
+    { "N", 78 },
+    { "Ntilde", 209 },
+    { "O", 79 },
+    { "Oacute", 211 },
+    { "Ocircumflex", 212 },
+    { "Odieresis", 214 },
+    { "Ograve", 210 },
+    { "Oslash", 216 },
+    { "Otilde", 213 },
+    { "P", 80 },
+    { "Q", 81 },
+    { "R", 82 },
+    { "S", 83 },
+    { "T", 84 },
+    { "Thorn", 222 },
+    { "U", 85 },
+    { "Uacute", 218 },
+    { "Ucircumflex", 219 },
+    { "Udieresis", 220 },
+    { "Ugrave", 217 },
+    { "V", 86 },
+    { "W", 87 },
+    { "X", 88 },
+    { "Y", 89 },
+    { "Yacute", 221 },
+    { "Z", 90 },
+    { "a", 97 },
+    { "aacute", 225 },
+    { "acircumflex", 226 },
+    { "acute", 180 },
+    { "adieresis", 228 },
+    { "ae", 230 },
+    { "agrave", 224 },
+    { "ampersand", 38 },
+    { "aring", 229 },
+    { "asciicircum", 94 },
+    { "asciitilde", 126 },
+    { "asterisk", 42 },
+    { "at", 64 },
+    { "atilde", 227 },
+    { "b", 98 },
+    { "backslash", 92 },
+    { "bar", 124 },
+    { "braceleft", 123 },
+    { "braceright", 125 },
+    { "bracketleft", 91 },
+    { "bracketright", 93 },
+    { "brokenbar", 166 },
+    { "florin", 166 },
+    { "c", 99 },
+    { "ccedilla", 231 },
+    { "cedilla", 184 },
+    { "cent", 162 },
+    { "colon", 58 },
+    { "comma", 44 },
+    { "controlACK", 6 },
+    { "controlBEL", 7 },
+    { "controlBS", 8 },
+    { "controlCAN", 24 },
+    { "controlCR", 13 },
+    { "controlDC1", 17 },
+    { "controlDC2", 18 },
+    { "controlDC3", 19 },
+    { "controlDC4", 20 },
+    { "controlDEL", 127 },
+    { "controlDLE", 16 },
+    { "controlEM", 25 },
+    { "controlENQ", 5 },
+    { "controlEOT", 4 },
+    { "controlESC", 27 },
+    { "controlETB", 23 },
+    { "controlETX", 3 },
+    { "controlFF", 12 },
+    { "controlFS", 28 },
+    { "controlGS", 29 },
+    { "controlHT", 9 },
+    { "controlLF", 10 },
+    { "controlNAK", 21 },
+    { "controlRS", 30 },
+    { "controlSI", 15 },
+    { "controlSO", 14 },
+    { "controlSOT", 2 },
+    { "controlSTX", 1 },
+    { "controlSUB", 26 },
+    { "controlSYN", 22 },
+    { "controlUS", 31 },
+    { "controlVT", 11 },
+    { "copyright", 169 },
+    { "currency", 164 },
+    { "fraction", 164 },
+    { "d", 100 },
+    { "degree", 176 },
+    { "dieresis", 168 },
+    { "divide", 247 },
+    { "dollar", 36 },
+    { "e", 101 },
+    { "eacute", 233 },
+    { "ecircumflex", 234 },
+    { "edieresis", 235 },
+    { "egrave", 232 },
+    { "eight", 56 },
+    { "equal", 61 },
+    { "eth", 240 },
+    { "exclam", 33 },
+    { "exclamdown", 161 },
+    { "f", 102 },
+    { "five", 53 },
+    { "four", 52 },
+    { "g", 103 },
+    { "germandbls", 223 },
+    { "grave", 96 },
+    { "quoteleft", 96 },
+    { "greater", 62 },
+    { "guillemotleft", 171 },
+    { "guillemotright", 187 },
+    { "h", 104 },
+    { "hyphen", 45 },
+    { "i", 105 },
+    { "iacute", 237 },
+    { "icircumflex", 238 },
+    { "idieresis", 239 },
+    { "igrave", 236 },
+    { "j", 106 },
+    { "k", 107 },
+    { "l", 108 },
+    { "less", 60 },
+    { "logicalnot", 172 },
+    { "m", 109 },
+    { "macron", 175 },
+    { "middot", 183 },
+    { "mu", 181 },
+    { "mu1", 181 },
+    { "multiply", 215 },
+    { "n", 110 },
+    { "nbspace", 160 },
+    { "nine", 57 },
+    { "nonbreakingspace", 160 },
+    { "ntilde", 241 },
+    { "numbersign", 35 },
+    { "o", 111 },
+    { "oacute", 243 },
+    { "ocircumflex", 244 },
+    { "odieresis", 246 },
+    { "ograve", 242 },
+    { "one", 49 },
+    { "onehalf", 189 },
+    { "onequarter", 188 },
+    { "onesuperior", 185 },
+    { "ordfeminine", 170 },
+    { "ordmasculine", 186 },
+    { "oslash", 248 },
+    { "otilde", 245 },
+    { "overscore", 175 },
+    { "p", 112 },
+    { "paragraph", 182 },
+    { "parenleft", 40 },
+    { "parenright", 41 },
+    { "percent", 37 },
+    { "period", 46 },
+    { "periodcentered", 183 },
+    { "plus", 43 },
+    { "plusminus", 177 },
+    { "q", 113 },
+    { "question", 63 },
+    { "questiondown", 191 },
+    { "quotedbl", 34 },
+    { "quotesingle", 39 },
+    { "quoteright", 39 },
+    { "r", 114 },
+    { "registered", 174 },
+    { "s", 115 },
+    { "section", 167 },
+    { "semicolon", 59 },
+    { "seven", 55 },
+    { "sfthyphen", 173 },
+    { "six", 54 },
+    { "slash", 47 },
+    { "softhyphen", 173 },
+    { "space", 32 },
+    { "spacehackarabic", 32 },
+    { "sterling", 163 },
+    { "t", 116 },
+    { "thorn", 254 },
+    { "three", 51 },
+    { "threequarters", 190 },
+    { "threesuperior", 179 },
+    { "two", 50 },
+    { "twosuperior", 178 },
+    { "u", 117 },
+    { "uacute", 250 },
+    { "ucircumflex", 251 },
+    { "udieresis", 252 },
+    { "ugrave", 249 },
+    { "underscore", 95 },
+    { "v", 118 },
+    { "verticalbar", 124 },
+    { "w", 119 },
+    { "x", 120 },
+    { "y", 121 },
+    { "yacute", 253 },
+    { "ydieresis", 255 },
+    { "yen", 165 },
+    { "z", 122 },
+    { "zero", 48 },
+    { NULL, -1 }
+};
+
+typedef struct _Parser Parser;
+
+typedef int (ParseProc) (Parser *parserPtr, char *record, int offset);
+
+typedef struct {
+    const char *key;
+    unsigned int nArgs;
+    ParseProc *proc;
+    size_t offset;
+} ParserSpec;
+
+typedef struct {
+    float llx, lly, urx, ury;
+} CharBBox;
+
+typedef struct {
+    float x, y;
+} Point;
+
+typedef struct {
+    short int first, second;
+} LigatureKey;
+
+typedef struct {
+    const char *successor;
+    const char *ligature;
+    short int index;
+} Ligature;
+
+typedef struct {
+    CharBBox bbox;
+    int index;
+    const char *name;
+    int hasLigature;
+    int hasKernPair;
+    Point w;
+    Point vVector;
+} CharMetrics;
+
+typedef struct {
+    float x, y;
+    short int first, second;
+} KernPairs;
+
+typedef struct {
+    short int first, second;
+} KernPairsKey;
+
+typedef struct {
+    float degree;
+    float minPointSize, maxPointSize;
+    float minKern, maxKern;
+} TrackKern;
+
+typedef struct {
+    const char *afmVersion;
+    const char *familyName;
+    const char *fontName;
+    const char *fullName;
+    const char *weight;
+    const char *comment;
+    const char *copyright;
+    const char *notice;
+    float italicAngle;
+    CharBBox fontBBox;
+    float underlinePosition;
+    float underlineThickness;
+    const char *characterSet;
+    int characters;
+    const char *version;
+    const char *encodingScheme;
+    float capHeight;
+    float xHeight;
+    float ascender, descender;
+    int metricSets;
+    Point charWidth;
+    int escChar;
+    int isFixedPitch;
+    int isBaseFont;
+    int isCIDFont;
+    int isFixedV;
+    int mappingScheme;
+    int nCharMetrics;
+    int nComposites;
+    int nDirection;
+    int nKernPairs;
+    int nTrackKern;
+
+    float stdHW, stdVW;
+    Point vVector;
+    TrackKern *trackKern;
+
+    KernPairs *kernPairs;
+    CharMetrics metrics[256];
+    Blt_HashTable metricsTable;
+    Blt_HashTable kernPairsTable;
+    Blt_HashTable ligatureTable;
+    Blt_HashTable symbolTable;
+    int refCount;
+    Blt_HashEntry *hashPtr;
+    float pointSize;			/* Current point size of font. */
+} AdobeFontMetrics;
+
+struct _Parser {
+    Tcl_Channel channel;		/* Channel to AdobeFontMetrics file. */
+    AdobeFontMetrics *afmPtr;
+    jmp_buf jmpbuf; 
+    Tcl_DString errors;			/* Contains error message. */
+    int nErrors;
+    int argc;				/* # arguments (word) of last line.  */
+    const char **argv;			/* Split of last line. */
+    Tcl_DString lastLine;		/* Contains last line read from file. */
+    int lineNumber;
+};
+
+static Blt_HashTable fontTable;
+static int initialized;
+
+static int ParseLine(Parser *parserPtr, ParserSpec *specs, int nSpecs, 
+		     ClientData clientData);
+
+static INLINE int 
+Points(AdobeFontMetrics *afmPtr, double x)
+{
+    return (int)round((afmPtr->pointSize * x) / 1000.0);
+}
+
+/*ARGSUSED*/
+static void
+ParserError TCL_VARARGS_DEF(Parser *, arg1)
+{
+    Parser *parserPtr;
+    const char *fmt;
+    char string[BUFSIZ+4];
+    int length;
+    va_list args;
+
+    parserPtr = TCL_VARARGS_START(Parser *, arg1, args);
+    fmt = va_arg(args, char *);
+    length = vsnprintf(string, BUFSIZ, fmt, args);
+    if (length > BUFSIZ) {
+	strcat(string, "...");
+    }
+    Tcl_DStringAppend(&parserPtr->errors, "line ", 5);
+    Tcl_DStringAppend(&parserPtr->errors, Blt_Itoa(parserPtr->lineNumber), -1);
+    Tcl_DStringAppend(&parserPtr->errors, ": ", 2);
+    Tcl_DStringAppend(&parserPtr->errors, string, -1);
+    Tcl_DStringAppend(&parserPtr->errors, "\n", -1);
+    va_end(args);
+    longjmp(parserPtr->jmpbuf, 0);
+}
+
+static int
+GetNumber(Parser *parserPtr, const char *string, float *valuePtr) 
+{
+    char *end;
+    double d;
+
+    errno = 0;
+    d = strtod(string, &end);		/* INTL: Tcl source. */
+    if (end == string) {
+    badDouble:
+	ParserError(parserPtr, "expected floating-point number but got \"%s\"",
+		    string);
+    }
+    if (errno != 0 && (d == HUGE_VAL || d == -HUGE_VAL || d == 0)) {
+	ParserError(parserPtr, "number \"%s\" is too big to represent",
+		    string);
+    }
+    while ((*end != 0) && isspace((unsigned char)(*end))) { /* INTL: ISO space. */
+	end++;
+    }
+    if (*end != 0) {
+	goto badDouble;
+    }
+    *valuePtr = (float)d;
+    return TCL_OK;
+}
+
+static int
+GetHexNumber(Parser *parserPtr, const char *string, int *valuePtr) 
+{
+    char *p;
+    int value;
+
+    if (*string == '<') {
+	string++;
+    }
+    value = strtoul(string, &p, 8);
+    if ((p == string) || (*p != '>')) {
+	ParserError(parserPtr, "expected hex number but got \"%s\"", string);
+    }
+    *valuePtr = value;
+    return TCL_OK;
+}
+
+static int 
+GetLine(Parser *parserPtr)
+{
+    Tcl_DStringSetLength(&parserPtr->lastLine, 0);
+    while (!Tcl_Eof(parserPtr->channel)) {
+	const char *p;
+	int code;
+
+	code = Tcl_Gets(parserPtr->channel, &parserPtr->lastLine);
+	if (code < 0) {
+	    if (Tcl_Eof(parserPtr->channel)) {
+		return TCL_RETURN;
+	    }
+	    ParserError(parserPtr, "error reading channel: %s\n", 
+		strerror(errno));
+	}
+	parserPtr->lineNumber++;
+	for (p = Tcl_DStringValue(&parserPtr->lastLine); isspace(*p); p++) {
+	    /* skip blanks */
+	}
+	if (*p == '\0') {
+	    continue;
+	}
+	return TCL_OK;
+    }
+    return TCL_RETURN;
+}
+
+static void 
+SplitLine(Parser *parserPtr, const char *line)
+{
+    const char *p;
+    int count;
+    size_t strSize, addrSize;
+
+    if (parserPtr->argv != NULL) {
+	free((char *)parserPtr->argv);
+	parserPtr->argv = NULL;
+	parserPtr->argc = 0;
+    }
+    /* Count the # of arguments to determine what size array to allocate. */
+    count = 0;
+    p = line;
+    while (*p != '\0') {
+	while (isspace(*p)) p++;	/* Skip whitespace. */
+	if (*p == '\0') {
+	    break;
+	}
+	while (!isspace(*p) && (*p != '\0')) p++;  /* Skip the word itself. */
+	count++;
+    }
+    if (count == 0) {
+	return;				/* No arguments. */
+    }
+    addrSize = sizeof(char **) * (count + 1);
+    strSize = p - line + 1;
+    {
+	char *buffer, *p;
+	const char **array;
+
+	buffer = malloc(addrSize + strSize);
+	assert(buffer);
+	p = buffer + addrSize;
+	strcpy(p, line);		/* Copy the string into the buffer. */
+	array = (const char **)buffer;
+	count = 0;
+	while (*p != '\0') {
+	    while (isspace(*p)) {
+		*p++ = '\0';	/* Convert whitespace to NULs. */
+	    }
+	    if (*p == '\0') {
+		break;
+	    }
+	    array[count] = p;
+	    while (!isspace(*p) && (*p != '\0')) p++;  
+	    count++;
+	}
+	array[count] = NULL;
+	parserPtr->argv = array;
+	parserPtr->argc = count;
+    }
+}
+
+static int 
+SplitNextLine(Parser *parserPtr)
+{
+    int result;
+
+    if (parserPtr->argv != NULL) {
+	free((char *)parserPtr->argv);
+	parserPtr->argv = NULL;
+	parserPtr->argc = 0;
+    }
+    result = GetLine(parserPtr);
+    if (result == TCL_OK) {
+	SplitLine(parserPtr, Tcl_DStringValue(&parserPtr->lastLine));
+	return TCL_OK;
+    }
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LookupKeyword --
+ *
+ *---------------------------------------------------------------------------
+ */
+static ParserSpec *
+LookupKeyword(ParserSpec *specs, int nSpecs, const char *string)
+{
+    char c;
+    int high, low;
+
+    low = 0;
+    high = nSpecs - 1;
+    c = string[0];
+    while (low <= high) {
+	ParserSpec *specPtr;
+	int compare;
+	int median;
+	
+	median = (low + high) >> 1;
+	specPtr = specs + median;
+
+	/* Test the first character */
+	compare = c - specPtr->key[0];
+	if (compare == 0) {
+	    /* Now test the entire string */
+	    compare = strcmp(string, specPtr->key);
+	}
+	if (compare < 0) {
+	    high = median - 1;
+	} else if (compare > 0) {
+	    low = median + 1;
+	} else {
+	    return specPtr;
+	}
+    }
+    return NULL;			/* Can't find operation */
+}
+
+static int
+ParseLine(Parser *parserPtr, ParserSpec *specs, int nSpecs, 
+	  ClientData clientData)
+{
+    ParserSpec *specPtr;
+
+    specPtr = LookupKeyword(specs, nSpecs, parserPtr->argv[0]);
+    if (specPtr == NULL) {
+	ParserError(parserPtr, "unknown keyword \"%s\"", parserPtr->argv[0]);
+    }
+    if ((specPtr->nArgs > 0) && (specPtr->nArgs != parserPtr->argc)) {
+	ParserError(parserPtr, "wrong # arguments for \"%s\"", specPtr->key);
+    }
+    if (specPtr->proc == NULL) {
+	return TCL_OK;
+    }
+    return (*specPtr->proc)(parserPtr, clientData, specPtr->offset);
+}
+
+static int 
+ParseEndSection(Parser *parserPtr, char *record, int offset)
+{
+    return TCL_CONTINUE;		/* Indicates end of section. */
+}
+
+static long
+LookupSymbol(AdobeFontMetrics *afmPtr, const char *symbol)
+{
+    Blt_HashEntry *hPtr;
+
+    hPtr = Blt_FindHashEntry(&afmPtr->symbolTable, symbol);
+    if (hPtr != NULL) {
+	return (long)Blt_GetHashValue(hPtr);
+    }
+    /*fprintf(stderr, "unknown symbol \"%s\"\n", symbol);*/
+    return -1;
+}
+
+static void
+InitSymbolTable(AdobeFontMetrics *afmPtr)
+{
+    Symbol *symPtr;
+
+    Blt_InitHashTable(&afmPtr->symbolTable, BLT_STRING_KEYS);
+    for (symPtr = isoLatin1Symbols; symPtr->name != NULL; symPtr++) {
+	Blt_HashEntry *hPtr;
+	int isNew;
+	
+	hPtr = Blt_CreateHashEntry(&afmPtr->symbolTable, symPtr->name, &isNew);
+	Blt_SetHashValue(hPtr, (ClientData)(long)symPtr->code);
+    }
+}
+
+static void
+UpdateSymbol(AdobeFontMetrics *afmPtr, long code, const char *symbol)
+{
+    Blt_HashEntry *hPtr;
+    int isNew;
+    
+    hPtr = Blt_CreateHashEntry(&afmPtr->symbolTable, symbol, &isNew);
+    Blt_SetHashValue(hPtr, (ClientData)code);
+}
+
+static void
+BuildKernPairsTable(AdobeFontMetrics *afmPtr)
+{
+    KernPairs *kp, *kend;
+
+    Blt_InitHashTable(&afmPtr->kernPairsTable, 
+		      sizeof(KernPairsKey) / sizeof(int));
+    for (kp = afmPtr->kernPairs, kend = kp + afmPtr->nKernPairs; kp < kend; 
+	 kp++) {
+	KernPairsKey key;
+	Blt_HashEntry *hPtr;
+	int isNew;
+	
+	memset(&key, 0, sizeof(key));
+	key.first = kp->first;
+	key.second = kp->second;
+	hPtr = Blt_CreateHashEntry(&afmPtr->kernPairsTable, (char *)&key, 
+		&isNew);
+	Blt_SetHashValue(hPtr, (ClientData)kp);
+    }
+}
+
+static KernPairs *
+GetKernPairs(AdobeFontMetrics *afmPtr, int c1, int c2)
+{
+    KernPairsKey key;
+    Blt_HashEntry *hPtr;
+
+    key.first = c1;
+    key.second = c2;
+    
+    hPtr = Blt_FindHashEntry(&afmPtr->kernPairsTable, (char *)&key);
+    if (hPtr == NULL) {
+	return NULL;
+    }
+    return Blt_GetHashValue(hPtr);
+}
+
+static Parser *
+NewParser(AdobeFontMetrics *afmPtr, const char *fileName)
+{
+    Parser *parserPtr;
+    Tcl_Channel channel;
+
+    channel = Tcl_OpenFileChannel(NULL, fileName, "r", 0);
+    if (channel == NULL) {
+	fprintf(stderr, "can't open %s\n", fileName);
+	return NULL;
+    }
+    if ((Tcl_SetChannelOption(NULL, channel, "-translation","auto")!=TCL_OK)||
+	(Tcl_SetChannelOption(NULL, channel, "-eofchar", "\x1a") != TCL_OK)) {
+	return NULL;
+    }
+    parserPtr = calloc(1, sizeof(Parser));
+    assert(parserPtr);
+    parserPtr->channel = channel;
+    parserPtr->afmPtr = afmPtr;
+    InitSymbolTable(afmPtr);
+    Tcl_DStringInit(&parserPtr->errors);
+    Tcl_DStringAppend(&parserPtr->errors, "error reading \"", -1);
+    Tcl_DStringAppend(&parserPtr->errors, fileName, -1);
+    Tcl_DStringAppend(&parserPtr->errors, "\": ", -1);
+    Tcl_DStringInit(&parserPtr->lastLine);
+    return parserPtr;
+}
+
+static void
+DestroyParser(Parser *parserPtr)
+{
+    if (parserPtr->argv != NULL) {
+	free((char *)parserPtr->argv);
+    }
+    Tcl_Close(NULL, parserPtr->channel);
+    Tcl_DStringFree(&parserPtr->errors);
+    Tcl_DStringFree(&parserPtr->lastLine);
+    free(parserPtr);
+}
+
+static void
+DestroyAdobeFontMetrics(AdobeFontMetrics *afmPtr)
+{
+    if (afmPtr->afmVersion != NULL) {
+	free((char *)afmPtr->afmVersion);
+    }
+    if (afmPtr->characterSet != NULL) {
+	free((char *)afmPtr->characterSet);
+    }
+    if (afmPtr->comment != NULL) {
+	free((char *)afmPtr->comment);
+    }
+    if (afmPtr->copyright != NULL) {
+	free((char *)afmPtr->copyright);
+    }
+    if (afmPtr->encodingScheme != NULL) {
+	free((char *)afmPtr->encodingScheme);
+    }
+    if (afmPtr->familyName != NULL) {
+	free((char *)afmPtr->familyName);
+    }
+    if (afmPtr->fontName != NULL) {
+	free((char *)afmPtr->fontName);
+    }
+    if (afmPtr->fullName != NULL) {
+	free((char *)afmPtr->fullName);
+    }
+    if (afmPtr->notice != NULL) {
+	free((char *)afmPtr->notice);
+    }
+    if (afmPtr->version != NULL) {
+	free((char *)afmPtr->version);
+    }
+    if (afmPtr->weight != NULL) {
+	free((char *)afmPtr->weight);
+    }
+    if (afmPtr->hashPtr != NULL) {
+	Blt_DeleteHashEntry(&fontTable, afmPtr->hashPtr);
+    }
+    Blt_DeleteHashTable(&afmPtr->kernPairsTable);
+    Blt_DeleteHashTable(&afmPtr->metricsTable);
+    Blt_DeleteHashTable(&afmPtr->symbolTable);
+    Blt_DeleteHashTable(&afmPtr->ligatureTable);
+    if (afmPtr->kernPairs != NULL) {
+	free(afmPtr->kernPairs);
+    }
+    if (afmPtr->trackKern != NULL) {
+	free(afmPtr->trackKern);
+    }
+    free((char *)afmPtr);
+}
+
+static int
+ParseInt(Parser *parserPtr, char *record, int offset)
+{
+    int *valuePtr = (int *)(record + offset);
+
+    if (Tcl_GetInt(NULL, parserPtr->argv[1], valuePtr) != TCL_OK) {
+	ParserError(parserPtr, "can't convert \"%s\" to integer.", 
+		    parserPtr->argv[1]);
+    }
+    return TCL_OK;
+}
+
+static int
+ParseHex(Parser *parserPtr, char *record, int offset)
+{
+    int *valuePtr = (int *)(record + offset);
+
+    return GetHexNumber(parserPtr, parserPtr->argv[1], valuePtr);
+}
+
+static int
+ParseBoolean(Parser *parserPtr, char *record, int offset)
+{
+    int *valuePtr = (int *)(record + offset);
+
+    if (Tcl_GetBoolean(NULL, parserPtr->argv[1], valuePtr) != TCL_OK) {
+	ParserError(parserPtr, "can't convert \"%s\" to boolean.", 
+		    parserPtr->argv[1]);
+    }
+    return TCL_OK;
+}
+
+
+static int
+ParseNumber(Parser *parserPtr, char *record, int offset)
+{
+    float *valuePtr = (float *)(record + offset);
+
+    return GetNumber(parserPtr, parserPtr->argv[1], valuePtr);
+}
+
+
+static int
+ParsePoint(Parser *parserPtr, char *record, int offset)
+{
+    Point *pointPtr = (Point *)(record + offset);
+
+    if ((GetNumber(parserPtr, parserPtr->argv[1], &pointPtr->x) != TCL_OK) ||
+	(GetNumber(parserPtr, parserPtr->argv[2], &pointPtr->y) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+static int
+ParseBBox(Parser *parserPtr, char *record, int offset)
+{
+    CharBBox *bboxPtr = (CharBBox *)(record + offset);
+    
+    if ((GetNumber(parserPtr, parserPtr->argv[1], &bboxPtr->llx) != TCL_OK) ||
+	(GetNumber(parserPtr, parserPtr->argv[2], &bboxPtr->lly) != TCL_OK) || 
+	(GetNumber(parserPtr, parserPtr->argv[3], &bboxPtr->urx) != TCL_OK) || 
+	(GetNumber(parserPtr, parserPtr->argv[4], &bboxPtr->ury) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+static int
+ParseString(Parser *parserPtr, char *record, int offset)
+{
+    char **args = (char **)(record + offset);
+
+    if (*args != NULL) {
+	free(*args);
+	*args = NULL;
+    }
+    *args = Tcl_Merge(parserPtr->argc - 1 , parserPtr->argv + 1);
+    if (*args == NULL) {
+	ParserError(parserPtr, "can't merge \"%s\" string.", 
+		    parserPtr->argv[0]);
+    }
+    return TCL_OK;
+}
+
+static int
+ParseName(Parser *parserPtr, char *record, int offset)
+{
+    const char **valuePtr = (const char **)(record + offset);
+
+    if (*valuePtr != NULL) {
+	free((char *)*valuePtr);
+    }
+    *valuePtr = Blt_Strdup(parserPtr->argv[1]);
+    return TCL_OK;
+}
+
+
+static int
+ParseStartComposites(Parser *parserPtr, char *record, int offset)
+{
+    int *valuePtr = (int *)(record + offset);
+    int n;
+
+    assert(*valuePtr == 0);
+    if (Tcl_GetInt(NULL, parserPtr->argv[1], &n) != TCL_OK) {
+	ParserError(parserPtr, "can't convert \"%s\" to integer", 
+		    parserPtr->argv[1]);
+    }
+    n++;
+    *valuePtr = n;
+    for (;;) {
+	if (SplitNextLine(parserPtr) == TCL_RETURN) {
+	    ParserError(parserPtr, "unexpected EOF in StartComposites");
+	}
+	if (strcmp(parserPtr->argv[0], "EndComposites") == 0) {
+	    return TCL_OK;
+	}
+    }
+    /*notreached*/
+    return TCL_ERROR;
+}
+
+
+static ParserSpec directionSpecs[] = {
+    { "CharWidth",	   3, ParsePoint,      FM(charWidth)	      },
+    { "EndDirection",	   1, ParseEndSection, 0		      },
+    { "IsFixedPitch",	   2, ParseBoolean,    FM(isFixedPitch)       },
+    { "ItalicAngle",	   2, ParseNumber,     FM(italicAngle)	      },
+    { "UnderlinePosition", 2, ParseNumber,     FM(underlinePosition)  },
+    { "UnderlineThickness",2, ParseNumber,     FM(underlineThickness) }
+};
+static int nDirectionSpecs = sizeof(directionSpecs) / sizeof(ParserSpec);
+
+
+static int
+ParseStartDirection(Parser *parserPtr, char *record, int offset)
+{
+    AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record;
+    int *valuePtr = (int *)(record + offset);
+    int n;
+    int result;
+
+    assert(*valuePtr == 0);
+    if (Tcl_GetInt(NULL, parserPtr->argv[1], &n) != TCL_OK) {
+	ParserError(parserPtr, "can't convert \"%s\" to integer.", 
+		    parserPtr->argv[1]);
+    }
+    do {
+	if (SplitNextLine(parserPtr) == TCL_RETURN) {
+	    ParserError(parserPtr, "unexpected EOF in StartDirection");
+	}
+	result = ParseLine(parserPtr, directionSpecs, nDirectionSpecs, afmPtr);
+    } while (result == TCL_OK);
+    if (result == TCL_CONTINUE) {
+	return TCL_OK;			/* Found EndKernPairs */
+    }
+    return TCL_ERROR;
+}
+
+static int 
+ParseTrackKern(Parser *parserPtr, char *record, int offset)
+{
+    TrackKern *tp = (TrackKern *)(record + offset);
+
+    if ((GetNumber(parserPtr, parserPtr->argv[1], &tp->degree) != TCL_OK) ||
+	(GetNumber(parserPtr, parserPtr->argv[2], &tp->minPointSize)!=TCL_OK) ||
+	(GetNumber(parserPtr, parserPtr->argv[3], &tp->minKern) != TCL_OK) ||
+	(GetNumber(parserPtr, parserPtr->argv[4], &tp->maxPointSize)!=TCL_OK) ||
+	(GetNumber(parserPtr, parserPtr->argv[5], &tp->maxKern) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+static ParserSpec trackKernSpecs[] = {
+    { "EndTrackKern",	 1, ParseEndSection, 0 },
+    { "TrackKern",	 6, ParseTrackKern,  0 },
+};
+static int nTrackKernSpecs = sizeof(trackKernSpecs) / sizeof(ParserSpec);
+
+static int
+ParseStartTrackKern(Parser *parserPtr, char *record, int offset)
+{
+    AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record;
+    TrackKern *tp;
+    int *valuePtr = (int *)(record + offset);
+    int n;
+    int result;
+
+    assert(*valuePtr == 0);
+    if (Tcl_GetInt(NULL, parserPtr->argv[1], &n) != TCL_OK) {
+	ParserError(parserPtr, "can't convert \"%s\" to integer.", 
+		parserPtr->argv[1]);
+    }
+    n++;
+    *valuePtr = n;
+    afmPtr->trackKern = calloc(n, sizeof(TrackKern));
+    assert(afmPtr->trackKern);
+    tp = afmPtr->trackKern;
+    do {
+	if (SplitNextLine(parserPtr) == TCL_RETURN) {
+	    ParserError(parserPtr, "unexpected EOF in StartTrackKern");
+	}
+	result = ParseLine(parserPtr, trackKernSpecs, nTrackKernSpecs, tp);
+	tp++;
+    } while (result == TCL_OK);
+    if (result == TCL_CONTINUE) {
+	assert((tp - afmPtr->trackKern) == n);
+	return TCL_OK;			/* Found EndTrackKern */
+    }
+    return TCL_ERROR;
+}
+
+
+static int 
+ParseKP(Parser *parserPtr, char *record, int offset)
+{
+    KernPairs *pairPtr = (KernPairs *)(record + offset);
+
+    pairPtr->first = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[1]);
+    pairPtr->second = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[2]);
+    if ((GetNumber(parserPtr, parserPtr->argv[3], &pairPtr->x) != TCL_OK) ||
+	(GetNumber(parserPtr, parserPtr->argv[4], &pairPtr->y) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+static int 
+ParseKPH(Parser *parserPtr, char *record, int offset)
+{
+    KernPairs *pairPtr = (KernPairs *)(record + offset);
+    int x, y;
+
+    pairPtr->first = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[1]);
+    pairPtr->second = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[2]);
+    if ((GetHexNumber(parserPtr, parserPtr->argv[3], &x) != TCL_OK) ||
+	(GetHexNumber(parserPtr, parserPtr->argv[4], &y) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    pairPtr->x = (float)x;
+    pairPtr->y = (float)y;
+    return TCL_OK;
+}
+
+static int 
+ParseKPX(Parser *parserPtr, char *record, int offset)
+{
+    KernPairs *pairPtr = (KernPairs *)(record + offset);
+
+    pairPtr->first = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[1]);
+    pairPtr->second = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[2]);
+    if (GetNumber(parserPtr, parserPtr->argv[3], &pairPtr->x) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    pairPtr->y = 0;
+    return TCL_OK;
+}
+
+static int 
+ParseKPY(Parser *parserPtr, char *record, int offset)
+{
+    KernPairs *pairPtr = (KernPairs *)(record + offset);
+
+    pairPtr->first = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[1]);
+    pairPtr->second = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[2]);
+    if (GetNumber(parserPtr, parserPtr->argv[3], &pairPtr->y) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    pairPtr->x = 0;
+    return TCL_OK;
+}
+
+static ParserSpec kernPairsSpecs[] = {
+    { "EndKernPairs",	1, ParseEndSection, 0 },
+    { "KP",		5, ParseKP,	    0 },
+    { "KPH",		5, ParseKPH,	    0 },
+    { "KPX",		4, ParseKPX,	    0 },
+    { "KPY",		4, ParseKPY,	    0 },
+};
+static int nKernPairsSpecs = sizeof(kernPairsSpecs) / sizeof(ParserSpec);
+
+static int
+ParseStartKernPairs(Parser *parserPtr, char *record, int offset)
+{
+    AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record;
+    int *valuePtr = (int *)(record + offset);
+    int n;
+    int result;
+    KernPairs *kp;
+
+    assert(*valuePtr == 0);
+    if (Tcl_GetInt(NULL, parserPtr->argv[1], &n) != TCL_OK) {
+ 	ParserError(parserPtr, "can't convert \"%s\" to integer.", 
+		    parserPtr->argv[1]);
+    }
+    n++;
+    *valuePtr = n;
+    afmPtr->kernPairs = calloc(n, sizeof(KernPairs));
+    assert(afmPtr->kernPairs);
+    kp = afmPtr->kernPairs;
+    do {
+	if (SplitNextLine(parserPtr) == TCL_RETURN) {
+	    ParserError(parserPtr, "unexpected EOF in StartKernPairs");
+	}
+	result = ParseLine(parserPtr, kernPairsSpecs, nKernPairsSpecs, kp);
+	kp++;
+    } while (result == TCL_OK);
+    if (result == TCL_CONTINUE) {
+	assert((kp - afmPtr->kernPairs) == *valuePtr);
+	return TCL_OK;			/* Found EndKernPairs */
+    }
+    return TCL_ERROR;
+}
+
+
+static ParserSpec kernDataSpecs[] = {
+    { "EndKernData",	 1, ParseEndSection,      0		  },
+    { "StartKernPairs",	 2, ParseStartKernPairs,  FM(nKernPairs)  },
+    { "StartKernPairs0", 2, ParseStartKernPairs,  FM(nKernPairs)  },
+    { "StartKernPairs1", 2, ParseStartKernPairs,  FM(nKernPairs)  },
+    { "StartTrackKern",	 2, ParseStartTrackKern,  FM(nTrackKern)  },
+};
+static int nKernDataSpecs = sizeof(kernDataSpecs) / sizeof(ParserSpec);
+
+static int
+ParseStartKernData(Parser *parserPtr, char *record, int offset)
+{
+    AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record;
+    int result;
+
+    do {
+	if (SplitNextLine(parserPtr) == TCL_RETURN) {
+	    ParserError(parserPtr, "unexpected EOF in StartKernPairs");
+	}
+	result = ParseLine(parserPtr, kernDataSpecs, nKernDataSpecs, afmPtr);
+    } while (result == TCL_OK);
+    if (result == TCL_CONTINUE) {
+	return TCL_OK;			/* Found EndKernData */
+    }
+    return TCL_ERROR;
+}
+
+
+static int
+ParseLigature(Parser *parserPtr, char *record, int offset)
+{
+    return TCL_OK;
+}
+
+static ParserSpec charMetricsSpecs[] = {
+    { "B",		5, ParseBBox,	    CM(bbox)	    },
+    { "C",		2, ParseInt,	    CM(index)	    },
+    { "CH",		2, ParseHex,	    CM(index)	    },
+    { "EndCharMetrics",	1, ParseEndSection, 0		    },
+    { "L",		3, ParseLigature,   CM(hasLigature) },
+    { "N",		2, ParseName,	    CM(name)	    },
+    { "VV",		3, ParsePoint,      CM(vVector)     },
+    { "W",		3, ParsePoint,      CM(w)           },
+    { "W0",		3, ParsePoint,      CM(w)           },
+    { "W1",		3, ParsePoint,      CM(w)           },
+    { "W0X",		2, ParseNumber,     CM(w.x)	    },
+    { "W0Y",		2, ParseNumber,     CM(w.y)	    },
+    { "W1X",		2, ParseNumber,     CM(w.x)	    },
+    { "W1Y",		2, ParseNumber,     CM(w.y)	    },
+    { "WX",		2, ParseNumber,     CM(w.x)	    },
+    { "WY",		2, ParseNumber,     CM(w.y)	    }
+};
+static int nCharMetricsSpecs = sizeof(charMetricsSpecs) / sizeof(ParserSpec);
+
+static int
+ParseStartCharMetrics(Parser *parserPtr, char *record, int offset)
+{
+    AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record;
+    int *valuePtr = (int *)(record + offset);
+    int count;
+    int i;
+
+    assert(*valuePtr == 0);
+    if (Tcl_GetInt(NULL, parserPtr->argv[1], &i) != TCL_OK) {
+	ParserError(parserPtr, "can't convert \"%s\" to integer.", 
+		    parserPtr->argv[1]);
+    }
+    i++;
+    *valuePtr = i;
+    for(i = 0; i < 256; i++) {
+	afmPtr->metrics[i].index = -1;
+    }
+    count = 0;
+    for (;;) {
+	int result;
+	CharMetrics cm;
+	const char *p;
+
+	result = GetLine(parserPtr);
+	if (result == TCL_RETURN) {
+	    ParserError(parserPtr, "unexpected EOF in StartCharMetrics");
+	}
+	memset(&cm, 0, sizeof(CharMetrics));
+	for(p = strtok(Tcl_DStringValue(&parserPtr->lastLine), ";"); p != NULL; 
+	    p = strtok(NULL, ";")) {
+	    SplitLine(parserPtr, p);
+	    if (parserPtr->argc == 0) {
+		continue;
+	    }
+	    result = ParseLine(parserPtr, charMetricsSpecs, nCharMetricsSpecs, 
+			       &cm);
+	    if (result != TCL_OK) {
+		break;
+	    }
+	}
+	count++;
+	if (cm.index != -1) {
+	    if (cm.name != NULL) {
+		UpdateSymbol(parserPtr->afmPtr, cm.index, cm.name);
+	    }
+	    afmPtr->metrics[cm.index] = cm;
+	}
+	if (result == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+	if (result == TCL_CONTINUE) {
+	    assert(count == *valuePtr);
+	    return TCL_OK;		/* Found EndCharMetrics */
+	}
+    }
+    return TCL_ERROR;
+}
+
+static ParserSpec fontMetricsSpecs[] = {
+    { "Ascender",	    2, ParseNumber,	      FM(ascender)  	     }, 
+    { "CapHeight",	    2, ParseNumber,	      FM(capHeight)	     },
+    { "CharWidth",	    3, ParsePoint,	      FM(charWidth)	     },
+    { "CharacterSet",	    0, ParseString,	      FM(characterSet)       },
+    { "Characters",	    2, ParseInt,	      FM(characters)	     },
+    { "Comment",	    0, NULL,		      FM(comment)	     },
+    { "Copyright",	    0, NULL,		      FM(copyright)	     },
+    { "Descender",	    2, ParseNumber,	      FM(descender)	     },
+    { "EncodingScheme",	    0, ParseString,	      FM(encodingScheme)     },
+    { "EndFontMetrics",	    1, ParseEndSection,	      0		             },
+    { "EscChar",	    2, ParseInt,	      FM(escChar)	     },
+    { "FamilyName",	    0, ParseString,	      FM(familyName)	     },
+    { "FontBBox",	    5, ParseBBox,	      FM(fontBBox)	     },
+    { "FontName",	    0, ParseString,	      FM(fontName)	     },
+    { "FullName",	    0, ParseString,	      FM(fullName)	     },
+    { "IsBaseFont",	    2, ParseBoolean,          FM(isBaseFont)	     },
+    { "IsCIDFont",	    2, ParseBoolean,          FM(isCIDFont)	     },
+    { "IsFixedPitch",	    2, ParseBoolean,          FM(isFixedPitch)       },
+    { "IsFixedV",	    2, ParseBoolean,          FM(isFixedV)	     },
+    { "ItalicAngle",	    2, ParseNumber,	      FM(italicAngle)        },
+    { "MappingScheme",	    2, ParseInt,	      FM(mappingScheme)      },
+    { "MetricSets",	    2, ParseInt,	      FM(metricSets)         },
+    { "Notice",		    0, NULL,		      FM(notice)	     },
+    { "StartCharMetrics",   2, ParseStartCharMetrics, FM(nCharMetrics)       },
+    { "StartComposites",    2, ParseStartComposites,  FM(nComposites)        },
+    { "StartDirection",	    2, ParseStartDirection,   FM(nDirection)         },
+    { "StartKernData",	    1, ParseStartKernData,    0                      },
+    { "StdHW",		    2, ParseNumber,           FM(stdHW)              },
+    { "StdVW",		    2, ParseNumber,           FM(stdVW)              },
+    { "UnderlinePosition",  2, ParseNumber,           FM(underlinePosition)  },
+    { "UnderlineThickness", 2, ParseNumber,           FM(underlineThickness) },
+    { "VVector",	    2, ParsePoint,            FM(vVector)            },
+    { "Version",	    0, ParseString,           FM(version)            },
+    { "Weight",		    0, ParseString,           FM(weight)             },
+    { "XHeight",	    2, ParseNumber,           FM(xHeight)            }
+};
+static int nFontMetricsSpecs = sizeof(fontMetricsSpecs) / sizeof(ParserSpec);
+
+static int 
+ParseStartFontMetrics(Parser *parserPtr, char *record, int offset)
+{
+    AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record;
+    const char **versionPtr = (const char **)(record + offset);
+    int result;
+
+    assert(*versionPtr == NULL);
+    *versionPtr = Blt_Strdup(parserPtr->argv[1]);
+    do {
+	if (SplitNextLine(parserPtr) == TCL_RETURN) {
+	    ParserError(parserPtr, "unexpected EOF in StartFontMetrics");
+	}
+	result = ParseLine(parserPtr, fontMetricsSpecs, nFontMetricsSpecs,
+			   afmPtr);
+    } while (result == TCL_OK);
+    if (result == TCL_CONTINUE) {
+	return TCL_OK;			/* Found EndFontMetrics */
+    }
+    return TCL_ERROR;
+}
+
+static ParserSpec afmSpecs[] = {
+    { "StartFontMetrics", 2, ParseStartFontMetrics, FM(afmVersion)  },
+};
+static int nAfmSpecs = sizeof(afmSpecs) / sizeof(ParserSpec);
+
+static AdobeFontMetrics *
+ParseAdobeFontMetricsFile(Tcl_Interp *interp, const char *fileName)
+{
+    AdobeFontMetrics *afmPtr;
+    Parser *parserPtr;
+    int result;
+
+    afmPtr = calloc(1, sizeof(AdobeFontMetrics));
+    assert(afmPtr);
+    parserPtr = NewParser(afmPtr, fileName);
+    if (parserPtr == NULL) {
+	free(afmPtr);
+	return NULL;
+    }
+    /* Set up jump for errors. */
+    if (setjmp(parserPtr->jmpbuf)) {
+	fprintf(stderr, "%s\n", Tcl_DStringValue(&parserPtr->errors));
+	DestroyParser(parserPtr);
+	DestroyAdobeFontMetrics(afmPtr);
+	return NULL;
+    }
+    for (;;) {
+	result = SplitNextLine(parserPtr);
+	if (result == TCL_RETURN) {
+	    break;
+	}
+	result = ParseLine(parserPtr, afmSpecs, nAfmSpecs, afmPtr);
+    }
+    DestroyParser(parserPtr);
+    if (result != TCL_RETURN) {
+	DestroyAdobeFontMetrics(afmPtr);
+	return NULL;
+    }
+    BuildKernPairsTable(afmPtr);
+    return afmPtr;
+}
+
+typedef struct {
+    const char *alias;
+    const char *fontName;
+} FontMap;
+
+static FontMap psFontMap[] =
+{
+    { "Arial",		        "Helvetica"	   },
+    { "AvantGarde",             "AvantGarde"       },
+    { "Bookman",                "Bookman"          },
+    { "Courier New",            "Courier"          },
+    { "Courier",                "Courier"          },
+    { "Geneva",                 "Helvetica"        },
+    { "Helvetica",              "Helvetica"        },
+    { "Mathematica1",		"Helvetica"	   },
+    { "Monaco",                 "Courier"          },
+    { "New Century Schoolbook", "NewCenturySchlbk" },
+    { "New York",               "Times"            },
+    { "Nimbus Roman No9 L"	"Times"		   },
+    { "Nimbus Sans L Condensed","Helvetica"        },
+    { "Nimbus Sans L",		"Helvetica"        },
+    { "Palatino",               "Palatino"         },
+    { "Standard Symbols L",	"Symbol"           },
+    { "Symbol",                 "Symbol"           },
+    { "Times New Roman",        "Times"            },
+    { "Times Roman",            "Times"            },
+    { "Times",                  "Times"            },
+    { "ZapfChancery",           "ZapfChancery"     },
+    { "ZapfDingbats",           "ZapfDingbats"     }
+};
+static int nPsFonts = sizeof(psFontMap) / sizeof(FontMap);
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LookupFontName --
+ *
+ *---------------------------------------------------------------------------
+ */
+static const char *
+LookupFontName(const char *string)
+{
+    char c;
+    int high, low;
+
+    low = 0;
+    high = nPsFonts - 1;
+    c = string[0];
+    while (low <= high) {
+	FontMap *mapPtr;
+	int compare;
+	int median;
+	
+	median = (low + high) >> 1;
+	mapPtr = psFontMap + median;
+
+	/* Test the first character */
+	compare = c - mapPtr->alias[0];
+	if (compare == 0) {
+	    /* Now test the entire string */
+	    compare = strcmp(string, mapPtr->alias);
+	}
+	if (compare < 0) {
+	    high = median - 1;
+	} else if (compare > 0) {
+	    low = median + 1;
+	} else {
+	    return mapPtr->fontName;
+	}
+    }
+    return "Helvetica";			/* Can't find font. */
+}
+
+static AdobeFontMetrics *
+GetAdobeFontMetrics(Tcl_Interp *interp, const char *psFontName) 
+{
+    AdobeFontMetrics *afmPtr;
+    Blt_HashEntry *hPtr;
+    int isNew;
+
+    if (!initialized) {
+	Blt_InitHashTable(&fontTable, BLT_STRING_KEYS);
+	initialized = TRUE;
+    }
+    psFontName = LookupFontName(psFontName);
+    hPtr = Blt_CreateHashEntry(&fontTable, psFontName, &isNew);
+    if (isNew) {
+	const char *path;
+	Tcl_DString ds;
+
+	path = Tcl_GetVar(interp, "tlt_library", TCL_GLOBAL_ONLY);
+	if (path == NULL) {
+	    Tcl_AppendResult(interp, "can't find \"tlt_library\" variable", 
+			     (char *)NULL);
+	    Blt_DeleteHashEntry(&fontTable, hPtr);
+	    return NULL;
+	}
+	Tcl_DStringInit(&ds);
+	Tcl_DStringAppend(&ds, path, -1);
+	Tcl_DStringAppend(&ds, "/afm/", 5);
+	Tcl_DStringAppend(&ds, psFontName, -1);
+	Tcl_DStringAppend(&ds, ".afm", 4);
+	afmPtr = ParseAdobeFontMetricsFile(interp, Tcl_DStringValue(&ds));
+	Tcl_DStringFree(&ds);
+	if (afmPtr == NULL) {
+	    Blt_DeleteHashEntry(&fontTable, hPtr);
+	    return NULL;
+	}
+	Blt_SetHashValue(hPtr, afmPtr);
+	afmPtr->hashPtr = hPtr;
+    } else {
+	afmPtr = Blt_GetHashValue(hPtr);
+    }
+    return afmPtr;
+}
+
+static AdobeFontMetrics *
+GetAdobeFontMetricsFromFont(Blt_Font font) 
+{
+    AdobeFontMetrics *afmPtr;
+    Tcl_DString ds;
+    double pointSize;
+    Tcl_Interp *interp;
+
+    Tcl_DStringInit(&ds);
+    pointSize = Blt_PostscriptFontName(font, &ds);
+    interp = Blt_GetFontInterp(font);
+    afmPtr = GetAdobeFontMetrics(interp, Tcl_DStringValue(&ds));
+    Tcl_DStringFree(&ds);
+    if (afmPtr != NULL) {
+	afmPtr->pointSize = pointSize;
+	return afmPtr;
+    }
+    return NULL;
+}    
+
+int 
+Blt_Ps_GetFontMetrics(Blt_Font font, Blt_FontMetrics *fmPtr) 
+{
+    AdobeFontMetrics *afmPtr;
+
+    afmPtr = GetAdobeFontMetricsFromFont(font);
+    if (afmPtr == NULL) {
+	return TCL_ERROR;
+    }
+    fmPtr->ascent    = Points(afmPtr, afmPtr->ascender);
+    fmPtr->descent   = Points(afmPtr, -afmPtr->descender);
+    fmPtr->linespace = Points(afmPtr, afmPtr->ascender - afmPtr->descender);
+    return TCL_OK;
+}
+
+int 
+Blt_Ps_TextWidth(Blt_Font font, const char *string, int nBytes) 
+{
+    AdobeFontMetrics *afmPtr;
+    const char *p, *pend;
+    float width;
+
+    afmPtr = GetAdobeFontMetricsFromFont(font);
+    if (afmPtr == NULL) {
+	fprintf(stderr, "can't find font\n");
+	return -1;
+    }
+    width = 0;
+    for (p = string, pend = string + nBytes; p < pend; /*empty*/) {
+	CharMetrics *cmPtr;
+	unsigned char c;
+	Tcl_UniChar ch;
+
+	p += Tcl_UtfToUniChar(p, &ch);
+	c = (unsigned char)(ch & 0xff);
+	cmPtr = afmPtr->metrics + c;
+	if (cmPtr->index < 0) {
+	    continue;			/* Ignore unencoded characters. */
+	}
+	width += cmPtr->w.x;
+    }
+    {
+	/* Kerning */
+	unsigned char c1, c2;
+	Tcl_UniChar ch;
+
+	p = string;
+	p += Tcl_UtfToUniChar(string, &ch);
+	c1 = (unsigned char)(ch & 0xff);
+	while (p < pend) {
+	    p += Tcl_UtfToUniChar(p, &ch);
+	    c2 = (unsigned char)(ch & 0xff);
+	    if (afmPtr->metrics[c1].hasKernPair) {
+		KernPairs *kp;
+		
+		kp = GetKernPairs(afmPtr, c1, c2);
+		width += kp->x;
+	    }
+	    c1 = c2;
+	}
+    }
+    return Points(afmPtr, width);
+}
+
diff --git a/tlt3.0/bltPsInt.h b/tlt3.0/bltPsInt.h
new file mode 100644
index 0000000..4b552c4
--- /dev/null
+++ b/tlt3.0/bltPsInt.h
@@ -0,0 +1,49 @@
+
+/*
+ * bltPsInt.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_PS_INT_H
+#define _BLT_PS_INT_H
+
+#include "bltPs.h"
+
+struct _Blt_Ps {
+    Tcl_Interp *interp;		/* Interpreter to report errors to. */
+
+    Tcl_DString dString;	/* Dynamic string used to contain the
+				 * PostScript generated. */
+    PageSetup *setupPtr;
+
+#define POSTSCRIPT_BUFSIZ	((BUFSIZ*2)-1)
+    /*
+     * Utility space for building strings.  Currently used to create
+     * PostScript output for the "postscript" command.
+     */
+    char scratchArr[POSTSCRIPT_BUFSIZ+1];
+};
+
+typedef struct _Blt_Ps PostScript;
+
+#endif /* BLT_PS_H */
diff --git a/tlt3.0/bltSpline.c b/tlt3.0/bltSpline.c
new file mode 100644
index 0000000..fb1a297
--- /dev/null
+++ b/tlt3.0/bltSpline.c
@@ -0,0 +1,1287 @@
+/*
+ *	Copyright 2009 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <assert.h>
+#include <float.h>
+#include <math.h>
+
+#include "bltInt.h"
+#include "bltSpline.h"
+#include "bltOp.h"
+#include "bltVector.h"
+
+typedef int (SplineProc)(Point2d origPts[], int nOrigPts, Point2d intpPts[],
+			 int nIntpPts);
+
+typedef double TriDiagonalMatrix[3];
+typedef struct {
+    double b, c, d;
+} Cubic2D;
+
+typedef struct {
+    double b, c, d, e, f;
+} Quint2D;
+
+/*
+ * Quadratic spline parameters
+ */
+#define E1	param[0]
+#define E2	param[1]
+#define V1	param[2]
+#define V2	param[3]
+#define W1	param[4]
+#define W2	param[5]
+#define Z1	param[6]
+#define Z2	param[7]
+#define Y1	param[8]
+#define Y2	param[9]
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Search --
+ *
+ *	Conducts a binary search for a value.  This routine is called
+ *	only if key is between x(0) and x(len - 1).
+ *
+ * Results:
+ *	Returns the index of the largest value in xtab for which
+ *	x[i] < key.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+Search(
+    Point2d points[],		/* Contains the abscissas of the data
+				 * points of interpolation. */
+    int nPoints,		/* Dimension of x. */
+    double key,			/* Value whose relative position in
+				 * x is to be located. */
+    int *foundPtr)		/* (out) Returns 1 if s is found in
+				 * x and 0 otherwise. */
+{
+    int high, low, mid;
+
+    low = 0;
+    high = nPoints - 1;
+
+    while (high >= low) {
+	mid = (high + low) / 2;
+	if (key > points[mid].x) {
+	    low = mid + 1;
+	} else if (key < points[mid].x) {
+	    high = mid - 1;
+	} else {
+	    *foundPtr = 1;
+	    return mid;
+	}
+    }
+    *foundPtr = 0;
+    return low;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * QuadChoose --
+ *
+ *	Determines the case needed for the computation of the parame-
+ *	ters of the quadratic spline.
+ *
+ * Results:
+ * 	Returns a case number (1-4) which controls how the parameters
+ * 	of the quadratic spline are evaluated.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+QuadChoose(
+    Point2d *p,			/* Coordinates of one of the points of
+				 * interpolation */
+    Point2d *q,			/* Coordinates of one of the points of
+				 * interpolation */
+    double m1,			/* Derivative condition at point P */
+    double m2,			/* Derivative condition at point Q */
+    double epsilon)		/* Error tolerance used to distinguish
+				 * cases when m1 or m2 is relatively
+				 * close to the slope or twice the
+				 * slope of the line segment joining
+				 * the points P and Q.  If
+				 * epsilon is not 0.0, then epsilon
+				 * should be greater than or equal to
+				 * machine epsilon.  */
+{
+    double slope;
+
+    /* Calculate the slope of the line joining P and Q. */
+    slope = (q->y - p->y) / (q->x - p->x);
+
+    if (slope != 0.0) {
+	double relerr;
+	double mref, mref1, mref2, prod1, prod2;
+
+	prod1 = slope * m1;
+	prod2 = slope * m2;
+
+	/* Find the absolute values of the slopes slope, m1, and m2. */
+	mref = fabs(slope);
+	mref1 = fabs(m1);
+	mref2 = fabs(m2);
+
+	/*
+	 * If the relative deviation of m1 or m2 from slope is less than
+	 * epsilon, then choose case 2 or case 3.
+	 */
+	relerr = epsilon * mref;
+	if ((fabs(slope - m1) > relerr) && (fabs(slope - m2) > relerr) &&
+	    (prod1 >= 0.0) && (prod2 >= 0.0)) {
+	    double prod;
+
+	    prod = (mref - mref1) * (mref - mref2);
+	    if (prod < 0.0) {
+		/*
+		 * l1, the line through (x1,y1) with slope m1, and l2,
+		 * the line through (x2,y2) with slope m2, intersect
+		 * at a point whose abscissa is between x1 and x2.
+		 * The abscissa becomes a knot of the spline.
+		 */
+		return 1;
+	    }
+	    if (mref1 > (mref * 2.0)) {
+		if (mref2 <= ((2.0 - epsilon) * mref)) {
+		    return 3;
+		}
+	    } else if (mref2 <= (mref * 2.0)) {
+		/*
+		 * Both l1 and l2 cross the line through
+		 * (x1+x2)/2.0,y1 and (x1+x2)/2.0,y2, which is the
+		 * midline of the rectangle formed by P and Q or both
+		 * m1 and m2 have signs different than the sign of
+		 * slope, or one of m1 and m2 has opposite sign from
+		 * slope and l1 and l2 intersect to the left of x1 or
+		 * to the right of x2.  The point (x1+x2)/2. is a knot
+		 * of the spline.
+		 */
+		return 2;
+	    } else if (mref1 <= ((2.0 - epsilon) * mref)) {
+		/*
+		 * In cases 3 and 4, sign(m1)=sign(m2)=sign(slope).
+		 * Either l1 or l2 crosses the midline, but not both.
+		 * Choose case 4 if mref1 is greater than
+		 * (2.-epsilon)*mref; otherwise, choose case 3.
+		 */
+		return 3;
+	    }
+	    /*
+	     * If neither l1 nor l2 crosses the midline, the spline
+	     * requires two knots between x1 and x2.
+	     */
+	    return 4;
+	} else {
+	    /*
+	     * The sign of at least one of the slopes m1 or m2 does not
+	     * agree with the sign of *slope*.
+	     */
+	    if ((prod1 < 0.0) && (prod2 < 0.0)) {
+		return 2;
+	    } else if (prod1 < 0.0) {
+		if (mref2 > ((epsilon + 1.0) * mref)) {
+		    return 1;
+		} else {
+		    return 2;
+		}
+	    } else if (mref1 > ((epsilon + 1.0) * mref)) {
+		return 1;
+	    } else {
+		return 2;
+	    }
+	}
+    } else if ((m1 * m2) >= 0.0) {
+	return 2;
+    } else {
+	return 1;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * QuadCases --
+ *
+ *	Computes the knots and other parameters of the spline on the
+ *	interval PQ.
+ *
+ *
+ * On input--
+ *
+ *	P and Q are the coordinates of the points of interpolation.
+ *
+ *	m1 is the slope at P.
+ *
+ *	m2 is the slope at Q.
+ *
+ *	ncase controls the number and location of the knots.
+ *
+ *
+ * On output--
+ *
+ *	(v1,v2),(w1,w2),(z1,z2), and (e1,e2) are the coordinates of
+ *	the knots and other parameters of the spline on P.
+ *	(e1,e2) and Q are used only if ncase=4.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+QuadCases(Point2d *p, Point2d *q, double m1, double m2, double param[], 
+	  int which)
+{
+    if ((which == 3) || (which == 4)) {	/* Parameters used in both 3 and 4 */
+	double mbar1, mbar2, mbar3, c1, d1, h1, j1, k1;
+
+	c1 = p->x + (q->y - p->y) / m1;
+	d1 = q->x + (p->y - q->y) / m2;
+	h1 = c1 * 2.0 - p->x;
+	j1 = d1 * 2.0 - q->x;
+	mbar1 = (q->y - p->y) / (h1 - p->x);
+	mbar2 = (p->y - q->y) / (j1 - q->x);
+
+	if (which == 4) {	/* Case 4. */
+	    Y1 = (p->x + c1) / 2.0;
+	    V1 = (p->x + Y1) / 2.0;
+	    V2 = m1 * (V1 - p->x) + p->y;
+	    Z1 = (d1 + q->x) / 2.0;
+	    W1 = (q->x + Z1) / 2.0;
+	    W2 = m2 * (W1 - q->x) + q->y;
+	    mbar3 = (W2 - V2) / (W1 - V1);
+	    Y2 = mbar3 * (Y1 - V1) + V2;
+	    Z2 = mbar3 * (Z1 - V1) + V2;
+	    E1 = (Y1 + Z1) / 2.0;
+	    E2 = mbar3 * (E1 - V1) + V2;
+	} else {		/* Case 3. */
+	    k1 = (p->y - q->y + q->x * mbar2 - p->x * mbar1) / (mbar2 - mbar1);
+	    if (fabs(m1) > fabs(m2)) {
+		Z1 = (k1 + p->x) / 2.0;
+	    } else {
+		Z1 = (k1 + q->x) / 2.0;
+	    }
+	    V1 = (p->x + Z1) / 2.0;
+	    V2 = p->y + m1 * (V1 - p->x);
+	    W1 = (q->x + Z1) / 2.0;
+	    W2 = q->y + m2 * (W1 - q->x);
+	    Z2 = V2 + (W2 - V2) / (W1 - V1) * (Z1 - V1);
+	}
+    } else if (which == 2) {	/* Case 2. */
+	Z1 = (p->x + q->x) / 2.0;
+	V1 = (p->x + Z1) / 2.0;
+	V2 = p->y + m1 * (V1 - p->x);
+	W1 = (Z1 + q->x) / 2.0;
+	W2 = q->y + m2 * (W1 - q->x);
+	Z2 = (V2 + W2) / 2.0;
+    } else {			/* Case 1. */
+	double ztwo;
+
+	Z1 = (p->y - q->y + m2 * q->x - m1 * p->x) / (m2 - m1);
+	ztwo = p->y + m1 * (Z1 - p->x);
+	V1 = (p->x + Z1) / 2.0;
+	V2 = (p->y + ztwo) / 2.0;
+	W1 = (Z1 + q->x) / 2.0;
+	W2 = (ztwo + q->y) / 2.0;
+	Z2 = V2 + (W2 - V2) / (W1 - V1) * (Z1 - V1);
+    }
+}
+
+static int
+QuadSelect(Point2d *p, Point2d *q, double m1, double m2, double epsilon,
+	   double param[])
+{
+    int ncase;
+
+    ncase = QuadChoose(p, q, m1, m2, epsilon);
+    QuadCases(p, q, m1, m2, param, ncase);
+    return ncase;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * QuadGetImage --
+ *
+ *---------------------------------------------------------------------------
+ */
+INLINE static double
+QuadGetImage(double p1, double p2, double p3, double x1, double x2, double x3)
+{
+    double A, B, C;
+    double y;
+
+    A = x1 - x2;
+    B = x2 - x3;
+    C = x1 - x3;
+
+    y = (p1 * (A * A) + p2 * 2.0 * B * A + p3 * (B * B)) / (C * C);
+    return y;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * QuadSpline --
+ *
+ *	Finds the image of a point in x.
+ *
+ *	On input
+ *
+ *	x	Contains the value at which the spline is evaluated.
+ *	leftX, leftY
+ *		Coordinates of the left-hand data point used in the
+ *		evaluation of x values.
+ *	rightX, rightY
+ *		Coordinates of the right-hand data point used in the
+ *		evaluation of x values.
+ *	Z1, Z2, Y1, Y2, E2, W2, V2
+ *		Parameters of the spline.
+ *	ncase	Controls the evaluation of the spline by indicating
+ *		whether one or two knots were placed in the interval
+ *		(xtabs,xtabs1).
+ *
+ * Results:
+ *	The image of the spline at x.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+QuadSpline(
+    Point2d *intp,		/* Value at which spline is evaluated */
+    Point2d *left,		/* Point to the left of the data point to
+				 * be evaluated */
+    Point2d *right,		/* Point to the right of the data point to
+				 * be evaluated */
+    double param[],		/* Parameters of the spline */
+    int ncase)			/* Controls the evaluation of the
+				 * spline by indicating whether one or
+				 * two knots were placed in the
+				 * interval (leftX,rightX) */
+{
+    double y;
+
+    if (ncase == 4) {
+	/*
+	 * Case 4:  More than one knot was placed in the interval.
+	 */
+
+	/*
+	 * Determine the location of data point relative to the 1st knot.
+	 */
+	if (Y1 > intp->x) {
+	    y = QuadGetImage(left->y, V2, Y2, Y1, intp->x, left->x);
+	} else if (Y1 < intp->x) {
+	    /*
+	     * Determine the location of the data point relative to
+	     * the 2nd knot.
+	     */
+	    if (Z1 > intp->x) {
+		y = QuadGetImage(Y2, E2, Z2, Z1, intp->x, Y1);
+	    } else if (Z1 < intp->x) {
+		y = QuadGetImage(Z2, W2, right->y, right->x, intp->x, Z1);
+	    } else {
+		y = Z2;
+	    }
+	} else {
+	    y = Y2;
+	}
+    } else {
+
+	/*
+	 * Cases 1, 2, or 3:
+	 *
+	 * Determine the location of the data point relative to the
+	 * knot.
+	 */
+	if (Z1 < intp->x) {
+	    y = QuadGetImage(Z2, W2, right->y, right->x, intp->x, Z1);
+	} else if (Z1 > intp->x) {
+	    y = QuadGetImage(left->y, V2, Z2, Z1, intp->x, left->x);
+	} else {
+	    y = Z2;
+	}
+    }
+    intp->y = y;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * QuadSlopes --
+ *
+ * 	Calculates the derivative at each of the data points.  The
+ * 	slopes computed will insure that an osculatory quadratic
+ * 	spline will have one additional knot between two adjacent
+ * 	points of interpolation.  Convexity and monotonicity are
+ * 	preserved wherever these conditions are compatible with the
+ * 	data.
+ *
+ * Results:
+ *	The output array "m" is filled with the derivates at each
+ *	data point.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+QuadSlopes(Point2d *points, double *m, int nPoints)
+{
+    double xbar, xmid, xhat, ydif1, ydif2;
+    double yxmid;
+    double m1, m2;
+    double m1s, m2s;
+    int i, n, l;
+
+    m1s = m2s = m1 = m2 = 0;
+    for (l = 0, i = 1, n = 2; i < (nPoints - 1); l++, i++, n++) {
+	/*
+	 * Calculate the slopes of the two lines joining three
+	 * consecutive data points.
+	 */
+	ydif1 = points[i].y - points[l].y;
+	ydif2 = points[n].y - points[i].y;
+	m1 = ydif1 / (points[i].x - points[l].x);
+	m2 = ydif2 / (points[n].x - points[i].x);
+	if (i == 1) {
+	    m1s = m1, m2s = m2;	/* Save slopes of starting point */
+	}
+	/*
+	 * If one of the preceding slopes is zero or if they have opposite
+	 * sign, assign the value zero to the derivative at the middle
+	 * point.
+	 */
+	if ((m1 == 0.0) || (m2 == 0.0) || ((m1 * m2) <= 0.0)) {
+	    m[i] = 0.0;
+	} else if (fabs(m1) > fabs(m2)) {
+	    /*
+	     * Calculate the slope by extending the line with slope m1.
+	     */
+	    xbar = ydif2 / m1 + points[i].x;
+	    xhat = (xbar + points[n].x) / 2.0;
+	    m[i] = ydif2 / (xhat - points[i].x);
+	} else {
+	    /*
+	     * Calculate the slope by extending the line with slope m2.
+	     */
+	    xbar = -ydif1 / m2 + points[i].x;
+	    xhat = (points[l].x + xbar) / 2.0;
+	    m[i] = ydif1 / (points[i].x - xhat);
+	}
+    }
+
+    /* Calculate the slope at the last point, x(n). */
+    i = nPoints - 2;
+    n = nPoints - 1;
+    if ((m1 * m2) < 0.0) {
+	m[n] = m2 * 2.0;
+    } else {
+	xmid = (points[i].x + points[n].x) / 2.0;
+	yxmid = m[i] * (xmid - points[i].x) + points[i].y;
+	m[n] = (points[n].y - yxmid) / (points[n].x - xmid);
+	if ((m[n] * m2) < 0.0) {
+	    m[n] = 0.0;
+	}
+    }
+
+    /* Calculate the slope at the first point, x(0). */
+    if ((m1s * m2s) < 0.0) {
+	m[0] = m1s * 2.0;
+    } else {
+	xmid = (points[0].x + points[1].x) / 2.0;
+	yxmid = m[1] * (xmid - points[1].x) + points[1].y;
+	m[0] = (yxmid - points[0].y) / (xmid - points[0].x);
+	if ((m[0] * m1s) < 0.0) {
+	    m[0] = 0.0;
+	}
+    }
+
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * QuadEval --
+ *
+ * 	QuadEval controls the evaluation of an osculatory quadratic
+ * 	spline.  The user may provide his own slopes at the points of
+ * 	interpolation or use the subroutine 'QuadSlopes' to calculate
+ * 	slopes which are consistent with the shape of the data.
+ *
+ * ON INPUT--
+ *   	intpPts	must be a nondecreasing vector of points at which the
+ *		spline will be evaluated.
+ *   	origPts	contains the abscissas of the data points to be
+ *		interpolated. xtab must be increasing.
+ *   	y	contains the ordinates of the data points to be
+ *		interpolated.
+ *   	m 	contains the slope of the spline at each point of
+ *		interpolation.
+ *   	nPoints	number of data points (dimension of xtab and y).
+ *   	numEval is the number of points of evaluation (dimension of
+ *		xval and yval).
+ *   	epsilon 	is a relative error tolerance used in subroutine
+ *		'QuadChoose' to distinguish the situation m(i) or
+ *		m(i+1) is relatively close to the slope or twice
+ *		the slope of the linear segment between xtab(i) and
+ *		xtab(i+1).  If this situation occurs, roundoff may
+ *		cause a change in convexity or monotonicity of the
+ *   		resulting spline and a change in the case number
+ *		provided by 'QuadChoose'.  If epsilon is not equal to zero,
+ *		then epsilon should be greater than or equal to machine
+ *		epsilon.
+ * ON OUTPUT--
+ * 	yval 	contains the images of the points in xval.
+ *   	err 	is one of the following error codes:
+ *      	0 - QuadEval ran normally.
+ *      	1 - xval(i) is less than xtab(1) for at least one
+ *		    i or xval(i) is greater than xtab(num) for at
+ *		    least one i. QuadEval will extrapolate to provide
+ *		    function values for these abscissas.
+ *      	2 - xval(i+1) < xval(i) for some i.
+ *
+ *
+ *  QuadEval calls the following subroutines or functions:
+ *      Search
+ *      QuadCases
+ *      QuadChoose
+ *      QuadSpline
+ *---------------------------------------------------------------------------
+ */
+static int
+QuadEval(
+    Point2d origPts[],
+    int nOrigPts,
+    Point2d intpPts[],
+    int nIntpPts,
+    double *m,			/* Slope of the spline at each point
+				 * of interpolation. */
+    double epsilon)		/* Relative error tolerance (see choose) */
+{
+    int error;
+    int i, j;
+    double param[10];
+    int ncase;
+    int start, end;
+    int l, p;
+    int n;
+    int found;
+
+    /* Initialize indices and set error result */
+    error = 0;
+    l = nOrigPts - 1;
+    p = l - 1;
+    ncase = 1;
+
+    /*
+     * Determine if abscissas of new vector are non-decreasing.
+     */
+    for (j = 1; j < nIntpPts; j++) {
+	if (intpPts[j].x < intpPts[j - 1].x) {
+	    return 2;
+	}
+    }
+    /*
+     * Determine if any of the points in xval are LESS than the
+     * abscissa of the first data point.
+     */
+    for (start = 0; start < nIntpPts; start++) {
+	if (intpPts[start].x >= origPts[0].x) {
+	    break;
+	}
+    }
+    /*
+     * Determine if any of the points in xval are GREATER than the
+     * abscissa of the l data point.
+     */
+    for (end = nIntpPts - 1; end >= 0; end--) {
+	if (intpPts[end].x <= origPts[l].x) {
+	    break;
+	}
+    }
+
+    if (start > 0) {
+	error = 1;		/* Set error value to indicate that
+				 * extrapolation has occurred. */
+	/*
+	 * Calculate the images of points of evaluation whose abscissas
+	 * are less than the abscissa of the first data point.
+	 */
+	ncase = QuadSelect(origPts, origPts + 1, m[0], m[1], epsilon, param);
+	for (j = 0; j < (start - 1); j++) {
+	    QuadSpline(intpPts + j, origPts, origPts + 1, param, ncase);
+	}
+	if (nIntpPts == 1) {
+	    return error;
+	}
+    }
+    if ((nIntpPts == 1) && (end != (nIntpPts - 1))) {
+	goto noExtrapolation;
+    }
+    
+    /*
+     * Search locates the interval in which the first in-range
+     * point of evaluation lies.
+     */
+
+    i = Search(origPts, nOrigPts, intpPts[start].x, &found);
+    
+    n = i + 1;
+    if (n >= nOrigPts) {
+	n = nOrigPts - 1;
+	i = nOrigPts - 2;
+    }
+    /*
+     * If the first in-range point of evaluation is equal to one
+     * of the data points, assign the appropriate value from y.
+     * Continue until a point of evaluation is found which is not
+     * equal to a data point.
+     */
+    if (found) {
+	do {
+	    intpPts[start].y = origPts[i].y;
+	    start++;
+	    if (start >= nIntpPts) {
+		return error;
+	    }
+	} while (intpPts[start - 1].x == intpPts[start].x);
+	
+	for (;;) {
+	    if (intpPts[start].x < origPts[n].x) {
+		break;	/* Break out of for-loop */
+	    }
+	    if (intpPts[start].x == origPts[n].x) {
+		do {
+		    intpPts[start].y = origPts[n].y;
+		    start++;
+		    if (start >= nIntpPts) {
+			return error;
+		    }
+		} while (intpPts[start].x == intpPts[start - 1].x);
+	    }
+	    i++;
+	    n++;
+	}
+    }
+    /*
+     * Calculate the images of all the points which lie within
+     * range of the data.
+     */
+    if ((i > 0) || (error != 1)) {
+	ncase = QuadSelect(origPts + i, origPts + n, m[i], m[n], 
+			   epsilon, param);
+    }
+    for (j = start; j <= end; j++) {
+	/*
+	 * If xx(j) - x(n) is negative, do not recalculate
+	 * the parameters for this section of the spline since
+	 * they are already known.
+	 */
+	if (intpPts[j].x == origPts[n].x) {
+	    intpPts[j].y = origPts[n].y;
+	    continue;
+	} else if (intpPts[j].x > origPts[n].x) {
+	    double delta;
+	    
+	    /* Determine that the routine is in the correct part of
+	       the spline. */
+	    do {
+		i++, n++;
+		delta = intpPts[j].x - origPts[n].x;
+	    } while (delta > 0.0);
+	    
+	    if (delta < 0.0) {
+		ncase = QuadSelect(origPts + i, origPts + n, m[i], 
+			   m[n], epsilon, param);
+	    } else if (delta == 0.0) {
+		intpPts[j].y = origPts[n].y;
+		continue;
+	    }
+	}
+	QuadSpline(intpPts + j, origPts + i, origPts + n, param, ncase);
+    }
+    
+    if (end == (nIntpPts - 1)) {
+	return error;
+    }
+    if ((n == l) && (intpPts[end].x != origPts[l].x)) {
+	goto noExtrapolation;
+    }
+
+    error = 1;			/* Set error value to indicate that
+				 * extrapolation has occurred. */
+    ncase = QuadSelect(origPts + p, origPts + l, m[p], m[l], epsilon, param);
+
+  noExtrapolation:
+    /*
+     * Calculate the images of the points of evaluation whose
+     * abscissas are greater than the abscissa of the last data point.
+     */
+    for (j = (end + 1); j < nIntpPts; j++) {
+	QuadSpline(intpPts + j, origPts + p, origPts + l, param, ncase);
+    }
+    return error;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ *		  Shape preserving quadratic splines
+ *		   by D.F.Mcallister & J.A.Roulier
+ *		    Coded by S.L.Dodd & M.Roulier
+ *			 N.C.State University
+ *
+ *---------------------------------------------------------------------------
+ */
+/*
+ * Driver routine for quadratic spline package
+ * On input--
+ *   X,Y    Contain n-long arrays of data (x is increasing)
+ *   XM     Contains m-long array of x values (increasing)
+ *   eps    Relative error tolerance
+ *   n      Number of input data points
+ *   m      Number of output data points
+ * On output--
+ *   work   Contains the value of the first derivative at each data point
+ *   ym     Contains the interpolated spline value at each data point
+ */
+int
+Blt_QuadraticSpline(Point2d *origPts, int nOrigPts, Point2d *intpPts, 
+		    int nIntpPts)
+{
+    double epsilon;
+    double *work;
+    int result;
+
+    work = malloc(nOrigPts * sizeof(double));
+    epsilon = 0.0;		/* TBA: adjust error via command-line option */
+    /* allocate space for vectors used in calculation */
+    QuadSlopes(origPts, work, nOrigPts);
+    result = QuadEval(origPts, nOrigPts, intpPts, nIntpPts, work, epsilon);
+    free(work);
+    if (result > 1) {
+	return FALSE;
+    }
+    return TRUE;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Reference:
+ *	Numerical Analysis, R. Burden, J. Faires and A. Reynolds.
+ *	Prindle, Weber & Schmidt 1981 pp 112
+ *
+ * Parameters:
+ *	origPts - vector of points, assumed to be sorted along x.
+ *	intpPts - vector of new points.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_NaturalSpline(Point2d *origPts, int nOrigPts, Point2d *intpPts, 
+		  int nIntpPts)
+{
+    Cubic2D *eq;
+    Point2d *ip, *iend;
+    TriDiagonalMatrix *A;
+    double *dx;		/* vector of deltas in x */
+    double x, dy, alpha;
+    int isKnot;
+    int i, j, n;
+
+    dx = malloc(sizeof(double) * nOrigPts);
+    /* Calculate vector of differences */
+    for (i = 0, j = 1; j < nOrigPts; i++, j++) {
+	dx[i] = origPts[j].x - origPts[i].x;
+	if (dx[i] < 0.0) {
+	    return 0;
+	}
+    }
+    n = nOrigPts - 1;		/* Number of intervals. */
+    A = malloc(sizeof(TriDiagonalMatrix) * nOrigPts);
+    if (A == NULL) {
+	free(dx);
+	return 0;
+    }
+    /* Vectors to solve the tridiagonal matrix */
+    A[0][0] = A[n][0] = 1.0;
+    A[0][1] = A[n][1] = 0.0;
+    A[0][2] = A[n][2] = 0.0;
+
+    /* Calculate the intermediate results */
+    for (i = 0, j = 1; j < n; j++, i++) {
+	alpha = 3.0 * ((origPts[j + 1].y / dx[j]) - (origPts[j].y / dx[i]) - 
+		       (origPts[j].y / dx[j]) + (origPts[i].y / dx[i]));
+	A[j][0] = 2 * (dx[j] + dx[i]) - dx[i] * A[i][1];
+	A[j][1] = dx[j] / A[j][0];
+	A[j][2] = (alpha - dx[i] * A[i][2]) / A[j][0];
+    }
+
+    eq = malloc(sizeof(Cubic2D) * nOrigPts);
+    if (eq == NULL) {
+	free(A);
+	free(dx);
+	return FALSE;
+    }
+    eq[0].c = eq[n].c = 0.0;
+    for (j = n, i = n - 1; i >= 0; i--, j--) {
+	eq[i].c = A[i][2] - A[i][1] * eq[j].c;
+	dy = origPts[i+1].y - origPts[i].y;
+	eq[i].b = (dy) / dx[i] - dx[i] * (eq[j].c + 2.0 * eq[i].c) / 3.0;
+	eq[i].d = (eq[j].c - eq[i].c) / (3.0 * dx[i]);
+    }
+    free(A);
+    free(dx);
+
+    /* Now calculate the new values */
+    for (ip = intpPts, iend = ip + nIntpPts; ip < iend; ip++) {
+	ip->y = 0.0;
+	x = ip->x;
+
+	/* Is it outside the interval? */
+	if ((x < origPts[0].x) || (x > origPts[n].x)) {
+	    continue;
+	}
+	/* Search for the interval containing x in the point array */
+	i = Search(origPts, nOrigPts, x, &isKnot);
+	if (isKnot) {
+	    ip->y = origPts[i].y;
+	} else {
+	    i--;
+	    x -= origPts[i].x;
+	    ip->y = origPts[i].y + x * (eq[i].b + x * (eq[i].c + x * eq[i].d));
+	}
+    }
+    free(eq);
+    return TRUE;
+}
+
+typedef struct {
+    double t;			/* Arc length of interval. */
+    double x;			/* 2nd derivative of X with respect to T */
+    double y;			/* 2nd derivative of Y with respect to T */
+} CubicSpline;
+
+/*
+ * The following two procedures solve the special linear system which arise
+ * in cubic spline interpolation. If x is assumed cyclic ( x[i]=x[n+i] ) the
+ * equations can be written as (i=0,1,...,n-1):
+ *     m[i][0] * x[i-1] + m[i][1] * x[i] + m[i][2] * x[i+1] = b[i] .
+ * In matrix notation one gets A * x = b, where the matrix A is tridiagonal
+ * with additional elements in the upper right and lower left position:
+ *   A[i][0] = A_{i,i-1}  for i=1,2,...,n-1    and    m[0][0] = A_{0,n-1} ,
+ *   A[i][1] = A_{i, i }  for i=0,1,...,n-1
+ *   A[i][2] = A_{i,i+1}  for i=0,1,...,n-2    and    m[n-1][2] = A_{n-1,0}.
+ * A should be symmetric (A[i+1][0] == A[i][2]) and positive definite.
+ * The size of the system is given in n (n>=1).
+ *
+ * In the first procedure the Cholesky decomposition A = C^T * D * C
+ * (C is upper triangle with unit diagonal, D is diagonal) is calculated.
+ * Return TRUE if decomposition exist.
+ */
+static int 
+SolveCubic1(TriDiagonalMatrix A[], int n)
+{
+    int i;
+    double m_ij, m_n, m_nn, d;
+
+    if (n < 1) {
+	return FALSE;		/* Dimension should be at least 1 */
+    }
+    d = A[0][1];		/* D_{0,0} = A_{0,0} */
+    if (d <= 0.0) {
+	return FALSE;		/* A (or D) should be positive definite */
+    }
+    m_n = A[0][0];		/*  A_{0,n-1}  */
+    m_nn = A[n - 1][1];		/* A_{n-1,n-1} */
+    for (i = 0; i < n - 2; i++) {
+	m_ij = A[i][2];		/*  A_{i,1}  */
+	A[i][2] = m_ij / d;	/* C_{i,i+1} */
+	A[i][0] = m_n / d;	/* C_{i,n-1} */
+	m_nn -= A[i][0] * m_n;	/* to get C_{n-1,n-1} */
+	m_n = -A[i][2] * m_n;	/* to get C_{i+1,n-1} */
+	d = A[i + 1][1] - A[i][2] * m_ij;	/* D_{i+1,i+1} */
+	if (d <= 0.0) {
+	    return FALSE;	/* Elements of D should be positive */
+	}
+	A[i + 1][1] = d;
+    }
+    if (n >= 2) {		/* Complete last column */
+	m_n += A[n - 2][2];	/* add A_{n-2,n-1} */
+	A[n - 2][0] = m_n / d;	/* C_{n-2,n-1} */
+	A[n - 1][1] = d = m_nn - A[n - 2][0] * m_n;	/* D_{n-1,n-1} */
+	if (d <= 0.0) {
+	    return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+/*
+ * The second procedure solves the linear system, with the Cholesky
+ * decomposition calculated above (in m[][]) and the right side b given
+ * in x[]. The solution x overwrites the right side in x[].
+ */
+static void 
+SolveCubic2(TriDiagonalMatrix A[], CubicSpline spline[], int nIntervals)
+{
+    int i;
+    double x, y;
+    int n, m;
+
+    n = nIntervals - 2;
+    m = nIntervals - 1;
+
+    /* Division by transpose of C : b = C^{-T} * b */
+    x = spline[m].x;
+    y = spline[m].y;
+    for (i = 0; i < n; i++) {
+	spline[i + 1].x -= A[i][2] * spline[i].x; /* C_{i,i+1} * x(i) */
+	spline[i + 1].y -= A[i][2] * spline[i].y; /* C_{i,i+1} * x(i) */
+	x -= A[i][0] * spline[i].x;	/* C_{i,n-1} * x(i) */
+	y -= A[i][0] * spline[i].y; /* C_{i,n-1} * x(i) */
+    }
+    if (n >= 0) {
+	/* C_{n-2,n-1} * x_{n-1} */
+	spline[m].x = x - A[n][0] * spline[n].x; 
+	spline[m].y = y - A[n][0] * spline[n].y; 
+    }
+    /* Division by D: b = D^{-1} * b */
+    for (i = 0; i < nIntervals; i++) {
+	spline[i].x /= A[i][1];
+	spline[i].y /= A[i][1];
+    }
+
+    /* Division by C: b = C^{-1} * b */
+    x = spline[m].x;
+    y = spline[m].y;
+    if (n >= 0) {
+	/* C_{n-2,n-1} * x_{n-1} */
+	spline[n].x -= A[n][0] * x;	
+	spline[n].y -= A[n][0] * y;	
+    }
+    for (i = (n - 1); i >= 0; i--) {
+	/* C_{i,i+1} * x_{i+1} + C_{i,n-1} * x_{n-1} */
+	spline[i].x -= A[i][2] * spline[i + 1].x + A[i][0] * x;
+	spline[i].y -= A[i][2] * spline[i + 1].y + A[i][0] * y;
+    }
+}
+
+/*
+ * Find second derivatives (x''(t_i),y''(t_i)) of cubic spline interpolation
+ * through list of points (x_i,y_i). The parameter t is calculated as the
+ * length of the linear stroke. The number of points must be at least 3.
+ * Note: For CLOSED_CONTOURs the first and last point must be equal.
+ */
+static CubicSpline *
+CubicSlopes(
+    Point2d points[],
+    int nPoints,		/* Number of points (nPoints>=3) */
+    int isClosed,		/* CLOSED_CONTOUR or OPEN_CONTOUR  */
+    double unitX, 
+    double unitY)		/* Unit length in x and y (norm=1) */
+{
+    CubicSpline *spline;
+    CubicSpline *s1, *s2;
+    int n, i;
+    double norm, dx, dy;
+    TriDiagonalMatrix *A;	/* The tri-diagonal matrix is saved here. */
+    
+    spline = malloc(sizeof(CubicSpline) * nPoints);
+    if (spline == NULL) {
+	return NULL;
+    }
+    A = malloc(sizeof(TriDiagonalMatrix) * nPoints);
+    if (A == NULL) {
+	free(spline);
+	return NULL;
+    }
+    /*
+     * Calculate first differences in (dxdt2[i], y[i]) and interval lengths
+     * in dist[i]:
+     */
+    s1 = spline;
+    for (i = 0; i < nPoints - 1; i++) {
+	s1->x = points[i+1].x - points[i].x;
+	s1->y = points[i+1].y - points[i].y;
+
+	/*
+	 * The Norm of a linear stroke is calculated in "normal coordinates"
+	 * and used as interval length:
+	 */
+	dx = s1->x / unitX;
+	dy = s1->y / unitY;
+	s1->t = sqrt(dx * dx + dy * dy);
+
+	s1->x /= s1->t;	/* first difference, with unit norm: */
+	s1->y /= s1->t;	/*   || (dxdt2[i], y[i]) || = 1      */
+	s1++;
+    }
+
+    /*
+     * Setup linear System:  Ax = b
+     */
+    n = nPoints - 2;		/* Without first and last point */
+    if (isClosed) {
+	/* First and last points must be equal for CLOSED_CONTOURs */
+	spline[nPoints - 1].t = spline[0].t;
+	spline[nPoints - 1].x = spline[0].x;
+	spline[nPoints - 1].y = spline[0].y;
+	n++;			/* Add last point (= first point) */
+    }
+    s1 = spline, s2 = s1 + 1;
+    for (i = 0; i < n; i++) {
+	/* Matrix A, mainly tridiagonal with cyclic second index 
+	   ("j = j+n mod n") 
+	*/
+	A[i][0] = s1->t;	/* Off-diagonal element A_{i,i-1} */
+	A[i][1] = 2.0 * (s1->t + s2->t);	/* A_{i,i} */
+	A[i][2] = s2->t;	/* Off-diagonal element A_{i,i+1} */
+
+	/* Right side b_x and b_y */
+	s1->x = (s2->x - s1->x) * 6.0;
+	s1->y = (s2->y - s1->y) * 6.0;
+
+	/* 
+	 * If the linear stroke shows a cusp of more than 90 degree,
+	 * the right side is reduced to avoid oscillations in the
+	 * spline: 
+	 */
+	/*
+	 * The Norm of a linear stroke is calculated in "normal coordinates"
+	 * and used as interval length:
+	 */
+	dx = s1->x / unitX;
+	dy = s1->y / unitY;
+	norm = sqrt(dx * dx + dy * dy) / 8.5;
+	if (norm > 1.0) {
+	    /* The first derivative will not be continuous */
+	    s1->x /= norm;
+	    s1->y /= norm;
+	}
+	s1++, s2++;
+    }
+
+    if (!isClosed) {
+	/* Third derivative is set to zero at both ends */
+	A[0][1] += A[0][0];	/* A_{0,0}     */
+	A[0][0] = 0.0;		/* A_{0,n-1}   */
+	A[n-1][1] += A[n-1][2]; /* A_{n-1,n-1} */
+	A[n-1][2] = 0.0;	/* A_{n-1,0}   */
+    }
+    /* Solve linear systems for dxdt2[] and y[] */
+
+    if (SolveCubic1(A, n)) {	/* Cholesky decomposition */
+	SolveCubic2(A, spline, n); /* A * dxdt2 = b_x */
+    } else {			/* Should not happen, but who knows ... */
+	free(A);
+	free(spline);
+	return NULL;
+    }
+    /* Shift all second derivatives one place right and update the ends. */
+    s2 = spline + n, s1 = s2 - 1;
+    for (/* empty */; s2 > spline; s2--, s1--) {
+	s2->x = s1->x;
+	s2->y = s1->y;
+    }
+    if (isClosed) {
+	spline[0].x = spline[n].x;
+	spline[0].y = spline[n].y;
+    } else {
+	/* Third derivative is 0.0 for the first and last interval. */
+	spline[0].x = spline[1].x; 
+	spline[0].y = spline[1].y; 
+	spline[n + 1].x = spline[n].x;
+	spline[n + 1].y = spline[n].y;
+    }
+    free( A);
+    return spline;
+}
+
+
+/*
+ * Calculate interpolated values of the spline function (defined via p_cntr
+ * and the second derivatives dxdt2[] and dydt2[]). The number of tabulated
+ * values is n. On an equidistant grid n_intpol values are calculated.
+ */
+static int
+CubicEval(Point2d *origPts, int nOrigPts, Point2d *intpPts, int nIntpPts,
+	  CubicSpline *spline)
+{
+    double t, tSkip, tMax;
+    Point2d q;
+    int i, j, count;
+
+    /* Sum the lengths of all the segments (intervals). */
+    tMax = 0.0;
+    for (i = 0; i < nOrigPts - 1; i++) {
+	tMax += spline[i].t;
+    }
+
+    /* Need a better way of doing this... */
+
+    /* The distance between interpolated points */
+    tSkip = (1. - 1e-7) * tMax / (nIntpPts - 1);
+    
+    t = 0.0;			/* Spline parameter value. */
+    q = origPts[0];
+    count = 0;
+
+    intpPts[count++] = q;	/* First point. */
+    t += tSkip;
+    
+    for (i = 0, j = 1; j < nOrigPts; i++, j++) {
+	Point2d p;
+	double d, hx, dx0, dx01, hy, dy0, dy01;
+	
+	d = spline[i].t;	/* Interval length */
+	p = q;
+	q = origPts[i+1];
+	hx = (q.x - p.x) / d;
+	hy = (q.y - p.y) / d;
+	dx0 = (spline[j].x + 2 * spline[i].x) / 6.0;
+	dy0 = (spline[j].y + 2 * spline[i].y) / 6.0;
+	dx01 = (spline[j].x - spline[i].x) / (6.0 * d);
+	dy01 = (spline[j].y - spline[i].y) / (6.0 * d);
+	while (t <= spline[i].t) { /* t in current interval ? */
+	    p.x += t * (hx + (t - d) * (dx0 + t * dx01));
+	    p.y += t * (hy + (t - d) * (dy0 + t * dy01));
+	    intpPts[count++] = p;
+	    t += tSkip;
+	}
+	/* Parameter t relative to start of next interval */
+	t -= spline[i].t;
+    }
+    return count;
+}
+
+/*
+ * Generate a cubic spline curve through the points (x_i,y_i) which are
+ * stored in the linked list p_cntr.
+ * The spline is defined as a 2d-function s(t) = (x(t),y(t)), where the
+ * parameter t is the length of the linear stroke.
+ */
+int
+Blt_NaturalParametricSpline(Point2d *origPts, int nOrigPts, Region2d *extsPtr,
+			    int isClosed, Point2d *intpPts, int nIntpPts)
+{
+    double unitX, unitY;	/* To define norm (x,y)-plane */
+    CubicSpline *spline;
+    int result;
+
+    if (nOrigPts < 3) {
+	return 0;
+    }
+    if (isClosed) {
+	origPts[nOrigPts].x = origPts[0].x;
+	origPts[nOrigPts].y = origPts[0].y;
+	nOrigPts++;
+    }
+    /* Width and height of the grid is used at unit length (2d-norm) */
+    unitX = extsPtr->right - extsPtr->left;
+    unitY = extsPtr->bottom - extsPtr->top;
+
+    if (unitX < FLT_EPSILON) {
+	unitX = FLT_EPSILON;
+    }
+    if (unitY < FLT_EPSILON) {
+	unitY = FLT_EPSILON;
+    }
+    /* Calculate parameters for cubic spline: 
+     *		t     = arc length of interval.
+     *		dxdt2 = second derivatives of x with respect to t, 
+     *		dydt2 = second derivatives of y with respect to t, 
+     */
+    spline = CubicSlopes(origPts, nOrigPts, isClosed, unitX, unitY);
+    if (spline == NULL) {
+	return 0;
+    }
+    result= CubicEval(origPts, nOrigPts, intpPts, nIntpPts, spline);
+    free(spline);
+    return result;
+}
+
+static INLINE void
+CatromCoeffs(Point2d *p, Point2d *a, Point2d *b, Point2d *c, Point2d *d)
+{
+    a->x = -p[0].x + 3.0 * p[1].x - 3.0 * p[2].x + p[3].x;
+    b->x = 2.0 * p[0].x - 5.0 * p[1].x + 4.0 * p[2].x - p[3].x;
+    c->x = -p[0].x + p[2].x;
+    d->x = 2.0 * p[1].x;
+    a->y = -p[0].y + 3.0 * p[1].y - 3.0 * p[2].y + p[3].y;
+    b->y = 2.0 * p[0].y - 5.0 * p[1].y + 4.0 * p[2].y - p[3].y;
+    c->y = -p[0].y + p[2].y;
+    d->y = 2.0 * p[1].y;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ParametricCatromSpline --
+ *
+ *	Computes a spline based upon the data points, returning a new (larger)
+ *	coordinate array of points.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_CatromParametricSpline(Point2d *points, int nPoints, Point2d *intpPts,
+			   int nIntpPts)
+{
+    int i;
+    Point2d *origPts;
+    double t;
+    int interval;
+    Point2d a, b, c, d;
+
+    assert(nPoints > 0);
+
+    /*
+     * The spline is computed in screen coordinates instead of data points so
+     * that we can select the abscissas of the interpolated points from each
+     * pixel horizontally across the plotting area.
+     */
+    origPts = malloc((nPoints + 4) * sizeof(Point2d));
+    memcpy(origPts + 1, points, sizeof(Point2d) * nPoints);
+
+    origPts[0] = origPts[1];
+    origPts[nPoints + 2] = origPts[nPoints + 1] = origPts[nPoints];
+
+    for (i = 0; i < nIntpPts; i++) {
+	interval = (int)intpPts[i].x;
+	t = intpPts[i].y;
+	assert(interval < nPoints);
+	CatromCoeffs(origPts + interval, &a, &b, &c, &d);
+	intpPts[i].x = (d.x + t * (c.x + t * (b.x + t * a.x))) / 2.0;
+	intpPts[i].y = (d.y + t * (c.y + t * (b.y + t * a.y))) / 2.0;
+    }
+    free(origPts);
+    return 1;
+}
diff --git a/tlt3.0/bltSpline.h b/tlt3.0/bltSpline.h
new file mode 100644
index 0000000..a9553e2
--- /dev/null
+++ b/tlt3.0/bltSpline.h
@@ -0,0 +1,43 @@
+/*
+ * bltSpline.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_SPLINE_H
+#define _BLT_SPLINE_H
+
+#include "bltInt.h"
+
+extern int Blt_NaturalSpline (Point2d *origPts, int nOrigPts, Point2d *intpPts,
+	int nIntpPts);
+
+extern int Blt_QuadraticSpline (Point2d *origPts, int nOrigPts, 
+	Point2d *intpPts, int nIntpPts);
+
+extern int Blt_NaturalParametricSpline (Point2d *origPts, int nOrigPts, 
+	Region2d *extsPtr, int isClosed, Point2d *intpPts, int nIntpPts);
+
+extern int Blt_CatromParametricSpline (Point2d *origPts, int nOrigPts, 
+	Point2d *intpPts, int nIntpPts);
+
+#endif
diff --git a/tlt3.0/bltSwitch.c b/tlt3.0/bltSwitch.c
new file mode 100644
index 0000000..8c4fee0
--- /dev/null
+++ b/tlt3.0/bltSwitch.c
@@ -0,0 +1,538 @@
+/*
+ * bltSwitch.c --
+ *
+ * This module implements command/argument switch parsing procedures for the
+ * BLT toolkit.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+
+#include "bltInt.h"
+#include "bltSwitch.h"
+
+static void
+DoHelp(Tcl_Interp *interp, Blt_SwitchSpec *specs)
+{
+    Tcl_DString ds;
+    Blt_SwitchSpec *sp;
+
+    Tcl_DStringInit(&ds);
+    Tcl_DStringAppend(&ds, "following switches are available:", -1);
+    for (sp = specs; sp->type != BLT_SWITCH_END; sp++) {
+	Tcl_DStringAppend(&ds, "\n    ", 4);
+	Tcl_DStringAppend(&ds, sp->switchName, -1);
+	Tcl_DStringAppend(&ds, " ", 1);
+	Tcl_DStringAppend(&ds, sp->help, -1);
+    }
+    Tcl_AppendResult(interp, Tcl_DStringValue(&ds), (char *)NULL);
+    Tcl_DStringFree(&ds);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FindSwitchSpec --
+ *
+ *	Search through a table of configuration specs, looking for one that
+ *	matches a given argvName.
+ *
+ * Results:
+ *	The return value is a pointer to the matching entry, or NULL if
+ *	nothing matched.  In that case an error message is left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_SwitchSpec *
+FindSwitchSpec(
+    Tcl_Interp *interp,		/* Used for reporting errors. */
+    Blt_SwitchSpec *specs,	/* Pointer to table of configuration
+				 * specifications for a widget. */
+    const char *name,		/* Name identifying a particular switch. */
+    int length,			/* Length of name. */
+    int needFlags,		/* Flags that must be present in matching
+				 * entry. */
+    int hateFlags)		/* Flags that must NOT be present in matching
+				 * entry. */
+{
+    Blt_SwitchSpec *sp;
+    char c;			/* First character of current argument. */
+    Blt_SwitchSpec *matchPtr;	/* Matching spec, or NULL. */
+
+    c = name[1];
+    matchPtr = NULL;
+    for (sp = specs; sp->type != BLT_SWITCH_END; sp++) {
+	if (sp->switchName == NULL) {
+	    continue;
+	}
+	if (((sp->flags & needFlags) != needFlags) || (sp->flags & hateFlags)) {
+	    continue;
+	}
+	if ((sp->switchName[1] != c) || 
+	    (strncmp(sp->switchName, name, length) != 0)) {
+	    continue;
+	}
+	if (sp->switchName[length] == '\0') {
+	    return sp;		/* Stop on a perfect match. */
+	}
+	if (matchPtr != NULL) {
+	    Tcl_AppendResult(interp, "ambiguous switch \"", name, "\"\n", 
+		(char *) NULL);
+	    DoHelp(interp, specs);
+	    return NULL;
+	}
+	matchPtr = sp;
+    }
+    if (strcmp(name, "-help") == 0) {
+	DoHelp(interp, specs);
+	return NULL;
+    }
+    if (matchPtr == NULL) {
+	Tcl_AppendResult(interp, "unknown switch \"", name, "\"\n", 
+			 (char *)NULL);
+	DoHelp(interp, specs);
+	return NULL;
+    }
+    return matchPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DoSwitch --
+ *
+ *	This procedure applies a single configuration switch to a widget
+ *	record.
+ *
+ * Results:
+ *	A standard TCL return value.
+ *
+ * Side effects:
+ *	WidgRec is modified as indicated by specPtr and value.  The old value
+ *	is recycled, if that is appropriate for the value type.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+DoSwitch(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    Blt_SwitchSpec *sp,		/* Specifier to apply. */
+    Tcl_Obj *objPtr,		/* Value to use to fill in widgRec. */
+    void *record)		/* Record whose fields are to be modified.
+				 * Values must be properly initialized. */
+{
+    do {
+	char *ptr;
+
+	ptr = (char *)record + sp->offset;
+	switch (sp->type) {
+	case BLT_SWITCH_BOOLEAN:
+	    {
+		int bool;
+
+		if (Tcl_GetBooleanFromObj(interp, objPtr, &bool) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		if (sp->mask > 0) {
+		    if (bool) {
+			*((int *)ptr) |= sp->mask;
+		    } else {
+			*((int *)ptr) &= ~sp->mask;
+		    }
+		} else {
+		    *((int *)ptr) = bool;
+		}
+	    }
+	    break;
+
+	case BLT_SWITCH_DOUBLE:
+	    if (Tcl_GetDoubleFromObj(interp, objPtr, (double *)ptr) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+
+	case BLT_SWITCH_OBJ:
+	    Tcl_IncrRefCount(objPtr);
+	    *(Tcl_Obj **)ptr = objPtr;
+	    break;
+
+	case BLT_SWITCH_FLOAT:
+	    {
+		double value;
+
+		if (Tcl_GetDoubleFromObj(interp, objPtr, &value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(float *)ptr = (float)value;
+	    }
+	    break;
+
+	case BLT_SWITCH_INT:
+	    if (Tcl_GetIntFromObj(interp, objPtr, (int *)ptr) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+
+	case BLT_SWITCH_INT_NNEG:
+	    {
+		long value;
+		
+		if (Blt_GetCountFromObj(interp, objPtr, COUNT_NNEG, 
+			&value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = (int)value;
+	    }
+	    break;
+
+	case BLT_SWITCH_INT_POS:
+	    {
+		long value;
+		
+		if (Blt_GetCountFromObj(interp, objPtr, COUNT_POS, 
+			&value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(int *)ptr = (int)value;
+	    }
+	    break;
+
+	case BLT_SWITCH_LIST:
+	    {
+		int argc;
+
+		if (Tcl_SplitList(interp, Tcl_GetString(objPtr), &argc, 
+				  (const char ***)ptr) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+	    }
+	    break;
+
+	case BLT_SWITCH_LONG:
+	    if (Tcl_GetLongFromObj(interp, objPtr, (long *)ptr) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+
+	case BLT_SWITCH_LONG_NNEG:
+	    {
+		long value;
+		
+		if (Blt_GetCountFromObj(interp, objPtr, COUNT_NNEG, 
+			&value) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(long *)ptr = value;
+	    }
+	    break;
+
+	case BLT_SWITCH_LONG_POS:
+	    {
+		long value;
+		
+		if (Blt_GetCountFromObj(interp, objPtr, COUNT_POS, &value)
+			!= TCL_OK) {
+		    return TCL_ERROR;
+		}
+		*(long *)ptr = value;
+	    }
+	    break;
+
+	case BLT_SWITCH_STRING: 
+	    {
+		char *value;
+		
+		value = Tcl_GetString(objPtr);
+		value =  (*value == '\0') ?  NULL : Blt_Strdup(value);
+		if (*(char **)ptr != NULL) {
+		    free(*(char **)ptr);
+		}
+		*(char **)ptr = value;
+	    }
+	    break;
+
+	case BLT_SWITCH_CUSTOM:
+	    assert(sp->customPtr != NULL);
+	    if ((*sp->customPtr->parseProc)(sp->customPtr->clientData, interp,
+		sp->switchName, objPtr, (char *)record, sp->offset, sp->flags) 
+		!= TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+
+	default: 
+	    Tcl_AppendResult(interp, "bad switch table: unknown type \"",
+		 Blt_Itoa(sp->type), "\"", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	sp++;
+    } while ((sp->switchName == NULL) && (sp->type != BLT_SWITCH_END));
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ParseSwitches --
+ *
+ *	Process command-line switches to fill in fields of a record with
+ *	resources and other parameters.
+ *
+ * Results:
+ *	Returns the number of arguments comsumed by parsing the command line.
+ *	If an error occurred, -1 will be returned and an error messages can be
+ *	found as the interpreter result.
+ *
+ * Side effects:
+ *	The fields of widgRec get filled in with information from argc/argv.
+ *	Old information in widgRec's fields gets recycled.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_ParseSwitches(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    Blt_SwitchSpec *specs,	/* Describes legal switches. */
+    int objc,			/* Number of elements in argv. */
+    Tcl_Obj *const *objv,	/* Command-line switches. */
+    void *record,		/* Record whose fields are to be modified.
+				 * Values must be properly initialized. */
+    int flags)			/* Used to specify additional flags that must
+				 * be present in switch specs for them to be
+				 * considered.  */
+{
+    Blt_SwitchSpec *sp;
+    int count;
+    int needFlags;		/* Specs must contain this set of flags or
+				 * else they are not considered. */
+    int hateFlags;		/* If a spec contains any bits here, it's not
+				 * considered. */
+
+    needFlags = flags & ~(BLT_SWITCH_USER_BIT - 1);
+    hateFlags = 0;
+
+    /*
+     * Pass 1:  Clear the change flags on all the specs so that we 
+     *          can check it later.
+     */
+    for (sp = specs; sp->type != BLT_SWITCH_END; sp++) {
+	sp->flags &= ~BLT_SWITCH_SPECIFIED;
+    }
+    /*
+     * Pass 2:  Process the arguments that match entries in the specs.
+     *		It's an error if the argument doesn't match anything.
+     */
+    for (count = 0; count < objc; count++) {
+	char *arg;
+	int length;
+
+	arg = Tcl_GetStringFromObj(objv[count], &length);
+	if (flags & BLT_SWITCH_OBJV_PARTIAL) {
+	    /* 
+	     * If the argument doesn't start with a '-' (not a switch) or is
+	     * '--', stop processing and return the number of arguments
+	     * comsumed.
+	     */
+	    if (arg[0] != '-') {
+		return count;
+	    }
+	    if ((arg[1] == '-') && (arg[2] == '\0')) {
+		return count + 1; /* include the "--" in the count. */
+	    }
+	}
+	sp = FindSwitchSpec(interp, specs, arg, length, needFlags, hateFlags);
+	if (sp == NULL) {
+	    return -1;
+	}
+	if (sp->type == BLT_SWITCH_BITMASK) {
+	    char *ptr;
+
+	    ptr = (char *)record + sp->offset;
+	    *((int *)ptr) |= sp->mask;
+	} else if (sp->type == BLT_SWITCH_BITMASK_INVERT) {
+	    char *ptr;
+	    
+	    ptr = (char *)record + sp->offset;
+	    *((int *)ptr) &= ~sp->mask;
+	} else if (sp->type == BLT_SWITCH_VALUE) {
+	    char *ptr;
+	    
+	    ptr = (char *)record + sp->offset;
+	    *((int *)ptr) = sp->mask;
+	} else {
+	    count++;
+	    if (count == objc) {
+		Tcl_AppendResult(interp, "value for \"", arg, "\" missing", 
+				 (char *) NULL);
+		return -1;
+	    }
+	    if (DoSwitch(interp, sp, objv[count], record) != TCL_OK) {
+		char msg[200];
+
+		sprintf_s(msg, 200, "\n    (processing \"%.40s\" switch)", 
+			sp->switchName);
+		Tcl_AddErrorInfo(interp, msg);
+		return -1;
+	    }
+	}
+	sp->flags |= BLT_SWITCH_SPECIFIED;
+    }
+    return count;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FreeSwitches --
+ *
+ *	Free up all resources associated with switches.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+void
+Blt_FreeSwitches(
+    Blt_SwitchSpec *specs,	/* Describes legal switches. */
+    void *record,		/* Record whose fields contain current values
+				 * for switches. */
+    int needFlags)		/* Used to specify additional flags that must
+				 * be present in config specs for them to be
+				 * considered. */
+{
+    Blt_SwitchSpec *sp;
+
+    for (sp = specs; sp->type != BLT_SWITCH_END; sp++) {
+	if ((sp->flags & needFlags) == needFlags) {
+	    char *ptr;
+
+	    ptr = (char *)record + sp->offset;
+	    switch (sp->type) {
+	    case BLT_SWITCH_STRING:
+	    case BLT_SWITCH_LIST:
+		if (*((char **) ptr) != NULL) {
+		    free(*((char **) ptr));
+		    *((char **) ptr) = NULL;
+		}
+		break;
+
+	    case BLT_SWITCH_OBJ:
+		if (*((Tcl_Obj **) ptr) != NULL) {
+		    Tcl_DecrRefCount(*((Tcl_Obj **)ptr));
+		    *((Tcl_Obj **) ptr) = NULL;
+		}
+		break;
+
+	    case BLT_SWITCH_CUSTOM:
+		assert(sp->customPtr != NULL);
+		if ((*(char **)ptr != NULL) && 
+		    (sp->customPtr->freeProc != NULL)) {
+		    (*sp->customPtr->freeProc)((char *)record, sp->offset, 
+			sp->flags);
+		}
+		break;
+
+	    default:
+		break;
+	    }
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_SwitchModified --
+ *
+ *      Given the configuration specifications and one or more switch patterns
+ *      (terminated by a NULL), indicate if any of the matching switches has
+ *      been reset.
+ *
+ * Results:
+ *      Returns 1 if one of the switches have changed, 0 otherwise.
+ *
+ *---------------------------------------------------------------------------
+ */
+int 
+Blt_SwitchChanged TCL_VARARGS_DEF(Blt_SwitchSpec *, arg1)
+{
+    va_list argList;
+    Blt_SwitchSpec *specs;
+    Blt_SwitchSpec *sp;
+    char *switchName;
+
+    specs = TCL_VARARGS_START(Blt_SwitchSpec *, arg1, argList);
+    while ((switchName = va_arg(argList, char *)) != NULL) {
+	for (sp = specs; sp->type != BLT_SWITCH_END; sp++) {
+	    if ((Tcl_StringMatch(sp->switchName, switchName)) &&
+		(sp->flags & BLT_SWITCH_SPECIFIED)) {
+		va_end(argList);
+		return 1;
+	    }
+	}
+    }
+    va_end(argList);
+    return 0;
+}
+
+int 
+Blt_ExprDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *valuePtr)
+{
+    /* First try to extract the value as a double precision number. */
+    if (Tcl_GetDoubleFromObj((Tcl_Interp *)NULL, objPtr, valuePtr) == TCL_OK) {
+	return TCL_OK;
+    }
+    /* Then try to parse it as an expression. */
+    if (Tcl_ExprDouble(interp, Tcl_GetString(objPtr), valuePtr) == TCL_OK) {
+	return TCL_OK;
+    }
+    return TCL_ERROR;
+}
+
+int 
+Blt_ExprIntFromObj(
+    Tcl_Interp *interp, 
+    Tcl_Obj *objPtr, 
+    int *valuePtr)
+{
+    long lvalue;
+
+    /* First try to extract the value as a simple integer. */
+    if (Tcl_GetIntFromObj((Tcl_Interp *)NULL, objPtr, valuePtr) == TCL_OK) {
+	return TCL_OK;
+    }
+    /* Otherwise try to parse it as an expression. */
+    if (Tcl_ExprLong(interp, Tcl_GetString(objPtr), &lvalue) == TCL_OK) {
+	*valuePtr = lvalue;
+	return TCL_OK;
+    }
+    return TCL_ERROR;
+}
+
diff --git a/tlt3.0/bltSwitch.h b/tlt3.0/bltSwitch.h
new file mode 100644
index 0000000..a075d0b
--- /dev/null
+++ b/tlt3.0/bltSwitch.h
@@ -0,0 +1,134 @@
+
+/*
+ * bltSwitch.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef BLT_SWITCH_H
+#define BLT_SWITCH_H
+
+#  include <stddef.h>
+
+#ifndef Blt_Offset
+#ifdef offsetof
+#define Blt_Offset(type, field) ((int) offsetof(type, field))
+#else
+#define Blt_Offset(type, field) ((int) ((char *) &((type *) 0)->field))
+#endif
+#endif /* Blt_Offset */
+
+typedef int (Blt_SwitchParseProc)(ClientData clientData, Tcl_Interp *interp, 
+	const char *switchName, Tcl_Obj *valueObjPtr, char *record, int offset,
+	int flags);
+typedef void (Blt_SwitchFreeProc)(char *record, int offset, int flags);
+
+typedef struct {
+    Blt_SwitchParseProc *parseProc; /* Procedure to parse a switch
+				     * value and store it in its *
+				     * converted form in the data *
+				     * record. */
+
+    Blt_SwitchFreeProc *freeProc; /* Procedure to free a switch. */
+
+    ClientData clientData;	/* Arbitrary one-word value used by
+				 * switch parser, passed to
+				 * parseProc. */
+} Blt_SwitchCustom;
+
+
+/*
+ * Type values for Blt_SwitchSpec structures.  See the user
+ * documentation for details.
+ */
+typedef enum {
+    BLT_SWITCH_BOOLEAN, 
+    BLT_SWITCH_DOUBLE, 
+    BLT_SWITCH_BITMASK, 
+    BLT_SWITCH_BITMASK_INVERT, 
+    BLT_SWITCH_FLOAT, 
+    BLT_SWITCH_INT, 
+    BLT_SWITCH_INT_NNEG, 
+    BLT_SWITCH_INT_POS,
+    BLT_SWITCH_LIST, 
+    BLT_SWITCH_LONG, 
+    BLT_SWITCH_LONG_NNEG, 
+    BLT_SWITCH_LONG_POS,
+    BLT_SWITCH_OBJ,
+    BLT_SWITCH_STRING, 
+    BLT_SWITCH_VALUE, 
+    BLT_SWITCH_CUSTOM, 
+    BLT_SWITCH_END
+} Blt_SwitchTypes;
+
+
+typedef struct {
+    Blt_SwitchTypes type;	/* Type of option, such as
+				 * BLT_SWITCH_COLOR; see definitions
+				 * below.  Last option in table must
+				 * have type BLT_SWITCH_END. */
+
+    const char *switchName;	/* Switch used to specify option in
+				 * argv.  NULL means this spec is part
+				 * of a group. */
+
+    const char *help;		/* Help string. */
+    int offset;			/* Where in widget record to store
+				 * value; use Blt_Offset macro to
+				 * generate values for this. */
+
+    int flags;			/* Any combination of the values
+				 * defined below. */
+
+    unsigned int mask;
+
+    Blt_SwitchCustom *customPtr; /* If type is BLT_SWITCH_CUSTOM then
+				 * this is a pointer to info about how
+				 * to parse and print the option.
+				 * Otherwise it is irrelevant. */
+} Blt_SwitchSpec;
+
+#define BLT_SWITCH_DEFAULTS		(0)
+#define BLT_SWITCH_ARGV_PARTIAL		(1<<1)
+#define BLT_SWITCH_OBJV_PARTIAL		(1<<1)
+
+/*
+ * Possible flag values for Blt_SwitchSpec structures.  Any bits at or
+ * above BLT_SWITCH_USER_BIT may be used by clients for selecting
+ * certain entries.
+ */
+#define BLT_SWITCH_NULL_OK		(1<<0)
+#define BLT_SWITCH_DONT_SET_DEFAULT	(1<<3)
+#define BLT_SWITCH_SPECIFIED		(1<<4)
+#define BLT_SWITCH_USER_BIT		(1<<8)
+
+extern int Blt_ParseSwitches(Tcl_Interp *interp, Blt_SwitchSpec *specPtr, 
+	int objc, Tcl_Obj *const *objv, void *rec, int flags);
+
+extern void Blt_FreeSwitches(Blt_SwitchSpec *specs, void *rec, int flags);
+
+extern int Blt_SwitchChanged TCL_VARARGS(Blt_SwitchSpec *, specs);
+ 
+#endif /* BLT_SWITCH_H */
diff --git a/tlt3.0/bltText.c b/tlt3.0/bltText.c
new file mode 100644
index 0000000..eff55e8
--- /dev/null
+++ b/tlt3.0/bltText.c
@@ -0,0 +1,1320 @@
+/*
+ * bltText.c --
+ *
+ * This module implements multi-line, rotate-able text for the BLT toolkit.
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <X11/Xutil.h>
+
+#include <tkPort.h>
+#include <tkInt.h>
+#include <tk3d.h>
+
+#include "bltInt.h"
+#include "bltMath.h"
+#include "bltHash.h"
+#include "bltImage.h"
+#include "bltBitmap.h"
+#include "bltFont.h"
+#include "bltText.h"
+#include "bltBgStyle.h"
+
+static Blt_HashTable bitmapGCTable;
+static int initialized;
+
+GC
+Blt_GetBitmapGC(Tk_Window tkwin)
+{
+    int isNew;
+    GC gc;
+    Display *display;
+    Blt_HashEntry *hPtr;
+
+    if (!initialized) {
+	Blt_InitHashTable(&bitmapGCTable, BLT_ONE_WORD_KEYS);
+	initialized = TRUE;
+    }
+    display = Tk_Display(tkwin);
+    hPtr = Blt_CreateHashEntry(&bitmapGCTable, (char *)display, &isNew);
+    if (isNew) {
+	Pixmap bitmap;
+	XGCValues gcValues;
+	unsigned long gcMask;
+	Window root;
+
+	root = Tk_RootWindow(tkwin);
+	bitmap = Tk_GetPixmap(display, root, 1, 1, 1);
+	gcValues.foreground = gcValues.background = 0;
+	gcMask = (GCForeground | GCBackground);
+	gc = Blt_GetPrivateGCFromDrawable(display, bitmap, gcMask, &gcValues);
+	Tk_FreePixmap(display, bitmap);
+	Blt_SetHashValue(hPtr, gc);
+    } else {
+	gc = (GC)Blt_GetHashValue(hPtr);
+    }
+    return gc;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetTextExtents --
+ *
+ *	Get the extents of a possibly multiple-lined text string.
+ *
+ * Results:
+ *	Returns via *widthPtr* and *heightPtr* the dimensions of the text
+ *	string.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_GetTextExtents(
+    Blt_Font font, 
+    int leader,
+    const char *text,		/* Text string to be measured. */
+    int textLen,		/* Length of the text. If -1, indicates that
+				 * text is an ASCIZ string that the length
+				 * should be computed with strlen. */
+    unsigned int *widthPtr, 
+    unsigned int *heightPtr)
+{
+    unsigned int lineHeight;
+
+    if (text == NULL) {
+	return;			/* NULL string? */
+    }
+    {
+	Blt_FontMetrics fm;
+
+	Blt_GetFontMetrics(font, &fm);
+	lineHeight = fm.linespace;
+    }
+    if (textLen < 0) {
+	textLen = strlen(text);
+    }
+    { 
+	unsigned int lineLen;		/* # of characters on each line */
+	const char *p, *pend;
+	const char *line;
+	unsigned int maxWidth, maxHeight;
+
+	maxWidth = maxHeight = 0;
+	lineLen = 0;
+	for (p = line = text, pend = text + textLen; p < pend; p++) {
+	    if (*p == '\n') {
+		if (lineLen > 0) {
+		    unsigned int lineWidth;
+		    
+		    lineWidth = Blt_TextWidth(font, line, lineLen);
+		    if (lineWidth > maxWidth) {
+			maxWidth = lineWidth;
+		    }
+		}
+		maxHeight += lineHeight;
+		line = p + 1;	/* Point to the start of the next line. */
+		lineLen = 0;	/* Reset counter to indicate the start of a
+				 * new line. */
+		continue;
+	    }
+	    lineLen++;
+	}
+	if ((lineLen > 0) && (*(p - 1) != '\n')) {
+	    unsigned int lineWidth;
+	    
+	    maxHeight += lineHeight;
+	    lineWidth = Blt_TextWidth(font, line, lineLen);
+	    if (lineWidth > maxWidth) {
+		maxWidth = lineWidth;
+	    }
+	}
+	*widthPtr = maxWidth;
+	*heightPtr = maxHeight;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Ts_GetExtents --
+ *
+ *	Get the extents of a possibly multiple-lined text string.
+ *
+ * Results:
+ *	Returns via *widthPtr* and *heightPtr* the dimensions of
+ *	the text string.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Ts_GetExtents(TextStyle *tsPtr, const char *text, unsigned int *widthPtr, 
+		  unsigned int *heightPtr)
+{
+
+    if (text == NULL) {
+	*widthPtr = *heightPtr = 0;
+    } else {
+	unsigned int w, h;
+
+	Blt_GetTextExtents(tsPtr->font, tsPtr->leader, text, -1, &w, &h);
+	*widthPtr = w + PADDING(tsPtr->xPad);
+	*heightPtr = h + PADDING(tsPtr->yPad);
+    } 
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetBoundingBox
+ *
+ *	Computes the dimensions of the bounding box surrounding a rectangle
+ *	rotated about its center.  If pointArr isn't NULL, the coordinates of
+ *	the rotated rectangle are also returned.
+ *
+ *	The dimensions are determined by rotating the rectangle, and doubling
+ *	the maximum x-coordinate and y-coordinate.
+ *
+ *		w = 2 * maxX,  h = 2 * maxY
+ *
+ *	Since the rectangle is centered at 0,0, the coordinates of the
+ *	bounding box are (-w/2,-h/2 w/2,-h/2, w/2,h/2 -w/2,h/2).
+ *
+ *  		0 ------- 1
+ *  		|         |
+ *  		|    x    |
+ *  		|         |
+ *  		3 ------- 2
+ *
+ * Results:
+ *	The width and height of the bounding box containing the rotated
+ *	rectangle are returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_GetBoundingBox(
+    int width, int height,	/* Unrotated region */
+    float angle,		/* Rotation of box */
+    double *rotWidthPtr, 
+    double *rotHeightPtr,	/* (out) Bounding box region */
+    Point2d *bbox)		/* (out) Points of the rotated box */
+{
+    int i;
+    double sinTheta, cosTheta;
+    double radians;
+    double xMax, yMax;
+    double x, y;
+    Point2d corner[4];
+
+    angle = fmod(angle, 360.0);
+    if (fmod(angle, (double)90.0) == 0.0) {
+	int ll, ur, ul, lr;
+	double rotWidth, rotHeight;
+	int quadrant;
+
+	/* Handle right-angle rotations specially. */
+
+	quadrant = (int)(angle / 90.0);
+	switch (quadrant) {
+	case ROTATE_270:	/* 270 degrees */
+	    ul = 3, ur = 0, lr = 1, ll = 2;
+	    rotWidth = (double)height;
+	    rotHeight = (double)width;
+	    break;
+	case ROTATE_90:		/* 90 degrees */
+	    ul = 1, ur = 2, lr = 3, ll = 0;
+	    rotWidth = (double)height;
+	    rotHeight = (double)width;
+	    break;
+	case ROTATE_180:	/* 180 degrees */
+	    ul = 2, ur = 3, lr = 0, ll = 1;
+	    rotWidth = (double)width;
+	    rotHeight = (double)height;
+	    break;
+	default:
+	case ROTATE_0:		/* 0 degrees */
+	    ul = 0, ur = 1, lr = 2, ll = 3;
+	    rotWidth = (double)width;
+	    rotHeight = (double)height;
+	    break;
+	}
+	if (bbox != NULL) {
+	    x = rotWidth * 0.5;
+	    y = rotHeight * 0.5;
+	    bbox[ll].x = bbox[ul].x = -x;
+	    bbox[ur].y = bbox[ul].y = -y;
+	    bbox[lr].x = bbox[ur].x = x;
+	    bbox[ll].y = bbox[lr].y = y;
+	}
+	*rotWidthPtr = rotWidth;
+	*rotHeightPtr = rotHeight;
+	return;
+    }
+    /* Set the four corners of the rectangle whose center is the origin. */
+    corner[1].x = corner[2].x = (double)width * 0.5;
+    corner[0].x = corner[3].x = -corner[1].x;
+    corner[2].y = corner[3].y = (double)height * 0.5;
+    corner[0].y = corner[1].y = -corner[2].y;
+
+    radians = (-angle / 180.0) * M_PI;
+    sinTheta = sin(radians), cosTheta = cos(radians);
+    xMax = yMax = 0.0;
+
+    /* Rotate the four corners and find the maximum X and Y coordinates */
+
+    for (i = 0; i < 4; i++) {
+	x = (corner[i].x * cosTheta) - (corner[i].y * sinTheta);
+	y = (corner[i].x * sinTheta) + (corner[i].y * cosTheta);
+	if (x > xMax) {
+	    xMax = x;
+	}
+	if (y > yMax) {
+	    yMax = y;
+	}
+	if (bbox != NULL) {
+	    bbox[i].x = x;
+	    bbox[i].y = y;
+	}
+    }
+
+    /*
+     * By symmetry, the width and height of the bounding box are twice the
+     * maximum x and y coordinates.
+     */
+    *rotWidthPtr = xMax + xMax;
+    *rotHeightPtr = yMax + yMax;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_TranslateAnchor --
+ *
+ * 	Translate the coordinates of a given bounding box based upon the
+ * 	anchor specified.  The anchor indicates where the given x-y position
+ * 	is in relation to the bounding box.
+ *
+ *  		nw --- n --- ne
+ *  		|            |
+ *  		w   center   e
+ *  		|            |
+ *  		sw --- s --- se
+ *
+ * 	The coordinates returned are translated to the origin of the bounding
+ * 	box (suitable for giving to XCopyArea, XCopyPlane, etc.)
+ *
+ * Results:
+ *	The translated coordinates of the bounding box are returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_TranslateAnchor(
+    int x, int y,		/* Window coordinates of anchor */
+    int w, int h,		/* Extents of the bounding box */
+    Tk_Anchor anchor,		/* Direction of the anchor */
+    int *xPtr, int *yPtr)
+{
+    switch (anchor) {
+    case TK_ANCHOR_NW:		/* Upper left corner */
+	break;
+    case TK_ANCHOR_W:		/* Left center */
+	y -= (h / 2);
+	break;
+    case TK_ANCHOR_SW:		/* Lower left corner */
+	y -= h;
+	break;
+    case TK_ANCHOR_N:		/* Top center */
+	x -= (w / 2);
+	break;
+    case TK_ANCHOR_CENTER:	/* Center */
+	x -= (w / 2);
+	y -= (h / 2);
+	break;
+    case TK_ANCHOR_S:		/* Bottom center */
+	x -= (w / 2);
+	y -= h;
+	break;
+    case TK_ANCHOR_NE:		/* Upper right corner */
+	x -= w;
+	break;
+    case TK_ANCHOR_E:		/* Right center */
+	x -= w;
+	y -= (h / 2);
+	break;
+    case TK_ANCHOR_SE:		/* Lower right corner */
+	x -= w;
+	y -= h;
+	break;
+    }
+    *xPtr = x;
+    *yPtr = y;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_AnchorPoint --
+ *
+ * 	Translates a position, using both the dimensions of the bounding box,
+ * 	and the anchor direction, returning the coordinates of the upper-left
+ * 	corner of the box. The anchor indicates where the given x-y position
+ * 	is in relation to the bounding box.
+ *
+ *  		nw --- n --- ne
+ *  		|            |
+ *  		w   center   e
+ *  		|            |
+ *  		sw --- s --- se
+ *
+ * 	The coordinates returned are translated to the origin of the bounding
+ * 	box (suitable for giving to XCopyArea, XCopyPlane, etc.)
+ *
+ * Results:
+ *	The translated coordinates of the bounding box are returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+Point2d
+Blt_AnchorPoint(
+    double x, double y,		/* Coordinates of anchor. */
+    double w, double h,		/* Extents of the bounding box */
+    Tk_Anchor anchor)		/* Direction of the anchor */
+{
+    Point2d t;
+
+    switch (anchor) {
+    case TK_ANCHOR_NW:		/* Upper left corner */
+	break;
+    case TK_ANCHOR_W:		/* Left center */
+	y -= (h * 0.5);
+	break;
+    case TK_ANCHOR_SW:		/* Lower left corner */
+	y -= h;
+	break;
+    case TK_ANCHOR_N:		/* Top center */
+	x -= (w * 0.5);
+	break;
+    case TK_ANCHOR_CENTER:	/* Center */
+	x -= (w * 0.5);
+	y -= (h * 0.5);
+	break;
+    case TK_ANCHOR_S:		/* Bottom center */
+	x -= (w * 0.5);
+	y -= h;
+	break;
+    case TK_ANCHOR_NE:		/* Upper right corner */
+	x -= w;
+	break;
+    case TK_ANCHOR_E:		/* Right center */
+	x -= w;
+	y -= (h * 0.5);
+	break;
+    case TK_ANCHOR_SE:		/* Lower right corner */
+	x -= w;
+	y -= h;
+	break;
+    }
+    t.x = x;
+    t.y = y;
+    return t;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Ts_CreateLayout --
+ *
+ *	Get the extents of a possibly multiple-lined text string.
+ *
+ * Results:
+ *	Returns via *widthPtr* and *heightPtr* the dimensions of the text
+ *	string.
+ *
+ *---------------------------------------------------------------------------
+ */
+TextLayout *
+Blt_Ts_CreateLayout(const char *text, int textLen, TextStyle *tsPtr)
+{
+    TextFragment *fp;
+    TextLayout *layoutPtr;
+    Blt_FontMetrics fm;
+    int count;			/* Count # of characters on each line */
+    int lineHeight;
+    size_t maxHeight, maxWidth;
+    size_t nFrags;
+    int width;			/* Running dimensions of the text */
+    const char *p, *endp, *start;
+    int i;
+    size_t size;
+
+    nFrags = 0;
+    endp = text + ((textLen < 0) ? strlen(text) : textLen);
+    for (p = text; p < endp; p++) {
+	if (*p == '\n') {
+	    nFrags++;
+	}
+    }
+    if ((p != text) && (*(p - 1) != '\n')) {
+	nFrags++;
+    }
+    size = sizeof(TextLayout) + (sizeof(TextFragment) * (nFrags - 1));
+
+    layoutPtr = calloc(1, size);
+    layoutPtr->nFrags = nFrags;
+
+    nFrags = count = 0;
+    width = maxWidth = 0;
+    maxHeight = tsPtr->padTop;
+    Blt_GetFontMetrics(tsPtr->font, &fm);
+    lineHeight = fm.linespace + tsPtr->leader;
+
+    fp = layoutPtr->fragments;
+    for (p = start = text; p < endp; p++) {
+	if (*p == '\n') {
+	    if (count > 0) {
+		width = Blt_TextWidth(tsPtr->font, start, count);
+		if (width > maxWidth) {
+		    maxWidth = width;
+		}
+	    } else {
+		width = 0;
+	    }
+	    fp->width = width;
+	    fp->count = count;
+	    fp->sy = fp->y = maxHeight + fm.ascent;
+	    fp->text = start;
+	    maxHeight += lineHeight;
+	    fp++;
+	    nFrags++;
+	    start = p + 1;	/* Start the text on the next line */
+	    count = 0;		/* Reset to indicate the start of a new
+				 * line */
+	    continue;
+	}
+	count++;
+    }
+
+    if (nFrags < layoutPtr->nFrags) {
+	width = Blt_TextWidth(tsPtr->font, start, count);
+	if (width > maxWidth) {
+	    maxWidth = width;
+	}
+	fp->width = width;
+	fp->count = count;
+	fp->sy = fp->y = maxHeight + fm.ascent;
+	fp->text = start;
+	maxHeight += lineHeight;
+	nFrags++;
+    }
+    maxHeight += tsPtr->padBottom;
+    maxWidth += PADDING(tsPtr->xPad);
+    fp = layoutPtr->fragments;
+    for (i = 0; i < nFrags; i++, fp++) {
+	switch (tsPtr->justify) {
+	default:
+	case TK_JUSTIFY_LEFT:
+	    /* No offset for left justified text strings */
+	    fp->x = fp->sx = tsPtr->padLeft;
+	    break;
+	case TK_JUSTIFY_RIGHT:
+	    fp->x = fp->sx = (maxWidth - fp->width) - tsPtr->padRight;
+	    break;
+	case TK_JUSTIFY_CENTER:
+	    fp->x = fp->sx = (maxWidth - fp->width) / 2;
+	    break;
+	}
+    }
+    if (tsPtr->underline >= 0) {
+	fp = layoutPtr->fragments;
+	for (i = 0; i < nFrags; i++, fp++) {
+	    int first, last;
+
+	    first = fp->text - text;
+	    last = first + fp->count;
+	    if ((tsPtr->underline >= first) && (tsPtr->underline < last)) {
+		layoutPtr->underlinePtr = fp;
+		layoutPtr->underline = tsPtr->underline - first;
+		break;
+	    }
+	}
+    }
+    layoutPtr->width = maxWidth;
+    layoutPtr->height = maxHeight - tsPtr->leader;
+    return layoutPtr;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DrawCharsWithEllipsis --
+ *
+ *	Draw a string of characters on the screen.  Blt_DrawChars()
+ *	expands control characters that occur in the string to 
+ *	\xNN sequences.  
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Information gets drawn on the screen.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_DrawCharsWithEllipsis(
+    Tk_Window tkwin,		/* Display on which to draw. */
+    Drawable drawable,		/* Window or pixmap in which to draw. */
+    GC gc,			/* Graphics context for drawing characters. */
+    Blt_Font font,		/* Font in which characters will be drawn;
+				 * must be the same as font used in GC. */
+    int depth,
+    float angle,
+    const char *text,		/* UTF-8 string to be displayed.  Need not be
+				 * '\0' terminated.  All Tk meta-characters
+				 * (tabs, control characters, and newlines)
+				 * should be stripped out of the string that
+				 * is passed to this function.  If they are
+				 * not stripped out, they will be displayed as
+				 * regular printing characters. */
+    int textLen,		/* # of bytes to draw in text string. */
+    int x, int y,		/* Coordinates at which to place origin of
+				 * string when drawing. */
+    int maxLength)
+{
+    int elWidth;
+    const char *s, *send;
+    Tcl_DString dString;
+    int nBytes;
+    int accum, threshold;
+
+#if HAVE_UTF
+    Tcl_UniChar ch;
+#endif /* HAVE_UTF */
+    accum = 0;
+    elWidth = Blt_TextWidth(font, "...", 3);
+    if (maxLength < elWidth) {
+	return;
+    }
+    threshold = maxLength - elWidth;
+    Tcl_DStringInit(&dString);
+#if !HAVE_UTF
+    nBytes = 1;
+#endif /* !HAVE_UTF */
+    for (s = text, send = s + textLen; s < send; s += nBytes) {
+#if HAVE_UTF
+	nBytes =  Tcl_UtfToUniChar (s, &ch);
+#endif /* HAVE_UTF */
+	accum += Blt_TextWidth(font, s, nBytes);
+	if (accum > threshold) {
+	    break;
+	}
+	Tcl_DStringAppend(&dString, s, nBytes);
+    }
+    if (s < send) {
+	Tcl_DStringAppend(&dString, "...", 3);
+    }
+    Blt_DrawChars(Tk_Display(tkwin), drawable, gc, font, depth, angle, 
+	Tcl_DStringValue(&dString), Tcl_DStringLength(&dString), x, y);
+    Tcl_DStringFree(&dString);
+}
+
+void
+Blt_DrawLayout(Tk_Window tkwin, Drawable drawable, GC gc, Blt_Font font,
+	       int depth, float angle, int x, int y, TextLayout *layoutPtr,
+	       int maxLength)
+{
+    TextFragment *fp, *fend;
+    Blt_FontMetrics fm;
+
+    Blt_GetFontMetrics(font, &fm);
+    for (fp = layoutPtr->fragments, fend = fp + layoutPtr->nFrags; 
+	 fp < fend; fp++) {
+	int sx, sy;
+
+	sx = x + fp->sx, sy = y + fp->sy;
+	if ((maxLength > 0) && ((fp->width + fp->x) > maxLength)) {
+	    Blt_DrawCharsWithEllipsis(tkwin, drawable, gc, font, depth, angle, 
+		fp->text, fp->count, sx, sy, maxLength - fp->x);
+	} else {
+ 	    Blt_DrawChars(Tk_Display(tkwin), drawable, gc, font, depth, angle, 
+		fp->text, fp->count, sx, sy);
+	}
+    }
+    if (layoutPtr->underlinePtr != NULL) {
+	fp = layoutPtr->underlinePtr;
+	Blt_UnderlineChars(Tk_Display(tkwin), drawable, gc, font, fp->text, 
+		fp->count, x + fp->sx, y + fp->sy, layoutPtr->underline, 
+		layoutPtr->underline + 1, maxLength);
+    }
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Ts_Bitmap --
+ *
+ *	Draw a bitmap, using the the given window coordinates as an anchor for
+ *	the text bounding box.
+ *
+ * Results:
+ *	Returns the bitmap representing the text string.
+ *
+ * Side Effects:
+ *	Bitmap is drawn using the given font and GC in the drawable at the
+ *	given coordinates, anchor, and rotation.
+ *
+ *---------------------------------------------------------------------------
+ */
+Pixmap
+Blt_Ts_Bitmap(
+    Tk_Window tkwin,
+    TextLayout *layoutPtr,		/* Text string to draw */
+    TextStyle *stylePtr,		/* Text attributes: rotation, color,
+					 * font, linespacing, justification,
+					 * etc. */
+    int *bmWidthPtr,
+    int *bmHeightPtr)			/* Extents of rotated text string */
+{
+    Pixmap bitmap;
+    GC gc;
+
+    /* Create a bitmap big enough to contain the text. */
+    bitmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_RootWindow(tkwin), 
+	layoutPtr->width, layoutPtr->height, 1);
+    assert(bitmap != None);
+    if (bitmap == None) {
+	return None;		/* Can't allocate pixmap. */
+    }
+    gc = Blt_GetBitmapGC(tkwin);
+
+    /* Clear the bitmap.  Background is 0. */
+    XSetForeground(Tk_Display(tkwin), gc, 0);
+    XFillRectangle(Tk_Display(tkwin), bitmap, gc, 0, 0, layoutPtr->width, 
+	layoutPtr->height);
+
+    /* Draw the text into the bitmap. Foreground is 1. */
+    XSetFont(Tk_Display(tkwin), gc, Blt_FontId(stylePtr->font));
+    XSetForeground(Tk_Display(tkwin), gc, 1);
+    Blt_DrawLayout(tkwin, bitmap, gc, stylePtr->font, 1, 0.0f, 0, 0, layoutPtr, 
+	stylePtr->maxLength);
+    *bmWidthPtr = layoutPtr->width, *bmHeightPtr = layoutPtr->height;
+    return bitmap;
+}
+
+static void
+DrawStandardLayout(Tk_Window tkwin, Drawable drawable, TextStyle *stylePtr, 
+		   TextLayout *layoutPtr, int x, int y)			
+{
+    int w, h;
+    /*
+     * This is the easy case of no rotation. Simply draw the text
+     * using the standard drawing routines.  Handle offset printing
+     * for engraved (disabled) text.
+     */
+    w = layoutPtr->width;
+    h = layoutPtr->height;
+    if ((stylePtr->maxLength > 0) && (stylePtr->maxLength < w)) {
+	w = stylePtr->maxLength;
+    }
+    Blt_TranslateAnchor(x, y, w, h, stylePtr->anchor, &x, &y);
+    if (stylePtr->state & (STATE_DISABLED | STATE_EMPHASIS)) {
+	TkBorder *borderPtr = (TkBorder *) Blt_BackgroundBorder(stylePtr->bg);
+	XColor *color1, *color2;
+
+	color1 = borderPtr->lightColorPtr, color2 = borderPtr->darkColorPtr;
+	if (stylePtr->state & STATE_EMPHASIS) {
+	    XColor *hold;
+	    
+	    hold = color1, color1 = color2, color2 = hold;
+	}
+	if (color1 != NULL) {
+	    XSetForeground(Tk_Display(tkwin), stylePtr->gc, color1->pixel);
+	}
+	Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, 
+		Tk_Depth(tkwin), 0.0f, x+1, y+1, layoutPtr,stylePtr->maxLength);
+	if (color2 != NULL) {
+	    XSetForeground(Tk_Display(tkwin), stylePtr->gc, color2->pixel);
+	}
+	Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, 
+		Tk_Depth(tkwin), 0.0f, x, y, layoutPtr, stylePtr->maxLength);
+	
+	/* Reset the foreground color back to its original setting, so not to
+	 * invalidate the GC cache. */
+	XSetForeground(Tk_Display(tkwin), stylePtr->gc, stylePtr->color->pixel);
+	
+	return;		/* Done */
+    }
+    Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, 
+	Tk_Depth(tkwin), 0.0f, x, y, layoutPtr, stylePtr->maxLength);
+}
+
+
+static void
+RotateStartingTextPositions(TextLayout *lPtr, int w, int h, float angle)
+{
+    Point2d off1, off2;
+    TextFragment *fp, *fend;
+    double radians;
+    double rw, rh;
+    double sinTheta, cosTheta;
+    
+    Blt_GetBoundingBox(w, h, angle, &rw, &rh, (Point2d *)NULL);
+    off1.x = (double)w * 0.5;
+    off1.y = (double)h * 0.5;
+    off2.x = rw * 0.5;
+    off2.y = rh * 0.5;
+    radians = (-angle / 180.0) * M_PI;
+    
+    sinTheta = sin(radians), cosTheta = cos(radians);
+    for (fp = lPtr->fragments, fend = fp + lPtr->nFrags; fp < fend; fp++) {
+	Point2d p, q;
+	
+	p.x = fp->x - off1.x;
+	p.y = fp->y - off1.y;
+	q.x = (p.x * cosTheta) - (p.y * sinTheta);
+	q.y = (p.x * sinTheta) + (p.y * cosTheta);
+	q.x += off2.x;
+	q.y += off2.y;
+	fp->sx = ROUND(q.x);
+	fp->sy = ROUND(q.y);
+    }
+}
+
+void
+Blt_RotateStartingTextPositions(TextLayout *lPtr, float angle)
+{
+    RotateStartingTextPositions(lPtr, lPtr->width, lPtr->height, angle);
+}
+
+int
+Blt_DrawTextWithRotatedFont(Tk_Window tkwin, Drawable drawable, float angle,
+			    TextStyle *stylePtr, TextLayout *layoutPtr, 
+			    int x, int y)
+{
+    double rw, rh;
+    int w, h;
+
+    w = layoutPtr->width;
+    h = layoutPtr->height;
+    if ((stylePtr->maxLength > 0) && (stylePtr->maxLength < w)) {
+	w = stylePtr->maxLength;
+    }
+    RotateStartingTextPositions(layoutPtr, w, h, angle);
+    Blt_GetBoundingBox(w, h, angle, &rw, &rh, (Point2d *)NULL);
+    Blt_TranslateAnchor(x, y, (int)rw, (int)rh, stylePtr->anchor, &x, &y);
+    if (stylePtr->state & (STATE_DISABLED | STATE_EMPHASIS)) {
+	TkBorder *borderPtr = (TkBorder *)Blt_BackgroundBorder(stylePtr->bg);
+	XColor *color1, *color2;
+	
+	color1 = borderPtr->lightColorPtr, color2 = borderPtr->darkColorPtr;
+	if (stylePtr->state & STATE_EMPHASIS) {
+	    XColor *hold;
+	    
+	    hold = color1, color1 = color2, color2 = hold;
+	}
+	if (color1 != NULL) {
+	    XSetForeground(Tk_Display(tkwin), stylePtr->gc, color1->pixel);
+	    Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, 
+		Tk_Depth(tkwin), angle, x, y, layoutPtr, stylePtr->maxLength); 
+	}
+	if (color2 != NULL) {
+	    XSetForeground(Tk_Display(tkwin), stylePtr->gc, color2->pixel);
+	    Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, 
+		Tk_Depth(tkwin), angle, x, y, layoutPtr, stylePtr->maxLength); 
+	}
+	XSetForeground(Tk_Display(tkwin), stylePtr->gc, stylePtr->color->pixel);
+	return TRUE;
+    }
+    XSetForeground(Tk_Display(tkwin), stylePtr->gc, stylePtr->color->pixel);
+    Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, 
+	Tk_Depth(tkwin), angle, x, y, layoutPtr, stylePtr->maxLength); 
+    return TRUE;
+}
+
+static void
+Blt_DrawTextWithRotatedBitmap(
+    Tk_Window tkwin,
+    Drawable drawable,
+    float angle,
+    TextStyle *stylePtr,		/* Text attribute information */
+    TextLayout *layoutPtr,
+    int x, int y)			/* Window coordinates to draw text */
+{
+    int width, height;
+    Display *display;
+    Pixmap bitmap;
+
+    display = Tk_Display(tkwin);
+    /*
+     * Rotate the text by writing the text into a bitmap and rotating the
+     * bitmap.  Set the clip mask and origin in the GC first.  And make sure
+     * we restore the GC because it may be shared.
+     */
+    stylePtr->angle = angle;
+
+    bitmap = Blt_Ts_Bitmap(tkwin, layoutPtr, stylePtr, &width, &height);
+    if (bitmap == None) {
+	return;
+    }
+    if ((bitmap != None) && (stylePtr->angle != 0.0)) {
+	Pixmap rotated;
+
+	rotated = Blt_RotateBitmap(tkwin, bitmap, width, height, 
+		stylePtr->angle, &width, &height);
+	Tk_FreePixmap(display, bitmap);
+	bitmap = rotated;
+    }
+    Blt_TranslateAnchor(x, y, width, height, stylePtr->anchor, &x, &y);
+    XSetClipMask(display, stylePtr->gc, bitmap);
+
+    if (stylePtr->state & (STATE_DISABLED | STATE_EMPHASIS)) {
+	TkBorder *borderPtr = (TkBorder *) Blt_BackgroundBorder(stylePtr->bg);
+	XColor *color1, *color2;
+
+	color1 = borderPtr->lightColorPtr, color2 = borderPtr->darkColorPtr;
+	if (stylePtr->state & STATE_EMPHASIS) {
+	    XColor *hold;
+
+	    hold = color1, color1 = color2, color2 = hold;
+	}
+	if (color1 != NULL) {
+	    XSetForeground(display, stylePtr->gc, color1->pixel);
+	}
+	XSetClipOrigin(display, stylePtr->gc, x + 1, y + 1);
+	XCopyPlane(display, bitmap, drawable, stylePtr->gc, 0, 0, width, 
+		height, x + 1, y + 1, 1);
+	if (color2 != NULL) {
+	    XSetForeground(display, stylePtr->gc, color2->pixel);
+	}
+	XSetClipOrigin(display, stylePtr->gc, x, y);
+	XCopyPlane(display, bitmap, drawable, stylePtr->gc, 0, 0, width, 
+		height, x, y, 1);
+	XSetForeground(display, stylePtr->gc, stylePtr->color->pixel);
+    } else {
+	XSetForeground(display, stylePtr->gc, stylePtr->color->pixel);
+	XSetClipOrigin(display, stylePtr->gc, x, y);
+	XCopyPlane(display, bitmap, drawable, stylePtr->gc, 0, 0, width, height, 
+		x, y, 1);
+    }
+    XSetClipMask(display, stylePtr->gc, None);
+    Tk_FreePixmap(display, bitmap);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Ts_DrawLayout --
+ *
+ *	Draw a text string, possibly rotated, using the the given window
+ *	coordinates as an anchor for the text bounding box.  If the text is
+ *	not rotated, simply use the X text drawing routines. Otherwise,
+ *	generate a bitmap of the rotated text.
+ *
+ * Results:
+ *	Returns the x-coordinate to the right of the text.
+ *
+ * Side Effects:
+ *	Text string is drawn using the given font and GC at the the given
+ *	window coordinates.
+ *
+ *      The Stipple, FillStyle, and TSOrigin fields of the GC are modified for
+ *      rotated text.  This assumes the GC is private, *not* shared (via
+ *      Tk_GetGC)
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Ts_DrawLayout(
+    Tk_Window tkwin,
+    Drawable drawable,
+    TextLayout *layoutPtr,
+    TextStyle *stylePtr,		/* Text attribute information */
+    int x, int y)			/* Window coordinates to draw text */
+{
+    float angle;
+
+    if ((stylePtr->gc == NULL) || (stylePtr->flags & UPDATE_GC)) {
+	Blt_Ts_ResetStyle(tkwin, stylePtr);
+    }
+    angle = (float)fmod(stylePtr->angle, 360.0);
+    if (angle < 0.0) {
+	angle += 360.0;
+    }
+    if (angle == 0.0) {
+	/*
+	 * This is the easy case of no rotation. Simply draw the text using
+	 * the standard drawing routines.  Handle offset printing for engraved
+	 * (disabled) text.
+	 */
+	DrawStandardLayout(tkwin, drawable, stylePtr, layoutPtr, x, y);
+	return;
+    }
+    if (Blt_CanRotateFont(stylePtr->font, angle)) {
+	if (Blt_DrawTextWithRotatedFont(tkwin, drawable, angle, stylePtr, 
+		layoutPtr, x, y)) {
+	    return;		/* Success. */
+	}
+    }
+    /*Fallthru*/
+    stylePtr->angle = (float)angle;
+    Blt_DrawTextWithRotatedBitmap(tkwin, drawable, angle, stylePtr, layoutPtr,
+		x, y);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Ts_DrawLayout --
+ *
+ *	Draw a text string, possibly rotated, using the the given window
+ *	coordinates as an anchor for the text bounding box.  If the text is
+ *	not rotated, simply use the X text drawing routines. Otherwise,
+ *	generate a bitmap of the rotated text.
+ *
+ * Results:
+ *	Returns the x-coordinate to the right of the text.
+ *
+ * Side Effects:
+ *	Text string is drawn using the given font and GC at the the given
+ *	window coordinates.
+ *
+ *      The Stipple, FillStyle, and TSOrigin fields of the GC are modified for
+ *      rotated text.  This assumes the GC is private, *not* shared (via
+ *      Tk_GetGC)
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Ts_DrawText(
+    Tk_Window tkwin,
+    Drawable drawable,
+    const char *text,
+    int textLen,
+    TextStyle *stylePtr,		/* Text attribute information */
+    int x, int y)			/* Window coordinates to draw text */
+{
+    TextLayout *layoutPtr;
+
+    layoutPtr = Blt_Ts_CreateLayout(text, textLen, stylePtr);
+    Blt_Ts_DrawLayout(tkwin, drawable, layoutPtr, stylePtr, x, y);
+    free(layoutPtr);
+}
+
+void
+Blt_DrawText2(
+    Tk_Window tkwin,
+    Drawable drawable,
+    const char *string,
+    TextStyle *stylePtr,		/* Text attribute information */
+    int x, int y,		/* Window coordinates to draw text */
+    Dim2D *areaPtr)
+{
+    TextLayout *layoutPtr;
+    int width, height;
+    float angle;
+
+    if ((string == NULL) || (*string == '\0')) {
+	return;			/* Empty string, do nothing */
+    }
+    layoutPtr = Blt_Ts_CreateLayout(string, -1, stylePtr);
+    Blt_Ts_DrawLayout(tkwin, drawable, layoutPtr, stylePtr, x, y);
+    angle = fmod(stylePtr->angle, 360.0);
+    if (angle < 0.0) {
+	angle += 360.0;
+    }
+    width = layoutPtr->width;
+    height = layoutPtr->height;
+    if (angle != 0.0) {
+	double rotWidth, rotHeight;
+
+	Blt_GetBoundingBox(width, height, angle, &rotWidth, &rotHeight, 
+	   (Point2d *)NULL);
+	width = ROUND(rotWidth);
+	height = ROUND(rotHeight);
+    }
+    areaPtr->width = width;
+    areaPtr->height = height;
+    free(layoutPtr);
+}
+
+void
+Blt_DrawText(
+    Tk_Window tkwin,
+    Drawable drawable,
+    const char *string,
+    TextStyle *stylePtr,		/* Text attribute information */
+    int x, int y)		/* Window coordinates to draw text */
+{
+    TextLayout *layoutPtr;
+
+    if ((string == NULL) || (*string == '\0')) {
+	return;			/* Empty string, do nothing */
+    }
+    layoutPtr = Blt_Ts_CreateLayout(string, -1, stylePtr);
+    Blt_Ts_DrawLayout(tkwin, drawable, layoutPtr, stylePtr, x, y);
+    free(layoutPtr);
+}
+
+void
+Blt_Ts_ResetStyle(Tk_Window tkwin, TextStyle *stylePtr)
+{
+    GC newGC;
+    XGCValues gcValues;
+    unsigned long gcMask;
+
+    gcMask = GCFont;
+    gcValues.font = Blt_FontId(stylePtr->font);
+    if (stylePtr->color != NULL) {
+	gcMask |= GCForeground;
+	gcValues.foreground = stylePtr->color->pixel;
+    }
+    newGC = Tk_GetGC(tkwin, gcMask, &gcValues);
+    if (stylePtr->gc != NULL) {
+	Tk_FreeGC(Tk_Display(tkwin), stylePtr->gc);
+    }
+    stylePtr->gc = newGC;
+    stylePtr->flags &= ~UPDATE_GC;
+}
+
+void
+Blt_Ts_FreeStyle(Display *display, TextStyle *stylePtr)
+{
+    if (stylePtr->gc != NULL) {
+	Tk_FreeGC(display, stylePtr->gc);
+    }
+}
+
+/*
+ * The following two structures are used to keep track of string
+ * measurement information when using the text layout facilities.
+ *
+ * A LayoutChunk represents a contiguous range of text that can be measured
+ * and displayed by low-level text calls.  In general, chunks will be
+ * delimited by newlines and tabs.  Low-level, platform-specific things
+ * like kerning and non-integer character widths may occur between the
+ * characters in a single chunk, but not between characters in different
+ * chunks.
+ *
+ * A TextLayout is a collection of LayoutChunks.  It can be displayed with
+ * respect to any origin.  It is the implementation of the Tk_TextLayout
+ * opaque token.
+ */
+
+typedef struct LayoutChunk {
+    const char *start;		/* Pointer to simple string to be displayed.
+				 * This is a pointer into the TkTextLayout's
+				 * string. */
+    int numBytes;		/* The number of bytes in this chunk. */
+    int numChars;		/* The number of characters in this chunk. */
+    int numDisplayChars;	/* The number of characters to display when
+				 * this chunk is displayed.  Can be less than
+				 * numChars if extra space characters were
+				 * absorbed by the end of the chunk.  This
+				 * will be < 0 if this is a chunk that is
+				 * holding a tab or newline. */
+    int x, y;			/* The origin of the first character in this
+				 * chunk with respect to the upper-left hand
+				 * corner of the TextLayout. */
+    int totalWidth;		/* Width in pixels of this chunk.  Used
+				 * when hit testing the invisible spaces at
+				 * the end of a chunk. */
+    int displayWidth;		/* Width in pixels of the displayable
+				 * characters in this chunk.  Can be less than
+				 * width if extra space characters were
+				 * absorbed by the end of the chunk. */
+} LayoutChunk;
+
+typedef struct TkTextLayout {
+    Blt_Font font;		/* The font used when laying out the text. */
+    const char *string;		/* The string that was layed out. */
+    int width;			/* The maximum width of all lines in the
+				 * text layout. */
+    int numChunks;		/* Number of chunks actually used in
+				 * following array. */
+    LayoutChunk chunks[1];	/* Array of chunks.  The actual size will
+				 * be maxChunks.  THIS FIELD MUST BE THE LAST
+				 * IN THE STRUCTURE. */
+} TkTextLayout;
+
+

+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FreeTextLayout --
+ *
+ *	This procedure is called to release the storage associated with
+ *	a Tk_TextLayout when it is no longer needed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+Blt_FreeTextLayout(Tk_TextLayout textLayout)
+{
+    TkTextLayout *layoutPtr = (TkTextLayout *) textLayout;
+
+    if (layoutPtr != NULL) {
+	free(layoutPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tk_CharBbox --
+ *
+ *	Use the information in the Tk_TextLayout token to return the
+ *	bounding box for the character specified by index.  
+ *
+ *	The width of the bounding box is the advance width of the
+ *	character, and does not include and left- or right-bearing.
+ *	Any character that extends partially outside of the
+ *	text layout is considered to be truncated at the edge.  Any
+ *	character which is located completely outside of the text
+ *	layout is considered to be zero-width and pegged against
+ *	the edge.
+ *
+ *	The height of the bounding box is the line height for this font,
+ *	extending from the top of the ascent to the bottom of the
+ *	descent.  Information about the actual height of the individual
+ *	letter is not available.
+ *
+ *	A text layout that contains no characters is considered to
+ *	contain a single zero-width placeholder character.
+ * 
+ * Results:
+ *	The return value is 0 if the index did not specify a character
+ *	in the text layout, or non-zero otherwise.  In that case,
+ *	*bbox is filled with the bounding box of the character.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Blt_CharBbox(
+    Tk_TextLayout layout,   /* Layout information, from a previous call to
+			     * Tk_ComputeTextLayout(). */
+    int index,		    /* The index of the character whose bbox is
+			     * desired. */
+    int *xPtr, int *yPtr,    /* Filled with the upper-left hand corner, in
+			     * pixels, of the bounding box for the character
+			     * specified by index, if non-NULL. */
+    int *widthPtr, 
+    int *heightPtr)	    /* Filled with the width and height of the
+			     * bounding box for the character specified by
+			     * index, if non-NULL. */
+{
+    TkTextLayout *layoutPtr;
+    LayoutChunk *chunkPtr;
+    int i, x, w;
+    Blt_Font font;
+    const char *end;
+    Blt_FontMetrics fm;
+
+    if (index < 0) {
+	return 0;
+    }
+
+    layoutPtr = (TkTextLayout *) layout;
+    chunkPtr = layoutPtr->chunks;
+    font = layoutPtr->font;
+
+    Blt_GetFontMetrics(font, &fm);
+    for (i = 0; i < layoutPtr->numChunks; i++) {
+	if (chunkPtr->numDisplayChars < 0) {
+	    if (index == 0) {
+		x = chunkPtr->x;
+		w = chunkPtr->totalWidth;
+		goto check;
+	    }
+	} else if (index < chunkPtr->numChars) {
+	    end = Tcl_UtfAtIndex(chunkPtr->start, index);
+	    if (xPtr != NULL) {
+		Blt_MeasureChars(font, chunkPtr->start,
+			end -  chunkPtr->start, -1, 0, &x);
+		x += chunkPtr->x;
+	    }
+	    if (widthPtr != NULL) {
+		Blt_MeasureChars(font, end, Tcl_UtfNext(end) - end, -1, 0, &w);
+	    }
+	    goto check;
+	}
+	index -= chunkPtr->numChars;
+	chunkPtr++;
+    }
+    if (index == 0) {
+	/*
+	 * Special case to get location just past last char in layout.
+	 */
+
+	chunkPtr--;
+	x = chunkPtr->x + chunkPtr->totalWidth;
+	w = 0;
+    } else {
+	return 0;
+    }
+
+    /*
+     * Ensure that the bbox lies within the text layout.  This forces all
+     * chars that extend off the right edge of the text layout to have
+     * truncated widths, and all chars that are completely off the right
+     * edge of the text layout to peg to the edge and have 0 width.
+     */
+    check:
+    if (yPtr != NULL) {
+	*yPtr = chunkPtr->y - fm.ascent;
+    }
+    if (heightPtr != NULL) {
+	*heightPtr = fm.ascent + fm.descent;
+    }
+
+    if (x > layoutPtr->width) {
+	x = layoutPtr->width;
+    }
+    if (xPtr != NULL) {
+	*xPtr = x;
+    }
+    if (widthPtr != NULL) {
+	if (x + w > layoutPtr->width) {
+	    w = layoutPtr->width - x;
+	}
+	*widthPtr = w;
+    }
+
+    return 1;
+}
+
diff --git a/tlt3.0/bltText.h b/tlt3.0/bltText.h
new file mode 100644
index 0000000..f59953b
--- /dev/null
+++ b/tlt3.0/bltText.h
@@ -0,0 +1,240 @@
+/*
+ * bltText.h --
+ *
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_TEXT_H
+#define _BLT_TEXT_H
+
+#include "bltBgStyle.h"
+
+#define DEF_TEXT_FLAGS (TK_PARTIAL_OK | TK_IGNORE_NEWLINES)
+#define UPDATE_GC	1
+
+/*
+ * TextFragment --
+ */
+typedef struct {
+    const char *text;			/* Text string to be displayed */
+
+    size_t count;			/* Number of bytes in text. The actual
+					 * character count may differ because of
+					 * multi-byte UTF encodings. */
+
+    short x, y;				/* X-Y offset of the baseline from the
+					 * upper-left corner of the bbox. */
+
+    short sx, sy;			/* Starting offset of text using rotated
+					 * font. */
+
+    int width;				/* Width of segment in pixels. This
+					 * information is used to draw
+					 * PostScript strings the same width
+					 * as X. */
+} TextFragment;
+
+
+/*
+ * TextItem --
+ * 
+ *	Parsed form for markup string.  Each item is a scrap of text
+ *	describes the font, position, and characters to be displayed.
+ *	
+ *	subscript x_y  very small subset of latex markup.
+ *	superscript x^y
+ *	grouping a^{x+y} a_{i,j}
+ *	supersuper a^{10^8}
+ *	\hat{a} \bar{b} \vec{c}
+ *	\overline{} \underline{}
+ *	\frac \tfrac
+ *	\Alpha \Beta ...
+ *	\mathbf{} \mathit{} \mathrm{}  \boldsymbol{}
+ *	\angstrom \degree 
+ *
+ *	-mathtext instead of -text 
+ *
+ *	Can use TextItem where you don't directly edit the text:
+ *	  label, treeview, graph, barchart...
+ *
+ *	Font selector (bold, italic, size adjust) from base font.
+ *	Global font table reference counted. 
+ *
+ */
+typedef struct {
+    const char *text;			/* Text string to be displayed */
+
+    size_t count;			/* Number of bytes in text. The actual
+					 * character count may differ because of
+					 * multi-byte UTF encodings. */
+
+    short int x, y;			/* X-Y offset of the baseline from the
+					 * upper-left corner of the bbox. */
+
+    short int sx, sy;			/* Starting offset of text using rotated
+					 * font. */
+
+    Blt_Font font;			/* Allocated font for this chunk. 
+					 * If NULL, use the global font. */
+
+    int underline;			/* Text is underlined */
+
+    int width;				/* Width of segment in pixels. This
+					 * information is used to draw
+					 * PostScript strings the same width
+					 * as X. (deprecated) */
+} TextItem;
+
+/*
+ * TextLayout --
+ */
+typedef struct {
+    TextFragment *underlinePtr;
+    int underline;
+    size_t width, height;	/* Dimensions of text bounding box */
+    size_t nFrags;		/* # fragments of text */
+    TextFragment fragments[1];	/* Information about each fragment of text */
+} TextLayout;
+
+/*
+ * TextStyle --
+ *
+ * 	A somewhat convenient structure to hold text attributes that determine
+ * 	how a text string is to be displayed on the screen or drawn with
+ * 	PostScript commands.  The alternative is to pass lots of parameters to
+ * 	the drawing and printing routines. This seems like a more efficient
+ * 	and less cumbersome way of passing parameters.
+ */
+typedef struct {
+    unsigned int state;			/* If non-zero, indicates to draw text
+					 * in the active color */
+    XColor *color;			/* Color to draw the text. */
+    Blt_Font font;			/* Font to use to draw text */
+    Blt_Background bg;			/* Background color of text.  This is
+					 * also used for drawing disabled
+					 * text. */
+    float angle;			/* Rotation of text in degrees. */
+    Tk_Justify justify;			/* Justification of the text
+					 * string. This only matters if the
+					 * text is composed of multiple
+					 * lines. */
+    Tk_Anchor anchor;			/* Indicates how the text is anchored
+					 * around its x,y coordinates. */
+    Blt_Pad xPad, yPad;			/* # pixels padding of around text
+					 * region. */
+    unsigned short int leader;		/* # pixels spacing between lines of
+					 * text. */
+    short int underline;		/* Index of character to be underlined,
+					 * -1 if no underline. */
+    int maxLength;			/* Maximum length in pixels of text */
+    /* Private fields. */
+    unsigned short flags;
+    GC gc;			/* GC used to draw the text */
+} TextStyle;
+
+extern TextLayout *Blt_Ts_CreateLayout(const char *string, int length, 
+	TextStyle *tsPtr);
+
+extern void Blt_Ts_DrawLayout(Tk_Window tkwin, Drawable drawable, 
+	TextLayout *textPtr, TextStyle *tsPtr, int x, int y);
+
+extern void Blt_Ts_GetExtents(TextStyle *tsPtr, const char *text, 
+	unsigned int *widthPtr, unsigned int *heightPtr);
+
+extern void Blt_Ts_ResetStyle(Tk_Window tkwin, TextStyle *tsPtr);
+
+extern void Blt_Ts_FreeStyle(Display *display, TextStyle *tsPtr);
+
+extern void Blt_DrawText(Tk_Window tkwin, Drawable drawable, 
+	const char *string, TextStyle *tsPtr, int x, int y);
+
+extern void Blt_DrawText2(Tk_Window tkwin, Drawable drawable, 
+	const char *string, TextStyle *tsPtr, int x, int y, Dim2D * dimPtr);
+
+extern Pixmap Blt_Ts_Bitmap(Tk_Window tkwin, TextLayout *textPtr, 
+	TextStyle *tsPtr, int *widthPtr, int *heightPtr);
+
+extern int Blt_DrawTextWithRotatedFont(Tk_Window tkwin, Drawable drawable, 
+	float angle, TextStyle *tsPtr, TextLayout *textPtr, int x, int y);
+
+extern void Blt_DrawLayout(Tk_Window tkwin, Drawable drawable, GC gc, 
+	Blt_Font font, int depth, float angle, int x, int y, 
+	TextLayout *layoutPtr, int maxLength);
+
+extern void Blt_GetTextExtents(Blt_Font font, int leader, const char *text, 
+	int textLen, unsigned int *widthPtr, unsigned int *heightPtr);
+
+extern void Blt_RotateStartingTextPositions(TextLayout *textPtr,
+	float angle);
+
+extern int Blt_CharBbox(Tk_TextLayout layout, int index, int *xPtr, 
+	int *yPtr, int *widthPtr, int *heightPtr);
+
+extern void Blt_Ts_DrawText(Tk_Window tkwin, Drawable drawable, 
+	const char *text, int textLen, TextStyle *tsPtr, int x, int y);
+
+extern void Blt_FreeTextLayout(Tk_TextLayout layout);
+
+#define Blt_Ts_GetAnchor(ts)		((ts).anchor)
+#define Blt_Ts_GetAngle(ts)		((ts).angle)
+#define Blt_Ts_GetBackground(ts)	((ts).bg)
+#define Blt_Ts_GetFont(ts)		((ts).font)
+#define Blt_Ts_GetForeground(ts)	((ts).color)
+#define Blt_Ts_GetJustify(ts)		((ts).justify)
+#define Blt_Ts_GetLeader(ts)		((ts).leader)
+
+#define Blt_Ts_SetAnchor(ts, a)	((ts).anchor = (a))
+#define Blt_Ts_SetAngle(ts, r)		((ts).angle = (float)(r))
+#define Blt_Ts_SetBackground(ts, b)	((ts).bg = (b))
+#define Blt_Ts_SetFont(ts, f)		\
+	(((ts).font != (f)) ? ((ts).font = (f), (ts).flags |= UPDATE_GC) : 0)
+#define Blt_Ts_SetForeground(ts, c)    \
+	(((ts).color != (c)) ? ((ts).color = (c), (ts).flags |= UPDATE_GC) : 0)
+#define Blt_Ts_SetGC(ts, g)	((ts).gc = (g))
+#define Blt_Ts_SetJustify(ts, j)	((ts).justify = (j))
+#define Blt_Ts_SetLeader(ts, l)	((ts).leader = (l))
+#define Blt_Ts_SetMaxLength(ts, l)	((ts).maxLength = (l))
+#define Blt_Ts_SetPadding(ts, l, r, t, b)    \
+	((ts).xPad.side1 = (l), \
+	(ts).xPad.side2 = (r),  \
+	(ts).yPad.side1 = (t),  \
+	(ts).yPad.side2 = (b))
+#define Blt_Ts_SetState(ts, s)		((ts).state = (s))
+#define Blt_Ts_SetUnderline(ts, ul)	((ts).underline = (ul))
+
+#define Blt_Ts_InitStyle(ts)		\
+    ((ts).anchor = TK_ANCHOR_NW,	\
+     (ts).color = (XColor *)NULL,	\
+     (ts).font = NULL,			\
+     (ts).justify = TK_JUSTIFY_LEFT,	\
+     (ts).leader = 0,			\
+     (ts).underline = -1,		       \
+     (ts).xPad.side1 = (ts).xPad.side2 = 0,    \
+     (ts).yPad.side1 = (ts).yPad.side2 = 0,    \
+     (ts).state = 0,			       \
+     (ts).flags = 0,			       \
+     (ts).gc = NULL,			       \
+     (ts).maxLength = -1,		       \
+     (ts).angle = 0.0)
+
+#endif /* _BLT_TEXT_H */
diff --git a/tlt3.0/bltUnixFont.c b/tlt3.0/bltUnixFont.c
new file mode 100644
index 0000000..cdc1661
--- /dev/null
+++ b/tlt3.0/bltUnixFont.c
@@ -0,0 +1,2658 @@
+/*
+ * bltUnixFont.c --
+ *
+ * This module implements freetype (Xft) and Tk fonts for the BLT toolkit.
+ * 
+ * The Blt_Font is a wrapper around the existing Tk font structure, adding
+ * Freetype fonts (via the XRender extension).  The original Tk font
+ * procedures act as a fallback if a suitable Xft enabled server can't be
+ * found.
+ *
+ *	Copyright 2005 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+
+#ifdef HAVE_LIBXFT
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include <X11/Xft/Xft.h>
+#endif
+
+#include <tkPort.h>
+#include <tkInt.h>
+#include <tkFont.h>
+
+#include "bltInt.h"
+#include "bltHash.h"
+#include "bltFont.h"
+#include "bltPs.h"
+
+/*
+ * This module provides antialiased fonts via Freetype as now does Tk 8.5.
+ * This version also includes rotated fonts. No subfont matching is done to
+ * avoid rotating dozens of subfonts for every rotated font.  It's possible
+ * that glyphs may be missing that exist in the Tk version.  The trade-off
+ * seems fair when weighing the benefit of high-quality antialiased rotated
+ * fonts.
+ *
+ * Font rotation is done via the freetype font matrix for outline fonts.  For
+ * bitmap fonts we fall back on drawing the text into a bitmap and rotate the
+ * bitmap.  This requires depth-aware versions of Tk_DrawChars, since Xft is
+ * drawing into a drawable of a different depth (depth is 1).
+ * 
+ * The best tactic is to 1) not use bitmapped fonts if better outline fonts
+ * are available and 2) provide our own font handling routines that allow font
+ * rotation and font aliasing.  The font aliases allow us to use a font name
+ * like "Sans Serif" that translates into a good font for that platform and
+ * set of fonts available (Xft or Xlfd font).
+ */
+ 
+typedef struct _Blt_Font _Blt_Font;
+
+enum FontTypes { 
+    FONT_UNKNOWN, 		/* Unknown font type. */
+    FONT_TK, 			/* Normal Tk font. */
+    FONT_FT 			/* Freetype font. */
+};
+
+#ifndef HAVE_LIBXFT
+#define FC_WEIGHT_THIN		    0
+#define FC_WEIGHT_EXTRALIGHT	    40
+#define FC_WEIGHT_ULTRALIGHT	    FC_WEIGHT_EXTRALIGHT
+#define FC_WEIGHT_LIGHT		    50
+#define FC_WEIGHT_BOOK		    75
+#define FC_WEIGHT_REGULAR	    80
+#define FC_WEIGHT_NORMAL	    FC_WEIGHT_REGULAR
+#define FC_WEIGHT_MEDIUM	    100
+#define FC_WEIGHT_DEMIBOLD	    180
+#define FC_WEIGHT_SEMIBOLD	    FC_WEIGHT_DEMIBOLD
+#define FC_WEIGHT_BOLD		    200
+#define FC_WEIGHT_EXTRABOLD	    205
+#define FC_WEIGHT_ULTRABOLD	    FC_WEIGHT_EXTRABOLD
+#define FC_WEIGHT_BLACK		    210
+#define FC_WEIGHT_HEAVY		    FC_WEIGHT_BLACK
+#define FC_WEIGHT_EXTRABLACK	    215
+#define FC_WEIGHT_ULTRABLACK	    FC_WEIGHT_EXTRABLACK
+
+#define FC_SLANT_ROMAN		    0
+#define FC_SLANT_ITALIC		    100
+#define FC_SLANT_OBLIQUE	    110
+
+#define FC_WIDTH_ULTRACONDENSED	    50
+#define FC_WIDTH_EXTRACONDENSED	    63
+#define FC_WIDTH_CONDENSED	    75
+#define FC_WIDTH_SEMICONDENSED	    87
+#define FC_WIDTH_NORMAL		    100
+#define FC_WIDTH_SEMIEXPANDED	    113
+#define FC_WIDTH_EXPANDED	    125
+#define FC_WIDTH_EXTRAEXPANDED	    150
+#define FC_WIDTH_ULTRAEXPANDED	    200
+
+#define FC_PROPORTIONAL		    0
+#define FC_DUAL			    90
+#define FC_MONO			    100
+#define FC_CHARCELL		    110
+
+#define FC_ANTIALIAS	    "antialias"		/* Bool (depends) */
+#define FC_AUTOHINT	    "autohint"		/* Bool (false) */
+#define FC_DECORATIVE	    "decorative"	/* Bool  */
+#define FC_EMBEDDED_BITMAP  "embeddedbitmap"	/* Bool  */
+#define FC_EMBOLDEN	    "embolden"		/* Bool */
+#define FC_FAMILY	    "family"		/* String */
+#define FC_GLOBAL_ADVANCE   "globaladvance"	/* Bool (true) */
+#define FC_HINTING	    "hinting"		/* Bool (true) */
+#define FC_MINSPACE	    "minspace"		/* Bool */
+#define FC_OUTLINE	    "outline"		/* Bool */
+#define FC_SCALABLE	    "scalable"		/* Bool */
+#define FC_SIZE		    "size"		/* Double */
+#define FC_SLANT	    "slant"		/* Int */
+#define FC_SPACING	    "spacing"		/* Int */
+#define FC_STYLE	    "style"		/* String */
+#define FC_VERTICAL_LAYOUT  "verticallayout"	/* Bool (false) */
+#define FC_WEIGHT	    "weight"		/* Int */
+#define FC_WIDTH	    "width"		/* Int */
+
+#endif
+
+#ifndef FC_WEIGHT_EXTRABLACK
+#define FC_WEIGHT_EXTRABLACK	    215
+#define FC_WEIGHT_ULTRABLACK	    FC_WEIGHT_EXTRABLACK
+#endif
+
+typedef struct {
+    char *family;
+    const char *weight;
+    const char *slant;
+    const char *width;
+    const char *spacing;
+    int size;			/* If negative, pixels, else points */
+} TkFontPattern;
+
+typedef struct {
+    const char *name;
+    int minChars;
+    const char *key;
+    int value;
+    const char *oldvalue;
+} FontSpec;
+    
+static FontSpec fontSpecs[] = {
+    { "black",        2, FC_WEIGHT,  FC_WEIGHT_BLACK,     "*"},
+    { "bold",         3, FC_WEIGHT,  FC_WEIGHT_BOLD,      "bold"},
+    { "book",         3, FC_WEIGHT,  FC_WEIGHT_MEDIUM,	  "medium"},
+    { "charcell",     2, FC_SPACING, FC_CHARCELL,	  "c"},
+    { "condensed",    2, FC_WIDTH,   FC_WIDTH_CONDENSED,  "condensed"},
+    { "demi",         4, FC_WEIGHT,  FC_WEIGHT_BOLD,      "semi"},
+    { "demibold",     5, FC_WEIGHT,  FC_WEIGHT_DEMIBOLD,  "semibold"},
+    { "dual",         2, FC_SPACING, FC_DUAL,		  "*"},
+    { "i",            1, FC_SLANT,   FC_SLANT_ITALIC,	  "i"},
+    { "italic",       2, FC_SLANT,   FC_SLANT_ITALIC,	  "i"},
+    { "light",        1, FC_WEIGHT,  FC_WEIGHT_LIGHT,	  "light"},
+    { "medium",       2, FC_WEIGHT,  FC_WEIGHT_MEDIUM,	  "medium"},
+    { "mono",         2, FC_SPACING, FC_MONO,		  "m"},
+    { "normal",       1, FC_WIDTH,   FC_WIDTH_NORMAL,	  "normal"},
+    { "o",            1, FC_SLANT,   FC_SLANT_OBLIQUE,	  "o"},
+    { "obilque",      2, FC_SLANT,   FC_SLANT_OBLIQUE,	  "o"},
+    { "overstrike",   2, NULL,       0,			  "*"},
+    { "proportional", 1, FC_SPACING, FC_PROPORTIONAL,	  "p"},
+    { "r",            1, FC_SLANT,   FC_SLANT_ROMAN,      "r"},
+    { "roman",        2, FC_SLANT,   FC_SLANT_ROMAN,      "r"},
+    { "semibold",     5, FC_WEIGHT,  FC_WEIGHT_DEMIBOLD,  "semibold"},
+    { "semicondensed",5, FC_WIDTH,   FC_WIDTH_SEMICONDENSED,  "semicondensed"},
+    { "underline",    1, NULL,       0,		          "*"},
+};
+static int nFontSpecs = sizeof(fontSpecs) / sizeof(FontSpec);
+
+static FontSpec weightSpecs[] ={
+    { "black",		2, FC_WEIGHT, FC_WEIGHT_BLACK,	    "bold"},
+    { "bold",		3, FC_WEIGHT, FC_WEIGHT_BOLD,	    "bold"},
+    { "book",		3, FC_WEIGHT, FC_WEIGHT_MEDIUM,	    "*"},
+    { "demi",		4, FC_WEIGHT, FC_WEIGHT_BOLD,	    "*"},
+    { "demibold",	5, FC_WEIGHT, FC_WEIGHT_DEMIBOLD,   "*"},
+    { "extrablack",	6, FC_WEIGHT, FC_WEIGHT_EXTRABLACK, "*"},
+    { "extralight",	6, FC_WEIGHT, FC_WEIGHT_EXTRALIGHT, "*"},
+    { "heavy",		1, FC_WEIGHT, FC_WEIGHT_HEAVY,      "*"},
+    { "light",		1, FC_WEIGHT, FC_WEIGHT_LIGHT,	    "light"},
+    { "medium",		1, FC_WEIGHT, FC_WEIGHT_MEDIUM,	    "medium"},
+    { "normal",         1, FC_WEIGHT, FC_WEIGHT_MEDIUM,     "normal"},
+    { "regular",	1, FC_WEIGHT, FC_WEIGHT_REGULAR,    "medium"},
+    { "semibold",	1, FC_WEIGHT, FC_WEIGHT_SEMIBOLD,   "semibold"},
+    { "thin",		1, FC_WEIGHT, FC_WEIGHT_THIN,       "thin"},
+    { "ultrablack",	7, FC_WEIGHT, FC_WEIGHT_ULTRABLACK, "*"},
+    { "ultrabold",	7, FC_WEIGHT, FC_WEIGHT_ULTRABOLD,  "*"},
+    { "ultralight",	6, FC_WEIGHT, FC_WEIGHT_ULTRALIGHT, "*"},
+};
+static int nWeightSpecs = sizeof(weightSpecs) / sizeof(FontSpec);
+
+static FontSpec slantSpecs[] ={
+    { "i",		1, FC_SLANT, FC_SLANT_ITALIC,	"i"},
+    { "italic",		2, FC_SLANT, FC_SLANT_ITALIC,	"i"},
+    { "o",		1, FC_SLANT, FC_SLANT_OBLIQUE,	"o"},
+    { "obilque",	3, FC_SLANT, FC_SLANT_OBLIQUE,	"o"},
+    { "r",		1, FC_SLANT, FC_SLANT_ROMAN,	"r"},
+    { "roman",		2, FC_SLANT, FC_SLANT_ROMAN,	"r"},
+};
+static int nSlantSpecs = sizeof(slantSpecs) / sizeof(FontSpec);
+
+static FontSpec widthSpecs[] ={
+    { "condensed",	1, FC_WIDTH, FC_WIDTH_CONDENSED,      "condensed"},
+    { "expanded",	3, FC_WIDTH, FC_WIDTH_EXPANDED,	      "*"},
+    { "extracondensed", 6, FC_WIDTH, FC_WIDTH_EXTRACONDENSED, "*"},
+    { "extraexpanded",	6, FC_WIDTH, FC_WIDTH_EXTRAEXPANDED,  "*"},
+    { "narrow",		2, FC_WIDTH, FC_WIDTH_CONDENSED,      "narrow"},
+    { "normal",		2, FC_WIDTH, FC_WIDTH_NORMAL,	      "normal"},
+    { "semicondensed",	5, FC_WIDTH, FC_WIDTH_SEMICONDENSED,  "semicondensed"},
+    { "semiexpanded",	5, FC_WIDTH, FC_WIDTH_SEMIEXPANDED,   "*"},
+    { "ultracondensed",	6, FC_WIDTH, FC_WIDTH_ULTRACONDENSED, "*"},
+    { "ultraexpanded",	6, FC_WIDTH, FC_WIDTH_ULTRAEXPANDED,  "*"},
+};
+static int nWidthSpecs = sizeof(widthSpecs) / sizeof(FontSpec);
+
+static FontSpec spacingSpecs[] = {
+    { "charcell",     2, FC_SPACING, FC_CHARCELL,	  "c"},
+    { "dual",         2, FC_SPACING, FC_DUAL,		  "*"},
+    { "mono",         2, FC_SPACING, FC_MONO,		  "m"},
+    { "proportional", 1, FC_SPACING, FC_PROPORTIONAL,	  "p"},
+};
+static int nSpacingSpecs = sizeof(spacingSpecs) / sizeof(FontSpec);
+
+static Blt_HashTable fontTable;
+static void TkGetFontFamilies(Tk_Window tkwin, Blt_HashTable *tablePtr);
+
+#ifdef HAVE_LIBXFT
+static void FtGetFontFamilies(Tk_Window tkwin, Blt_HashTable *tablePtr);
+static int initialized = FALSE;
+
+static int
+IsXRenderAvailable(Tk_Window tkwin)
+{
+    static int isXRenderAvail = -1;
+
+    if (isXRenderAvail < 0) {
+	int eventBase, errorBase;
+
+	isXRenderAvail = FALSE;
+	Blt_InitHashTable(&fontTable, BLT_STRING_KEYS);
+	initialized = TRUE;
+	if (!XRenderQueryExtension(Tk_Display(tkwin), &eventBase, &errorBase)) {
+	    return FALSE;
+	}
+	if (XRenderFindVisualFormat(Tk_Display(tkwin), Tk_Visual(tkwin)) == 0) {
+	    return FALSE;
+	}
+	isXRenderAvail = TRUE;
+    }
+    return isXRenderAvail;
+}
+#endif
+
+static double
+PointsToPixels(Tk_Window tkwin, int size)
+{
+    double d;
+
+    if (size < 0) {
+        return -size;
+    }
+    d = size * 25.4 / 72.0;
+    d *= WidthOfScreen(Tk_Screen(tkwin));
+    d /= WidthMMOfScreen(Tk_Screen(tkwin));
+    return d;
+}
+
+static double
+PixelsToPoints(Tk_Window tkwin, int size)
+{
+    double d;
+
+    if (size >= 0) {
+	return size;
+    }
+    d = -size * 72.0 / 25.4;
+    d *= WidthMMOfScreen(Tk_Screen(tkwin));
+    d /= WidthOfScreen(Tk_Screen(tkwin));
+    return d;
+}
+
+static void
+ParseXLFD(const char *fontName, int *argcPtr, char ***argvPtr)
+{
+    char *p, *pend, *desc, *buf;
+    size_t arrayLen, stringLen;
+    int count;
+    char **field;
+
+    arrayLen = (sizeof(char *) * (XLFD_NUMFIELDS + 1));
+    stringLen = strlen(fontName);
+    buf = calloc(1, arrayLen + stringLen + 1);
+    desc = buf + arrayLen;
+    strcpy(desc, fontName);
+    field = (char **)buf;
+
+    count = 0;
+    for (p = desc, pend = p + stringLen; p < pend; p++, count++) {
+	char *word;
+
+	field[count] = NULL;
+	/* Get the next word, separated by dashes (-). */
+	word = p;
+	while ((*p != '\0') && (*p != '-')) {
+	    if (((*p & 0x80) == 0) && Tcl_UniCharIsUpper((unsigned char)(*p))) {
+		*p = (char)Tcl_UniCharToLower((unsigned char)(*p));
+	    }
+	    p++;
+	}
+	if (*p != '\0') {
+	    *p = '\0';
+	}
+	if ((word[0] == '\0') || 
+	    (((word[0] == '*') || (word[0] == '?')) && (word[1] == '\0'))) {
+	    continue;		/* Field not specified. -- -*- -?- */
+	}
+	field[count] = word;
+    }
+
+    /*
+     * An XLFD of the form -adobe-times-medium-r-*-12-*-* is pretty common,
+     * but it is (strictly) malformed, because the first * is eliding both the
+     * Setwidth and the Addstyle fields. If the Addstyle field is a number,
+     * then assume the above incorrect form was used and shift all the rest of
+     * the fields right by one, so the number gets interpreted as a pixelsize.
+     * This fix is so that we don't get a million reports that "it works under
+     * X (as a native font name), but gives a syntax error under Windows (as a
+     * parsed set of attributes)".
+     */
+
+    if ((count > XLFD_ADD_STYLE) && (field[XLFD_ADD_STYLE] != NULL)) {
+	int dummy;
+
+	if (Tcl_GetInt(NULL, field[XLFD_ADD_STYLE], &dummy) == TCL_OK) {
+	    int j;
+	    
+	    for (j = XLFD_NUMFIELDS - 1; j >= XLFD_ADD_STYLE; j--) {
+		field[j + 1] = field[j];
+	    }
+	    field[XLFD_ADD_STYLE] = NULL;
+	    count++;
+	}
+    }
+    *argcPtr = count;
+    *argvPtr = field;
+
+    field[XLFD_NUMFIELDS] = NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SearchForFontSpec --
+ *
+ *      Performs a binary search on the array of font specification to find a
+ *      partial, anchored match for the given option string.
+ *
+ * Results:
+ *	If the string matches unambiguously the index of the specification in
+ *	the array is returned.  If the string does not match, even as an
+ *	abbreviation, any operation, -1 is returned.  If the string matches,
+ *	but ambiguously -2 is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+SearchForFontSpec(
+    FontSpec *table,		/* Table of font options.  */
+    int nSpecs,			/* # specifications in font spec table. */
+    const char *string)		/* Name of font option to search for. */
+{
+    char c;
+    int high, low;
+    size_t length;
+
+    low = 0;
+    high = nSpecs - 1;
+    c = tolower((unsigned char)string[0]);
+    length = strlen(string);
+    while (low <= high) {
+	FontSpec *sp;
+	int compare;
+	int median;
+	
+	median = (low + high) >> 1;
+	sp = table + median;
+
+	/* Test the first character */
+	compare = c - sp->name[0];
+	if (compare == 0) {
+	    /* Now test the entire string */
+	    compare = strncasecmp(string, sp->name, length);
+	    if (compare == 0) {
+		if ((int)length < sp->minChars) {
+		    return -2;	/* Ambiguous spec name */
+		}
+	    }
+	}
+	if (compare < 0) {
+	    high = median - 1;
+	} else if (compare > 0) {
+	    low = median + 1;
+	} else {
+	    return median;	/* Spec found. */
+	}
+    }
+    return -1;			/* Can't find spec */
+}
+
+static FontSpec *
+FindSpec(Tcl_Interp *interp, FontSpec *tablePtr, int nSpecs, const char *string)
+{
+    int n;
+    
+    n = SearchForFontSpec(tablePtr, nSpecs, string);
+    if (n < 0) {
+	if (n == -1) {
+	    if (interp != NULL) {
+		Tcl_AppendResult(interp, "unknown ", tablePtr[0].key,
+			     " specification \"", string, "\"", (char *)NULL); 
+	    }
+	}
+	if (n == -2) {
+	    if (interp != NULL) {
+		Tcl_AppendResult(interp, "ambiguous ", tablePtr[0].key,
+			     " specification \"", string, "\"", (char *)NULL); 
+	    }
+	}
+	return NULL;
+    }
+    return tablePtr + n;
+}
+
+static Blt_HashTable aliasTable;
+static int alias_initialized = 0;
+
+typedef struct {
+    const char *name, *aliases[10];
+} FontAlias;
+
+#ifdef HAVE_LIBXFT
+static FontAlias xftFontAliases[] = {
+    { "math",	{ "mathematica1",  "nimbus sans l condensed", "courier"}},
+    { "serif",  { "times new roman", "nimbus roman no9 l" "times" }},
+    { "sans serif", { "arial", "nimbus sans l", "helvetica" }},
+    { "monospace", { "courier new", "nimbus mono l", "courier" }},
+    { "symbol", { "standard symbols l", "symbol" }},
+    { NULL }
+};
+#endif
+
+static FontAlias xlfdFontAliases[] = {
+    { "math",		{"courier"}},
+    { "serif",		{"times"}},
+    { "sans serif",	{ "helvetica" }},
+    { "monospace",	{ "courier" }},
+    { NULL }
+};
+
+static void
+MakeAliasTable(Tk_Window tkwin)
+{
+    Blt_HashTable familyTable;
+    FontAlias *fp;
+    FontAlias *table;
+
+    Blt_InitHashTable(&familyTable, TCL_STRING_KEYS);
+#ifdef HAVE_LIBXFT
+    if (IsXRenderAvailable(tkwin)) {
+	FtGetFontFamilies(tkwin, &familyTable);
+    } else {
+	TkGetFontFamilies(tkwin, &familyTable);
+    }
+#else 
+    TkGetFontFamilies(tkwin, &familyTable);
+#endif
+    Blt_InitHashTable(&aliasTable, TCL_STRING_KEYS);
+#ifdef HAVE_LIBXFT
+    table = (IsXRenderAvailable(tkwin)) ? xftFontAliases : xlfdFontAliases;
+#else 
+    table = xlfdFontAliases;
+#endif
+    for(fp = table; fp->name != NULL; fp++) {
+	Blt_HashEntry *hPtr;
+	const char **alias;
+	   
+	for (alias = fp->aliases; *alias != NULL; alias++) {
+	    hPtr = Blt_FindHashEntry(&familyTable, *alias);
+	    if (hPtr != NULL) {
+		int isNew;
+		
+		hPtr = Blt_CreateHashEntry(&aliasTable, fp->name, &isNew);
+		Blt_SetHashValue(hPtr, *alias);
+		break;
+	    }
+	}
+    }
+    Blt_DeleteHashTable(&familyTable);
+}
+
+static const char *
+GetAlias(const char *family)
+{
+    Blt_HashEntry *hPtr;
+
+    strtolower((char *)family);
+    hPtr = Blt_FindHashEntry(&aliasTable, family);
+    if (hPtr != NULL) {
+	return Blt_GetHashValue(hPtr);
+    }
+    return family;
+}
+
+static Blt_NameOfFontProc		TkNameOfFontProc;
+static Blt_GetFontMetricsProc		TkGetFontMetricsProc;
+static Blt_FontIdProc			TkFontIdProc;
+static Blt_MeasureCharsProc		TkMeasureCharsProc;
+static Blt_TextStringWidthProc		TkTextStringWidthProc;
+static Blt_FreeFontProc			TkFreeFontProc;
+static Blt_DrawCharsProc		TkDrawCharsProc;
+static Blt_PostscriptFontNameProc	TkPostscriptFontNameProc;
+static Blt_FamilyOfFontProc		TkFamilyOfFontProc;
+static Blt_CanRotateFontProc		TkCanRotateFontProc;
+static Blt_UnderlineCharsProc		TkUnderlineCharsProc;
+
+static Blt_FontClass tkFontClass = {
+    FONT_TK,
+    TkNameOfFontProc,		/* Blt_NameOfFontProc */
+    TkFamilyOfFontProc,		/* Blt_FamilyOfFontProc */
+    TkFontIdProc,		/* Blt_FontIdProc */
+    TkGetFontMetricsProc,	/* Blt_GetFontMetricsProc */
+    TkMeasureCharsProc,		/* Blt_MeasureCharsProc */
+    TkTextStringWidthProc,	/* Blt_TextWidthProc */
+    TkCanRotateFontProc,	/* Blt_CanRotateFontProc */
+    TkDrawCharsProc,		/* Blt_DrawCharsProc */
+    TkPostscriptFontNameProc,	/* Blt_PostscriptFontNameProc */
+    TkFreeFontProc,		/* Blt_FreeFontProc */
+    TkUnderlineCharsProc,	/* Blt_UnderlineCharsProc */
+};
+
+static TkFontPattern *
+TkNewFontPattern(void)
+{
+    TkFontPattern *patternPtr;
+
+    patternPtr = calloc(1, sizeof(TkFontPattern));
+    return patternPtr;
+}
+
+static void
+TkFreeFontPattern(TkFontPattern *patternPtr)
+{
+    if (patternPtr->family != NULL) {
+	free((char *)patternPtr->family);
+    }
+    free(patternPtr);
+}
+
+
+static void
+TkGetFontFamilies(Tk_Window tkwin, Blt_HashTable *tablePtr)
+{
+    char **list, **np, **nend;
+    const char *pat;
+    int n;
+    
+    pat = "-*-*-*-*-*-*-*-*-*-*-*-*-*-*";
+    list = XListFonts(Tk_Display(tkwin), pat, 10000, &n);
+    for (np = list, nend = np + n; np < nend; np++) {
+	Blt_HashEntry *hPtr;
+	int isNew;
+	char *family, *dash;
+	
+	/* Parse out the family name. Assume the names are all lower case. */
+	dash = strchr(*np+1, '-');
+	if (dash == NULL) {
+	    continue;
+	}
+	family = dash+1;
+	dash = strchr(family, '-');
+	if (dash != NULL) {
+	    *dash = '\0';
+	}
+	hPtr = Blt_CreateHashEntry(tablePtr, family, &isNew);
+	Blt_SetHashValue(hPtr, NULL);
+    }
+    XFreeFontNames(list);
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkParseTkDesc --
+ *
+ *	Parses an array of Tcl_Objs as a Tk style font description .  
+ *	
+ *	      "family [size] [optionList]"
+ *
+ * Results:
+ *	Returns a pattern structure, filling in with the necessary fields.
+ *	Returns NULL if objv doesn't contain a  Tk font description.
+ *
+ * Side effects:
+ *	Memory is allocated for the font pattern and the its strings.
+ *
+ *---------------------------------------------------------------------------
+ */
+static TkFontPattern *
+TkParseTkDesc(Tcl_Interp *interp, int objc, Tcl_Obj **objv)
+{
+    TkFontPattern *patternPtr;
+    Tcl_Obj **aobjv;
+    int aobjc;
+    int i;
+
+    patternPtr = TkNewFontPattern();
+
+    /* Font family. */
+    {
+	char *family, *dash;
+	family = Tcl_GetString(objv[0]);
+	dash = strchr(family, '-');
+	if (dash != NULL) {
+	    int size;
+	    
+	    if (Tcl_GetInt(NULL, dash + 1, &size) != TCL_OK) {
+		goto error;
+	    }
+	    patternPtr->size = size;
+	}
+	if (dash != NULL) {
+	    *dash = '\0';
+	}
+	patternPtr->family = Blt_Strdup(GetAlias(family));
+	if (dash != NULL) {
+	    *dash = '-';
+	    i = 1;
+	}
+	objv++, objc--;
+    }
+    if (objc > 0) {
+	int size;
+
+	if (Tcl_GetIntFromObj(NULL, objv[0], &size) == TCL_OK) {
+	    patternPtr->size = size;
+	    objv++, objc--;
+	}
+    }
+    aobjc = objc, aobjv = objv;
+    if (objc > 0) {
+	if (Tcl_ListObjGetElements(NULL, objv[0], &aobjc, &aobjv) != TCL_OK) {
+	    goto error;
+	}
+    }
+    for (i = 0; i < aobjc; i++) {
+	FontSpec *specPtr;
+	const char *key;
+
+	key = Tcl_GetString(aobjv[i]);
+	specPtr = FindSpec(interp, fontSpecs, nFontSpecs, key);
+	if (specPtr == NULL) {
+	    goto error;
+	}
+	if (specPtr->key == NULL) {
+	    continue;
+	}
+	if (strcmp(specPtr->key, FC_WEIGHT) == 0) {
+	    patternPtr->weight = specPtr->oldvalue;
+	} else if (strcmp(specPtr->key, FC_SLANT) == 0) {
+	    patternPtr->slant = specPtr->oldvalue;
+	} else if (strcmp(specPtr->key, FC_SPACING) == 0) {
+	    patternPtr->spacing = specPtr->oldvalue;
+	} else if (strcmp(specPtr->key, FC_WIDTH) == 0) {
+	    patternPtr->width = specPtr->oldvalue;
+	}
+    }
+    return patternPtr;
+ error:
+    TkFreeFontPattern(patternPtr);
+    return NULL;
+}	
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkParseNameValuePairs --
+ *
+ *	Given Tcl_Obj list of name value pairs, parse the list saving
+ *	in the values in a font pattern structure.
+ *	
+ *	      "-family family -size size -weight weight"
+ *
+ * Results:
+ *	Returns a pattern structure, filling in with the necessary fields.
+ *	Returns NULL if objv doesn't contain a valid name-value list 
+ *	describing a font.
+ *
+ * Side effects:
+ *	Memory is allocated for the font pattern and the its strings.
+ *
+ *---------------------------------------------------------------------------
+ */
+static TkFontPattern *
+TkParseNameValuePairs(Tcl_Interp *interp, Tcl_Obj *objPtr) 
+{
+    TkFontPattern *patternPtr;
+    Tcl_Obj **objv;
+    int objc;
+    int i;
+
+    if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) ||
+	(objc < 1)) {
+	return NULL;		/* Can't split list or list is empty. */
+    }
+    if (objc & 0x1) {
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "odd number of elements, missing value",
+			 (char *)NULL);
+	}
+	return NULL;		/* Odd number of elements in list. */
+    }
+    patternPtr = TkNewFontPattern();
+    for (i = 0; i < objc; i += 2) {
+	const char *key, *value;
+
+	key = Tcl_GetString(objv[i]);
+	value = Tcl_GetString(objv[i+1]);
+	if (strcmp(key, "-family") == 0) {
+	    if (patternPtr->family != NULL) {
+		free(patternPtr->family);
+	    }
+	    patternPtr->family = Blt_Strdup(GetAlias(value));
+	} else if (strcmp(key, "-size") == 0) {
+	    int size;
+
+	    if (Tcl_GetIntFromObj(interp, objv[i+1], &size) != TCL_OK) {
+		goto error;
+	    }
+	    patternPtr->size = size;
+	} else if (strcmp(key, "-weight") == 0) {
+	    FontSpec *specPtr;
+
+	    specPtr = FindSpec(interp, weightSpecs, nWeightSpecs, value);
+	    if (specPtr == NULL) {
+		goto error;
+	    }
+	    patternPtr->weight = specPtr->oldvalue;
+	} else if (strcmp(key, "-slant") == 0) {
+	    FontSpec *specPtr;
+
+	    specPtr = FindSpec(interp, slantSpecs, nSlantSpecs, value);
+	    if (specPtr == NULL) {
+		goto error;
+	    }
+	    patternPtr->slant = specPtr->oldvalue;
+	} else if (strcmp(key, "-spacing") == 0) {
+	    FontSpec *specPtr;
+
+	    specPtr = FindSpec(interp, spacingSpecs, nSpacingSpecs, value);
+	    if (specPtr == NULL) {
+		goto error;
+	    }
+	    patternPtr->spacing = specPtr->oldvalue;
+	} else if (strcmp(key, "-hint") == 0) {
+	    /* Ignore */
+	} else if (strcmp(key, "-rgba") == 0) {
+	    /* Ignore */
+	} else if (strcmp(key, "-underline") == 0) {
+	    /* Ignore */
+	} else if (strcmp(key, "-overstrike") == 0) {
+	    /* Ignore */
+	} else {
+	    /* Ignore */
+	}
+    }
+    return patternPtr;
+ error:
+    TkFreeFontPattern(patternPtr);
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkParseNameValuePairs --
+ *
+ *	Given the name of a Tk font object, get its configuration values 
+ *	save the data in a font pattern structure.
+ *	
+ *	      "-family family -size size -weight weight"
+ *
+ * Results:
+ *	Returns a pattern structure, filling in with the necessary fields.
+ *	Returns NULL if objv doesn't contain a valid name-value list 
+ *	describing a font.
+ *
+ * Side effects:
+ *	Memory is allocated for the font pattern and the its strings.
+ *
+ *---------------------------------------------------------------------------
+ */
+static TkFontPattern *
+TkParseFontObj(Tcl_Interp *interp, Tcl_Obj *objPtr) 
+{
+    TkFontPattern *patternPtr;
+    Tcl_Obj *cmd[3];
+    int result;
+
+    patternPtr = NULL;
+    cmd[0] = Tcl_NewStringObj("font", -1);
+    cmd[1] = Tcl_NewStringObj("configure", -1);
+    cmd[2] = objPtr;
+    Tcl_IncrRefCount(cmd[0]);
+    Tcl_IncrRefCount(cmd[1]);
+    Tcl_IncrRefCount(cmd[2]);
+    result = Tcl_EvalObjv(interp, 3, cmd, 0);
+    Tcl_DecrRefCount(cmd[2]);
+    Tcl_DecrRefCount(cmd[1]);
+    Tcl_DecrRefCount(cmd[0]);
+    if (result == TCL_OK) {
+	patternPtr = TkParseNameValuePairs(interp, Tcl_GetObjResult(interp));
+    }
+    Tcl_ResetResult(interp);
+    return patternPtr;
+}
+
+/* 
+ *---------------------------------------------------------------------------
+ *
+ * TkGetPattern --
+ * 
+ *	Parses the font description so that the font can rewritten with an
+ *	aliased font name.  This allows us to use
+ *
+ *	  "Sans Serif", "Serif", "Math", "Monospace"
+ *
+ *	font names that correspond to the proper font regardless if the
+ *	standard X fonts or XFT fonts are being used.
+ *
+ *	Leave XLFD font descriptions alone.  Let users describe exactly the
+ *	font they wish.
+ *
+ *---------------------------------------------------------------------------
+ */
+static TkFontPattern *
+TkGetPattern(Tcl_Interp *interp, Tcl_Obj *objPtr)
+{
+    TkFontPattern *patternPtr;
+    char *desc;
+
+    desc = Tcl_GetString(objPtr);
+    while (isspace(*desc)) {
+	desc++;			/* Skip leading blanks. */
+    }
+    if (*desc == '-') {
+	/* 
+	 * Case 1: XLFD font description or Tk attribute list.   
+	 *
+	 *   If the font description starts with a '-', it could be either an
+	 *   old fashion XLFD font description or a Tk font attribute
+	 *   option-value list.
+	 */
+	patternPtr = TkParseNameValuePairs(interp, objPtr);
+	if (patternPtr == NULL) {
+	    return NULL;		/* XLFD font description */
+	}
+    } else if (*desc == '*') {
+	return NULL;		/* XLFD font description */
+    } else if (strpbrk(desc, "::") != NULL) {
+	patternPtr = TkParseFontObj(interp, objPtr);
+    } else {
+	int objc;
+	Tcl_Obj **objv;
+	/* 
+	 * Case 3: Tk-style description.   
+	 */
+	if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) || 
+	    (objc < 1)) {
+	    return NULL;		/* Can't split into a list or
+					 * list is empty. */
+	}
+	patternPtr = NULL;
+	if (objc == 1) {
+	    /* 
+	     * Case 3a: Tk font object name.
+	     *
+	     *   Assuming that Tk font object names won't contain whitespace,
+	     *   see if its a font object.
+	     */
+	    patternPtr = TkParseFontObj(interp, objv[0]);
+	} 
+	if (patternPtr == NULL) {
+	    /* 
+	     * Case 3b: List of font attributes in the form "family size
+	     *		?attrs?"
+	     */
+	    patternPtr = TkParseTkDesc(interp, objc, objv);
+	}
+    }	
+    return patternPtr;
+}
+
+static void
+TkWriteXLFDDescription(Tk_Window tkwin, TkFontPattern *patternPtr, 
+		       Tcl_DString *resultPtr)
+{
+    const char *string;
+    int size;
+    
+    /* Rewrite the font description using the aliased family. */
+    Tcl_DStringInit(resultPtr);
+
+    /* Foundry */
+    Tcl_DStringAppend(resultPtr, "-*-", 3);
+    /* Family */
+    string = (patternPtr->family != NULL) ? patternPtr->family : "*";
+    Tcl_DStringAppend(resultPtr, string, -1);
+    Tcl_DStringAppend(resultPtr, "-", 1);
+    /* Weight */
+    string = (patternPtr->weight == NULL) ? "*" : patternPtr->weight;
+    Tcl_DStringAppend(resultPtr, string, -1);
+    Tcl_DStringAppend(resultPtr, "-", 1);
+    /* Slant */
+    string = (patternPtr->slant == NULL) ? "*" : patternPtr->slant;
+    Tcl_DStringAppend(resultPtr, string, -1);
+    Tcl_DStringAppend(resultPtr, "-", 1);
+    /* Width */
+    string = (patternPtr->width == NULL) ? "*" : patternPtr->width;
+    Tcl_DStringAppend(resultPtr, string, -1);
+    /* Style */
+    Tcl_DStringAppend(resultPtr, "-*-", 3);
+    /* Pixel size */
+    size = (int)(PointsToPixels(tkwin, patternPtr->size) + 0.5);
+    string = (size == 0) ? "*" : Blt_Itoa(size);
+    Tcl_DStringAppend(resultPtr, string, -1);
+    /* Point size */
+    Tcl_DStringAppend(resultPtr, "-", 1);
+    size = (int)(PixelsToPoints(tkwin, patternPtr->size) + 0.5);
+    string = (size == 0) ? "*" : Blt_Itoa(size);
+    Tcl_DStringAppend(resultPtr, string, -1);
+    
+    /* resx, resy */
+    Tcl_DStringAppend(resultPtr, "-*-*-", 5);
+    /* Spacing */
+    string = (patternPtr->spacing == NULL) ? "*" : patternPtr->spacing;
+    Tcl_DStringAppend(resultPtr, string, -1);
+    /* Average Width, Registry, Encoding */
+    Tcl_DStringAppend(resultPtr, "-*-*-*-", 7);
+}
+    
+/* 
+ *---------------------------------------------------------------------------
+ *
+ * TkGetFontFromObj --
+ * 
+ *	Opens a Tk font based on the description in the Tcl_Obj.  We first
+ *	parse the description and if necessary rewrite it using the proper
+ *	font aliases.  The font names
+ *
+ *	  "Sans Serif", "Serif", "Math", "Monospace"
+ *
+ *	correspond to the proper font regardless if the standard X fonts or
+ *	XFT fonts are being used.
+ *
+ *	Leave XLFD font descriptions alone.  Let users describe exactly the
+ *	font they wish.
+ *
+ *	Outside of reimplementing the Tk font mechanism, rewriting the
+ *	font allows use to better handle programs that must work with
+ *	X servers with and without the XRender extension.  It means 
+ *	that the widget's default font settings do not have to use
+ *	XLFD fonts even if XRender is available.
+ *	
+ *---------------------------------------------------------------------------
+ */
+static Tk_Font
+TkGetFontFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+    Tk_Font tkFont;
+    TkFontPattern *patternPtr;
+
+    if (!alias_initialized) {
+	MakeAliasTable(tkwin);
+	alias_initialized++;
+    }
+    patternPtr = TkGetPattern(interp, objPtr);
+    if (patternPtr == NULL) {
+	tkFont = Tk_GetFont(interp, tkwin, Tcl_GetString(objPtr));
+    } else {
+	Tcl_DString ds;
+
+	/* Rewrite the font description using the aliased family. */
+	TkWriteXLFDDescription(tkwin, patternPtr, &ds);
+	tkFont = Tk_GetFont(interp, tkwin, Tcl_DStringValue(&ds));
+	Tcl_DStringFree(&ds);
+	TkFreeFontPattern(patternPtr);
+    }
+    return tkFont;
+}
+
+static const char *
+TkNameOfFontProc(_Blt_Font *fontPtr) 
+{
+    return Tk_NameOfFont(fontPtr->clientData);
+}
+
+static const char *
+TkFamilyOfFontProc(_Blt_Font *fontPtr) 
+{
+    return ((TkFont *)fontPtr->clientData)->fa.family;
+}
+
+static Font
+TkFontIdProc(_Blt_Font *fontPtr) 
+{
+    return Tk_FontId(fontPtr->clientData);
+}
+
+static void
+TkGetFontMetricsProc(_Blt_Font *fontPtr, Blt_FontMetrics *fmPtr)
+{
+    TkFont *tkFontPtr = fontPtr->clientData;
+    Tk_FontMetrics fm;
+
+    Tk_GetFontMetrics(fontPtr->clientData, &fm);
+    fmPtr->ascent = fm.ascent;
+    fmPtr->descent = fm.descent;
+    fmPtr->linespace = fm.linespace;
+    fmPtr->tabWidth = tkFontPtr->tabWidth;
+    fmPtr->underlinePos = tkFontPtr->underlinePos;
+    fmPtr->underlineHeight = tkFontPtr->underlineHeight;
+}
+
+static int
+TkMeasureCharsProc(_Blt_Font *fontPtr, const char *text, int nBytes, int max, 
+		   int flags, int *lengthPtr)
+{
+    return Tk_MeasureChars(fontPtr->clientData, text, nBytes, max, flags, 
+	lengthPtr);
+}
+
+static int
+TkTextStringWidthProc(_Blt_Font *fontPtr, const char *string, int nBytes)
+{
+    return Tk_TextWidth(fontPtr->clientData, string, nBytes);
+}    
+
+static void
+TkDrawCharsProc(
+    Display *display,		/* Display on which to draw. */
+    Drawable drawable,		/* Window or pixmap in which to draw. */
+    GC gc,			/* Graphics context for drawing characters. */
+    _Blt_Font *fontPtr,		/* Font in which characters will be drawn;
+				 * must be the same as font used in GC. */
+    int depth,			/* Not used. */
+    float angle,		/* Not used. */
+    const char *text,		/* UTF-8 string to be displayed.  Need not be
+				 * '\0' terminated.  All Tk meta-characters
+				 * (tabs, control characters, and newlines)
+				 * should be stripped out of the string that
+				 * is passed to this function.  If they are
+				 * not stripped out, they will be displayed as
+				 * regular printing characters. */
+    int nBytes,			/* Number of bytes in string. */
+    int x, int y)		/* Coordinates at which to place origin of
+				 * string when drawing. */
+{
+    Tk_DrawChars(display, drawable, gc, fontPtr->clientData,text, nBytes, x, y);
+}
+
+static int
+TkPostscriptFontNameProc(_Blt_Font *fontPtr, Tcl_DString *resultPtr) 
+{
+    TkFont *tkFontPtr;
+    unsigned int flags;
+
+    tkFontPtr = (TkFont *)fontPtr->clientData;
+    flags = 0;
+    if (tkFontPtr->fa.slant != TK_FS_ROMAN) {
+	flags |= FONT_ITALIC;
+    }
+    if (tkFontPtr->fa.weight != TK_FW_NORMAL) {
+	flags |= FONT_BOLD;
+    }
+    Blt_Ps_FontName(tkFontPtr->fa.family, flags, resultPtr);
+    return tkFontPtr->fa.size;
+}
+
+static int
+TkCanRotateFontProc(_Blt_Font *fontPtr, float angle) 
+{
+    return FALSE;
+}
+
+static void
+TkFreeFontProc(_Blt_Font *fontPtr) 
+{
+    Tk_FreeFont(fontPtr->clientData);
+    free(fontPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkUnderlineCharsProc --
+ *
+ *	This procedure draws an underline for a given range of characters in a
+ *	given string.  It doesn't draw the characters (which are assumed to
+ *	have been displayed previously); it just draws the underline.  This
+ *	procedure would mainly be used to quickly underline a few characters
+ *	without having to construct an underlined font.  To produce properly
+ *	underlined text, the appropriate underlined font should be constructed
+ *	and used.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Information gets displayed in "drawable".
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+TkUnderlineCharsProc(
+    Display *display,		/* Display on which to draw. */
+    Drawable drawable,		/* Window or pixmap in which to draw. */
+    GC gc,			/* Graphics context for actually drawing
+				 * line. */
+    _Blt_Font *fontPtr,		/* Font used in GC; must have been
+				 * allocated by Tk_GetFont().  Used for
+				 * character dimensions, etc. */
+    const char *text,		/* String containing characters to be
+				 * underlined or overstruck. */
+    int textLen,		/* Unused. */
+    int x, int y,		/* Coordinates at which first character of
+				 * string is drawn. */
+    int first,			/* Byte offset of the first character. */
+    int last,			/* Byte offset after the last character. */
+    int xMax)
+{
+    Tk_UnderlineChars(display, drawable, gc, fontPtr->clientData, text, x, y, 
+	first, last);
+}
+
+#ifdef HAVE_LIBXFT
+
+static Blt_NameOfFontProc		FtNameOfFontProc;
+static Blt_FamilyOfFontProc		FtFamilyOfFontProc;
+static Blt_FontIdProc			FtFontIdProc;
+static Blt_GetFontMetricsProc		FtGetFontMetricsProc;
+static Blt_MeasureCharsProc		FtMeasureCharsProc;
+static Blt_TextStringWidthProc		FtTextStringWidthProc;
+static Blt_FreeFontProc			FtFreeFontProc;
+static Blt_DrawCharsProc		FtDrawCharsProc;
+static Blt_PostscriptFontNameProc	FtPostscriptFontNameProc;
+static Blt_CanRotateFontProc		FtCanRotateFontProc;
+static Blt_UnderlineCharsProc		FtUnderlineCharsProc;
+
+static Blt_FontClass ftFontClass = {
+    FONT_FT,
+    FtNameOfFontProc,			/* Blt_NameOfFontProc */
+    FtFamilyOfFontProc,			/* Blt_FamilyOfFontProc */
+    FtFontIdProc,			/* Blt_FontIdProc */
+    FtGetFontMetricsProc,		/* Blt_GetFontMetricsProc */
+    FtMeasureCharsProc,			/* Blt_MeasureCharsProc */
+    FtTextStringWidthProc,		/* Blt_TextStringWidthProc */
+    FtCanRotateFontProc,		/* Blt_CanRotateFontProc */
+    FtDrawCharsProc,			/* Blt_DrawCharsProc */
+    FtPostscriptFontNameProc,		/* Blt_PostscriptFontNameProc */
+    FtFreeFontProc,			/* Blt_FreeFontProc */
+    FtUnderlineCharsProc,		/* Blt_UnderlineCharsProc */
+};
+
+/* 
+ * Freetype font container.
+ */
+typedef struct {
+    char *name;				/* Name of the font (malloc-ed). */
+    int refCount;			/* Reference count for this structure.
+					 * When refCount reaches zero, it
+					 * means to free the resources
+					 * associated with this structure. */
+    Blt_HashEntry *hashPtr;		/* Pointer to this entry in global
+					 * font hash table. Used to remove the
+					 * entry * from the table. */
+    Font fid;				/* Font id used to fake out
+					 * Tk_FontId. */
+    FcPattern *pattern;			/* Pattern matching the current
+					 * non-rotated font. Used to create
+					 * rotated fonts by duplicating the
+					 * pattern and adding  a rotation
+					 * matrix. */
+
+    Blt_HashTable fontTable;		/* Hash table containing an Xft font
+					 * for each angle it's used at. Will
+					 * always contain a 0 degree
+					 * entry. */
+
+    /* Information specific to the display/drawable being used. The drawables
+     * are changed as the drawable changes for each drawing request.
+     * Typically this will change for each pixmap. */
+
+    Drawable drawable;			/* Drawable associated with draw. */
+    XftDraw *draw;			/* Current Xft drawable. */
+    int drawDepth;			/* Depth of current drawable. */
+
+    XftColor color;			/* Color to be displayed.  We don't
+					 * actually allocate this color, since
+					 * we assume it's been already
+					 * allocated by the standard Tk
+					 * procedures. */
+
+    /* Saved Information from the Tk_Window used to created the initial
+     * font. */
+    Display *display;		
+    Visual *visual;
+    int screenNum;
+    Colormap colormap;
+
+    int underlineHeight;		/* Thickness of underline
+					 * rectangle. */
+    int underlinePos;			/* Offset of underline. */
+    int tabWidth;
+} FtFont;
+
+static FontSpec rgbaSpecs[] = {
+    { "bgr",	 1, FC_RGBA, FC_RGBA_BGR,     },
+    { "none",	 1, FC_RGBA, FC_RGBA_NONE,    },
+    { "rgb",	 1, FC_RGBA, FC_RGBA_RGB,     },
+    { "unknown", 1, FC_RGBA, FC_RGBA_UNKNOWN, },
+    { "vbgr",	 2, FC_RGBA, FC_RGBA_VBGR,    },
+    { "vrgb",	 2, FC_RGBA, FC_RGBA_VRGB,    },
+};
+static int nRgbaSpecs = sizeof(rgbaSpecs) / sizeof(FontSpec);
+
+static FontSpec hintSpecs[] = {
+    { "full",	 1, FC_HINT_STYLE, FC_HINT_FULL,    },
+    { "medium",	 1, FC_HINT_STYLE, FC_HINT_MEDIUM,  },
+    { "none",    1, FC_HINT_STYLE, FC_HINT_NONE,    },
+    { "slight",	 1, FC_HINT_STYLE, FC_HINT_SLIGHT,  },
+};
+static int nHintSpecs = sizeof(hintSpecs) / sizeof(FontSpec);
+
+static void
+FtGetFontFamilies(Tk_Window tkwin, Blt_HashTable *tablePtr)
+{
+    XftFontSet *fsPtr;
+    int i;
+    
+    fsPtr = XftListFonts(Tk_Display(tkwin), 
+			 Tk_ScreenNumber(tkwin), 
+			 (char*)NULL, /* pattern elements */
+			 XFT_FAMILY, (char*)NULL); /* fields */
+    for (i = 0; i < fsPtr->nfont; i++) {
+	FcResult result;
+	FcChar8 *family;
+	
+	result = FcPatternGetString(fsPtr->fonts[i], FC_FAMILY, 0, &family);
+	if (result == FcResultMatch) {
+	    int isNew;
+	    char *name;
+
+	    /* Family names must be all lower case in the hash table. */
+	    name = Blt_Strdup((const char *)family);
+	    strtolower(name);
+	    Blt_CreateHashEntry(tablePtr, name, &isNew);
+	    free(name);
+	}
+    }
+    XftFontSetDestroy(fsPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FtParseTkDesc --
+ *
+ *	Try to open a Xft font from an Tk style font description.
+ *
+ * Results:
+ *	Return value is TCL_ERROR if string was not a fully specified XLFD.
+ *	Otherwise, fills font attribute buffer with the values parsed from the
+ *	XLFD and returns TCL_OK.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static FcPattern *
+FtParseTkDesc(Tcl_Interp *interp, Tk_Window tkwin, int objc, Tcl_Obj **objv)
+{
+    FcPattern *pattern;
+    int i;
+    const char *family;
+
+    pattern = FcPatternCreate();
+    FcPatternAddBool(pattern, FC_ANTIALIAS, FcTrue);
+
+    /* Font family. */
+    family = GetAlias(Tcl_GetString(objv[0]));
+    FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *)family);
+
+    /* Size */
+    if (objc > 1) {
+	int size;
+
+	if (Tcl_GetIntFromObj(NULL, objv[1], &size) != TCL_OK) {
+	    goto error;
+	}
+	FcPatternAddDouble(pattern, FC_SIZE, PixelsToPoints(tkwin, size));
+    }
+    i = 2;
+    if (objc == 3) {
+	if (Tcl_ListObjGetElements(interp, objv[2], &objc, &objv) != TCL_OK) {
+	    goto error;
+	}
+	i = 0;
+    }
+    for (/*empty*/; i < objc; i++) {
+	FontSpec *specPtr;
+	
+	specPtr = FindSpec(interp, fontSpecs, nFontSpecs, 
+			   Tcl_GetString(objv[i]));
+	if (specPtr == NULL) {
+	    goto error;
+	}
+	if (specPtr->key != NULL) {
+	    FcPatternAddInteger(pattern, specPtr->key, specPtr->value);
+	}
+    }
+    return pattern;
+ error:
+    if (pattern != NULL) {
+	FcPatternDestroy(pattern);
+    }
+    return NULL;
+}	
+
+static FcPattern *
+FtParseTkFontAttributeList(Tcl_Interp *interp, Tk_Window tkwin, 
+			   Tcl_Obj *objPtr) 
+{
+    FcPattern *pattern;
+    Tcl_Obj **objv;
+    int objc;
+    int i;
+
+    if ((Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) ||
+	(objc < 1)) {
+	return NULL;		/* Can't split list or list is empty. */
+    }
+    if (objc & 0x1) {
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "odd number of elements, missing value",
+			 (char *)NULL);
+	}
+	return NULL;		/* Odd number of elements in list. */
+    }
+    pattern = FcPatternCreate();
+    FcPatternAddBool(pattern, FC_ANTIALIAS, FcTrue);
+    for (i = 0; i < objc; i += 2) {
+	char *key, *value;
+
+	key = Tcl_GetString(objv[i]);
+	value = Tcl_GetString(objv[i+1]);
+	if (strcmp(key, "-family") == 0) {
+	    const char *family;
+
+	    family = GetAlias(value);
+	    FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *)family);
+	} else if (strcmp(key, "-size") == 0) {
+	    int size;
+
+	    if (Tcl_GetIntFromObj(interp, objv[i+1], &size) != TCL_OK) {
+		goto error;
+	    }
+	    FcPatternAddDouble(pattern, FC_SIZE, PixelsToPoints(tkwin, size));
+	} else if (strcmp(key, "-weight") == 0) {
+	    FontSpec *specPtr;
+
+	    specPtr = FindSpec(interp, weightSpecs, nWeightSpecs, value);
+	    if (specPtr == NULL) {
+		goto error;
+	    }
+	    FcPatternAddInteger(pattern, FC_WEIGHT, specPtr->value);
+	} else if (strcmp(key, "-slant") == 0) {
+	    FontSpec *specPtr;
+
+	    specPtr = FindSpec(interp, slantSpecs, nSlantSpecs, value);
+	    if (specPtr == NULL) {
+		goto error;
+	    }
+	    FcPatternAddInteger(pattern, FC_SLANT, specPtr->value);
+	} else if (strcmp(key, "-hint") == 0) {
+	    FontSpec *specPtr;
+
+	    specPtr = FindSpec(interp, hintSpecs, nHintSpecs, value);
+	    if (specPtr == NULL) {
+		goto error;
+	    }
+	    FcPatternAddInteger(pattern, FC_HINT_STYLE, specPtr->value);
+	} else if (strcmp(key, "-rgba") == 0) {
+	    FontSpec *specPtr;
+
+	    specPtr = FindSpec(interp, rgbaSpecs, nRgbaSpecs, value);
+	    if (specPtr == NULL) {
+		goto error;
+	    }
+	    FcPatternAddInteger(pattern, FC_RGBA, specPtr->value);
+	} else if (strcmp(key, "-underline") == 0) {
+	    /* Ignore */
+	} else if (strcmp(key, "-overstrike") == 0) {
+	    /* Ignore */
+	} else {
+	    if (interp != NULL) {
+		Tcl_AppendResult(interp, "unknown switch \"", key, 
+			     "\" in font description.", (char *)NULL);
+	    }
+	    goto error;
+	}
+    }
+    return pattern;
+ error:
+    FcPatternDestroy(pattern);
+    return NULL;
+}
+
+static FcPattern *
+FtGetAttributesFromFontObj(Tk_Window tkwin, Tcl_Interp *interp, 
+			   Tcl_Obj *objPtr) 
+{
+    FcPattern *pattern;
+    Tcl_Obj *cmd[3];
+    int result;
+
+    cmd[0] = Tcl_NewStringObj("font", -1);
+    cmd[1] = Tcl_NewStringObj("configure", -1);
+    cmd[2] = objPtr;
+    result = Blt_GlobalEvalObjv(interp, 3, cmd);
+    if (result == TCL_OK) {
+	pattern = FtParseTkFontAttributeList(interp, tkwin, 
+		Tcl_GetObjResult(interp));
+    } else {
+	pattern = NULL;
+    }
+    Tcl_ResetResult(interp);
+    return pattern;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FtParseXLFD --
+ *
+ *	Try to open a Xft font from an XLFD description.
+ *
+ * Results:
+ *	Return value is TCL_ERROR if string was not a fully specified XLFD.
+ *	Otherwise, fills font attribute buffer with the values parsed from the
+ *	XLFD and returns TCL_OK.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static FcPattern *
+FtParseXLFD(Tcl_Interp *interp, Tk_Window tkwin, char *fontName)
+{
+    FcPattern *pattern;
+    FontSpec *specPtr;
+    int argc;
+    char **argv;
+    double size;
+
+    if (fontName[0] == '-') {
+	fontName++;
+    }
+    ParseXLFD(fontName, &argc, &argv);
+
+    pattern = FcPatternCreate();
+    FcPatternAddBool(pattern, FC_ANTIALIAS, FcTrue);
+
+    if (argv[XLFD_FOUNDRY] != NULL) {
+	FcPatternAddString(pattern, FC_FOUNDRY, 
+		(const FcChar8 *)argv[XLFD_FOUNDRY]);
+    }
+    if (argv[XLFD_FAMILY] != NULL) {
+	FcPatternAddString(pattern, FC_FAMILY, 
+		(const FcChar8 *)argv[XLFD_FAMILY]);
+    }
+    if (argv[XLFD_WEIGHT] != NULL) {
+	specPtr = FindSpec(interp, weightSpecs, nWeightSpecs, 
+			   argv[XLFD_WEIGHT]);
+	if (specPtr == NULL) {
+	    goto error;
+	}
+	FcPatternAddInteger(pattern, FC_WEIGHT, specPtr->value);
+    }
+    if (argv[XLFD_SLANT] != NULL) {
+	specPtr = FindSpec(interp, slantSpecs, nSlantSpecs, argv[XLFD_SLANT]);
+	if (specPtr == NULL) {
+	    goto error;
+	}
+	FcPatternAddInteger(pattern, FC_SLANT, specPtr->value);
+    }
+    if (argv[XLFD_SETWIDTH] != NULL) {
+	specPtr = FindSpec(interp, widthSpecs, nWidthSpecs, 
+			   argv[XLFD_SETWIDTH]);
+	if (specPtr == NULL) {
+	    goto error;
+	}
+	FcPatternAddInteger(pattern, FC_WIDTH, specPtr->value);
+    }
+    if (argv[XLFD_ADD_STYLE] != NULL) {
+	FcPatternAddString(pattern, FC_STYLE, 
+		(const FcChar8 *)argv[XLFD_ADD_STYLE]);
+    }
+    size = 12.0;
+    if (argv[XLFD_PIXEL_SIZE] != NULL) {
+	int value;
+	if (argv[XLFD_PIXEL_SIZE][0] == '[') {
+	    /*
+	     * Some X fonts have the point size specified as follows:
+	     *
+	     *	    [ N1 N2 N3 N4 ]
+	     *
+	     * where N1 is the point size (in points, not decipoints!), and
+	     * N2, N3, and N4 are some additional numbers that I don't know
+	     * the purpose of, so I ignore them.
+	     */
+	    value = atoi(argv[XLFD_PIXEL_SIZE]+1);
+	} else if (Tcl_GetInt(NULL, argv[XLFD_PIXEL_SIZE], &value) == TCL_OK) {
+	    /* empty */
+	} else {
+	    goto error;
+	}
+	size = PixelsToPoints(tkwin, -value);
+    }
+
+    if (argv[XLFD_POINT_SIZE] != NULL) {
+	int value;
+	if (argv[XLFD_POINT_SIZE][0] == '[') {
+	    /*
+	     * Some X fonts have the point size specified as follows:
+	     *
+	     *	    [ N1 N2 N3 N4 ]
+	     *
+	     * where N1 is the point size (in points, not decipoints!), and
+	     * N2, N3, and N4 are some additional numbers that I don't know
+	     * the purpose of, so I ignore them.
+	     */
+	    value = atoi(argv[XLFD_POINT_SIZE]+1);
+	} else if (Tcl_GetInt(NULL, argv[XLFD_POINT_SIZE], &value) == TCL_OK) {
+	    /* empty */
+	} else {
+	    goto error;
+	}
+	size = PixelsToPoints(tkwin, -value) * 0.1;
+    }
+
+    FcPatternAddDouble(pattern, FC_SIZE, (double)size);
+
+    if (argv[XLFD_SPACING] != NULL) {
+	specPtr = FindSpec(interp, spacingSpecs, nSpacingSpecs, 
+			   argv[XLFD_SPACING]);
+	if (specPtr == NULL) {
+	    goto error;
+	}
+	FcPatternAddInteger(pattern, FC_SPACING, specPtr->value);
+    }
+    free((char *)argv);
+    return pattern;
+ error:
+    free((char *)argv);
+    FcPatternDestroy(pattern);
+    return NULL;
+}
+
+
+static void
+FtDeleteFont(FtFont *ftPtr)
+{
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch cursor;
+    
+    for (hPtr = Blt_FirstHashEntry(&ftPtr->fontTable, &cursor); 
+	 hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	XftFont *xftPtr;
+	
+	xftPtr = Blt_GetHashValue(hPtr);
+	XftFontClose(ftPtr->display, xftPtr);
+    }
+    Blt_DeleteHashTable(&ftPtr->fontTable);
+    
+    if (ftPtr->name != NULL) {
+	free(ftPtr->name);
+    }
+    if (ftPtr->draw != 0) {
+	XftDrawDestroy(ftPtr->draw);
+    }
+    if (ftPtr->fid) {
+	XUnloadFont(ftPtr->display, ftPtr->fid);
+    }
+    Blt_DeleteHashEntry(&fontTable, ftPtr->hashPtr);
+    free(ftPtr);
+}
+
+static int
+FtMeasureChars(FtFont *ftPtr, const char *source, int nBytes, int maxLength,
+	       int flags, int *lengthPtr)
+{
+    FcChar32 c;
+    XGlyphInfo extents;
+    int clen;
+    int curX, newX;
+    int termByte = 0, termX = 0;
+    int curByte, newByte, sawNonSpace;
+    XftFont *xftPtr;
+    Blt_HashEntry *hPtr;
+    
+    hPtr = Blt_FindHashEntry(&ftPtr->fontTable, (char *)0L);
+    if (hPtr == NULL) {
+	return 0;
+    }
+    xftPtr = Blt_GetHashValue(hPtr);
+    curX = 0;
+    curByte = 0;
+    sawNonSpace = 0;
+    while (nBytes > 0) {
+	Tcl_UniChar unichar;
+
+	clen = Tcl_UtfToUniChar(source, &unichar);
+	c = (FcChar32)unichar;
+
+	if (clen <= 0) {
+	    /* This can't happen (but see #1185640) */
+	    *lengthPtr = curX;
+	    return curByte;
+	}
+
+	source += clen;
+	nBytes -= clen;
+	if (c < 256 && isspace(c)) {		/* I18N: ??? */
+	    if (sawNonSpace) {
+		termByte = curByte;
+		termX = curX;
+		sawNonSpace = 0;
+	    }
+	} else {
+	    sawNonSpace = 1;
+	}
+
+	XftTextExtents32(ftPtr->display, xftPtr, &c, 1, &extents);
+
+	newX = curX + extents.xOff;
+	newByte = curByte + clen;
+	if (maxLength >= 0 && newX > maxLength) {
+	    if ((flags & TK_PARTIAL_OK) ||
+		((flags & TK_AT_LEAST_ONE && curByte == 0))) {
+		curX = newX;
+		curByte = newByte;
+	    } else if ((flags & TK_WHOLE_WORDS) && (termX != 0)) {
+		curX = termX;
+		curByte = termByte;
+	    }
+	    break;
+	}
+
+	curX = newX;
+	curByte = newByte;
+    }
+    *lengthPtr = curX;
+    return curByte;
+}
+
+static void
+FtSetFontParams(Tk_Window tkwin, FtFont *ftPtr, XftFont *xftPtr)
+{
+    FT_UInt glyph;
+    XGlyphInfo metrics;
+    double size;
+    FcResult result;
+
+    /*
+     * Get information used for drawing underlines from the 0 angle font.
+     */
+    glyph = XftCharIndex(ftPtr->display, xftPtr, '0');
+    XftGlyphExtents(ftPtr->display, xftPtr, &glyph, 1, &metrics);
+    
+    ftPtr->underlinePos = xftPtr->descent / 2;
+    result = FcPatternGetDouble(xftPtr->pattern, FC_SIZE, 0, &size);
+    if (result != FcResultMatch) {
+	size = 12.0;
+    }
+    ftPtr->underlineHeight = (int)(PointsToPixels(tkwin,(int)size)/10.0 + 0.5);
+    if (ftPtr->underlineHeight == 0) {
+	ftPtr->underlineHeight = 1;
+    }
+    if ((ftPtr->underlinePos + ftPtr->underlineHeight) > xftPtr->descent) {
+	/*
+	 * If this set of values would cause the bottom of the underline bar
+	 * to stick below the descent of the font, jack the underline up a bit
+	 * higher.
+	 */
+	ftPtr->underlineHeight = xftPtr->descent - ftPtr->underlinePos;
+	if (ftPtr->underlineHeight == 0) {
+	    ftPtr->underlinePos--;
+	    ftPtr->underlineHeight = 1;
+	}
+    }
+    FtMeasureChars(ftPtr, "0", 1, -1, 0, &ftPtr->tabWidth);
+    if (ftPtr->tabWidth == 0) {
+	ftPtr->tabWidth = xftPtr->max_advance_width;
+    }
+    ftPtr->tabWidth *= 8;
+    /*
+     * Make sure the tab width isn't zero (some fonts may not have enough
+     * information to set a reasonable tab width).
+     */
+    if (ftPtr->tabWidth == 0) {
+	ftPtr->tabWidth = 1;
+    }
+}
+
+static FtFont *
+FtNewFont(Tcl_Interp *interp, Tk_Window tkwin, const char *fontName, 
+	  XftFont *xftPtr)
+{
+    Blt_HashEntry *hPtr;
+    FtFont *ftPtr;
+    int isNew;
+
+    ftPtr = calloc(1, sizeof(FtFont));
+    ftPtr->name = Blt_Strdup(fontName);
+    ftPtr->visual = Tk_Visual(tkwin);
+    ftPtr->colormap = Tk_Colormap(tkwin);
+    ftPtr->display = Tk_Display(tkwin);
+    ftPtr->fid = XLoadFont(Tk_Display(tkwin), "fixed");
+    ftPtr->color.pixel = 0xFFFFFFFF;
+    ftPtr->pattern = xftPtr->pattern;
+    ftPtr->refCount = 1;
+    /* 
+     * Initialize the Xft font table for this font.  Add the initial Xft font
+     * for the case of 0 degrees rotation.
+     */
+    Blt_InitHashTable(&ftPtr->fontTable, BLT_ONE_WORD_KEYS);
+    hPtr = Blt_CreateHashEntry(&ftPtr->fontTable, (char *)0L, &isNew);
+    assert(isNew);
+    Blt_SetHashValue(hPtr, xftPtr);
+
+    /* Add the font information to the font table. */
+    hPtr = Blt_CreateHashEntry(&fontTable, fontName, &isNew);
+    assert(isNew);
+    Blt_SetHashValue(hPtr, ftPtr);
+    ftPtr->hashPtr = hPtr;
+    FtSetFontParams(tkwin, ftPtr, xftPtr);
+    return ftPtr;
+}
+
+/*
+ * FtGetPattern --
+ *
+ *	Generates an pattern based upon the font description provided.  The
+ *	description is parsed base upon Tk's font selection rules (listed
+ *	below).
+ *
+ *      Tk's Font Selection Rules:
+ *
+ *	When font description font is used, the system attempts to parse the
+ *	description according to each of the above five rules, in the order
+ *	specified.  Cases [1] and [2] must match the name of an existing named
+ *	font or of a system font.  Cases [3], [4], and [5] are accepted on all
+ *	platforms and the closest available font will be used.  In some
+ *	situations it may not be possible to find any close font (e.g., the
+ *	font family was a garbage value); in that case, some system-dependant
+ *	default font is chosen.  If the font description does not match any of
+ *	the above patterns, an error is generated.
+ *
+ * [1] fontname
+ *	The name of a named font, created using the font create command.  When
+ *	a widget uses a named font, it is guaranteed that this will never
+ *	cause an error, as long as the named font exists, no mat- ter what
+ *	potentially invalid or meaningless set of attributes the named font
+ *	has.  If the named font cannot be displayed with exactly the specified
+ *	attributes, some other close font will be substituted automatically.
+ *	
+ *	[Query the named font (using "font configure") and generate an Xft
+ *	font with the same attributes.  It's assumed that these names don't
+ *	start with a '*' or '-'.]
+ *
+ * [2] systemfont
+ *	The platform-specific name of a font, interpreted by the graphics
+ *	server.  This also includes, under X, an XLFD (see [4]) for which a
+ *	single ``*'' character was used to elide more than one field in the
+ *	middle of the name.  See PLATFORM-SPECIFIC issues for a list of the
+ *	system fonts.
+ *
+ *	[Same as above. Query the named font (using "font configure") and
+ *	generate an Xft font with the same attributes.]
+ *
+ * [3] family ?size? ?style? ?style ...? 
+ *	A properly formed list whose first element is the desired font family
+ *	and whose optional second element is the desired size.  The
+ *	interpretation of the size attribute follows the same rules described
+ *	for -size in FONT OPTIONS below.  Any additional optional arguments
+ *	following the size are font styles.  Possible values for the style
+ *	arguments are as follows:
+ *
+ *	   normal, bold, roman, italic, underline, overstrike 
+ *
+ *	[Parse the list of attributes and generate a corresponding Xft font.]
+ *
+ * [4] X-font names (XLFD)
+ *	A Unix-centric font name of the form -foundry-family-weight
+ *	slant-setwidth-addstyle-pixel-point-resx-resy-spacing-width
+ *	charset-encoding.  The ``*'' character may be used to skip indi vidual
+ *	fields that the user does not care about.  There must be exactly one
+ *	``*'' for each field skipped, except that a ``*'' at the end of the
+ *	XLFD skips any remaining fields; the shortest valid XLFD is simply
+ *	``*'', signifying all fields as defaults.  Any fields that were
+ *	skipped are given default values.  For compatibility, an XLFD always
+ *	chooses a font of the specified pixel size (not point size); although
+ *	this interpretation is not strictly correct, all existing applications
+ *	using XLFDs assumed that one ``point'' was in fact one pixel and would
+ *	display incorrectly (generally larger) if the correct size font were
+ *	actually used.
+ *
+ *	[Parse the font description and generate a corresponding Xft font.]
+ *
+ * [5] option value ?option value ...?
+ *	A properly formed list of option-value pairs that specify the desired
+ *	attributes of the font, in the same format used when defining a named
+ *	font.
+ *
+ *	[Parse the option-value list and generate a corresponding Xft font.]
+ *
+ *  Extra:
+ * [6] Xft font description.
+ *
+ *	[Handle the newer Xft font descriptions.]
+ */
+
+static FcPattern *
+FtGetPattern(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+    FcPattern *pattern;
+    char *desc;
+
+    desc = Tcl_GetString(objPtr);
+    while (isspace(*desc)) {
+	desc++;			/* Skip leading blanks. */
+    }
+    if (*desc == '-') {
+	/* 
+	 * Case 1: XLFD font description or Tk attribute list.   
+	 *
+	 *   If the font description starts with a '-', it could be either an
+	 *   old fashion XLFD font description or a Tk font attribute
+	 *   option-value list.
+	 */
+	pattern = FtParseTkFontAttributeList(NULL, tkwin, objPtr);
+	if (pattern == NULL) {
+	    /* Try parsing it as an XLFD font description. */
+	    pattern = FtParseXLFD(interp, tkwin, desc);
+	}
+    } else if (*desc == '*') {
+	pattern = FtParseXLFD(interp, tkwin, desc);
+    } else if (strpbrk(desc, ":,=") != NULL) {
+	/* 
+	 * Case 2: XFT font description.   
+	 *
+	 *   If the font description contains a ':', '=', or ',' in it, we
+	 *   assume it's a new XFT font description. We want to allow these
+	 *   font descriptions too.
+	 */
+	pattern = NULL;
+	if (strstr(desc, "::") != NULL) {
+	    pattern = FtGetAttributesFromFontObj(tkwin, interp, objPtr);
+	} 
+	if (pattern == NULL) {
+	    pattern = FcNameParse((const FcChar8 *)desc);
+	}
+    } else {
+	int objc;
+	Tcl_Obj **objv;
+	/* 
+	 * Case 3: Tk-style description.   
+	 */
+	if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) || 
+	    (objc < 1)) {
+	    return NULL;		/* Can't split into a list or list is
+					 * empty. */
+	}
+	if (objc == 1) {
+	    /* 
+	     * Case 3a: Tk font object name.
+	     *
+	     *   Assuming that Tk font object names won't contain whitespace,
+	     *   see if its a font object.
+	     */
+
+	    pattern = FtGetAttributesFromFontObj(tkwin, interp, objv[0]);
+	    if (pattern == NULL) {
+		pattern = FcNameParse((const FcChar8 *)desc);
+	    }
+	} else {
+	    /* 
+	     * Case 3b: List of font attributes in the form "family size
+	     *		?attrs?"
+	     */
+	    pattern = FtParseTkDesc(interp, tkwin, objc, objv);
+	}
+    }	
+    return pattern;
+}
+
+static FcPattern *
+FtGetFontPattern(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+    FcPattern *pattern;
+
+    pattern = FtGetPattern(interp, tkwin, objPtr);
+    if (pattern != NULL) {
+	FcPattern *match;
+	FcResult result;
+
+	/* 
+	 * XftFontMatch only sets *result* on complete match failures.  So
+	 * initialize it here for a successful match. We'll accept partial
+	 * matches.
+	 */
+	result = FcResultMatch; 
+	match = XftFontMatch(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), 
+		pattern, &result);
+	FcPatternDestroy(pattern);
+	if ((match != NULL) && (result == FcResultMatch)) {
+	    return match;
+	}
+    }
+    return NULL;
+}
+
+static XftFont *
+FtOpenFont(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+    FcPattern *pattern;
+
+    pattern = FtGetFontPattern(interp, tkwin, objPtr);
+    if (pattern != NULL) {
+	return XftFontOpenPattern(Tk_Display(tkwin), pattern);
+    }
+    return NULL;
+}
+
+static FtFont *
+FtGetFontFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+    Blt_HashEntry *hPtr;
+    char *desc;
+
+    desc = Tcl_GetString(objPtr);
+    while (isspace(*desc)) {
+	desc++;			/* Skip leading blanks. */
+    }
+    /* Is the font already in the cache? */
+    hPtr = Blt_FindHashEntry(&fontTable, desc);
+    if (hPtr != NULL) {
+	FtFont *ftPtr;
+
+	ftPtr = Tcl_GetHashValue(hPtr);
+	ftPtr->refCount++;
+	return ftPtr;
+    } else {
+	XftFont *xftPtr;
+
+	xftPtr = FtOpenFont(interp, tkwin, objPtr);
+	if (xftPtr != NULL) {
+	    return FtNewFont(interp, tkwin, desc, xftPtr);
+	}
+    }
+    return NULL;
+}
+
+const char *
+Blt_GetFontFileFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *sizePtr)
+{
+    Tk_Window tkwin;
+    FcResult result;
+    FcChar8 *fileName;
+    FcPattern *pattern;
+    double size;
+
+    tkwin = Tk_MainWindow(interp);
+    if (!alias_initialized) {
+	MakeAliasTable(tkwin);
+	alias_initialized++;
+    }
+    if (!IsXRenderAvailable(tkwin)) {
+	Tcl_AppendResult(interp, "can't open Xft font: ",
+		"X server doesn't support XRENDER extension",
+		(char *)NULL);
+	return NULL;
+    }
+    pattern = FtGetFontPattern(interp, tkwin, objPtr);
+    if (pattern == NULL) {
+	return NULL;
+    }
+    result = FcPatternGetDouble(pattern, FC_SIZE, 0, &size);
+    if (result != FcResultMatch) {
+	size = 12.0;
+    }
+    result = FcPatternGetString(pattern, FC_FILE, 0, &fileName);
+    FcPatternDestroy(pattern);
+    if (result != FcResultMatch) {
+	return NULL;
+    }
+    *sizePtr = size;
+    return (const char *)fileName;
+}
+
+const char *
+Blt_GetFontFile(Tcl_Interp *interp, const char *fontName, double *sizePtr)
+{
+    Tcl_Obj *objPtr;
+    const char *fileName;
+
+    objPtr = Tcl_NewStringObj(fontName, strlen(fontName));
+    Tcl_IncrRefCount(objPtr);
+    fileName = Blt_GetFontFileFromObj(interp, objPtr, sizePtr);
+    Tcl_DecrRefCount(objPtr);
+    return fileName;
+}
+
+
+static const char *
+FtNameOfFontProc(_Blt_Font *fontPtr) 
+{
+    FtFont *ftPtr = fontPtr->clientData;
+    return ftPtr->name;
+}
+
+static const char *
+FtFamilyOfFontProc(_Blt_Font *fontPtr) 
+{
+    FtFont *ftPtr = fontPtr->clientData;
+    FcChar8 *string; 
+    FcResult result;
+
+    result = FcPatternGetString(ftPtr->pattern, FC_FAMILY, 0, &string);
+    if (result == FcResultMatch) {
+	return (const char *)string;
+    }
+    return NULL;
+}
+
+
+static Font
+FtFontIdProc(_Blt_Font *fontPtr)
+{
+    FtFont *ftPtr = fontPtr->clientData;
+    return ftPtr->fid;
+}
+
+static void
+FtGetFontMetricsProc(_Blt_Font *fontPtr, Blt_FontMetrics *mPtr)
+{
+    FtFont *ftPtr = fontPtr->clientData;
+    Blt_HashEntry *hPtr;
+
+    /* Always take font metrics from the non-rotated font. */
+    hPtr = Blt_FindHashEntry(&ftPtr->fontTable, (char *)0L);
+    if (hPtr != NULL) {
+	FT_UInt glyph;
+	XGlyphInfo metrics;
+	XftFont *xftPtr;
+
+	xftPtr = Blt_GetHashValue(hPtr);
+	glyph = XftCharIndex(ftPtr->display, xftPtr, '0');
+	XftGlyphExtents(ftPtr->display, xftPtr, &glyph, 1, &metrics);
+	mPtr->ascent = xftPtr->ascent;
+	mPtr->descent = xftPtr->descent;
+	mPtr->linespace = mPtr->ascent + mPtr->descent;
+	mPtr->tabWidth = ftPtr->tabWidth;
+	mPtr->underlinePos = ftPtr->underlinePos;
+	mPtr->underlineHeight = ftPtr->underlineHeight;
+    }
+}
+
+static int
+FtMeasureCharsProc(
+    _Blt_Font *fontPtr,
+    const char *source,	
+    int nBytes,
+    int maxLength,
+    int flags,
+    int *lengthPtr)
+{
+    FtFont *ftPtr = fontPtr->clientData;
+
+    return FtMeasureChars(ftPtr, source, nBytes, maxLength, flags, lengthPtr);
+}
+
+static int
+FtTextStringWidthProc(Blt_Font font, const char *string, int nBytes)
+{
+    int width;
+
+    FtMeasureCharsProc(font, string, nBytes, -1, 0, &width);
+    return width;
+}    
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FtPostscriptFontNameProc --
+ *
+ *	Given a Xft font, return the name of the corresponding Postscript
+ *	font.
+ *
+ * Results:
+ *	The return value is the pointsize of the given Xft font.  The name of
+ *	the Postscript font is appended to dsPtr.
+ *
+ * Side effects:
+ *	If the font does not exist on the printer, the print job will fail at
+ *	print time.  Given a "reasonable" Postscript printer, the following
+ *	Tk_Font font families should print correctly:
+ *
+ *	    Avant Garde, Arial, Bookman, Courier, Courier New, Geneva,
+ *	    Helvetica, Monaco, New Century Schoolbook, New York, Palatino,
+ *	    Symbol, Times, Times New Roman, Zapf Chancery, and Zapf Dingbats.
+ *
+ *	Any other Xft font families may not print correctly because the
+ *	computed Postscript font name may be incorrect.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+FtPostscriptFontNameProc(_Blt_Font *fontPtr, Tcl_DString *resultPtr)	
+{
+    FtFont *ftPtr = fontPtr->clientData;
+    FcChar8 *string;
+    const char *family;
+    FcResult result;
+    int weight, slant;
+    double size;
+    int flags;
+
+    result = FcPatternGetString(ftPtr->pattern, FC_FAMILY, 0, &string);
+    family = (result == FcResultMatch) ? (const char *)string : "Unknown";
+    result = FcPatternGetInteger(ftPtr->pattern, FC_WEIGHT, 0, &weight);
+    if (result != FcResultMatch) {
+	weight = FC_WEIGHT_MEDIUM;
+    }
+    result = FcPatternGetInteger(ftPtr->pattern, FC_SLANT, 0, &slant);
+    if (result != FcResultMatch) {
+	slant = FC_SLANT_ROMAN;
+    }
+    flags = 0;
+    if (weight > FC_WEIGHT_MEDIUM) {
+	flags |= FONT_BOLD;
+    } 
+    if (slant > FC_SLANT_ROMAN) {
+	flags |= FONT_ITALIC;
+    }
+    Blt_Ps_FontName(family, flags, resultPtr);
+    result = FcPatternGetDouble(ftPtr->pattern, FC_SIZE, 0, &size);
+    if (result != FcResultMatch) {
+	size = 12.0;
+    }
+    return (int)size;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FtUnderlineCharsProc --
+ *
+ *	This procedure draws an underline for a given range of characters in a
+ *	given string.  It doesn't draw the characters (which are assumed to
+ *	have been displayed previously); it just draws the underline.  This
+ *	procedure would mainly be used to quickly underline a few characters
+ *	without having to construct an underlined font.  To produce properly
+ *	underlined text, the appropriate underlined font should be constructed
+ *	and used.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Information gets displayed in "drawable".
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+FtUnderlineCharsProc(
+    Display *display,			/* Display on which to draw. */
+    Drawable drawable,			/* Window or pixmap in which to
+					 * draw. */
+    GC gc,				/* Graphics context for actually
+					 * drawing line. */
+    _Blt_Font *fontPtr,
+    const char *text,			/* String containing characters to be
+					 * underlined or overstruck. */
+    int textLen,
+    int x, int y,			/* Coordinates at which first
+					 * character of string is drawn. */
+    int first,				/* Index of first byte of first
+					 * character. */
+    int last,				/* Index of first byte after the last
+					 * character. */
+    int maxLength)
+{
+    int elWidth;
+    const char *s, *send;
+    FtFont *ftPtr = fontPtr->clientData;
+    int firstX, lastX, clipX;
+    int nBytes;
+    int accum, threshold, index, next;
+    int clipped;
+
+    /* Compute the width of an ellipsis and verify that we're not bigger 
+     * than it. */
+    elWidth = Blt_TextWidth(fontPtr, "...", 3);
+    if (maxLength < 0) {
+	maxLength = threshold = 10000;
+    } else {
+	threshold = maxLength - elWidth;
+    }
+#if !HAVE_UTF
+    nBytes = 1;
+#endif /* !HAVE_UTF */
+    /* Compute the length of the string, stopping when we've surpassed our
+     * threshold. Also save the first and last coordinates of the substring to
+     * be underlined. */
+    clipX = lastX = -1, firstX = 0;
+    accum = next = 0;
+    clipped = FALSE;
+    for (index = 0, s = text, send = s + textLen; s < send; 
+	 s += nBytes, index++, accum += next) {
+#if HAVE_UTF
+	Tcl_UniChar ch;
+#endif /* HAVE_UTF */
+    
+	if (index == first) {
+	    firstX = accum;
+	}
+	if (index == last) {
+	    lastX = accum;
+	    break;
+	}
+#if HAVE_UTF
+	nBytes =  Tcl_UtfToUniChar(s, &ch);
+#endif /* HAVE_UTF */
+	next = Blt_TextWidth(fontPtr, s, nBytes);
+	if ((next + accum) <= threshold) {
+	    clipX = accum + next;	/* Remember the last length where text
+					 * plus the ellipsis fit */
+	}
+	if ((next + accum) > maxLength) {
+	    clipped = TRUE;
+	    break;
+	}
+    }
+    if (lastX < 0) {
+	lastX = accum;
+    }
+    if (clipped) {
+	if ((s < send) && (accum < elWidth)) {
+	    return;			/* Not enough room for "..." */
+	}
+	lastX = clipX + elWidth;
+    }
+    x += firstX;
+    y += ftPtr->underlinePos + 1;
+    XFillRectangle(display, drawable, gc, x, y, (unsigned int)(lastX - firstX),
+	    (unsigned int)ftPtr->underlineHeight);
+}
+
+static int
+FtCanRotateFontProc(_Blt_Font *fontPtr, float angle) 
+{
+    FcPattern *pattern;
+    FcResult result;
+    FtFont *ftPtr = fontPtr->clientData;
+    int boolean;
+    long angle10;
+
+    angle10 = (long)((double)angle * 10.0);
+    if (Blt_FindHashEntry(&ftPtr->fontTable, (char *)angle10) != NULL) {
+	return TRUE;			/* Rotated font already exists. */
+    }
+
+    /* 
+     * I don't know if this is correct.  Some PCF fonts don't rotate properly.
+     * The chararcter positions are rotated but the glyph itself is drawn with
+     * no rotation.  The standard Adobe Helvetica font is a good example of
+     * this.  So I need to bail on those fonts.  I check if scalable=True in
+     * the Xft font pattern to determine if the font will rotate properly.
+     */
+    result = FcPatternGetBool(ftPtr->pattern, FC_SCALABLE, 0, &boolean);
+    if ((result == FcResultMatch) && (!boolean)) {
+	return FALSE;
+    }
+    {
+	XftMatrix matrix;
+	double cosTheta, sinTheta, theta;
+
+	theta = ((double)angle / 180.0) * M_PI;
+	sinTheta = sin(theta);
+	cosTheta = cos(theta);
+	
+	XftMatrixInit(&matrix);
+	XftMatrixRotate(&matrix, cosTheta, sinTheta);
+	pattern = FcPatternDuplicate(ftPtr->pattern);
+	FcPatternAddMatrix(pattern, FC_MATRIX, &matrix);
+    }
+
+    {
+	FcResult result;
+	FcPattern *match;
+
+	/* 
+	 * XftFontMatch only sets *result* on complete match failures.  So
+	 * initialize it here for a successful match. We'll accept partial
+	 * matches. 
+	 */
+	result = FcResultMatch; 
+	match = XftFontMatch(ftPtr->display, ftPtr->screenNum, pattern,&result);
+	if ((match != NULL) && (result == FcResultMatch)) {
+	    XftFont *xftPtr;
+	
+	    xftPtr = XftFontOpenPattern(ftPtr->display, match);
+	    /* Add the new rotated font to the hash table. */
+	    if (xftPtr != NULL) {
+		Blt_HashEntry *hPtr;
+		int isNew;
+		
+		hPtr = Blt_CreateHashEntry(&ftPtr->fontTable, (char *)angle10, 
+			&isNew);
+		assert(isNew);
+		Blt_SetHashValue(hPtr, xftPtr);
+		FcPatternDestroy(pattern);
+		return TRUE;
+	    }
+	}
+	FcPatternDestroy(pattern);
+    }
+    return FALSE;
+}
+
+static void
+FtDrawCharsProc(
+    Display *display,			/* Display on which to draw. */
+    Drawable drawable,			/* Window or pixmap in which to draw. */
+    GC gc,				/* Graphics context for drawing
+					 * characters. */
+    _Blt_Font *fontPtr,			/* Font in which characters will be
+					 * drawn; must be the same as font
+					 * used in *GC. */
+    int depth,
+    float angle,
+    const char *source,			/* UTF-8 string to be displayed.  Need
+					 * not be '\0' terminated.  All Tk
+					 * meta-characters (tabs, control
+					 * characters, and newlines) should be
+					 * stripped out of the string that is
+					 * passed to this function.  If they
+					 * are not stripped out, they will be
+					 * displayed as regular printing
+					 * characters. */
+    int nBytes,				/* # of bytes in string. */
+    int x, int y)			/* Coordinates at which to place
+					 * origin of string when drawing. */
+{
+    XftFont *xftPtr;
+    FtFont *ftPtr = fontPtr->clientData;
+    Blt_HashEntry *hPtr;
+    long angle10;
+
+    angle10 = (long)(angle * 10.0);
+    hPtr = Blt_FindHashEntry(&ftPtr->fontTable, (char *)angle10);
+    if (hPtr == NULL) {
+	fprintf(stderr, "can't find font %s rotated at %g degrees\n", 
+		ftPtr->name, angle);
+	return;			/* Can't find instance at requested angle. */
+    }
+    xftPtr = Blt_GetHashValue(hPtr);
+    if ((ftPtr->draw == 0) || (ftPtr->drawDepth != depth)) {
+	XftDraw *draw;
+
+	if (depth == 1) {
+	    draw = XftDrawCreateBitmap(display, drawable);
+	} else {
+	    draw = XftDrawCreate(display, drawable, ftPtr->visual, 
+				 ftPtr->colormap);
+	}
+	if (ftPtr->draw != 0) {
+	    XftDrawDestroy(ftPtr->draw);
+	}
+	ftPtr->drawDepth = depth;
+	ftPtr->draw = draw;
+	ftPtr->drawable = drawable;
+    } else {
+	Tk_ErrorHandler handler;
+        handler = Tk_CreateErrorHandler(display, -1, -1, -1, 
+		(Tk_ErrorProc *)NULL, (ClientData) NULL);
+	XftDrawChange(ftPtr->draw, drawable);
+	ftPtr->drawable = drawable;
+	Tk_DeleteErrorHandler(handler);
+    }
+    {
+	XGCValues values;
+
+	XGetGCValues(display, gc, GCForeground, &values);
+	if (values.foreground != ftPtr->color.pixel) {
+	    XColor xc;
+	    
+	    xc.pixel = values.foreground;
+	    XQueryColor(display, ftPtr->colormap, &xc);
+	    ftPtr->color.color.red = xc.red;
+	    ftPtr->color.color.green = xc.green;
+	    ftPtr->color.color.blue = xc.blue;
+	    ftPtr->color.color.alpha = 0xffff; /* Assume opaque. */
+	    ftPtr->color.pixel = values.foreground;
+	}
+    }
+
+    {
+#define NUM_SPEC    1024
+	XftGlyphFontSpec *specPtr;
+	XftGlyphFontSpec specs[NUM_SPEC+1];
+	int nSpecs;
+	const int maxCoord = 0x7FFF; /* Xft coordinates are 16 bit values */
+
+	nSpecs = 0;
+	specPtr = specs;
+	while ((nBytes > 0) && (x <= maxCoord) && (y <= maxCoord)) {
+	    XftChar32 c;
+	    int charLen;
+	    XGlyphInfo metrics;
+	    
+	    charLen = XftUtf8ToUcs4((XftChar8 *)source, &c, nBytes);
+	    if (charLen <= 0) {
+		/* This should not happen, but it can. */
+		return;
+	    }
+	    source += charLen;
+	    nBytes -= charLen;
+	    
+	    specPtr = specs + nSpecs;
+	    specPtr->font = xftPtr;
+	    specPtr->glyph = XftCharIndex(display, xftPtr, c);
+	    specPtr->x = x;
+	    specPtr->y = y;
+	    XftGlyphExtents(display, xftPtr, &specPtr->glyph, 1, &metrics);
+	    x += metrics.xOff;
+	    y += metrics.yOff;
+	    nSpecs++, specPtr++;
+	    if (nSpecs == NUM_SPEC) {
+		XftDrawGlyphFontSpec(ftPtr->draw, &ftPtr->color, specs, nSpecs);
+		nSpecs = 0;
+		specPtr = specs;
+	    }
+	}
+	if (nSpecs > 0) {
+	    XftDrawGlyphFontSpec(ftPtr->draw, &ftPtr->color, specs, nSpecs);
+	}
+    }
+}
+
+static void
+FtFreeFontProc(_Blt_Font *fontPtr)
+{
+    FtFont *ftPtr = fontPtr->clientData;
+
+    ftPtr->refCount--;
+    if (ftPtr->refCount <= 0) {
+	FtDeleteFont(ftPtr);
+    }
+    free(fontPtr);
+}
+
+#endif	/* HAVE_LIBXFT */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetFontFromObj -- 
+ *
+ *	Given a string description of a font, map the description to a
+ *	corresponding Tk_Font that represents the font.
+ *
+ * Results:
+ *	The return value is token for the font, or NULL if an error prevented
+ *	the font from being created.  If NULL is returned, an error message
+ *	will be left in the interp's result.
+ *
+ * Side effects:
+ *	The font is added to an internal database with a reference count.  For
+ *	each call to this procedure, there should eventually be a call to
+ *	Tk_FreeFont() or Tk_FreeFontFromObj() so that the database is cleaned
+ *	up when fonts aren't in use anymore.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_Font
+Blt_GetFontFromObj(
+    Tcl_Interp *interp,			/* Interp for database and error
+					 * return. */
+    Tk_Window tkwin,			/* For display on which font will be
+					 * used. */
+    Tcl_Obj *objPtr)			/* String describing font, as: named
+					 * font, native format, or parseable
+					 * string. */
+{
+    _Blt_Font *fontPtr; 
+    
+    fontPtr = calloc(1, sizeof(_Blt_Font));
+    if (fontPtr == NULL) {
+	return NULL;		/* Out of memory. */
+    }
+    if (!alias_initialized) {
+	MakeAliasTable(tkwin);
+	alias_initialized++;
+    }
+#ifdef HAVE_LIBXFT
+    if (IsXRenderAvailable(tkwin)) {
+	FtFont *ftPtr;
+
+	/* Check first if we open the specified font as an XFT font. */
+	ftPtr = FtGetFontFromObj(interp, tkwin, objPtr);
+	if (ftPtr != NULL) {
+	    fontPtr->classPtr = &ftFontClass;
+	    fontPtr->clientData = ftPtr;
+	    fontPtr->interp = interp;
+	    fontPtr->display = Tk_Display(tkwin);
+	    return fontPtr;		/* Found Xft font.  */
+	}
+	/* Otherwise fall thru and try to open font as a normal Tk font. */
+    }
+#endif	/* HAVE_LIBXFT */
+    fontPtr->clientData = TkGetFontFromObj(interp, tkwin, objPtr);
+    if (fontPtr->clientData == NULL) {
+	free(fontPtr);
+	return NULL;			/* Failed to find either Xft or Tk
+					 * fonts. */
+    }
+    fontPtr->classPtr = &tkFontClass;
+    fontPtr->interp = interp;
+    fontPtr->display = Tk_Display(tkwin);
+    return fontPtr;			/* Found Tk font. */
+}
+
+
+Blt_Font
+Blt_AllocFontFromObj(
+    Tcl_Interp *interp,		/* Interp for database and error return. */
+    Tk_Window tkwin,		/* For screen on which font will be used. */
+    Tcl_Obj *objPtr)		/* Object describing font, as: named font,
+				 * native format, or parseable string. */
+{
+    return Blt_GetFontFromObj(interp, tkwin, objPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetFont -- 
+ *
+ *	Given a string description of a font, map the description to a
+ *	corresponding Tk_Font that represents the font.
+ *
+ * Results:
+ *	The return value is token for the font, or NULL if an error prevented
+ *	the font from being created.  If NULL is returned, an error message
+ *	will be left in interp's result object.
+ *
+ * Side effects:
+ * 	The font is added to an internal database with a reference count.  For
+ * 	each call to this procedure, there should eventually be a call to
+ * 	Blt_FreeFont so that the database is cleaned up when fonts aren't in
+ * 	use anymore.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Blt_Font
+Blt_GetFont(
+    Tcl_Interp *interp,		/* Interp for database and error return. */
+    Tk_Window tkwin,		/* For screen on which font will be used. */
+    const char *string)		/* Object describing font, as: named font,
+				 * native format, or parseable string. */
+{
+    Blt_Font font;
+    Tcl_Obj *objPtr;
+
+    objPtr = Tcl_NewStringObj(string, strlen(string));
+    Tcl_IncrRefCount(objPtr);
+    font = Blt_GetFontFromObj(interp, tkwin, objPtr);
+    Tcl_DecrRefCount(objPtr);
+    return font;
+}
+
+Tcl_Interp *
+Blt_GetFontInterp(_Blt_Font *fontPtr) 
+{
+    return fontPtr->interp;
+}
+
+int
+Blt_TextWidth(_Blt_Font *fontPtr, const char *string, int length)
+{
+    if (Blt_Ps_IsPrinting()) {
+	int width;
+
+	width = Blt_Ps_TextWidth(fontPtr, string, length);
+	if (width >= 0) {
+	    return width;
+	}
+    }
+    return (*fontPtr->classPtr->textWidth)(fontPtr, string, length);
+}
+
+void
+Blt_GetFontMetrics(_Blt_Font *fontPtr, Blt_FontMetrics *fmPtr)
+{
+    if (Blt_Ps_IsPrinting()) {
+	if (Blt_Ps_GetFontMetrics(fontPtr, fmPtr) == TCL_OK) {
+	    return;
+	}
+    }
+    return (*fontPtr->classPtr->getFontMetrics)(fontPtr, fmPtr);
+}
+
+
diff --git a/tlt3.0/bltUnixWindow.c b/tlt3.0/bltUnixWindow.c
new file mode 100644
index 0000000..88fb60f
--- /dev/null
+++ b/tlt3.0/bltUnixWindow.c
@@ -0,0 +1,211 @@
+
+/*
+ * bltUnixWindow.c --
+ *
+ * This module implements additional window functionality for the BLT
+ * toolkit, such as transparent Tk windows, and reparenting Tk
+ * windows.
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+
+#include <tkPort.h>
+#include <tkInt.h>
+
+#include "bltInt.h"
+
+Window
+Blt_GetParentWindow(Display *display, Window window)
+{
+    Window root, parent;
+    Window *dummy;
+    unsigned int count;
+
+    if (XQueryTree(display, window, &root, &parent, &dummy, &count) > 0) {
+	XFree(dummy);
+	return parent;
+    }
+    return None;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetWindowId --
+ *
+ *      Returns the XID for the Tk_Window given.  Starting in Tk 8.0,
+ *      the toplevel widgets are wrapped by another window.  Currently
+ *      there's no way to get at that window, other than what is done
+ *      here: query the X window hierarchy and retrieve the parent.
+ *
+ * Results:
+ *      Returns the X Window ID of the widget.  If it's a toplevel, then
+ *	the XID of the wrapper is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+Window
+Blt_GetWindowId(Tk_Window tkwin)
+{
+    Window window;
+
+    Tk_MakeWindowExist(tkwin);
+    window = Tk_WindowId(tkwin);
+    if (Tk_IsTopLevel(tkwin)) {
+	Window parent;
+
+	parent = Blt_GetParentWindow(Tk_Display(tkwin), window);
+	if (parent != None) {
+	    window = parent;
+	}
+	window = parent;
+    }
+    return window;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * XGeometryErrorProc --
+ *
+ *	Flags errors generated from XGetGeometry calls to the X server.
+ *
+ * Results:
+ *	Always returns 0.
+ *
+ * Side Effects:
+ *	Sets a flag, indicating an error occurred.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static int
+XGeometryErrorProc(ClientData clientData, XErrorEvent *errEventPtr)
+{
+    int *errorPtr = clientData;
+
+    *errorPtr = FALSE;
+    return 0;
+}
+
+int
+Blt_GetWindowRegion(Display *display, Window window, int *xPtr, int *yPtr, 
+		    int *widthPtr, int *heightPtr)
+{
+    Tk_ErrorHandler handler;
+    Window root;
+    int any = -1;
+    int result;
+    int x, y;
+    unsigned int w, h, bw, depth;
+
+    handler = Tk_CreateErrorHandler(display, any, X_GetGeometry, any, 
+	XGeometryErrorProc, &result);
+    result = XGetGeometry(display, window, &root, &x, &y, &w, &h, &bw, &depth);
+    if (!result) {
+	goto error;
+    }
+    if (widthPtr != NULL) {
+	*widthPtr = (int)w;
+    }
+    if (heightPtr != NULL) {
+	*heightPtr = (int)h;
+    }
+    if ((xPtr != NULL) || (yPtr != NULL)) {
+	int rootX, rootY;
+	rootX = rootY = 0;
+
+	do {
+	    Window *children, parent;
+	    unsigned int n;
+	    
+	    parent = -1;
+	    result = XGetGeometry(display, window, &root, &x, &y, &w, &h, 
+				  &bw, &depth);
+	    if (!result) {
+		goto error;
+	    }
+	    rootX += x + bw;
+	    rootY += y + bw;
+	    result = XQueryTree(display, window, &root, &parent, &children, &n);
+	    XFree(children);
+	    if (!result) {
+		goto error;
+	    }
+	    window = parent;
+	} while (window != root);
+
+	if (xPtr != NULL) {
+	    *xPtr = rootX;
+	}
+	if (yPtr != NULL) {
+	    *yPtr = rootY;
+	}
+    }
+    Tk_DeleteErrorHandler(handler);
+    XSync(display, False);
+    return TCL_OK;
+ error:
+    Tk_DeleteErrorHandler(handler);
+    XSync(display, False);
+    fprintf(stderr, "failed to get window region\n");
+    return TCL_ERROR;
+}
+
+int
+Blt_GetWindowFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Window *windowPtr)
+{
+    const char *string;
+
+    string = Tcl_GetString(objPtr);
+    if (string[0] == '.') {
+	Tk_Window tkwin;
+
+	tkwin = Tk_NameToWindow(interp, string, Tk_MainWindow(interp));
+	if (tkwin == NULL) {
+	    return TCL_ERROR;
+	}
+	if (Tk_WindowId(tkwin) == None) {
+	    Tk_MakeWindowExist(tkwin);
+	}
+	*windowPtr = (Tk_IsTopLevel(tkwin)) ? Blt_GetWindowId(tkwin) : 
+	    Tk_WindowId(tkwin);
+    } else if (strcmp(string, "root") == 0) {
+	*windowPtr = Tk_RootWindow(Tk_MainWindow(interp));
+    } else {
+
+	int id;
+
+	if (Tcl_GetIntFromObj(interp, objPtr, &id) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	*windowPtr = (Window)id;
+    }
+    return TCL_OK;
+}
+
diff --git a/tlt3.0/bltUtil.c b/tlt3.0/bltUtil.c
new file mode 100644
index 0000000..bdf4b42
--- /dev/null
+++ b/tlt3.0/bltUtil.c
@@ -0,0 +1,731 @@
+
+/*
+ * bltUtil.c --
+ *
+ * This module implements utility procedures for the BLT toolkit.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+
+#include "bltInt.h"
+#include "bltOp.h"
+#include "bltHash.h"
+#include "bltDBuffer.h"
+
+char* Blt_Strdup(const char *string)
+{
+    size_t size;
+    char *ptr;
+
+    size = strlen(string) + 1;
+    ptr = malloc(size * sizeof(char));
+    if (ptr != NULL) {
+	strcpy(ptr, string);
+    }
+    return ptr;
+}
+
+void strtolower(char *s)
+{
+    while (*s != '\0') {
+	*s = tolower((unsigned char)(*s));
+	s++;
+    }
+}
+
+int TclGetLong(
+    Tcl_Interp *interp,		/* Interpreter used for error reporting if not
+				 * NULL. */
+    CONST char *src,		/* String containing a (possibly signed) long
+				 * integer in a form acceptable to
+				 * Tcl_GetLongFromObj(). */
+    long *longPtr)		/* Place to store converted long result. */
+{
+    Tcl_Obj obj;
+    int code;
+
+    obj.refCount = 1;
+    obj.bytes = (char *) src;
+    obj.length = strlen(src);
+    obj.typePtr = NULL;
+
+    code = Tcl_GetLongFromObj(interp, &obj, longPtr);
+    if (obj.refCount > 1) {
+	Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
+    }
+    return code;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetDoubleFromString --
+ *
+ *      Converts a string into a double precision number.  This differs from
+ *	Tcl's version in that it also allows NaN and +/-Inf.  There are 
+ *	cases where NaNs are used to indicate holes in the data. 
+ *
+ * Results:
+ *      Returns a standard Tcl result.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_GetDoubleFromString(Tcl_Interp *interp, const char *s, double *valuePtr)
+{
+    char *end;
+    double d;
+    
+    errno = 0;
+    d = strtod(s, &end); /* INTL: Tcl source. */
+    if (end == s) {
+	badDouble:
+        if (interp != (Tcl_Interp *) NULL) {
+            Tcl_AppendResult(interp,
+		"expected floating-point number but got \"", s, "\"", 
+		(char *) NULL);
+        }
+	return TCL_ERROR;
+    }
+    if (errno != 0 && (d == HUGE_VAL || d == -HUGE_VAL || d == 0)) {
+        if (interp != (Tcl_Interp *) NULL) {
+	    char msg[64 + TCL_INTEGER_SPACE];
+	
+	    sprintf(msg, "unknown floating-point error, errno = %d", errno);
+	    Tcl_AppendToObj(Tcl_GetObjResult(interp), msg, -1);
+	    Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", msg, (char *) NULL);
+        }
+	return TCL_ERROR;
+    }
+    while ((*end != 0) && isspace((unsigned char)(*end))) { /* INTL: ISO space. */
+	end++;
+    }
+    if (*end != 0) {
+	goto badDouble;
+    }
+    *valuePtr = d;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetDoubleFromObj --
+ *
+ *      Converts a Tcl_Obj into a double precision number.  This differs from
+ *	Tcl's version in that it also allows NaN and +/-Inf.  There are 
+ *	cases where NaNs are used to indicate holes in the data. 
+ *
+ * Results:
+ *      Returns a standard Tcl result.
+ *
+ * Side Effects:
+ *	tclDoubleType is no longer available (in 8.5) as a global variable.
+ *	We have to get a double obj and save its type pointer.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *valuePtr)
+{
+    const char *string;
+    static Tcl_ObjType *tclDoubleTypePtr = NULL;
+
+    if (tclDoubleTypePtr == NULL) {
+	Tcl_Obj *objPtr;
+	
+	objPtr = Tcl_NewDoubleObj(0.0);
+	tclDoubleTypePtr = (Tcl_ObjType*)(objPtr->typePtr);
+	Tcl_DecrRefCount(objPtr);
+    }
+    if (objPtr->typePtr == tclDoubleTypePtr) {
+	*valuePtr = objPtr->internalRep.doubleValue;
+	return TCL_OK;
+    }
+    string = Tcl_GetString(objPtr);
+    return Blt_GetDoubleFromString(interp, string, valuePtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_CompareDictionary
+ *
+ *	This function compares two strings as if they were being used in
+ *	an index or card catalog.  The case of alphabetic characters is
+ *	ignored, except to break ties.  Thus "B" comes before "b" but
+ *	after "a".  Also, integers embedded in the strings compare in
+ *	numerical order.  In other words, "x10y" comes after "x9y", not
+ *      before it as it would when using strcmp().
+ *
+ * Results:
+ *      A negative result means that the first element comes before the
+ *      second, and a positive result means that the second element
+ *      should come first.  A result of zero means the two elements
+ *      are equal and it doesn't matter which comes first.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+#if HAVE_UTF
+int
+Blt_DictionaryCompare(const char *left, const char *right)
+{
+    Tcl_UniChar uniLeft, uniRight, uniLeftLower, uniRightLower;
+    int diff, zeros;
+    int secondaryDiff = 0;
+
+    for(;;) {
+	if ((isdigit((unsigned char)(*right))) && (isdigit((unsigned char)(*left)))) { 
+	    /*
+	     * There are decimal numbers embedded in the two strings.  Compare
+	     * them as numbers, rather than strings.  If one number has more
+	     * leading zeros than the other, the number with more leading
+	     * zeros sorts later, but only as a secondary choice.
+	     */
+
+	    zeros = 0;
+	    while ((*right == '0') && (isdigit((unsigned char)(right[1])))) {
+		right++;
+		zeros--;
+	    }
+	    while ((*left == '0') && (isdigit((unsigned char)(left[1])))) {
+		left++;
+		zeros++;
+	    }
+	    if (secondaryDiff == 0) {
+		secondaryDiff = zeros;
+	    }
+
+	    /*
+	     * The code below compares the numbers in the two strings without
+	     * ever converting them to integers.  It does this by first
+	     * comparing the lengths of the numbers and then comparing the
+	     * digit values.
+	     */
+
+	    diff = 0;
+	    for (;;) {
+		if (diff == 0) {
+		    diff = (unsigned char)(*left) - (unsigned char)(*right);
+		}
+		right++;
+		left++;
+
+		/* Ignore commas in numbers. */
+		if (*left == ',') {
+		    left++;
+		}
+		if (*right == ',') {
+		    right++;
+		}
+
+		if (!isdigit((unsigned char)(*right))) { /* INTL: digit */
+		    if (isdigit((unsigned char)(*left))) { /* INTL: digit */
+			return 1;
+		    } else {
+			/*
+			 * The two numbers have the same length. See
+			 * if their values are different.
+			 */
+
+			if (diff != 0) {
+			    return diff;
+			}
+			break;
+		    }
+		} else if (!isdigit((unsigned char)(*left))) { /* INTL: digit */
+		    return -1;
+		}
+	    }
+	    continue;
+	}
+
+	/*
+	 * Convert character to Unicode for comparison purposes.  If either
+	 * string is at the terminating null, do a byte-wise comparison and
+	 * bail out immediately.
+	 */
+	if ((*left != '\0') && (*right != '\0')) {
+	    left += Tcl_UtfToUniChar(left, &uniLeft);
+	    right += Tcl_UtfToUniChar(right, &uniRight);
+	    /*
+	     * Convert both chars to lower for the comparison, because
+	     * dictionary sorts are case insensitve.  Convert to lower, not
+	     * upper, so chars between Z and a will sort before A (where most
+	     * other interesting punctuations occur)
+	     */
+	    uniLeftLower = Tcl_UniCharToLower(uniLeft);
+	    uniRightLower = Tcl_UniCharToLower(uniRight);
+	} else {
+	    diff = (unsigned char)(*left) - (unsigned char)(*right);
+	    break;
+	}
+
+        diff = uniLeftLower - uniRightLower;
+        if (diff) {
+	    return diff;
+	} else if (secondaryDiff == 0) {
+	    if (Tcl_UniCharIsUpper(uniLeft) &&
+		    Tcl_UniCharIsLower(uniRight)) {
+		secondaryDiff = -1;
+	    } else if (Tcl_UniCharIsUpper(uniRight)
+		    && Tcl_UniCharIsLower(uniLeft)) {
+		secondaryDiff = 1;
+	    }
+        }
+    }
+    if (diff == 0) {
+	diff = secondaryDiff;
+    }
+    return diff;
+}
+
+#else 
+
+int
+Blt_DictionaryCompare(const char *left, const char *right) 
+{
+    int diff, zeros;
+    int secondaryDiff = 0;
+
+    while (1) {
+	if (isdigit((unsigned char)(*right)) && isdigit((unsigned char)(*left))) {
+	    /*
+	     * There are decimal numbers embedded in the two strings.  Compare
+	     * them as numbers, rather than strings.  If one number has more
+	     * leading zeros than the other, the number with more leading
+	     * zeros sorts later, but only as a secondary choice.
+	     */
+
+	    zeros = 0;
+	    while ((*right == '0') && (isdigit((unsigned char)(right[1])))) {
+		right++;
+		zeros--;
+	    }
+	    while ((*left == '0') && (isdigit((unsigned char)(left[1])))) {
+		left++;
+		zeros++;
+	    }
+	    if (secondaryDiff == 0) {
+		secondaryDiff = zeros;
+	    }
+
+	    /*
+	     * The code below compares the numbers in the two strings without
+	     * ever converting them to integers.  It does this by first
+	     * comparing the lengths of the numbers and then comparing the
+	     * digit values.
+	     */
+
+	    diff = 0;
+	    while (1) {
+		if (diff == 0) {
+		    diff = (unsigned char)(*left) - (unsigned char)(*right);
+		}
+		right++;
+		left++;
+		/* Ignore commas in numbers. */
+		if (*left == ',') {
+		    left++;
+		}
+		if (*right == ',') {
+		    right++;
+		}
+		if (!isdigit((unsigned char)(*right))) {
+		    if (isdigit((unsigned char)(*left))) {
+			return 1;
+		    } else {
+			/*
+			 * The two numbers have the same length. See
+			 * if their values are different.
+			 */
+
+			if (diff != 0) {
+			    return diff;
+			}
+			break;
+		    }
+		} else if (!isdigit((unsigned char)(*left))) {
+		    return -1;
+		}
+	    }
+	    continue;
+	}
+        diff = (unsigned char)(*left) - (unsigned char)(*right);
+        if (diff) {
+            if (isupper((unsigned char)(*left)) && islower((unsigned char)(*right))) {
+                diff = (unsigned char)(tolower(*left)) - (unsigned char)(*right);
+                if (diff) {
+		    return diff;
+                } else if (secondaryDiff == 0) {
+		    secondaryDiff = -1;
+                }
+            } else if (isupper((unsigned char)(*right)) && islower((unsigned char)(*left))) {
+                diff = (unsigned char)(*left) - (unsigned char)(tolower((unsigned char)(*right)));
+                if (diff) {
+		    return diff;
+                } else if (secondaryDiff == 0) {
+		    secondaryDiff = 1;
+                }
+            } else {
+                return diff;
+            }
+        }
+        if (*left == 0) {
+	    break;
+	}
+        left++;
+        right++;
+    }
+    if (diff == 0) {
+	diff = secondaryDiff;
+    }
+    return diff;
+}
+#endif
+
+/*ARGSUSED*/
+void
+Blt_Panic TCL_VARARGS_DEF(const char *, arg1)
+{
+    const char *format;
+    va_list args;
+
+    format = TCL_VARARGS_START(const char *, arg1, args);
+    vfprintf(stderr, format, args);
+    fprintf(stderr, "\n");
+    fflush(stderr);
+    abort();
+}
+
+/*ARGSUSED*/
+int sprintf_s(char *s, size_t size, const char *fmt, /*args*/ ...) 
+{
+    va_list ap;
+    int n;
+
+    va_start(ap, fmt);
+    n = vsnprintf(s, size, fmt, ap);
+    if ((n != (int)size) && (size > 0)) {
+	s[size-1] = '\0';
+    }
+    va_end(ap);
+    return n;
+}
+
+static char stringRep[200];
+
+const char *
+Blt_Itoa(int value)
+{
+    sprintf_s(stringRep, 200, "%d", value);
+    return stringRep;
+}
+
+const char *
+Blt_Ltoa(long value)
+{
+    sprintf_s(stringRep, 200, "%ld", value);
+    return stringRep;
+}
+
+const char *
+Blt_Utoa(unsigned int value)
+{
+    sprintf_s(stringRep, 200, "%u", value);
+    return stringRep;
+}
+
+const char *
+Blt_Dtoa(Tcl_Interp *interp, double value)
+{
+    Tcl_PrintDouble(interp, value, stringRep);
+    return stringRep;
+}
+
+int
+Blt_GlobalEvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int i;
+    int result;
+
+    for (i = 0; i < objc; i++) {
+	Tcl_IncrRefCount(objv[i]);
+    }
+    result = Tcl_EvalObjv(interp, objc, objv, TCL_EVAL_GLOBAL);
+    for (i = 0; i < objc; i++) {
+	Tcl_DecrRefCount(objv[i]);
+    }
+    return result;
+}
+
+int
+Blt_GetCountFromObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr,
+    int check,				/* Can be COUNT_POS, COUNT_NNEG,
+					 * or COUNT_ANY, */
+    long *valuePtr)
+{
+    long count;
+
+    if (Tcl_GetLongFromObj(interp, objPtr, &count) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    switch (check) {
+    case COUNT_NNEG:
+	if (count < 0) {
+	    Tcl_AppendResult(interp, "bad value \"", Tcl_GetString(objPtr), 
+		"\": can't be negative", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	break;
+    case COUNT_POS:
+	if (count <= 0) {
+	    Tcl_AppendResult(interp, "bad value \"", Tcl_GetString(objPtr), 
+		"\": must be positive", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	break;
+    case COUNT_ANY:
+	break;
+    }
+    *valuePtr = count;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BinaryOpSearch --
+ *
+ *      Performs a binary search on the array of command operation
+ *      specifications to find a partial, anchored match for the given
+ *      operation string.
+ *
+ * Results:
+ *	If the string matches unambiguously the index of the specification in
+ *	the array is returned.  If the string does not match, even as an
+ *	abbreviation, any operation, -1 is returned.  If the string matches,
+ *	but ambiguously -2 is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+BinaryOpSearch(Blt_OpSpec *specs, int nSpecs, const char *string, int length)
+{
+    char c;
+    int high, low;
+
+    low = 0;
+    high = nSpecs - 1;
+    c = string[0];
+    while (low <= high) {
+	Blt_OpSpec *specPtr;
+	int compare;
+	int median;
+	
+	median = (low + high) >> 1;
+	specPtr = specs + median;
+
+	/* Test the first character */
+	compare = c - specPtr->name[0];
+	if (compare == 0) {
+	    /* Now test the entire string */
+	    compare = strncmp(string, specPtr->name, length);
+	    if (compare == 0) {
+		if ((int)length < specPtr->minChars) {
+		    return -2;	/* Ambiguous operation name */
+		}
+	    }
+	}
+	if (compare < 0) {
+	    high = median - 1;
+	} else if (compare > 0) {
+	    low = median + 1;
+	} else {
+	    return median;		/* Op found. */
+	}
+    }
+    return -1;				/* Can't find operation */
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LinearOpSearch --
+ *
+ *      Performs a binary search on the array of command operation
+ *      specifications to find a partial, anchored match for the given
+ *      operation string.
+ *
+ * Results:
+ *	If the string matches unambiguously the index of the specification in
+ *	the array is returned.  If the string does not match, even as an
+ *	abbreviation, any operation, -1 is returned.  If the string matches,
+ *	but ambiguously -2 is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+LinearOpSearch(Blt_OpSpec *specs, int nSpecs, const char *string, int length)
+{
+    Blt_OpSpec *specPtr;
+    char c;
+    int nMatches, last;
+    int i;
+
+    c = string[0];
+    nMatches = 0;
+    last = -1;
+    for (specPtr = specs, i = 0; i < nSpecs; i++, specPtr++) {
+	if ((c == specPtr->name[0]) && 
+	    (strncmp(string, specPtr->name, length) == 0)) {
+	    last = i;
+	    nMatches++;
+	    if ((int)length == specPtr->minChars) {
+		break;
+	    }
+	}
+    }
+    if (nMatches > 1) {
+	return -2;			/* Ambiguous operation name */
+    } 
+    if (nMatches == 0) {
+	return -1;			/* Can't find operation */
+    } 
+    return last;			/* Op found. */
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetOpFromObj --
+ *
+ *      Find the command operation given a string name.  This is useful where
+ *      a group of command operations have the same argument signature.
+ *
+ * Results:
+ *      If found, a pointer to the procedure (function pointer) is returned.
+ *      Otherwise NULL is returned and an error message containing a list of
+ *      the possible commands is returned in interp->result.
+ *
+ *---------------------------------------------------------------------------
+ */
+void *
+Blt_GetOpFromObj(
+    Tcl_Interp *interp,			/* Interpreter to report errors to */
+    int nSpecs,				/* # of specifications in array */
+    Blt_OpSpec *specs,			/* Op specification array */
+    int operPos,			/* Position of operation in argument
+					 * list. */
+    int objc,				/* # of arguments in the argument *
+					 * vector.  This includes any
+					 * prefixed arguments */
+    Tcl_Obj *const *objv,		/* Argument vector */
+    int flags)
+{
+    Blt_OpSpec *specPtr;
+    const char *string;
+    int length;
+    int n;
+
+    if (objc <= operPos) {		/* No operation argument */
+	Tcl_AppendResult(interp, "wrong # args: ", (char *)NULL);
+      usage:
+	Tcl_AppendResult(interp, "should be one of...", (char *)NULL);
+	for (n = 0; n < nSpecs; n++) {
+	    int i;
+
+	    Tcl_AppendResult(interp, "\n  ", (char *)NULL);
+	    for (i = 0; i < operPos; i++) {
+		Tcl_AppendResult(interp, Tcl_GetString(objv[i]), " ", 
+			 (char *)NULL);
+	    }
+	    specPtr = specs + n;
+	    Tcl_AppendResult(interp, specPtr->name, " ", specPtr->usage,
+		(char *)NULL);
+	}
+	return NULL;
+    }
+    string = Tcl_GetStringFromObj(objv[operPos], &length);
+    if (flags & BLT_OP_LINEAR_SEARCH) {
+	n = LinearOpSearch(specs, nSpecs, string, length);
+    } else {
+	n = BinaryOpSearch(specs, nSpecs, string, length);
+    }
+    if (n == -2) {
+	char c;
+
+	Tcl_AppendResult(interp, "ambiguous", (char *)NULL);
+	if (operPos > 2) {
+	    Tcl_AppendResult(interp, " ", Tcl_GetString(objv[operPos - 1]), 
+		(char *)NULL);
+	}
+	Tcl_AppendResult(interp, " operation \"", string, "\" matches: ",
+	    (char *)NULL);
+
+	c = string[0];
+	for (n = 0; n < nSpecs; n++) {
+	    specPtr = specs + n;
+	    if ((c == specPtr->name[0]) &&
+		(strncmp(string, specPtr->name, length) == 0)) {
+		Tcl_AppendResult(interp, " ", specPtr->name, (char *)NULL);
+	    }
+	}
+	return NULL;
+
+    } else if (n == -1) {	      /* Can't find operation, display help */
+	Tcl_AppendResult(interp, "bad", (char *)NULL);
+	if (operPos > 2) {
+	    Tcl_AppendResult(interp, " ", Tcl_GetString(objv[operPos - 1]), 
+		(char *)NULL);
+	}
+	Tcl_AppendResult(interp, " operation \"", string, "\": ", (char *)NULL);
+	goto usage;
+    }
+    specPtr = specs + n;
+    if ((objc < specPtr->minArgs) || 
+	((specPtr->maxArgs > 0) && (objc > specPtr->maxArgs))) {
+	int i;
+
+	Tcl_AppendResult(interp, "wrong # args: should be \"", (char *)NULL);
+	for (i = 0; i < operPos; i++) {
+	    Tcl_AppendResult(interp, Tcl_GetString(objv[i]), " ", 
+		(char *)NULL);
+	}
+	Tcl_AppendResult(interp, specPtr->name, " ", specPtr->usage, "\"",
+	    (char *)NULL);
+	return NULL;
+    }
+    return specPtr->proc;
+}
+
diff --git a/tlt3.0/bltVecCmd.c b/tlt3.0/bltVecCmd.c
new file mode 100644
index 0000000..2fd6beb
--- /dev/null
+++ b/tlt3.0/bltVecCmd.c
@@ -0,0 +1,2418 @@
+/*
+ * bltVecCmd.c --
+ *
+ * This module implements vector data objects.
+ *
+ *	Copyright 1995-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Code for binary data read operation was donated by Harold Kirsch.
+ *
+ */
+
+/*
+ * TODO:
+ *	o Add H. Kirsch's vector binary read operation
+ *		x binread file0
+ *		x binread -file file0
+ *
+ *	o Add ASCII/binary file reader
+ *		x read fileName
+ *
+ *	o Allow Tcl-based client notifications.
+ *		vector x
+ *		x notify call Display
+ *		x notify delete Display
+ *		x notify reorder #1 #2
+ */
+
+#include <assert.h>
+#include <math.h>
+#include <float.h>
+
+#include "bltInt.h"
+#include "bltVecInt.h"
+#include "bltOp.h"
+#include "bltNsUtil.h"
+#include "bltSwitch.h"
+
+typedef int (VectorCmdProc)(Vector *vPtr, Tcl_Interp *interp, int objc, 
+	Tcl_Obj *const *objv);
+
+static Blt_SwitchParseProc ObjToFFTVector;
+static Blt_SwitchCustom fftVectorSwitch = {
+    ObjToFFTVector, NULL, (ClientData)0,
+};
+
+static Blt_SwitchParseProc ObjToIndex;
+static Blt_SwitchCustom indexSwitch = {
+    ObjToIndex, NULL, (ClientData)0,
+};
+
+typedef struct {
+    Tcl_Obj *formatObjPtr;
+    int from, to;
+} PrintSwitches;
+
+static Blt_SwitchSpec printSwitches[] = 
+{
+    {BLT_SWITCH_OBJ,    "-format", "string",
+	Blt_Offset(PrintSwitches, formatObjPtr), 0},
+    {BLT_SWITCH_CUSTOM, "-from",   "index",
+	Blt_Offset(PrintSwitches, from),         0, 0, &indexSwitch},
+    {BLT_SWITCH_CUSTOM, "-to",     "index",
+	Blt_Offset(PrintSwitches, to),           0, 0, &indexSwitch},
+    {BLT_SWITCH_END}
+};
+
+
+typedef struct {
+    int flags;
+} SortSwitches;
+
+#define SORT_DECREASING (1<<0)
+#define SORT_UNIQUE	(1<<1)
+
+static Blt_SwitchSpec sortSwitches[] = 
+{
+    {BLT_SWITCH_BITMASK, "-decreasing", "",
+	Blt_Offset(SortSwitches, flags),   0, SORT_DECREASING},
+    {BLT_SWITCH_BITMASK, "-reverse",   "",
+	Blt_Offset(SortSwitches, flags),   0, SORT_DECREASING},
+    {BLT_SWITCH_BITMASK, "-uniq",     "", 
+	Blt_Offset(SortSwitches, flags),   0, SORT_UNIQUE},
+    {BLT_SWITCH_END}
+};
+
+typedef struct {
+    double delta;
+    Vector *imagPtr;	/* Vector containing imaginary part. */
+    Vector *freqPtr;	/* Vector containing frequencies. */
+    VectorInterpData *dataPtr;
+    int mask;			/* Flags controlling FFT. */
+} FFTData;
+
+
+static Blt_SwitchSpec fftSwitches[] = {
+    {BLT_SWITCH_CUSTOM, "-imagpart",    "vector",
+	Blt_Offset(FFTData, imagPtr), 0, 0, &fftVectorSwitch},
+    {BLT_SWITCH_BITMASK, "-noconstant", "",
+	Blt_Offset(FFTData, mask), 0, FFT_NO_CONSTANT},
+    {BLT_SWITCH_BITMASK, "-spectrum", "",
+	  Blt_Offset(FFTData, mask), 0, FFT_SPECTRUM},
+    {BLT_SWITCH_BITMASK, "-bartlett",  "",
+	 Blt_Offset(FFTData, mask), 0, FFT_BARTLETT},
+    {BLT_SWITCH_DOUBLE, "-delta",   "float",
+	Blt_Offset(FFTData, mask), 0, 0, },
+    {BLT_SWITCH_CUSTOM, "-frequencies", "vector",
+	Blt_Offset(FFTData, freqPtr), 0, 0, &fftVectorSwitch},
+    {BLT_SWITCH_END}
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToFFTVector --
+ *
+ *	Convert a string representing a vector into its vector structure.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToFFTVector(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    const char *switchName,	/* Not used. */
+    Tcl_Obj *objPtr,		/* Name of vector. */
+    char *record,		/* Structure record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    FFTData *dataPtr = (FFTData *)record;
+    Vector *vPtr;
+    Vector **vPtrPtr = (Vector **)(record + offset);
+    int isNew;			/* Not used. */
+    char *string;
+
+    string = Tcl_GetString(objPtr);
+    vPtr = Blt_Vec_Create(dataPtr->dataPtr, string, string, string, &isNew);
+    if (vPtr == NULL) {
+	return TCL_ERROR;
+    }
+    *vPtrPtr = vPtr;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ObjToIndex --
+ *
+ *	Convert a string representing a vector into its vector structure.
+ *
+ * Results:
+ *	The return value is a standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ObjToIndex(
+    ClientData clientData,	/* Contains the vector in question to verify
+				 * its length. */
+    Tcl_Interp *interp,		/* Interpreter to send results back to */
+    const char *switchName,	/* Not used. */
+    Tcl_Obj *objPtr,		/* Name of vector. */
+    char *record,		/* Structure record */
+    int offset,			/* Offset to field in structure */
+    int flags)			/* Not used. */
+{
+    Vector *vPtr = clientData;
+    int *indexPtr = (int *)(record + offset);
+    int index;
+
+    if (Blt_Vec_GetIndex(interp, vPtr, Tcl_GetString(objPtr), &index, 
+	INDEX_CHECK, (Blt_VectorIndexProc **)NULL) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    *indexPtr = index;
+    return TCL_OK;
+
+}
+
+static Tcl_Obj *
+GetValues(Vector *vPtr, int first, int last)
+{ 
+    Tcl_Obj *listObjPtr;
+    double *vp, *vend;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    for (vp = vPtr->valueArr + first, vend = vPtr->valueArr + last; vp <= vend;
+	vp++) { 
+	Tcl_ListObjAppendElement(vPtr->interp, listObjPtr, 
+		Tcl_NewDoubleObj(*vp));
+    } 
+    return listObjPtr;
+}
+
+static void
+ReplicateValue(Vector *vPtr, int first, int last, double value)
+{ 
+    double *vp, *vend;
+ 
+    for (vp = vPtr->valueArr + first, vend = vPtr->valueArr + last; 
+	 vp <= vend; vp++) { 
+	*vp = value; 
+    } 
+    vPtr->notifyFlags |= UPDATE_RANGE; 
+}
+
+static int
+CopyList(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int i;
+
+    if (Blt_Vec_SetLength(interp, vPtr, objc) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    for (i = 0; i < objc; i++) {
+	double value;
+
+	if (Blt_ExprDoubleFromObj(interp, objv[i], &value) != TCL_OK) {
+	    Blt_Vec_SetLength(interp, vPtr, i);
+	    return TCL_ERROR;
+	}
+	vPtr->valueArr[i] = value;
+    }
+    return TCL_OK;
+}
+
+static int
+AppendVector(Vector *destPtr, Vector *srcPtr)
+{
+    size_t nBytes;
+    size_t oldSize, newSize;
+
+    oldSize = destPtr->length;
+    newSize = oldSize + srcPtr->last - srcPtr->first + 1;
+    if (Blt_Vec_ChangeLength(destPtr->interp, destPtr, newSize) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    nBytes = (newSize - oldSize) * sizeof(double);
+    memcpy((char *)(destPtr->valueArr + oldSize),
+	(srcPtr->valueArr + srcPtr->first), nBytes);
+    destPtr->notifyFlags |= UPDATE_RANGE;
+    return TCL_OK;
+}
+
+static int
+AppendList(Vector *vPtr, int objc, Tcl_Obj *const *objv)
+{
+    Tcl_Interp *interp = vPtr->interp;
+    int count;
+    int i;
+    double value;
+    int oldSize;
+
+    oldSize = vPtr->length;
+    if (Blt_Vec_ChangeLength(interp, vPtr, vPtr->length + objc) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    count = oldSize;
+    for (i = 0; i < objc; i++) {
+	if (Blt_ExprDoubleFromObj(interp, objv[i], &value) != TCL_OK) {
+	    Blt_Vec_ChangeLength(interp, vPtr, count);
+	    return TCL_ERROR;
+	}
+	vPtr->valueArr[count++] = value;
+    }
+    vPtr->notifyFlags |= UPDATE_RANGE;
+    return TCL_OK;
+}
+
+/* Vector instance option commands */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AppendOp --
+ *
+ *	Appends one of more TCL lists of values, or vector objects onto the
+ *	end of the current vector object.
+ *
+ * Results:
+ *	A standard TCL result.  If a current vector can't be created, 
+ *	resized, any of the named vectors can't be found, or one of lists of
+ *	values is invalid, TCL_ERROR is returned.
+ *
+ * Side Effects:
+ *	Clients of current vector will be notified of the change.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+AppendOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int i;
+    int result;
+    Vector *v2Ptr;
+
+    for (i = 2; i < objc; i++) {
+	v2Ptr = Blt_Vec_ParseElement((Tcl_Interp *)NULL, vPtr->dataPtr, 
+	       Tcl_GetString(objv[i]), (const char **)NULL, NS_SEARCH_BOTH);
+	if (v2Ptr != NULL) {
+	    result = AppendVector(vPtr, v2Ptr);
+	} else {
+	    int nElem;
+	    Tcl_Obj **elemObjArr;
+
+	    if (Tcl_ListObjGetElements(interp, objv[i], &nElem, &elemObjArr) 
+		!= TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    result = AppendList(vPtr, nElem, elemObjArr);
+	}
+	if (result != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    if (objc > 2) {
+	if (vPtr->flush) {
+	    Blt_Vec_FlushCache(vPtr);
+	}
+	Blt_Vec_UpdateClients(vPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ClearOp --
+ *
+ *	Deletes all the accumulated array indices for the TCL array associated
+ *	will the vector.  This routine can be used to free excess memory from
+ *	a large vector.
+ *
+ * Results:
+ *	Always returns TCL_OK.
+ *
+ * Side Effects:
+ *	Memory used for the entries of the TCL array variable is freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ClearOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Blt_Vec_FlushCache(vPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DeleteOp --
+ *
+ *	Deletes the given indices from the vector.  If no indices are provided
+ *	the entire vector is deleted.
+ *
+ * Results:
+ *	A standard TCL result.  If any of the given indices is invalid,
+ *	interp->result will an error message and TCL_ERROR is returned.
+ *
+ * Side Effects:
+ *	The clients of the vector will be notified of the vector
+ *	deletions.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+DeleteOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    unsigned char *unsetArr;
+    int i, j;
+    int count;
+    char *string;
+
+    /* FIXME: Don't delete vector with no indices.  */
+    if (objc == 2) {
+	Blt_Vec_Free(vPtr);
+	return TCL_OK;
+    }
+
+    /* Allocate an "unset" bitmap the size of the vector. */
+    unsetArr = calloc(sizeof(unsigned char), (vPtr->length + 7) / 8);
+#define SetBit(i) \
+    unsetArr[(i) >> 3] |= (1 << ((i) & 0x07))
+#define GetBit(i) \
+    (unsetArr[(i) >> 3] & (1 << ((i) & 0x07)))
+
+    for (i = 2; i < objc; i++) {
+	string = Tcl_GetString(objv[i]);
+	if (Blt_Vec_GetIndexRange(interp, vPtr, string, 
+		(INDEX_COLON | INDEX_CHECK), (Blt_VectorIndexProc **) NULL) 
+		!= TCL_OK) {
+	    free(unsetArr);
+	    return TCL_ERROR;
+	}
+	for (j = vPtr->first; j <= vPtr->last; j++) {
+	    SetBit(j);		/* Mark the range of elements for deletion. */
+	}
+    }
+    count = 0;
+    for (i = 0; i < vPtr->length; i++) {
+	if (GetBit(i)) {
+	    continue;		/* Skip elements marked for deletion. */
+	}
+	if (count < i) {
+	    vPtr->valueArr[count] = vPtr->valueArr[i];
+	}
+	count++;
+    }
+    free(unsetArr);
+    vPtr->length = count;
+    if (vPtr->flush) {
+	Blt_Vec_FlushCache(vPtr);
+    }
+    Blt_Vec_UpdateClients(vPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DupOp --
+ *
+ *	Creates one or more duplicates of the vector object.
+ *
+ * Results:
+ *	A standard TCL result.  If a new vector can't be created,
+ *      or and existing vector resized, TCL_ERROR is returned.
+ *
+ * Side Effects:
+ *	Clients of existing vectors will be notified of the change.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+DupOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int i;
+
+    for (i = 2; i < objc; i++) {
+	Vector *v2Ptr;
+	char *name;
+	int isNew;
+
+	name = Tcl_GetString(objv[i]);
+	v2Ptr = Blt_Vec_Create(vPtr->dataPtr, name, name, name, &isNew);
+	if (v2Ptr == NULL) {
+	    return TCL_ERROR;
+	}
+	if (v2Ptr == vPtr) {
+	    continue;
+	}
+	if (Blt_Vec_Duplicate(v2Ptr, vPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (!isNew) {
+	    if (v2Ptr->flush) {
+		Blt_Vec_FlushCache(v2Ptr);
+	    }
+	    Blt_Vec_UpdateClients(v2Ptr);
+	}
+    }
+    return TCL_OK;
+}
+
+
+/* spinellia at acm.org START */
+
+/* fft implementation */
+/*ARGSUSED*/
+static int
+FFTOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Vector *v2Ptr = NULL;
+    int isNew;
+    FFTData data;
+    char *realVecName;
+
+    memset(&data, 0, sizeof(data));
+    data.delta = 1.0;
+
+    realVecName = Tcl_GetString(objv[2]);
+    v2Ptr = Blt_Vec_Create(vPtr->dataPtr, realVecName, realVecName, 
+	realVecName, &isNew);
+    if (v2Ptr == NULL) {
+        return TCL_ERROR;
+    }
+    if (v2Ptr == vPtr) {
+	Tcl_AppendResult(interp, "real vector \"", realVecName, "\"", 
+		" can't be the same as the source", (char *)NULL);
+        return TCL_ERROR;
+    }
+    if (Blt_ParseSwitches(interp, fftSwitches, objc - 3, objv + 3, &data, 
+	BLT_SWITCH_DEFAULTS) < 0) {
+	return TCL_ERROR;
+    }
+    if (Blt_Vec_FFT(interp, v2Ptr, data.imagPtr, data.freqPtr, data.delta,
+	      data.mask, vPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    /* Update bookkeeping. */
+    if (!isNew) {
+	if (v2Ptr->flush) {
+	    Blt_Vec_FlushCache(v2Ptr);
+	}
+	Blt_Vec_UpdateClients(v2Ptr);
+    }
+    if (data.imagPtr != NULL) {
+        if (data.imagPtr->flush) {
+            Blt_Vec_FlushCache(data.imagPtr);
+        }
+        Blt_Vec_UpdateClients(data.imagPtr);
+    }
+    if (data.freqPtr != NULL) {
+        if (data.freqPtr->flush) {
+            Blt_Vec_FlushCache(data.freqPtr);
+        }
+        Blt_Vec_UpdateClients(data.freqPtr);
+    }
+    return TCL_OK;
+}	
+
+/*ARGSUSED*/
+static int
+InverseFFTOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int isNew;
+    char *name;
+    Vector *srcImagPtr;
+    Vector *destRealPtr;
+    Vector *destImagPtr;
+
+    name = Tcl_GetString(objv[2]);
+    if (Blt_Vec_LookupName(vPtr->dataPtr, name, &srcImagPtr) != TCL_OK ) {
+	return TCL_ERROR;
+    }
+    name = Tcl_GetString(objv[3]);
+    destRealPtr = Blt_Vec_Create(vPtr->dataPtr, name, name, name, &isNew);
+    name = Tcl_GetString(objv[4]);
+    destImagPtr = Blt_Vec_Create(vPtr->dataPtr, name, name, name, &isNew);
+
+    if (Blt_Vec_InverseFFT(interp, srcImagPtr, destRealPtr, destImagPtr, vPtr) 
+	!= TCL_OK ){
+	return TCL_ERROR;
+    }
+    if (destRealPtr->flush) {
+	Blt_Vec_FlushCache(destRealPtr);
+    }
+    Blt_Vec_UpdateClients(destRealPtr);
+
+    if (destImagPtr->flush) {
+	Blt_Vec_FlushCache(destImagPtr);
+    }
+    Blt_Vec_UpdateClients(destImagPtr);
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * IndexOp --
+ *
+ *	Sets or reads the value of the index.  This simulates what the
+ *	vector's variable does.
+ *
+ * Results:
+ *	A standard TCL result.  If the index is invalid,
+ *	interp->result will an error message and TCL_ERROR is returned.
+ *	Otherwise interp->result will contain the values.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+IndexOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int first, last;
+    char *string;
+
+    string = Tcl_GetString(objv[2]);
+    if (Blt_Vec_GetIndexRange(interp, vPtr, string, INDEX_ALL_FLAGS, 
+		(Blt_VectorIndexProc **) NULL) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    first = vPtr->first, last = vPtr->last;
+    if (objc == 3) {
+	Tcl_Obj *listObjPtr;
+
+	if (first == vPtr->length) {
+	    Tcl_AppendResult(interp, "can't get index \"", string, "\"",
+		(char *)NULL);
+	    return TCL_ERROR;	/* Can't read from index "++end" */
+	}
+	listObjPtr = GetValues(vPtr, first, last);
+	Tcl_SetObjResult(interp, listObjPtr);
+    } else {
+	double value;
+
+	/* FIXME: huh? Why set values here?.  */
+	if (first == SPECIAL_INDEX) {
+	    Tcl_AppendResult(interp, "can't set index \"", string, "\"",
+		(char *)NULL);
+	    return TCL_ERROR;	/* Tried to set "min" or "max" */
+	}
+	if (Blt_ExprDoubleFromObj(interp, objv[3], &value) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (first == vPtr->length) {
+	    if (Blt_Vec_ChangeLength(interp, vPtr, vPtr->length + 1) 
+		!= TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+	ReplicateValue(vPtr, first, last, value);
+	Tcl_SetObjResult(interp, objv[3]);
+	if (vPtr->flush) {
+	    Blt_Vec_FlushCache(vPtr);
+	}
+	Blt_Vec_UpdateClients(vPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LengthOp --
+ *
+ *	Returns the length of the vector.  If a new size is given, the
+ *	vector is resized to the new vector.
+ *
+ * Results:
+ *	A standard TCL result.  If the new length is invalid,
+ *	interp->result will an error message and TCL_ERROR is returned.
+ *	Otherwise interp->result will contain the length of the vector.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+LengthOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    if (objc == 3) {
+	int nElem;
+
+	if (Tcl_GetIntFromObj(interp, objv[2], &nElem) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (nElem < 0) {
+	    Tcl_AppendResult(interp, "bad vector size \"", 
+		Tcl_GetString(objv[2]), "\"", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	if ((Blt_Vec_SetSize(interp, vPtr, nElem) != TCL_OK) ||
+	    (Blt_Vec_SetLength(interp, vPtr, nElem) != TCL_OK)) {
+	    return TCL_ERROR;
+	} 
+	if (vPtr->flush) {
+	    Blt_Vec_FlushCache(vPtr);
+	}
+	Blt_Vec_UpdateClients(vPtr);
+    }
+    Tcl_SetIntObj(Tcl_GetObjResult(interp), vPtr->length);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MapOp --
+ *
+ *	Queries or sets the offset of the array index from the base
+ *	address of the data array of values.
+ *
+ * Results:
+ *	A standard TCL result.  If the source vector doesn't exist
+ *	or the source list is not a valid list of numbers, TCL_ERROR
+ *	returned.  Otherwise TCL_OK is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+MapOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    if (objc > 2) {
+	if (Blt_Vec_MapVariable(interp, vPtr, Tcl_GetString(objv[2])) 
+	    != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    if (vPtr->arrayName != NULL) {
+	Tcl_SetStringObj(Tcl_GetObjResult(interp), vPtr->arrayName, -1);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MaxOp --
+ *
+ *	Returns the maximum value of the vector.
+ *
+ * Results:
+ *	A standard TCL result. 
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+MaxOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Tcl_SetDoubleObj(Tcl_GetObjResult(interp), Blt_Vec_Max(vPtr));
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MergeOp --
+ *
+ *	Merges the values from the given vectors to the current vector.
+ *
+ * Results:
+ *	A standard TCL result.  If any of the given vectors differ in size,
+ *	TCL_ERROR is returned.  Otherwise TCL_OK is returned and the
+ *	vector data will contain merged values of the given vectors.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+MergeOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Vector **vecArr;
+    int refSize, nElem;
+    int i;
+    double *valuePtr, *valueArr;
+    Vector **vPtrPtr;
+    
+    /* Allocate an array of vector pointers of each vector to be
+     * merged in the current vector.  */
+    vecArr = malloc(sizeof(Vector *) * objc);
+    vPtrPtr = vecArr;
+
+    refSize = -1;
+    nElem = 0;
+    for (i = 2; i < objc; i++) {
+	Vector *v2Ptr;
+	int length;
+
+	if (Blt_Vec_LookupName(vPtr->dataPtr, Tcl_GetString(objv[i]), &v2Ptr)
+		!= TCL_OK) {
+	    free(vecArr);
+	    return TCL_ERROR;
+	}
+	/* Check that all the vectors are the same length */
+	length = v2Ptr->last - v2Ptr->first + 1;
+	if (refSize < 0) {
+	    refSize = length;
+	} else if (length != refSize) {
+	    Tcl_AppendResult(vPtr->interp, "vectors \"", vPtr->name,
+		"\" and \"", v2Ptr->name, "\" differ in length",
+		(char *)NULL);
+	    free(vecArr);
+	    return TCL_ERROR;
+	}
+	*vPtrPtr++ = v2Ptr;
+	nElem += refSize;
+    }
+    *vPtrPtr = NULL;
+
+    valueArr = malloc(sizeof(double) * nElem);
+    if (valueArr == NULL) {
+	Tcl_AppendResult(vPtr->interp, "not enough memory to allocate ", 
+		 Blt_Itoa(nElem), " vector elements", (char *)NULL);
+	return TCL_ERROR;
+    }
+
+    /* Merge the values from each of the vectors into the current vector */
+    valuePtr = valueArr;
+    for (i = 0; i < refSize; i++) {
+	Vector **vpp;
+
+	for (vpp = vecArr; *vpp != NULL; vpp++) {
+	    *valuePtr++ = (*vpp)->valueArr[i + (*vpp)->first];
+	}
+    }
+    free(vecArr);
+    Blt_Vec_Reset(vPtr, valueArr, nElem, nElem, TCL_DYNAMIC);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MinOp --
+ *
+ *	Returns the minimum value of the vector.
+ *
+ * Results:
+ *	A standard TCL result. 
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+MinOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Tcl_SetDoubleObj(Tcl_GetObjResult(interp), Blt_Vec_Min(vPtr));
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NormalizeOp --
+ *
+ *	Normalizes the vector.
+ *
+ * Results:
+ *	A standard TCL result.  If the density is invalid, TCL_ERROR
+ *	is returned.  Otherwise TCL_OK is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+NormalizeOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int i;
+    double range;
+
+    Blt_Vec_UpdateRange(vPtr);
+    range = vPtr->max - vPtr->min;
+    if (objc > 2) {
+	Vector *v2Ptr;
+	int isNew;
+	char *string;
+
+	string = Tcl_GetString(objv[2]);
+	v2Ptr = Blt_Vec_Create(vPtr->dataPtr, string, string, string, &isNew);
+	if (v2Ptr == NULL) {
+	    return TCL_ERROR;
+	}
+	if (Blt_Vec_SetLength(interp, v2Ptr, vPtr->length) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	for (i = 0; i < vPtr->length; i++) {
+	    v2Ptr->valueArr[i] = (vPtr->valueArr[i] - vPtr->min) / range;
+	}
+	Blt_Vec_UpdateRange(v2Ptr);
+	if (!isNew) {
+	    if (v2Ptr->flush) {
+		Blt_Vec_FlushCache(v2Ptr);
+	    }
+	    Blt_Vec_UpdateClients(v2Ptr);
+	}
+    } else {
+	Tcl_Obj *listObjPtr;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	for (i = 0; i < vPtr->length; i++) {
+	    double norm;
+
+	    norm = (vPtr->valueArr[i] - vPtr->min) / range;
+	    Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewDoubleObj(norm));
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NotifyOp --
+ *
+ *	Notify clients of vector.
+ *
+ * Results:
+ *	A standard TCL result.  If any of the given vectors differ in size,
+ *	TCL_ERROR is returned.  Otherwise TCL_OK is returned and the
+ *	vector data will contain merged values of the given vectors.
+ *
+ *  x vector notify now
+ *  x vector notify always
+ *  x vector notify whenidle
+ *  x vector notify update {}
+ *  x vector notify delete {}
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+NotifyOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int option;
+    int bool;
+    enum optionIndices {
+	OPTION_ALWAYS, OPTION_NEVER, OPTION_WHENIDLE, 
+	OPTION_NOW, OPTION_CANCEL, OPTION_PENDING
+    };
+    static const char *optionArr[] = {
+	"always", "never", "whenidle", "now", "cancel", "pending", NULL
+    };
+
+    if (Tcl_GetIndexFromObj(interp, objv[2], optionArr, "qualifier", TCL_EXACT,
+	    &option) != TCL_OK) {
+	return TCL_OK;
+    }
+    switch (option) {
+    case OPTION_ALWAYS:
+	vPtr->notifyFlags &= ~NOTIFY_WHEN_MASK;
+	vPtr->notifyFlags |= NOTIFY_ALWAYS;
+	break;
+    case OPTION_NEVER:
+	vPtr->notifyFlags &= ~NOTIFY_WHEN_MASK;
+	vPtr->notifyFlags |= NOTIFY_NEVER;
+	break;
+    case OPTION_WHENIDLE:
+	vPtr->notifyFlags &= ~NOTIFY_WHEN_MASK;
+	vPtr->notifyFlags |= NOTIFY_WHENIDLE;
+	break;
+    case OPTION_NOW:
+	/* FIXME: How does this play when an update is pending? */
+	Blt_Vec_NotifyClients(vPtr);
+	break;
+    case OPTION_CANCEL:
+	if (vPtr->notifyFlags & NOTIFY_PENDING) {
+	    vPtr->notifyFlags &= ~NOTIFY_PENDING;
+	    Tcl_CancelIdleCall(Blt_Vec_NotifyClients, (ClientData)vPtr);
+	}
+	break;
+    case OPTION_PENDING:
+	bool = (vPtr->notifyFlags & NOTIFY_PENDING);
+	Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool);
+	break;
+    }	
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PopulateOp --
+ *
+ *	Creates or resizes a new vector based upon the density specified.
+ *
+ * Results:
+ *	A standard TCL result.  If the density is invalid, TCL_ERROR
+ *	is returned.  Otherwise TCL_OK is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+PopulateOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Vector *v2Ptr;
+    int size, density;
+    int isNew;
+    int i, j;
+    double *valuePtr;
+    int count;
+    char *string;
+
+    string = Tcl_GetString(objv[2]);
+    v2Ptr = Blt_Vec_Create(vPtr->dataPtr, string, string, string, &isNew);
+    if (v2Ptr == NULL) {
+	return TCL_ERROR;
+    }
+    if (vPtr->length == 0) {
+	return TCL_OK;		/* Source vector is empty. */
+    }
+    if (Tcl_GetIntFromObj(interp, objv[3], &density) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (density < 1) {
+	Tcl_AppendResult(interp, "bad density \"", Tcl_GetString(objv[3]), 
+		"\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    size = (vPtr->length - 1) * (density + 1) + 1;
+    if (Blt_Vec_SetLength(interp, v2Ptr, size) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    count = 0;
+    valuePtr = v2Ptr->valueArr;
+    for (i = 0; i < (vPtr->length - 1); i++) {
+	double slice, range;
+
+	range = vPtr->valueArr[i + 1] - vPtr->valueArr[i];
+	slice = range / (double)(density + 1);
+	for (j = 0; j <= density; j++) {
+	    *valuePtr = vPtr->valueArr[i] + (slice * (double)j);
+	    valuePtr++;
+	    count++;
+	}
+    }
+    count++;
+    *valuePtr = vPtr->valueArr[i];
+    assert(count == v2Ptr->length);
+    if (!isNew) {
+	if (v2Ptr->flush) {
+	    Blt_Vec_FlushCache(v2Ptr);
+	}
+	Blt_Vec_UpdateClients(v2Ptr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ValuesOp --
+ *
+ *	Print the values vector.
+ *
+ * Results:
+ *	A standard TCL result.  
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ValuesOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    PrintSwitches switches;
+
+    switches.formatObjPtr = NULL;
+    switches.from = 0;
+    switches.to = vPtr->length - 1;
+    indexSwitch.clientData = vPtr;
+    if (Blt_ParseSwitches(interp, printSwitches, objc - 2, objv + 2, &switches, 
+	BLT_SWITCH_DEFAULTS) < 0) {
+	return TCL_ERROR;
+    }
+    if (switches.from > switches.to) {
+	int tmp;
+	/* swap positions. */
+	tmp = switches.to;
+	switches.to = switches.from;
+	switches.from = tmp;
+    }
+    if (switches.formatObjPtr == NULL) {
+	Tcl_Obj *listObjPtr;
+	int i;
+
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	for (i = switches.from; i <= switches.to; i++) {
+	    Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewDoubleObj(vPtr->valueArr[i]));
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+    } else {
+	Tcl_DString ds;
+	char buffer[200];
+	const char *fmt;
+	int i;
+
+	Tcl_DStringInit(&ds);
+	fmt = Tcl_GetString(switches.formatObjPtr);
+	for (i = switches.from; i <= switches.to; i++) {
+	    sprintf(buffer, fmt, vPtr->valueArr[i]);
+	    Tcl_DStringAppend(&ds, buffer, -1);
+	}
+	Tcl_DStringResult(interp, &ds);
+	Tcl_DStringFree(&ds);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RangeOp --
+ *
+ *	Returns a TCL list of the range of vector values specified.
+ *
+ * Results:
+ *	A standard TCL result.  If the given range is invalid, TCL_ERROR
+ *	is returned.  Otherwise TCL_OK is returned and interp->result
+ *	will contain the list of values.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+RangeOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Tcl_Obj *listObjPtr;
+    int first, last;
+    int i;
+
+    if (objc == 2) {
+	first = 0;
+	last = vPtr->length - 1;
+    } else if (objc == 4) {
+	if ((Blt_Vec_GetIndex(interp, vPtr, Tcl_GetString(objv[2]), &first, 
+		INDEX_CHECK, (Blt_VectorIndexProc **) NULL) != TCL_OK) ||
+	    (Blt_Vec_GetIndex(interp, vPtr, Tcl_GetString(objv[3]), &last, 
+		INDEX_CHECK, (Blt_VectorIndexProc **) NULL) != TCL_OK)) {
+	    return TCL_ERROR;
+	}
+    } else {
+	Tcl_AppendResult(interp, "wrong # args: should be \"",
+		Tcl_GetString(objv[0]), " range ?first last?", (char *)NULL);
+	return TCL_ERROR;
+    }
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if (first > last) {
+	/* Return the list reversed */
+	for (i = last; i <= first; i++) {
+	    Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewDoubleObj(vPtr->valueArr[i]));
+	}
+    } else {
+	for (i = first; i <= last; i++) {
+	    Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewDoubleObj(vPtr->valueArr[i]));
+	}
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * InRange --
+ *
+ *	Determines if a value lies within a given range.
+ *
+ *	The value is normalized and compared against the interval
+ *	[0..1], where 0.0 is the minimum and 1.0 is the maximum.
+ *	DBL_EPSILON is the smallest number that can be represented
+ *	on the host machine, such that (1.0 + epsilon) != 1.0.
+ *
+ *	Please note, min cannot be greater than max.
+ *
+ * Results:
+ *	If the value is within of the interval [min..max], 1 is 
+ *	returned; 0 otherwise.
+ *
+ *---------------------------------------------------------------------------
+ */
+INLINE static int
+InRange(double value, double min, double max)
+{
+    double range;
+
+    range = max - min;
+    if (range < DBL_EPSILON) {
+	return (fabs(max - value) < DBL_EPSILON);
+    } else {
+	double norm;
+
+	norm = (value - min) / range;
+	return ((norm >= -DBL_EPSILON) && ((norm - 1.0) < DBL_EPSILON));
+    }
+}
+
+enum NativeFormats {
+    FMT_UNKNOWN = -1,
+    FMT_UCHAR, FMT_CHAR,
+    FMT_USHORT, FMT_SHORT,
+    FMT_UINT, FMT_INT,
+    FMT_ULONG, FMT_LONG,
+    FMT_FLOAT, FMT_DOUBLE
+};
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetBinaryFormat
+ *
+ *      Translates a format string into a native type.  Valid formats are
+ *
+ *		signed		i1, i2, i4, i8
+ *		unsigned 	u1, u2, u4, u8
+ *		real		r4, r8, r16
+ *
+ *	There must be a corresponding native type.  For example, this for
+ *	reading 2-byte binary integers from an instrument and converting them
+ *	to unsigned shorts or ints.
+ *
+ *---------------------------------------------------------------------------
+ */
+static enum NativeFormats
+GetBinaryFormat(Tcl_Interp *interp, char *string, int *sizePtr)
+{
+    char c;
+
+    c = tolower(string[0]);
+    if (Tcl_GetInt(interp, string + 1, sizePtr) != TCL_OK) {
+	Tcl_AppendResult(interp, "unknown binary format \"", string,
+	    "\": incorrect byte size", (char *)NULL);
+	return FMT_UNKNOWN;
+    }
+    switch (c) {
+    case 'r':
+	if (*sizePtr == sizeof(double)) {
+	    return FMT_DOUBLE;
+	} else if (*sizePtr == sizeof(float)) {
+	    return FMT_FLOAT;
+	}
+	break;
+
+    case 'i':
+	if (*sizePtr == sizeof(char)) {
+	    return FMT_CHAR;
+	} else if (*sizePtr == sizeof(int)) {
+	    return FMT_INT;
+	} else if (*sizePtr == sizeof(long)) {
+	    return FMT_LONG;
+	} else if (*sizePtr == sizeof(short)) {
+	    return FMT_SHORT;
+	}
+	break;
+
+    case 'u':
+	if (*sizePtr == sizeof(unsigned char)) {
+	    return FMT_UCHAR;
+	} else if (*sizePtr == sizeof(unsigned int)) {
+	    return FMT_UINT;
+	} else if (*sizePtr == sizeof(unsigned long)) {
+	    return FMT_ULONG;
+	} else if (*sizePtr == sizeof(unsigned short)) {
+	    return FMT_USHORT;
+	}
+	break;
+
+    default:
+	Tcl_AppendResult(interp, "unknown binary format \"", string,
+	    "\": should be either i#, r#, u# (where # is size in bytes)",
+	    (char *)NULL);
+	return FMT_UNKNOWN;
+    }
+    Tcl_AppendResult(interp, "can't handle format \"", string, "\"", 
+		     (char *)NULL);
+    return FMT_UNKNOWN;
+}
+
+static int
+CopyValues(Vector *vPtr, char *byteArr, enum NativeFormats fmt, int size, 
+	int length, int swap, int *indexPtr)
+{
+    int i, n;
+    int newSize;
+
+    if ((swap) && (size > 1)) {
+	int nBytes = size * length;
+	unsigned char *p;
+	int left, right;
+
+	for (i = 0; i < nBytes; i += size) {
+	    p = (unsigned char *)(byteArr + i);
+	    for (left = 0, right = size - 1; left < right; left++, right--) {
+		p[left] ^= p[right];
+		p[right] ^= p[left];
+		p[left] ^= p[right];
+	    }
+
+	}
+    }
+    newSize = *indexPtr + length;
+    if (newSize > vPtr->length) {
+	if (Blt_Vec_ChangeLength(vPtr->interp, vPtr, newSize) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+#define CopyArrayToVector(vPtr, arr) \
+    for (i = 0, n = *indexPtr; i < length; i++, n++) { \
+	(vPtr)->valueArr[n] = (double)(arr)[i]; \
+    }
+
+    switch (fmt) {
+    case FMT_CHAR:
+	CopyArrayToVector(vPtr, (char *)byteArr);
+	break;
+
+    case FMT_UCHAR:
+	CopyArrayToVector(vPtr, (unsigned char *)byteArr);
+	break;
+
+    case FMT_INT:
+	CopyArrayToVector(vPtr, (int *)byteArr);
+	break;
+
+    case FMT_UINT:
+	CopyArrayToVector(vPtr, (unsigned int *)byteArr);
+	break;
+
+    case FMT_LONG:
+	CopyArrayToVector(vPtr, (long *)byteArr);
+	break;
+
+    case FMT_ULONG:
+	CopyArrayToVector(vPtr, (unsigned long *)byteArr);
+	break;
+
+    case FMT_SHORT:
+	CopyArrayToVector(vPtr, (short int *)byteArr);
+	break;
+
+    case FMT_USHORT:
+	CopyArrayToVector(vPtr, (unsigned short int *)byteArr);
+	break;
+
+    case FMT_FLOAT:
+	CopyArrayToVector(vPtr, (float *)byteArr);
+	break;
+
+    case FMT_DOUBLE:
+	CopyArrayToVector(vPtr, (double *)byteArr);
+	break;
+
+    case FMT_UNKNOWN:
+	break;
+    }
+    *indexPtr += length;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * BinreadOp --
+ *
+ *	Reads binary values from a TCL channel. Values are either appended to
+ *	the end of the vector or placed at a given index (using the "-at"
+ *	option), overwriting existing values.  Data is read until EOF is found
+ *	on the channel or a specified number of values are read.  (note that
+ *	this is not necessarily the same as the number of bytes).
+ *
+ *	The following flags are supported:
+ *		-swap		Swap bytes
+ *		-at index	Start writing data at the index.
+ *		-format fmt	Specifies the format of the data.
+ *
+ *	This binary reader was created and graciously donated by Harald Kirsch
+ *	(kir at iitb.fhg.de).  Anything that's wrong is due to my (gah) munging
+ *	of the code.
+ *
+ * Results:
+ *	Returns a standard TCL result. The interpreter result will contain the
+ *	number of values (not the number of bytes) read.
+ *
+ * Caveats:
+ *	Channel reads must end on an element boundary.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+BinreadOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Tcl_Channel channel;
+    char *byteArr;
+    char *string;
+    enum NativeFormats fmt;
+    int arraySize, bytesRead;
+    int count, total;
+    int first;
+    int size, length, mode;
+    int swap;
+    int i;
+
+    string = Tcl_GetString(objv[2]);
+    channel = Tcl_GetChannel(interp, string, &mode);
+    if (channel == NULL) {
+	return TCL_ERROR;
+    }
+    if ((mode & TCL_READABLE) == 0) {
+	Tcl_AppendResult(interp, "channel \"", string,
+	    "\" wasn't opened for reading", (char *)NULL);
+	return TCL_ERROR;
+    }
+    first = vPtr->length;
+    fmt = FMT_DOUBLE;
+    size = sizeof(double);
+    swap = FALSE;
+    count = 0;
+
+    if (objc > 3) {
+	string = Tcl_GetString(objv[3]);
+	if (string[0] != '-') {
+	    long int value;
+	    /* Get the number of values to read.  */
+	    if (Tcl_GetLongFromObj(interp, objv[3], &value) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (value < 0) {
+		Tcl_AppendResult(interp, "count can't be negative", 
+				 (char *)NULL);
+		return TCL_ERROR;
+	    }
+	    count = (size_t)value;
+	    objc--, objv++;
+	}
+    }
+    /* Process any option-value pairs that remain.  */
+    for (i = 3; i < objc; i++) {
+	string = Tcl_GetString(objv[i]);
+	if (strcmp(string, "-swap") == 0) {
+	    swap = TRUE;
+	} else if (strcmp(string, "-format") == 0) {
+	    i++;
+	    if (i >= objc) {
+		Tcl_AppendResult(interp, "missing arg after \"", string,
+		    "\"", (char *)NULL);
+		return TCL_ERROR;
+	    }
+	    string = Tcl_GetString(objv[i]);
+	    fmt = GetBinaryFormat(interp, string, &size);
+	    if (fmt == FMT_UNKNOWN) {
+		return TCL_ERROR;
+	    }
+	} else if (strcmp(string, "-at") == 0) {
+	    i++;
+	    if (i >= objc) {
+		Tcl_AppendResult(interp, "missing arg after \"", string,
+		    "\"", (char *)NULL);
+		return TCL_ERROR;
+	    }
+	    string = Tcl_GetString(objv[i]);
+	    if (Blt_Vec_GetIndex(interp, vPtr, string, &first, 0, 
+			 (Blt_VectorIndexProc **)NULL) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (first > vPtr->length) {
+		Tcl_AppendResult(interp, "index \"", string,
+		    "\" is out of range", (char *)NULL);
+		return TCL_ERROR;
+	    }
+	}
+    }
+
+#define BUFFER_SIZE 1024
+    if (count == 0) {
+	arraySize = BUFFER_SIZE * size;
+    } else {
+	arraySize = count * size;
+    }
+
+    byteArr = malloc(arraySize);
+    /* FIXME: restore old channel translation later? */
+    if (Tcl_SetChannelOption(interp, channel, "-translation",
+	    "binary") != TCL_OK) {
+	return TCL_ERROR;
+    }
+    total = 0;
+    while (!Tcl_Eof(channel)) {
+	bytesRead = Tcl_Read(channel, byteArr, arraySize);
+	if (bytesRead < 0) {
+	    Tcl_AppendResult(interp, "error reading channel: ",
+		Tcl_PosixError(interp), (char *)NULL);
+	    return TCL_ERROR;
+	}
+	if ((bytesRead % size) != 0) {
+	    Tcl_AppendResult(interp, "error reading channel: short read",
+		(char *)NULL);
+	    return TCL_ERROR;
+	}
+	length = bytesRead / size;
+	if (CopyValues(vPtr, byteArr, fmt, size, length, swap, &first)
+	    != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	total += length;
+	if (count > 0) {
+	    break;
+	}
+    }
+    free(byteArr);
+
+    if (vPtr->flush) {
+	Blt_Vec_FlushCache(vPtr);
+    }
+    Blt_Vec_UpdateClients(vPtr);
+
+    /* Set the result as the number of values read.  */
+    Tcl_SetIntObj(Tcl_GetObjResult(interp), total);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SearchOp --
+ *
+ *	Searches for a value in the vector. Returns the indices of all vector
+ *	elements matching a particular value.
+ *
+ * Results:
+ *	Always returns TCL_OK.  interp->result will contain a list of the
+ *	indices of array elements matching value. If no elements match,
+ *	interp->result will contain the empty string.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SearchOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    double min, max;
+    int i;
+    int wantValue;
+    char *string;
+    Tcl_Obj *listObjPtr;
+
+    wantValue = FALSE;
+    string = Tcl_GetString(objv[2]);
+    if ((string[0] == '-') && (strcmp(string, "-value") == 0)) {
+	wantValue = TRUE;
+	objv++, objc--;
+    }
+    if (Blt_ExprDoubleFromObj(interp, objv[2], &min) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    max = min;
+    if (objc > 4) {
+ 	Tcl_AppendResult(interp, "wrong # arguments: should be \"",
+		Tcl_GetString(objv[0]), " search ?-value? min ?max?", 
+		(char *)NULL);
+	return TCL_ERROR;
+    }
+    if ((objc > 3) && 
+	(Blt_ExprDoubleFromObj(interp, objv[3], &max) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    if ((min - max) >= DBL_EPSILON) {
+	return TCL_OK;		/* Bogus range. Don't bother looking. */
+    }
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    if (wantValue) {
+	for (i = 0; i < vPtr->length; i++) {
+	    if (InRange(vPtr->valueArr[i], min, max)) {
+		Tcl_ListObjAppendElement(interp, listObjPtr, 
+			Tcl_NewDoubleObj(vPtr->valueArr[i]));
+	    }
+	}
+    } else {
+	for (i = 0; i < vPtr->length; i++) {
+	    if (InRange(vPtr->valueArr[i], min, max)) {
+		Tcl_ListObjAppendElement(interp, listObjPtr,
+			 Tcl_NewIntObj(i + vPtr->offset));
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * OffsetOp --
+ *
+ *	Queries or sets the offset of the array index from the base address of
+ *	the data array of values.
+ *
+ * Results:
+ *	A standard TCL result.  If the source vector doesn't exist or the
+ *	source list is not a valid list of numbers, TCL_ERROR returned.
+ *	Otherwise TCL_OK is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+OffsetOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    if (objc == 3) {
+	int newOffset;
+
+	if (Tcl_GetIntFromObj(interp, objv[2], &newOffset) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	vPtr->offset = newOffset;
+    }
+    Tcl_SetIntObj(Tcl_GetObjResult(interp), vPtr->offset);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RandomOp --
+ *
+ *	Generates random values for the length of the vector.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+RandomOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int i;
+
+    for (i = 0; i < vPtr->length; i++) {
+	vPtr->valueArr[i] = drand48();
+    }
+    if (vPtr->flush) {
+	Blt_Vec_FlushCache(vPtr);
+    }
+    Blt_Vec_UpdateClients(vPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SeqOp --
+ *
+ *	Generates a sequence of values in the vector.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SeqOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int n;
+    double start, stop;
+    
+    if (Blt_ExprDoubleFromObj(interp, objv[2], &start) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Blt_ExprDoubleFromObj(interp, objv[3], &stop) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    n = vPtr->length;
+    if ((objc > 4) && (Blt_ExprIntFromObj(interp, objv[4], &n) != TCL_OK)) {
+	return TCL_ERROR;
+    }
+    if (n > 1) {
+	int i;
+	double step;
+
+	if (Blt_Vec_SetLength(interp, vPtr, n) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	step = (stop - start) / (double)(n - 1);
+	for (i = 0; i < n; i++) { 
+	    vPtr->valueArr[i] = start + (step * i);
+	}
+	if (vPtr->flush) {
+	    Blt_Vec_FlushCache(vPtr);
+	}
+	Blt_Vec_UpdateClients(vPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SetOp --
+ *
+ *	Sets the data of the vector object from a list of values.
+ *
+ * Results:
+ *	A standard TCL result.  If the source vector doesn't exist or the
+ *	source list is not a valid list of numbers, TCL_ERROR returned.
+ *	Otherwise TCL_OK is returned.
+ *
+ * Side Effects:
+ *	The vector data is reset.  Clients of the vector are notified.  Any
+ *	cached array indices are flushed.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SetOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int result;
+    Vector *v2Ptr;
+    int nElem;
+    Tcl_Obj **elemObjArr;
+
+    /* The source can be either a list of numbers or another vector.  */
+
+    v2Ptr = Blt_Vec_ParseElement((Tcl_Interp *)NULL, vPtr->dataPtr, 
+	   Tcl_GetString(objv[2]), NULL, NS_SEARCH_BOTH);
+    if (v2Ptr != NULL) {
+	if (vPtr == v2Ptr) {
+	    Vector *tmpPtr;
+	    /* 
+	     * Source and destination vectors are the same.  Copy the source
+	     * first into a temporary vector to avoid memory overlaps.
+	     */
+	    tmpPtr = Blt_Vec_New(vPtr->dataPtr);
+	    result = Blt_Vec_Duplicate(tmpPtr, v2Ptr);
+	    if (result == TCL_OK) {
+		result = Blt_Vec_Duplicate(vPtr, tmpPtr);
+	    }
+	    Blt_Vec_Free(tmpPtr);
+	} else {
+	    result = Blt_Vec_Duplicate(vPtr, v2Ptr);
+	}
+    } else if (Tcl_ListObjGetElements(interp, objv[2], &nElem, &elemObjArr) 
+	       == TCL_OK) {
+	result = CopyList(vPtr, interp, nElem, elemObjArr);
+    } else {
+	return TCL_ERROR;
+    }
+
+    if (result == TCL_OK) {
+	/*
+	 * The vector has changed; so flush the array indices (they're wrong
+	 * now), find the new range of the data, and notify the vector's
+	 * clients that it's been modified.
+	 */
+	if (vPtr->flush) {
+	    Blt_Vec_FlushCache(vPtr);
+	}
+	Blt_Vec_UpdateClients(vPtr);
+    }
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SimplifyOp --
+ *
+ *	Sets the data of the vector object from a list of values.
+ *
+ * Results:
+ *	A standard TCL result.  If the source vector doesn't exist or the
+ *	source list is not a valid list of numbers, TCL_ERROR returned.
+ *	Otherwise TCL_OK is returned.
+ *
+ * Side Effects:
+ *	The vector data is reset.  Clients of the vector are notified.  Any
+ *	cached array indices are flushed.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SimplifyOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    size_t i, n;
+    int length, nPoints;
+    int *simple;
+    double tolerance = 10.0;
+    Point2d *orig, *reduced;
+
+    length = vPtr->length;
+    nPoints = vPtr->length / 2;
+    simple  = malloc(nPoints * sizeof(int));
+    reduced = malloc(nPoints * sizeof(Point2d));
+    orig = (Point2d *)vPtr->valueArr;
+    n = Blt_SimplifyLine(orig, 0, nPoints - 1, tolerance, simple);
+    for (i = 0; i < n; i++) {
+	reduced[i] = orig[simple[i]];
+    }
+    free(simple);
+    Blt_Vec_Reset(vPtr, (double *)reduced, n * 2, vPtr->length, TCL_DYNAMIC);
+    /*
+     * The vector has changed; so flush the array indices (they're wrong
+     * now), find the new range of the data, and notify the vector's
+     * clients that it's been modified.
+     */
+    if (vPtr->flush) {
+	Blt_Vec_FlushCache(vPtr);
+    }
+    Blt_Vec_UpdateClients(vPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SplitOp --
+ *
+ *	Copies the values from the vector evenly into one of more vectors.
+ *
+ * Results:
+ *	A standard TCL result.  
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+SplitOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    int nVectors;
+
+    nVectors = objc - 2;
+    if ((vPtr->length % nVectors) != 0) {
+	Tcl_AppendResult(interp, "can't split vector \"", vPtr->name, 
+	   "\" into ", Blt_Itoa(nVectors), " even parts.", (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (nVectors > 0) {
+	Vector *v2Ptr;
+	char *string;		/* Name of vector. */
+	int i, j, k;
+	int oldSize, newSize, extra, isNew;
+
+	extra = vPtr->length / nVectors;
+	for (i = 0; i < nVectors; i++) {
+	    string = Tcl_GetString(objv[i+2]);
+	    v2Ptr = Blt_Vec_Create(vPtr->dataPtr, string, string, string,
+		&isNew);
+	    oldSize = v2Ptr->length;
+	    newSize = oldSize + extra;
+	    if (Blt_Vec_SetLength(interp, v2Ptr, newSize) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    for (j = i, k = oldSize; j < vPtr->length; j += nVectors, k++) {
+		v2Ptr->valueArr[k] = vPtr->valueArr[j];
+	    }
+	    Blt_Vec_UpdateClients(v2Ptr);
+	    if (v2Ptr->flush) {
+		Blt_Vec_FlushCache(v2Ptr);
+	    }
+	}
+    }
+    return TCL_OK;
+}
+
+
+static Vector **sortVectors;	/* Pointer to the array of values currently
+				 * being sorted. */
+static int nSortVectors;
+static int sortDecreasing;	/* Indicates the ordering of the sort. If
+				 * non-zero, the vectors are sorted in
+				 * decreasing order */
+
+static int
+CompareVectors(void *a, void *b)
+{
+    double delta;
+    int i;
+    int sign;
+    Vector *vPtr;
+
+    sign = (sortDecreasing) ? -1 : 1;
+    for (i = 0; i < nSortVectors; i++) {
+	vPtr = sortVectors[i];
+	delta = vPtr->valueArr[*(int *)a] - vPtr->valueArr[*(int *)b];
+	if (delta < 0.0) {
+	    return (-1 * sign);
+	} else if (delta > 0.0) {
+	    return (1 * sign);
+	}
+    }
+    return 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_SortMap --
+ *
+ *	Returns an array of indices that represents the sorted mapping of the
+ *	original vector.
+ *
+ * Results:
+ *	A standard TCL result.  If any of the auxiliary vectors are a
+ *	different size than the sorted vector object, TCL_ERROR is returned.
+ *	Otherwise TCL_OK is returned.
+ *
+ * Side Effects:
+ *	The vectors are sorted.
+ *
+ *	vecName sort ?switches? vecName vecName...
+ *---------------------------------------------------------------------------
+ */
+size_t *
+Blt_Vec_SortMap(Vector **vectors, int nVectors)
+{
+    size_t *map;
+    int i;
+    Vector *vPtr = *vectors;
+    int length;
+
+    length = vPtr->last - vPtr->first + 1;
+    map = malloc(sizeof(size_t) * length);
+    for (i = vPtr->first; i <= vPtr->last; i++) {
+	map[i] = i;
+    }
+    /* Set global variables for sorting routine. */
+    sortVectors = vectors;
+    nSortVectors = nVectors;
+    qsort((char *)map, length, sizeof(size_t), 
+	  (QSortCompareProc *)CompareVectors);
+    return map;
+}
+
+static size_t *
+SortVectors(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Vector **vectors, *v2Ptr;
+    size_t *map;
+    int i;
+
+    vectors = malloc(sizeof(Vector *) * (objc + 1));
+    vectors[0] = vPtr;
+    map = NULL;
+    for (i = 0; i < objc; i++) {
+	if (Blt_Vec_LookupName(vPtr->dataPtr, Tcl_GetString(objv[i]), 
+		&v2Ptr) != TCL_OK) {
+	    goto error;
+	}
+	if (v2Ptr->length != vPtr->length) {
+	    Tcl_AppendResult(interp, "vector \"", v2Ptr->name,
+		"\" is not the same size as \"", vPtr->name, "\"",
+		(char *)NULL);
+	    goto error;
+	}
+	vectors[i + 1] = v2Ptr;
+    }
+    map = Blt_Vec_SortMap(vectors, objc + 1);
+  error:
+    free(vectors);
+    return map;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SortOp --
+ *
+ *	Sorts the vector object and any other vectors according to sorting
+ *	order of the vector object.
+ *
+ * Results:
+ *	A standard TCL result.  If any of the auxiliary vectors are a
+ *	different size than the sorted vector object, TCL_ERROR is returned.
+ *	Otherwise TCL_OK is returned.
+ *
+ * Side Effects:
+ *	The vectors are sorted.
+ *
+ *	vecName sort ?switches? vecName vecName...
+ *---------------------------------------------------------------------------
+ */
+static int
+SortOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    Vector *v2Ptr;
+    double *copy;
+    size_t *map;
+    size_t sortLength, nBytes;
+    int result;
+    int i;
+    unsigned int n;
+    SortSwitches switches;
+
+    sortDecreasing = FALSE;
+    switches.flags = 0;
+    i = Blt_ParseSwitches(interp, sortSwitches, objc - 2, objv + 2, &switches, 
+		BLT_SWITCH_OBJV_PARTIAL);
+    if (i < 0) {
+	return TCL_ERROR;
+    }
+    objc -= i, objv += i;
+    sortDecreasing = (switches.flags & SORT_DECREASING);
+    if (objc > 2) {
+	map = SortVectors(vPtr, interp, objc - 2, objv + 2);
+    } else {
+	map = Blt_Vec_SortMap(&vPtr, 1);
+    }
+    if (map == NULL) {
+	return TCL_ERROR;
+    }
+    sortLength = vPtr->length;
+    /*
+     * Create an array to store a copy of the current values of the
+     * vector. We'll merge the values back into the vector based upon the
+     * indices found in the index array.
+     */
+    nBytes = sizeof(double) * sortLength;
+    copy = malloc(nBytes);
+    memcpy((char *)copy, (char *)vPtr->valueArr, nBytes);
+    if (switches.flags & SORT_UNIQUE) {
+	int count;
+
+	for (count = n = 1; n < sortLength; n++) {
+	    size_t next, prev;
+
+	    next = map[n];
+	    prev = map[n - 1];
+	    if (copy[next] != copy[prev]) {
+		map[count] = next;
+		count++;
+	    }
+	}
+	sortLength = count;
+	nBytes = sortLength * sizeof(double);
+    }
+    if (sortLength != vPtr->length) {
+	Blt_Vec_SetLength(interp, vPtr, sortLength);
+    }
+    for (n = 0; n < sortLength; n++) {
+	vPtr->valueArr[n] = copy[map[n]];
+    }
+    if (vPtr->flush) {
+	Blt_Vec_FlushCache(vPtr);
+    }
+    Blt_Vec_UpdateClients(vPtr);
+
+    /* Now sort any other vectors in the same fashion.  The vectors must be
+     * the same size as the map though.  */
+    result = TCL_ERROR;
+    for (i = 2; i < objc; i++) {
+	if (Blt_Vec_LookupName(vPtr->dataPtr, Tcl_GetString(objv[i]), 
+		&v2Ptr) != TCL_OK) {
+	    goto error;
+	}
+	if (sortLength != v2Ptr->length) {
+	    Blt_Vec_SetLength(interp, v2Ptr, sortLength);
+	}
+	memcpy((char *)copy, (char *)v2Ptr->valueArr, nBytes);
+	for (n = 0; n < sortLength; n++) {
+	    v2Ptr->valueArr[n] = copy[map[n]];
+	}
+	Blt_Vec_UpdateClients(v2Ptr);
+	if (v2Ptr->flush) {
+	    Blt_Vec_FlushCache(v2Ptr);
+	}
+    }
+    result = TCL_OK;
+  error:
+    free(copy);
+    free(map);
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * InstExprOp --
+ *
+ *	Computes the result of the expression which may be either a scalar
+ *	(single value) or vector (list of values).
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+InstExprOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+
+    if (Blt_ExprVector(interp, Tcl_GetString(objv[2]), (Blt_Vector *)vPtr) 
+	!= TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (vPtr->flush) {
+	Blt_Vec_FlushCache(vPtr);
+    }
+    Blt_Vec_UpdateClients(vPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ArithOp --
+ *
+ * Results:
+ *	A standard TCL result.  If the source vector doesn't exist or the
+ *	source list is not a valid list of numbers, TCL_ERROR returned.
+ *	Otherwise TCL_OK is returned.
+ *
+ * Side Effects:
+ *	The vector data is reset.  Clients of the vector are notified.
+ *	Any cached array indices are flushed.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+ArithOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+{
+    double value;
+    int i;
+    Vector *v2Ptr;
+    double scalar;
+    Tcl_Obj *listObjPtr;
+    char *string;
+
+    v2Ptr = Blt_Vec_ParseElement((Tcl_Interp *)NULL, vPtr->dataPtr, 
+	Tcl_GetString(objv[2]), NULL, NS_SEARCH_BOTH);
+    if (v2Ptr != NULL) {
+	int j;
+	int length;
+
+	length = v2Ptr->last - v2Ptr->first + 1;
+	if (length != vPtr->length) {
+	    Tcl_AppendResult(interp, "vectors \"", Tcl_GetString(objv[0]), 
+		"\" and \"", Tcl_GetString(objv[2]), 
+		"\" are not the same length", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	string = Tcl_GetString(objv[1]);
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	switch (string[0]) {
+	case '*':
+	    for (i = 0, j = v2Ptr->first; i < vPtr->length; i++, j++) {
+		value = vPtr->valueArr[i] * v2Ptr->valueArr[j];
+		Tcl_ListObjAppendElement(interp, listObjPtr,
+			 Tcl_NewDoubleObj(value));
+	    }
+	    break;
+
+	case '/':
+	    for (i = 0, j = v2Ptr->first; i < vPtr->length; i++, j++) {
+		value = vPtr->valueArr[i] / v2Ptr->valueArr[j];
+		Tcl_ListObjAppendElement(interp, listObjPtr,
+			 Tcl_NewDoubleObj(value));
+	    }
+	    break;
+
+	case '-':
+	    for (i = 0, j = v2Ptr->first; i < vPtr->length; i++, j++) {
+		value = vPtr->valueArr[i] - v2Ptr->valueArr[j];
+		Tcl_ListObjAppendElement(interp, listObjPtr,
+			 Tcl_NewDoubleObj(value));
+	    }
+	    break;
+
+	case '+':
+	    for (i = 0, j = v2Ptr->first; i < vPtr->length; i++, j++) {
+		value = vPtr->valueArr[i] + v2Ptr->valueArr[j];
+		Tcl_ListObjAppendElement(interp, listObjPtr,
+			 Tcl_NewDoubleObj(value));
+	    }
+	    break;
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+
+    } else if (Blt_ExprDoubleFromObj(interp, objv[2], &scalar) == TCL_OK) {
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+	string = Tcl_GetString(objv[1]);
+	switch (string[0]) {
+	case '*':
+	    for (i = 0; i < vPtr->length; i++) {
+		value = vPtr->valueArr[i] * scalar;
+		Tcl_ListObjAppendElement(interp, listObjPtr,
+			 Tcl_NewDoubleObj(value));
+	    }
+	    break;
+
+	case '/':
+	    for (i = 0; i < vPtr->length; i++) {
+		value = vPtr->valueArr[i] / scalar;
+		Tcl_ListObjAppendElement(interp, listObjPtr,
+			 Tcl_NewDoubleObj(value));
+	    }
+	    break;
+
+	case '-':
+	    for (i = 0; i < vPtr->length; i++) {
+		value = vPtr->valueArr[i] - scalar;
+		Tcl_ListObjAppendElement(interp, listObjPtr,
+			 Tcl_NewDoubleObj(value));
+	    }
+	    break;
+
+	case '+':
+	    for (i = 0; i < vPtr->length; i++) {
+		value = vPtr->valueArr[i] + scalar;
+		Tcl_ListObjAppendElement(interp, listObjPtr,
+			 Tcl_NewDoubleObj(value));
+	    }
+	    break;
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+    } else {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VectorInstCmd --
+ *
+ *	Parses and invokes the appropriate vector instance command option.
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Blt_OpSpec vectorInstOps[] =
+{
+    {"*",         1, ArithOp,     3, 3, "item",},	/*Deprecated*/
+    {"+",         1, ArithOp,     3, 3, "item",},	/*Deprecated*/
+    {"-",         1, ArithOp,     3, 3, "item",},	/*Deprecated*/
+    {"/",         1, ArithOp,     3, 3, "item",},	/*Deprecated*/
+    {"append",    1, AppendOp,    3, 0, "item ?item...?",},
+    {"binread",   1, BinreadOp,   3, 0, "channel ?numValues? ?flags?",},
+    {"clear",     1, ClearOp,     2, 2, "",},
+    {"delete",    2, DeleteOp,    2, 0, "index ?index...?",},
+    {"dup",       2, DupOp,       3, 0, "vecName",},
+    {"expr",      1, InstExprOp,  3, 3, "expression",},
+    {"fft",	  1, FFTOp,	  3, 0, "vecName ?switches?",},
+    {"index",     3, IndexOp,     3, 4, "index ?value?",},
+    {"inversefft",3, InverseFFTOp,4, 4, "vecName vecName",},
+    {"length",    1, LengthOp,    2, 3, "?newSize?",},
+    {"max",       2, MaxOp,       2, 2, "",},
+    {"merge",     2, MergeOp,     3, 0, "vecName ?vecName...?",},
+    {"min",       2, MinOp,       2, 2, "",},
+    {"normalize", 3, NormalizeOp, 2, 3, "?vecName?",},	/*Deprecated*/
+    {"notify",    3, NotifyOp,    3, 3, "keyword",},
+    {"offset",    1, OffsetOp,    2, 3, "?offset?",},
+    {"populate",  1, PopulateOp,  4, 4, "vecName density",},
+    {"random",    4, RandomOp,    2, 2, "",},	/*Deprecated*/
+    {"range",     4, RangeOp,     2, 4, "first last",},
+    {"search",    3, SearchOp,    3, 5, "?-value? value ?value?",},
+    {"seq",       3, SeqOp,       4, 5, "begin end ?num?",},
+    {"set",       3, SetOp,       3, 3, "list",},
+    {"simplify",  2, SimplifyOp,  2, 2, },
+    {"sort",      2, SortOp,      2, 0, "?switches? ?vecName...?",},
+    {"split",     2, SplitOp,     2, 0, "?vecName...?",},
+    {"values",    3, ValuesOp,    2, 0, "?switches?",},
+    {"variable",  3, MapOp,       2, 3, "?varName?",},
+};
+
+static int nInstOps = sizeof(vectorInstOps) / sizeof(Blt_OpSpec);
+
+int
+Blt_Vec_InstCmd(ClientData clientData, Tcl_Interp *interp, int objc,
+		Tcl_Obj *const *objv)
+{
+    VectorCmdProc *proc;
+    Vector *vPtr = clientData;
+
+    vPtr->first = 0;
+    vPtr->last = vPtr->length - 1;
+    proc = Blt_GetOpFromObj(interp, nInstOps, vectorInstOps, BLT_OP_ARG1, objc,
+	objv, 0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    return (*proc) (vPtr, interp, objc, objv);
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_VarTrace --
+ *
+ * Results:
+ *	Returns NULL on success.  Only called from a variable trace.
+ *
+ * Side effects:
+ *
+ *---------------------------------------------------------------------------
+ */
+char *
+Blt_Vec_VarTrace(ClientData clientData, Tcl_Interp *interp, const char *part1, 
+		 const char *part2, int flags)
+{
+    Blt_VectorIndexProc *indexProc;
+    Vector *vPtr = clientData;
+    int first, last;
+    int varFlags;
+#define MAX_ERR_MSG	1023
+    static char message[MAX_ERR_MSG + 1];
+
+    if (part2 == NULL) {
+	if (flags & TCL_TRACE_UNSETS) {
+	  free((void*)(vPtr->arrayName));
+	  vPtr->arrayName = NULL;
+	  if (vPtr->freeOnUnset) {
+	    Blt_Vec_Free(vPtr);
+	  }
+	}
+	return NULL;
+    }
+    if (Blt_Vec_GetIndexRange(interp, vPtr, part2, INDEX_ALL_FLAGS, &indexProc)
+	 != TCL_OK) {
+	goto error;
+    }
+    first = vPtr->first, last = vPtr->last;
+    varFlags = TCL_LEAVE_ERR_MSG | (TCL_GLOBAL_ONLY & flags);
+    if (flags & TCL_TRACE_WRITES) {
+	double value;
+	Tcl_Obj *objPtr;
+
+	if (first == SPECIAL_INDEX) { /* Tried to set "min" or "max" */
+	    return (char *)"read-only index";
+	}
+	objPtr = Tcl_GetVar2Ex(interp, part1, part2, varFlags);
+	if (objPtr == NULL) {
+	    goto error;
+	}
+	if (Blt_ExprDoubleFromObj(interp, objPtr, &value) != TCL_OK) {
+	    if ((last == first) && (first >= 0)) {
+		/* Single numeric index. Reset the array element to
+		 * its old value on errors */
+		Tcl_SetVar2Ex(interp, part1, part2, objPtr, varFlags);
+	    }
+	    goto error;
+	}
+	if (first == vPtr->length) {
+	    if (Blt_Vec_ChangeLength((Tcl_Interp *)NULL, vPtr, vPtr->length + 1)
+		 != TCL_OK) {
+		return (char *)"error resizing vector";
+	    }
+	}
+	/* Set possibly an entire range of values */
+	ReplicateValue(vPtr, first, last, value);
+    } else if (flags & TCL_TRACE_READS) {
+	double value;
+	Tcl_Obj *objPtr;
+
+	if (vPtr->length == 0) {
+	    if (Tcl_SetVar2(interp, part1, part2, "", varFlags) == NULL) {
+		goto error;
+	    }
+	    return NULL;
+	}
+	if  (first == vPtr->length) {
+	    return (char *)"write-only index";
+	}
+	if (first == last) {
+	    if (first >= 0) {
+		value = vPtr->valueArr[first];
+	    } else {
+		vPtr->first = 0, vPtr->last = vPtr->length - 1;
+		value = (*indexProc) ((Blt_Vector *) vPtr);
+	    }
+	    objPtr = Tcl_NewDoubleObj(value);
+	    if (Tcl_SetVar2Ex(interp, part1, part2, objPtr, varFlags) == NULL) {
+		Tcl_DecrRefCount(objPtr);
+		goto error;
+	    }
+	} else {
+	    objPtr = GetValues(vPtr, first, last);
+	    if (Tcl_SetVar2Ex(interp, part1, part2, objPtr, varFlags) == NULL) {
+		Tcl_DecrRefCount(objPtr);
+		goto error;
+	    }
+	}
+    } else if (flags & TCL_TRACE_UNSETS) {
+	int i, j;
+
+	if ((first == vPtr->length) || (first == SPECIAL_INDEX)) {
+	    return (char *)"special vector index";
+	}
+	/*
+	 * Collapse the vector from the point of the first unset element.
+	 * Also flush any array variable entries so that the shift is
+	 * reflected when the array variable is read.
+	 */
+	for (i = first, j = last + 1; j < vPtr->length; i++, j++) {
+	    vPtr->valueArr[i] = vPtr->valueArr[j];
+	}
+	vPtr->length -= ((last - first) + 1);
+	if (vPtr->flush) {
+	    Blt_Vec_FlushCache(vPtr);
+	}
+    } else {
+	return (char *)"unknown variable trace flag";
+    }
+    if (flags & (TCL_TRACE_UNSETS | TCL_TRACE_WRITES)) {
+	Blt_Vec_UpdateClients(vPtr);
+    }
+    Tcl_ResetResult(interp);
+    return NULL;
+
+ error: 
+    strncpy(message, Tcl_GetStringResult(interp), MAX_ERR_MSG);
+    message[MAX_ERR_MSG] = '\0';
+    return message;
+}
diff --git a/tlt3.0/bltVecInt.h b/tlt3.0/bltVecInt.h
new file mode 100644
index 0000000..a01c8c8
--- /dev/null
+++ b/tlt3.0/bltVecInt.h
@@ -0,0 +1,250 @@
+/*
+ * bltVecInt.h --
+ *
+ *	Copyright 1995-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "bltInt.h"
+#include <bltHash.h>
+#include <bltChain.h>
+#include <bltVector.h>
+
+#define VECTOR_THREAD_KEY	"BLT Vector Data"
+#define VECTOR_MAGIC		((unsigned int) 0x46170277)
+
+/* These defines allow parsing of different types of indices */
+
+#define INDEX_SPECIAL	(1<<0)	/* Recognize "min", "max", and "++end" as
+				 * valid indices */
+#define INDEX_COLON	(1<<1)	/* Also recognize a range of indices separated
+				 * by a colon */
+#define INDEX_CHECK	(1<<2)	/* Verify that the specified index or range of
+				 * indices are within limits */
+#define INDEX_ALL_FLAGS    (INDEX_SPECIAL | INDEX_COLON | INDEX_CHECK)
+
+#define SPECIAL_INDEX		-2
+
+#define FFT_NO_CONSTANT		(1<<0)
+#define FFT_BARTLETT		(1<<1)
+#define FFT_SPECTRUM		(1<<2)
+
+typedef struct {
+    Blt_HashTable vectorTable;	/* Table of vectors */
+    Blt_HashTable mathProcTable; /* Table of vector math functions */
+    Blt_HashTable indexProcTable;
+    Tcl_Interp *interp;
+    unsigned int nextId;
+} VectorInterpData;
+
+/*
+ * Vector --
+ *
+ *	A vector is an array of double precision values.  It can be accessed
+ *	through a TCL command, a TCL array variable, or C API. The storage for
+ *	the array points initially to a statically allocated buffer, but to
+ *	malloc-ed memory if more is necessary.
+ *
+ *	Vectors can be shared by several clients (for example, two different
+ *	graph widgets).  The data is shared. When a client wants to use a
+ *	vector, it allocates a vector identifier, which identifies the client.
+ *	Clients use this ID to specify a callback routine to be invoked
+ *	whenever the vector is modified or destroyed.  Whenever the vector is
+ *	updated or destroyed, each client is notified of the change by their
+ *	callback routine.
+ */
+
+typedef struct {
+
+    /*
+     * If you change these fields, make sure you change the definition of
+     * Blt_Vector in bltInt.h and blt.h too.
+     */
+
+    double *valueArr;		/* Array of values (malloc-ed) */
+
+    int length;			/* Current number of values in the array. */
+
+    int size;			/* Maximum number of values that can be stored
+				 * in the value array. */
+
+    double min, max;		/* Minimum and maximum values in the vector */
+
+    int dirty;			/* Indicates if the vector has been updated */
+
+    int reserved;
+
+    /* The following fields are local to this module  */
+
+    const char *name;		/* The namespace-qualified name of the vector.
+				 * It points to the hash key allocated for the
+				 * entry in the vector hash table. */
+
+    VectorInterpData *dataPtr;
+    Tcl_Interp *interp;		/* Interpreter associated with the
+				 * vector */
+
+    Blt_HashEntry *hashPtr;	/* If non-NULL, pointer in a hash table to
+				 * track the vectors in use. */
+
+    Tcl_FreeProc *freeProc;	/* Address of procedure to call to release
+				 * storage for the value array, Optionally can
+				 * be one of the following: TCL_STATIC,
+				 * TCL_DYNAMIC, or TCL_VOLATILE. */
+
+    const char *arrayName;	/* The name of the TCL array variable mapped
+				 * to the vector (malloc'ed). If NULL,
+				 * indicates that the vector isn't mapped to
+				 * any variable */
+
+    Tcl_Namespace *nsPtr;	/* Namespace context of the vector itself. */
+
+    int offset;			/* Offset from zero of the vector's starting
+				 * index */
+
+    Tcl_Command cmdToken;	/* Token for vector's TCL command. */
+
+    Blt_Chain chain;		/* List of clients using this vector */
+
+    int notifyFlags;		/* Notification flags. See definitions
+				 * below */
+
+    int varFlags;		/* Indicate if the variable is global,
+				 * namespace, or local */
+
+    int freeOnUnset;		/* For backward compatibility only: If
+				 * non-zero, free the vector when its variable
+				 * is unset. */
+    int flush;
+
+    int first, last;		/* Selected region of vector. This is used
+				 * mostly for the math routines */
+} Vector;
+
+#define NOTIFY_UPDATED		((int)BLT_VECTOR_NOTIFY_UPDATE)
+#define NOTIFY_DESTROYED	((int)BLT_VECTOR_NOTIFY_DESTROY)
+
+#define NOTIFY_NEVER		(1<<3)	/* Never notify clients of updates to
+					 * the vector */
+#define NOTIFY_ALWAYS		(1<<4)	/* Notify clients after each update
+					 * of the vector is made */
+#define NOTIFY_WHENIDLE		(1<<5)	/* Notify clients at the next idle point
+					 * that the vector has been updated. */
+
+#define NOTIFY_PENDING		(1<<6)	/* A do-when-idle notification of the
+					 * vector's clients is pending. */
+#define NOTIFY_NOW		(1<<7)	/* Notify clients of changes once
+					 * immediately */
+
+#define NOTIFY_WHEN_MASK	(NOTIFY_NEVER|NOTIFY_ALWAYS|NOTIFY_WHENIDLE)
+
+#define UPDATE_RANGE		(1<<9)	/* The data of the vector has changed.
+					 * Update the min and max limits when
+					 * they are needed */
+
+#define FindRange(array, first, last, min, max) \
+{ \
+    min = max = 0.0; \
+    if (first <= last) { \
+	register int i; \
+	min = max = array[first]; \
+	for (i = first + 1; i <= last; i++) { \
+	    if (min > array[i]) { \
+		min = array[i]; \
+	    } else if (max < array[i]) { \
+		max = array[i]; \
+	    } \
+	} \
+    } \
+}
+
+extern void Blt_Vec_InstallSpecialIndices(Blt_HashTable *tablePtr);
+
+extern void Blt_Vec_InstallMathFunctions(Blt_HashTable *tablePtr);
+
+extern void Blt_Vec_UninstallMathFunctions(Blt_HashTable *tablePtr);
+
+extern VectorInterpData *Blt_Vec_GetInterpData (Tcl_Interp *interp);
+
+extern double Blt_Vec_Max(Vector *vecObjPtr);
+extern double Blt_Vec_Min(Vector *vecObjPtr);
+
+extern Vector *Blt_Vec_New(VectorInterpData *dataPtr);
+
+extern int Blt_Vec_Duplicate(Vector *destPtr, Vector *srcPtr);
+
+extern int Blt_Vec_SetLength(Tcl_Interp *interp, Vector *vPtr, 
+	int length);
+
+extern int Blt_Vec_SetSize(Tcl_Interp *interp, Vector *vPtr, 
+	int size);
+
+extern int Blt_Vec_ChangeLength(Tcl_Interp *interp, Vector *vPtr, 
+	int length);
+
+extern Vector *Blt_Vec_ParseElement(Tcl_Interp *interp, 
+	VectorInterpData *dataPtr, const char *start, const char **endPtr, 
+	int flags);
+
+extern void Blt_Vec_Free(Vector *vPtr);
+
+extern size_t *Blt_Vec_SortMap(Vector **vectors, int nVectors);
+
+extern int Blt_Vec_LookupName(VectorInterpData *dataPtr, 
+	const char *vecName, Vector **vPtrPtr);
+
+extern Vector *Blt_Vec_Create(VectorInterpData *dataPtr, 
+	const char *name, const char *cmdName, const char *varName, 
+	int *newPtr);
+
+extern void Blt_Vec_UpdateRange(Vector *vPtr);
+
+extern void Blt_Vec_UpdateClients(Vector *vPtr);
+
+extern void Blt_Vec_FlushCache(Vector *vPtr);
+
+extern int Blt_Vec_Reset(Vector *vPtr, double *dataArr,
+	int nValues, int arraySize, Tcl_FreeProc *freeProc);
+
+extern int  Blt_Vec_GetIndex(Tcl_Interp *interp, Vector *vPtr, 
+	const char *string, int *indexPtr, int flags, 
+	Blt_VectorIndexProc **procPtrPtr);
+
+extern int  Blt_Vec_GetIndexRange(Tcl_Interp *interp, Vector *vPtr, 
+	const char *string, int flags, Blt_VectorIndexProc **procPtrPtr);
+
+extern int Blt_Vec_MapVariable(Tcl_Interp *interp, Vector *vPtr, 
+	const char *name);
+
+extern int Blt_Vec_FFT(Tcl_Interp *interp, Vector *realPtr,
+	Vector *phasesPtr, Vector *freqPtr, double delta, 
+	int flags, Vector *srcPtr);
+
+extern int Blt_Vec_InverseFFT(Tcl_Interp *interp, Vector *iSrcPtr, 
+	Vector *rDestPtr, Vector *iDestPtr, Vector *srcPtr);
+
+extern Tcl_ObjCmdProc Blt_Vec_InstCmd;
+
+extern Tcl_VarTraceProc Blt_Vec_VarTrace;
+
+extern Tcl_IdleProc Blt_Vec_NotifyClients;
+
diff --git a/tlt3.0/bltVecMath.c b/tlt3.0/bltVecMath.c
new file mode 100644
index 0000000..8c0ad69
--- /dev/null
+++ b/tlt3.0/bltVecMath.c
@@ -0,0 +1,1897 @@
+
+/*
+ * bltVecMath.c --
+ *
+ * This module implements mathematical expressions with vector data
+ * objects.
+ *
+ *	Copyright 1995-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <float.h>
+#include <math.h>
+
+#include "bltInt.h"
+#include "bltVecInt.h"
+#include "bltNsUtil.h"
+#include "bltParse.h"
+
+/*
+ * Three types of math functions:
+ *
+ *	ComponentProc		Function is applied in multiple calls to
+ *				each component of the vector.
+ *	VectorProc		Entire vector is passed, each component is
+ *				modified.
+ *	ScalarProc		Entire vector is passed, single scalar value
+ *				is returned.
+ */
+
+typedef double (ComponentProc)(double value);
+typedef int (VectorProc)(Vector *vPtr);
+typedef double (ScalarProc)(Vector *vPtr);
+
+/*
+ * Built-in math functions:
+ */
+typedef int (GenericMathProc) ();
+
+/*
+ * MathFunction --
+ *
+ *	Contains information about math functions that can be called
+ *	for vectors.  The table of math functions is global within the
+ *	application.  So you can't define two different "sqrt"
+ *	functions.
+ */
+typedef struct {
+    const char *name;		/* Name of built-in math function.  If
+				 * NULL, indicates that the function
+				 * was user-defined and dynamically
+				 * allocated.  Function names are
+				 * global across all interpreters. */
+
+    void *proc;			/* Procedure that implements this math
+				 * function. */
+
+    ClientData clientData;	/* Argument to pass when invoking the
+				 * function. */
+
+} MathFunction;
+
+
+/*
+ * Macros for testing floating-point values for certain special cases:
+ *
+ *	IS_NAN	Test for not-a-number by comparing a value against itself
+ *	IF_INF	Test for infinity by comparing against the largest floating
+ *		point value.
+ */
+
+#define IS_NAN(v) ((v) != (v))
+
+#ifdef DBL_MAX
+#   define IS_INF(v) (((v) > DBL_MAX) || ((v) < -DBL_MAX))
+#else
+#   define IS_INF(v) 0
+#endif
+
+/* The data structure below is used to describe an expression value,
+ * which can be either a double-precision floating-point value, or a
+ * string.  A given number has only one value at a time.  */
+
+#define STATIC_STRING_SPACE 150
+
+/*
+ * Tokens --
+ *
+ *	The token types are defined below.  In addition, there is a
+ *	table associating a precedence with each operator.  The order
+ *	of types is important.  Consult the code before changing it.
+ */
+enum Tokens {
+    VALUE, OPEN_PAREN, CLOSE_PAREN, COMMA, END, UNKNOWN,
+    MULT = 8, DIVIDE, MOD, PLUS, MINUS,
+    LEFT_SHIFT, RIGHT_SHIFT,
+    LESS, GREATER, LEQ, GEQ, EQUAL, NEQ,
+    OLD_BIT_AND, EXPONENT, OLD_BIT_OR, OLD_QUESTY, OLD_COLON,
+    AND, OR, UNARY_MINUS, OLD_UNARY_PLUS, NOT, OLD_BIT_NOT
+};
+
+typedef struct {
+    Vector *vPtr;
+    char staticSpace[STATIC_STRING_SPACE];
+    ParseValue pv;		/* Used to hold a string value, if any. */
+} Value;
+
+/*
+ * ParseInfo --
+ *
+ *	The data structure below describes the state of parsing an
+ *	expression.  It's passed among the routines in this module.
+ */
+typedef struct {
+    const char *expr;		/* The entire right-hand side of the
+				 * expression, as originally passed to
+				 * Blt_ExprVector. */
+
+    const char *nextPtr;	/* Position of the next character to
+				 * be scanned from the expression
+				 * string. */
+
+    enum Tokens token;		/* Type of the last token to be parsed
+				 * from nextPtr.  See below for
+				 * definitions.  Corresponds to the
+				 * characters just before nextPtr. */
+
+} ParseInfo;
+
+/*
+ * Precedence table.  The values for non-operator token types are ignored.
+ */
+static int precTable[] =
+{
+    0, 0, 0, 0, 0, 0, 0, 0,
+    12, 12, 12,			/* MULT, DIVIDE, MOD */
+    11, 11,			/* PLUS, MINUS */
+    10, 10,			/* LEFT_SHIFT, RIGHT_SHIFT */
+    9, 9, 9, 9,			/* LESS, GREATER, LEQ, GEQ */
+    8, 8,			/* EQUAL, NEQ */
+    7,				/* OLD_BIT_AND */
+    13,				/* EXPONENTIATION */
+    5,				/* OLD_BIT_OR */
+    4,				/* AND */
+    3,				/* OR */
+    2,				/* OLD_QUESTY */
+    1,				/* OLD_COLON */
+    14, 14, 14, 14		/* UNARY_MINUS, OLD_UNARY_PLUS, NOT,
+				 * OLD_BIT_NOT */
+};
+
+
+/*
+ * Forward declarations.
+ */
+
+static int NextValue(Tcl_Interp *interp, ParseInfo *piPtr, int prec, 
+	Value *valuePtr);
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Sort --
+ *
+ *	A vector math function.  Sorts the values of the given 
+ *	vector.
+ *
+ * Results:
+ *	Always TCL_OK.
+ *
+ * Side Effects:
+ *	The vector is sorted.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+Sort(Vector *vPtr)
+{
+    size_t *map;
+    double *values;
+    int i;
+
+    map = Blt_Vec_SortMap(&vPtr, 1);
+    values = malloc(sizeof(double) * vPtr->length);
+    for(i = vPtr->first; i <= vPtr->last; i++) {
+	values[i] = vPtr->valueArr[map[i]];
+    }
+    free(map);
+    for (i = vPtr->first; i <= vPtr->last; i++) {
+	vPtr->valueArr[i] = values[i];
+    }
+    free(values);
+    return TCL_OK;
+}
+
+static double
+Length(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+
+    return (double)(vPtr->last - vPtr->first + 1);
+}
+
+double
+Blt_VecMax(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+
+    return Blt_Vec_Max(vPtr);
+}
+
+double
+Blt_VecMin(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+
+    return Blt_Vec_Min(vPtr);
+}
+
+
+static double
+Product(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+    double prod;
+    double *vp, *vend;
+
+    prod = 1.0;
+    for(vp = vPtr->valueArr + vPtr->first,
+	    vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) {
+	prod *= *vp;
+    }
+    return prod;
+}
+
+static double
+Sum(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+    double sum, c;
+    double *vp, *vend;
+
+    /* Kahan summation algorithm */
+
+    vp = vPtr->valueArr + vPtr->first;
+    sum = *vp++;
+    c = 0.0;			/* A running compensation for lost
+				 * low-order bits.*/
+    for (vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) {
+	double y, t;
+	
+        y = *vp - c;		/* So far, so good: c is zero.*/
+        t = sum + y;		/* Alas, sum is big, y small, so
+				 * low-order digits of y are lost.*/
+        c = (t - sum) - y;	/* (t - sum) recovers the high-order
+				 * part of y; subtracting y recovers
+				 * -(low part of y) */
+	sum = t;
+    }
+    return sum;
+}
+
+static double
+Mean(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+    double sum;
+    int n;
+
+    sum = Sum(vectorPtr);
+    n = vPtr->last - vPtr->first + 1;
+    return sum / (double)n;
+}
+
+/*
+ *  var = 1/N Sum( (x[i] - mean)^2 )
+ */
+static double
+Variance(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+    double var, mean;
+    double *vp, *vend;
+    int count;
+
+    mean = Mean(vectorPtr);
+    var = 0.0;
+    count = 0;
+    for(vp = vPtr->valueArr + vPtr->first,
+	vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) {
+	double dx;
+
+	dx = *vp - mean;
+	var += dx * dx;
+	count++;
+    }
+    if (count < 2) {
+	return 0.0;
+    }
+    var /= (double)(count - 1);
+    return var;
+}
+
+/*
+ *  skew = Sum( (x[i] - mean)^3 ) / (var^3/2)
+ */
+static double
+Skew(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+    double diff, var, skew, mean, diffsq;
+    double *vp, *vend;
+    int count;
+
+    mean = Mean(vectorPtr);
+    var = skew = 0.0;
+    count = 0;
+    for(vp = vPtr->valueArr + vPtr->first,
+	    vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) {
+	diff = *vp - mean;
+	diff = fabs(diff);
+	diffsq = diff * diff;
+	var += diffsq;
+	skew += diffsq * diff;
+	count++;
+    }
+    if (count < 2) {
+	return 0.0;
+    }
+    var /= (double)(count - 1);
+    skew /= count * var * sqrt(var);
+    return skew;
+}
+
+static double
+StdDeviation(Blt_Vector *vectorPtr)
+{
+    double var;
+
+    var = Variance(vectorPtr);
+    if (var > 0.0) {
+	return sqrt(var);
+    }
+    return 0.0;
+}
+
+
+static double
+AvgDeviation(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+    double diff, avg, mean;
+    double *vp, *vend;
+    int count;
+
+    mean = Mean(vectorPtr);
+    avg = 0.0;
+    count = 0;
+    for(vp = vPtr->valueArr + vPtr->first,
+	    vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) {
+	diff = *vp - mean;
+	avg += fabs(diff);
+	count++;
+    }
+    if (count < 2) {
+	return 0.0;
+    }
+    avg /= (double)count;
+    return avg;
+}
+
+
+static double
+Kurtosis(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+    double diff, diffsq, kurt, var, mean;
+    double *vp, *vend;
+    int count;
+
+    mean = Mean(vectorPtr);
+    var = kurt = 0.0;
+    count = 0;
+    for(vp = vPtr->valueArr + vPtr->first,
+	    vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) {
+	diff = *vp - mean;
+	diffsq = diff * diff;
+	var += diffsq;
+	kurt += diffsq * diffsq;
+	count++;
+    }
+    if (count < 2) {
+	return 0.0;
+    }
+    var /= (double)(count - 1);
+    if (var == 0.0) {
+	return 0.0;
+    }
+    kurt /= (count * var * var);
+    return kurt - 3.0;		/* Fisher Kurtosis */
+}
+
+
+static double
+Median(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+    size_t *map;
+    double q2;
+    int mid;
+
+    if (vPtr->length == 0) {
+	return -DBL_MAX;
+    }
+    map = Blt_Vec_SortMap(&vPtr, 1);
+    mid = (vPtr->length - 1) / 2;
+
+    /*  
+     * Determine Q2 by checking if the number of elements [0..n-1] is
+     * odd or even.  If even, we must take the average of the two
+     * middle values.  
+     */
+    if (vPtr->length & 1) { /* Odd */
+	q2 = vPtr->valueArr[map[mid]];
+    } else {			/* Even */
+	q2 = (vPtr->valueArr[map[mid]] + 
+	      vPtr->valueArr[map[mid + 1]]) * 0.5;
+    }
+    free(map);
+    return q2;
+}
+
+static double
+Q1(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+    double q1;
+    size_t *map;
+
+    if (vPtr->length == 0) {
+	return -DBL_MAX;
+    } 
+    map = Blt_Vec_SortMap(&vPtr, 1);
+
+    if (vPtr->length < 4) {
+	q1 = vPtr->valueArr[map[0]];
+    } else {
+	int mid, q;
+
+	mid = (vPtr->length - 1) / 2;
+	q = mid / 2;
+
+	/* 
+	 * Determine Q1 by checking if the number of elements in the
+	 * bottom half [0..mid) is odd or even.   If even, we must
+	 * take the average of the two middle values.
+	 */
+	if (mid & 1) {		/* Odd */
+	    q1 = vPtr->valueArr[map[q]]; 
+	} else {		/* Even */
+	    q1 = (vPtr->valueArr[map[q]] + 
+		  vPtr->valueArr[map[q + 1]]) * 0.5; 
+	}
+    }
+    free(map);
+    return q1;
+}
+
+static double
+Q3(Blt_Vector *vectorPtr)
+{
+    Vector *vPtr = (Vector *)vectorPtr;
+    double q3;
+    size_t *map;
+
+    if (vPtr->length == 0) {
+	return -DBL_MAX;
+    } 
+
+    map = Blt_Vec_SortMap(&vPtr, 1);
+
+    if (vPtr->length < 4) {
+	q3 = vPtr->valueArr[map[vPtr->length - 1]];
+    } else {
+	int mid, q;
+
+	mid = (vPtr->length - 1) / 2;
+	q = (vPtr->length + mid) / 2;
+
+	/* 
+	 * Determine Q3 by checking if the number of elements in the
+	 * upper half (mid..n-1] is odd or even.   If even, we must
+	 * take the average of the two middle values.
+	 */
+	if (mid & 1) {		/* Odd */
+	    q3 = vPtr->valueArr[map[q]];
+	} else {		/* Even */
+	    q3 = (vPtr->valueArr[map[q]] + 
+		  vPtr->valueArr[map[q + 1]]) * 0.5; 
+	}
+    }
+    free(map);
+    return q3;
+}
+
+
+static int
+Norm(Blt_Vector *vector)
+{
+    Vector *vPtr = (Vector *)vector;
+    double norm, range, min, max;
+    int i;
+
+    min = Blt_Vec_Min(vPtr);
+    max = Blt_Vec_Max(vPtr);
+    range = max - min;
+    for (i = 0; i < vPtr->length; i++) {
+	norm = (vPtr->valueArr[i] - min) / range;
+	vPtr->valueArr[i] = norm;
+    }
+    return TCL_OK;
+}
+
+
+static double
+Nonzeros(Blt_Vector *vector)
+{
+    Vector *vPtr = (Vector *)vector;
+    int count;
+    double *vp, *vend;
+
+    count = 0;
+    for(vp = vPtr->valueArr + vPtr->first,
+	    vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) {
+	if (*vp == 0.0) {
+	    count++;
+	}
+    }
+    return (double) count;
+}
+
+static double
+Fabs(double value)
+{
+    if (value < 0.0) {
+	return -value;
+    }
+    return value;
+}
+
+static double
+Round(double value)
+{
+    if (value < 0.0) {
+	return ceil(value - 0.5);
+    } else {
+	return floor(value + 0.5);
+    }
+}
+
+static double
+Fmod(double x, double y)
+{
+    if (y == 0.0) {
+	return 0.0;
+    }
+    return x - (floor(x / y) * y);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MathError --
+ *
+ *	This procedure is called when an error occurs during a
+ *	floating-point operation.  It reads errno and sets
+ *	interp->result accordingly.
+ *
+ * Results:
+ *	Interp->result is set to hold an error message.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+MathError(
+    Tcl_Interp *interp,		/* Where to store error message. */
+    double value)		/* Value returned after error; used to
+				 * distinguish underflows from
+				 * overflows. */
+{
+    if ((errno == EDOM) || (value != value)) {
+	Tcl_AppendResult(interp, "domain error: argument not in valid range",
+	    (char *)NULL);
+	Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", 
+			 Tcl_GetStringResult(interp), (char *)NULL);
+    } else if ((errno == ERANGE) || IS_INF(value)) {
+	if (value == 0.0) {
+	    Tcl_AppendResult(interp, 
+			     "floating-point value too small to represent",
+		(char *)NULL);
+	    Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", 
+			     Tcl_GetStringResult(interp), (char *)NULL);
+	} else {
+	    Tcl_AppendResult(interp, 
+			     "floating-point value too large to represent",
+		(char *)NULL);
+	    Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", 
+			     Tcl_GetStringResult(interp), (char *)NULL);
+	}
+    } else {
+	Tcl_AppendResult(interp, "unknown floating-point error, ",
+		"errno = ", Blt_Itoa(errno), (char *)NULL);
+	Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", 
+			 Tcl_GetStringResult(interp), (char *)NULL);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ParseString --
+ *
+ *	Given a string (such as one coming from command or variable
+ *	substitution), make a Value based on the string.  The value
+ *	will be a floating-point or integer, if possible, or else it
+ *	will just be a copy of the string.
+ *
+ * Results:
+ *	TCL_OK is returned under normal circumstances, and TCL_ERROR
+ *	is returned if a floating-point overflow or underflow occurred
+ *	while reading in a number.  The value at *valuePtr is modified
+ *	to hold a number, if possible.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+ParseString(
+    Tcl_Interp *interp,		/* Where to store error message. */
+    const char *string,		/* String to turn into value. */
+    Value *valuePtr)		/* Where to store value information.
+				 * Caller must have initialized pv field. */
+{
+    const char *endPtr;
+    double value;
+
+    errno = 0;
+
+    /*   
+     * The string can be either a number or a vector.  First try to
+     * convert the string to a number.  If that fails then see if
+     * we can find a vector by that name.
+     */
+
+    value = strtod(string, (char **)&endPtr);
+    if ((endPtr != string) && (*endPtr == '\0')) {
+	if (errno != 0) {
+	    Tcl_ResetResult(interp);
+	    MathError(interp, value);
+	    return TCL_ERROR;
+	}
+	/* Numbers are stored as single element vectors. */
+	if (Blt_Vec_ChangeLength(interp, valuePtr->vPtr, 1) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	valuePtr->vPtr->valueArr[0] = value;
+	return TCL_OK;
+    } else {
+	Vector *vPtr;
+
+	while (isspace((unsigned char)(*string))) {
+	    string++;		/* Skip spaces leading the vector name. */    
+	}
+	vPtr = Blt_Vec_ParseElement(interp, valuePtr->vPtr->dataPtr, 
+		string, &endPtr, NS_SEARCH_BOTH);
+	if (vPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	if (*endPtr != '\0') {
+	    Tcl_AppendResult(interp, "extra characters after vector", 
+			     (char *)NULL);
+	    return TCL_ERROR;
+	}
+	/* Copy the designated vector to our temporary. */
+	Blt_Vec_Duplicate(valuePtr->vPtr, vPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ParseMathFunction --
+ *
+ *	This procedure is invoked to parse a math function from an
+ *	expression string, carry out the function, and return the
+ *	value computed.
+ *
+ * Results:
+ *	TCL_OK is returned if all went well and the function's value
+ *	was computed successfully.  If the name doesn't match any
+ *	known math function, returns TCL_RETURN. And if a format error
+ *	was found, TCL_ERROR is returned and an error message is left
+ *	in interp->result.
+ *
+ *	After a successful return piPtr will be updated to point to
+ *	the character just after the function call, the token is set
+ *	to VALUE, and the value is stored in valuePtr.
+ *
+ * Side effects:
+ *	Embedded commands could have arbitrary side-effects.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ParseMathFunction(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
+    const char *start,		/* Start of string to parse */
+    ParseInfo *piPtr,		/* Describes the state of the parse.
+				 * piPtr->nextPtr must point to the
+				 * first character of the function's
+				 * name. */
+    Value *valuePtr)		/* Where to store value, if that is
+				 * what's parsed from string.  Caller
+				 * must have initialized pv field
+				 * correctly. */
+{
+    Blt_HashEntry *hPtr;
+    MathFunction *mathPtr;	/* Info about math function. */
+    char *p;
+    VectorInterpData *dataPtr;	/* Interpreter-specific data. */
+    GenericMathProc *proc;
+
+    /*
+     * Find the end of the math function's name and lookup the
+     * record for the function.
+     */
+    p = (char *)start;
+    while (isspace((unsigned char)(*p))) {
+	p++;
+    }
+    piPtr->nextPtr = p;
+    while (isalnum((unsigned char)(*p)) || (*p == '_')) {
+	p++;
+    }
+    if (*p != '(') {
+	return TCL_RETURN;	/* Must start with open parenthesis */
+    }
+    dataPtr = valuePtr->vPtr->dataPtr;
+    *p = '\0';
+    hPtr = Blt_FindHashEntry(&dataPtr->mathProcTable, piPtr->nextPtr);
+    *p = '(';
+    if (hPtr == NULL) {
+	return TCL_RETURN;	/* Name doesn't match any known function */
+    }
+    /* Pick up the single value as the argument to the function */
+    piPtr->token = OPEN_PAREN;
+    piPtr->nextPtr = p + 1;
+    valuePtr->pv.next = valuePtr->pv.buffer;
+    if (NextValue(interp, piPtr, -1, valuePtr) != TCL_OK) {
+	return TCL_ERROR;	/* Parse error */
+    }
+    if (piPtr->token != CLOSE_PAREN) {
+	Tcl_AppendResult(interp, "unmatched parentheses in expression \"",
+	    piPtr->expr, "\"", (char *)NULL);
+	return TCL_ERROR;	/* Missing right parenthesis */
+    }
+    mathPtr = Blt_GetHashValue(hPtr);
+    proc = mathPtr->proc;
+    if ((*proc) (mathPtr->clientData, interp, valuePtr->vPtr) != TCL_OK) {
+	return TCL_ERROR;	/* Function invocation error */
+    }
+    piPtr->token = VALUE;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NextToken --
+ *
+ *	Lexical analyzer for expression parser:  parses a single value,
+ *	operator, or other syntactic element from an expression string.
+ *
+ * Results:
+ *	TCL_OK is returned unless an error occurred while doing lexical
+ *	analysis or executing an embedded command.  In that case a
+ *	standard TCL error is returned, using interp->result to hold
+ *	an error message.  In the event of a successful return, the token
+ *	and field in piPtr is updated to refer to the next symbol in
+ *	the expression string, and the expr field is advanced past that
+ *	token;  if the token is a value, then the value is stored at
+ *	valuePtr.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+NextToken(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
+    ParseInfo *piPtr,		/* Describes the state of the parse. */
+    Value *valuePtr)		/* Where to store value, if that is
+				 * what's parsed from string.  Caller
+				 * must have initialized pv field
+				 * correctly. */
+{
+    const char *p;
+    const char *endPtr;
+    const char *var;
+    int result;
+
+    p = piPtr->nextPtr;
+    while (isspace((unsigned char)(*p))) {
+	p++;
+    }
+    if (*p == '\0') {
+	piPtr->token = END;
+	piPtr->nextPtr = p;
+	return TCL_OK;
+    }
+    /*
+     * Try to parse the token as a floating-point number. But check
+     * that the first character isn't a "-" or "+", which "strtod"
+     * will happily accept as an unary operator.  Otherwise, we might
+     * accidently treat a binary operator as unary by mistake, which
+     * will eventually cause a syntax error.
+     */
+    if ((*p != '-') && (*p != '+')) {
+	double value;
+
+	errno = 0;
+	value = strtod(p, (char **)&endPtr);
+	if (endPtr != p) {
+	    if (errno != 0) {
+		MathError(interp, value);
+		return TCL_ERROR;
+	    }
+	    piPtr->token = VALUE;
+	    piPtr->nextPtr = endPtr;
+
+	    /*
+	     * Save the single floating-point value as an 1-component vector.
+	     */
+	    if (Blt_Vec_ChangeLength(interp, valuePtr->vPtr, 1) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    valuePtr->vPtr->valueArr[0] = value;
+	    return TCL_OK;
+	}
+    }
+    piPtr->nextPtr = p + 1;
+    switch (*p) {
+    case '$':
+	piPtr->token = VALUE;
+	var = Tcl_ParseVar(interp, p, &endPtr);
+	if (var == NULL) {
+	    return TCL_ERROR;
+	}
+	piPtr->nextPtr = endPtr;
+	Tcl_ResetResult(interp);
+	result = ParseString(interp, var, valuePtr);
+	return result;
+
+    case '[':
+	piPtr->token = VALUE;
+	result = Blt_ParseNestedCmd(interp, p + 1, 0, &endPtr, &valuePtr->pv);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	piPtr->nextPtr = endPtr;
+	Tcl_ResetResult(interp);
+	result = ParseString(interp, valuePtr->pv.buffer, valuePtr);
+	return result;
+
+    case '"':
+	piPtr->token = VALUE;
+	result = Blt_ParseQuotes(interp, p + 1, '"', 0, &endPtr, &valuePtr->pv);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	piPtr->nextPtr = endPtr;
+	Tcl_ResetResult(interp);
+	result = ParseString(interp, valuePtr->pv.buffer, valuePtr);
+	return result;
+
+    case '{':
+	piPtr->token = VALUE;
+	result = Blt_ParseBraces(interp, p + 1, &endPtr, &valuePtr->pv);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	piPtr->nextPtr = endPtr;
+	Tcl_ResetResult(interp);
+	result = ParseString(interp, valuePtr->pv.buffer, valuePtr);
+	return result;
+
+    case '(':
+	piPtr->token = OPEN_PAREN;
+	break;
+
+    case ')':
+	piPtr->token = CLOSE_PAREN;
+	break;
+
+    case ',':
+	piPtr->token = COMMA;
+	break;
+
+    case '*':
+	piPtr->token = MULT;
+	break;
+
+    case '/':
+	piPtr->token = DIVIDE;
+	break;
+
+    case '%':
+	piPtr->token = MOD;
+	break;
+
+    case '+':
+	piPtr->token = PLUS;
+	break;
+
+    case '-':
+	piPtr->token = MINUS;
+	break;
+
+    case '^':
+	piPtr->token = EXPONENT;
+	break;
+
+    case '<':
+	switch (*(p + 1)) {
+	case '<':
+	    piPtr->nextPtr = p + 2;
+	    piPtr->token = LEFT_SHIFT;
+	    break;
+	case '=':
+	    piPtr->nextPtr = p + 2;
+	    piPtr->token = LEQ;
+	    break;
+	default:
+	    piPtr->token = LESS;
+	    break;
+	}
+	break;
+
+    case '>':
+	switch (*(p + 1)) {
+	case '>':
+	    piPtr->nextPtr = p + 2;
+	    piPtr->token = RIGHT_SHIFT;
+	    break;
+	case '=':
+	    piPtr->nextPtr = p + 2;
+	    piPtr->token = GEQ;
+	    break;
+	default:
+	    piPtr->token = GREATER;
+	    break;
+	}
+	break;
+
+    case '=':
+	if (*(p + 1) == '=') {
+	    piPtr->nextPtr = p + 2;
+	    piPtr->token = EQUAL;
+	} else {
+	    piPtr->token = UNKNOWN;
+	}
+	break;
+
+    case '&':
+	if (*(p + 1) == '&') {
+	    piPtr->nextPtr = p + 2;
+	    piPtr->token = AND;
+	} else {
+	    piPtr->token = UNKNOWN;
+	}
+	break;
+
+    case '|':
+	if (*(p + 1) == '|') {
+	    piPtr->nextPtr = p + 2;
+	    piPtr->token = OR;
+	} else {
+	    piPtr->token = UNKNOWN;
+	}
+	break;
+
+    case '!':
+	if (*(p + 1) == '=') {
+	    piPtr->nextPtr = p + 2;
+	    piPtr->token = NEQ;
+	} else {
+	    piPtr->token = NOT;
+	}
+	break;
+
+    default:
+	piPtr->token = VALUE;
+	result = ParseMathFunction(interp, p, piPtr, valuePtr);
+	if ((result == TCL_OK) || (result == TCL_ERROR)) {
+	    return result;
+	} else {
+	    Vector *vPtr;
+
+	    while (isspace((unsigned char)(*p))) {
+		p++;		/* Skip spaces leading the vector name. */    
+	    }
+	    vPtr = Blt_Vec_ParseElement(interp, valuePtr->vPtr->dataPtr, 
+			p, &endPtr, NS_SEARCH_BOTH);
+	    if (vPtr == NULL) {
+		return TCL_ERROR;
+	    }
+	    Blt_Vec_Duplicate(valuePtr->vPtr, vPtr);
+	    piPtr->nextPtr = endPtr;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NextValue --
+ *
+ *	Parse a "value" from the remainder of the expression in piPtr.
+ *
+ * Results:
+ *	Normally TCL_OK is returned.  The value of the expression is
+ *	returned in *valuePtr.  If an error occurred, then interp->result
+ *	contains an error message and TCL_ERROR is returned.
+ *	InfoPtr->token will be left pointing to the token AFTER the
+ *	expression, and piPtr->nextPtr will point to the character just
+ *	after the terminating token.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+NextValue(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
+    ParseInfo *piPtr,	/* Describes the state of the parse
+				 * just before the value (i.e. NextToken will
+				 * be called to get first token of value). */
+    int prec,			/* Treat any un-parenthesized operator
+				 * with precedence <= this as the end
+				 * of the expression. */
+    Value *valuePtr)		/* Where to store the value of the expression.
+				 * Caller must have initialized pv field. */
+{
+    Value value2;		/* Second operand for current operator.  */
+    int operator;		/* Current operator (either unary or binary). */
+    int gotOp;			/* Non-zero means already lexed the operator
+				 * (while picking up value for unary operator).
+				 * Don't lex again. */
+    int result;
+    Vector *vPtr, *v2Ptr;
+    int i;
+
+    /*
+     * There are two phases to this procedure.  First, pick off an initial
+     * value.  Then, parse (binary operator, value) pairs until done.
+     */
+
+    vPtr = valuePtr->vPtr;
+    v2Ptr = Blt_Vec_New(vPtr->dataPtr);
+    gotOp = FALSE;
+    value2.vPtr = v2Ptr;
+    value2.pv.buffer = value2.pv.next = value2.staticSpace;
+    value2.pv.end = value2.pv.buffer + STATIC_STRING_SPACE - 1;
+    value2.pv.expandProc = Blt_ExpandParseValue;
+    value2.pv.clientData = NULL;
+
+    result = NextToken(interp, piPtr, valuePtr);
+    if (result != TCL_OK) {
+	goto done;
+    }
+    if (piPtr->token == OPEN_PAREN) {
+
+	/* Parenthesized sub-expression. */
+
+	result = NextValue(interp, piPtr, -1, valuePtr);
+	if (result != TCL_OK) {
+	    goto done;
+	}
+	if (piPtr->token != CLOSE_PAREN) {
+	    Tcl_AppendResult(interp, "unmatched parentheses in expression \"",
+		piPtr->expr, "\"", (char *)NULL);
+	    result = TCL_ERROR;
+	    goto done;
+	}
+    } else {
+	if (piPtr->token == MINUS) {
+	    piPtr->token = UNARY_MINUS;
+	}
+	if (piPtr->token >= UNARY_MINUS) {
+	    operator = piPtr->token;
+	    result = NextValue(interp, piPtr, precTable[operator], valuePtr);
+	    if (result != TCL_OK) {
+		goto done;
+	    }
+	    gotOp = TRUE;
+	    /* Process unary operators. */
+	    switch (operator) {
+	    case UNARY_MINUS:
+		for(i = 0; i < vPtr->length; i++) {
+		    vPtr->valueArr[i] = -(vPtr->valueArr[i]);
+		}
+		break;
+
+	    case NOT:
+		for(i = 0; i < vPtr->length; i++) {
+		    vPtr->valueArr[i] = (double)(!vPtr->valueArr[i]);
+		}
+		break;
+	    default:
+		Tcl_AppendResult(interp, "unknown operator", (char *)NULL);
+		goto error;
+	    }
+	} else if (piPtr->token != VALUE) {
+	    Tcl_AppendResult(interp, "missing operand", (char *)NULL);
+	    goto error;
+	}
+    }
+    if (!gotOp) {
+	result = NextToken(interp, piPtr, &value2);
+	if (result != TCL_OK) {
+	    goto done;
+	}
+    }
+    /*
+     * Got the first operand.  Now fetch (operator, operand) pairs.
+     */
+    for (;;) {
+	operator = piPtr->token;
+
+	value2.pv.next = value2.pv.buffer;
+	if ((operator < MULT) || (operator >= UNARY_MINUS)) {
+	    if ((operator == END) || (operator == CLOSE_PAREN) || 
+		(operator == COMMA)) {
+		result = TCL_OK;
+		goto done;
+	    } else {
+		Tcl_AppendResult(interp, "bad operator", (char *)NULL);
+		goto error;
+	    }
+	}
+	if (precTable[operator] <= prec) {
+	    result = TCL_OK;
+	    goto done;
+	}
+	result = NextValue(interp, piPtr, precTable[operator], &value2);
+	if (result != TCL_OK) {
+	    goto done;
+	}
+	if ((piPtr->token < MULT) && (piPtr->token != VALUE) &&
+	    (piPtr->token != END) && (piPtr->token != CLOSE_PAREN) &&
+	    (piPtr->token != COMMA)) {
+	    Tcl_AppendResult(interp, "unexpected token in expression",
+		(char *)NULL);
+	    goto error;
+	}
+	/*
+	 * At this point we have two vectors and an operator.
+	 */
+
+	if (v2Ptr->length == 1) {
+	    double *opnd;
+	    double scalar;
+
+	    /*
+	     * 2nd operand is a scalar.
+	     */
+	    scalar = v2Ptr->valueArr[0];
+	    opnd = vPtr->valueArr;
+	    switch (operator) {
+	    case MULT:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] *= scalar;
+		}
+		break;
+
+	    case DIVIDE:
+		if (scalar == 0.0) {
+		    Tcl_AppendResult(interp, "divide by zero", (char *)NULL);
+		    goto error;
+		}
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] /= scalar;
+		}
+		break;
+
+	    case PLUS:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] += scalar;
+		}
+		break;
+
+	    case MINUS:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] -= scalar;
+		}
+		break;
+
+	    case EXPONENT:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = pow(opnd[i], scalar);
+		}
+		break;
+
+	    case MOD:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = Fmod(opnd[i], scalar);
+		}
+		break;
+
+	    case LESS:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] < scalar);
+		}
+		break;
+
+	    case GREATER:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] > scalar);
+		}
+		break;
+
+	    case LEQ:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] <= scalar);
+		}
+		break;
+
+	    case GEQ:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] >= scalar);
+		}
+		break;
+
+	    case EQUAL:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] == scalar);
+		}
+		break;
+
+	    case NEQ:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] != scalar);
+		}
+		break;
+
+	    case AND:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] && scalar);
+		}
+		break;
+
+	    case OR:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] || scalar);
+		}
+		break;
+
+	    case LEFT_SHIFT:
+		{
+		    int offset;
+
+		    offset = (int)scalar % vPtr->length;
+		    if (offset > 0) {
+			double *hold;
+			int j;
+
+			hold = malloc(sizeof(double) * offset);
+			for (i = 0; i < offset; i++) {
+			    hold[i] = opnd[i];
+			}
+			for (i = offset, j = 0; i < vPtr->length; i++, j++) {
+			    opnd[j] = opnd[i];
+			}
+			for (i = 0, j = vPtr->length - offset;
+			     j < vPtr->length; i++, j++) {
+			    opnd[j] = hold[i];
+			}
+			free(hold);
+		    }
+		}
+		break;
+
+	    case RIGHT_SHIFT:
+		{
+		    int offset;
+
+		    offset = (int)scalar % vPtr->length;
+		    if (offset > 0) {
+			double *hold;
+			int j;
+			
+			hold = malloc(sizeof(double) * offset);
+			for (i = vPtr->length - offset, j = 0; 
+			     i < vPtr->length; i++, j++) {
+			    hold[j] = opnd[i];
+			}
+			for (i = vPtr->length - offset - 1, 
+				 j = vPtr->length - 1; i >= 0; i--, j--) {
+			    opnd[j] = opnd[i];
+			}
+			for (i = 0; i < offset; i++) {
+			    opnd[i] = hold[i];
+			}
+			free(hold);
+		    }
+		}
+		break;
+
+	    default:
+		Tcl_AppendResult(interp, "unknown operator in expression",
+		    (char *)NULL);
+		goto error;
+	    }
+
+	} else if (vPtr->length == 1) {
+	    double *opnd;
+	    double scalar;
+
+	    /*
+	     * 1st operand is a scalar.
+	     */
+	    scalar = vPtr->valueArr[0];
+	    Blt_Vec_Duplicate(vPtr, v2Ptr);
+	    opnd = vPtr->valueArr;
+	    switch (operator) {
+	    case MULT:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] *= scalar;
+		}
+		break;
+
+	    case PLUS:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] += scalar;
+		}
+		break;
+
+	    case DIVIDE:
+		for(i = 0; i < vPtr->length; i++) {
+		    if (opnd[i] == 0.0) {
+			Tcl_AppendResult(interp, "divide by zero",
+			    (char *)NULL);
+			goto error;
+		    }
+		    opnd[i] = (scalar / opnd[i]);
+		}
+		break;
+
+	    case MINUS:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = scalar - opnd[i];
+		}
+		break;
+
+	    case EXPONENT:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = pow(scalar, opnd[i]);
+		}
+		break;
+
+	    case MOD:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = Fmod(scalar, opnd[i]);
+		}
+		break;
+
+	    case LESS:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(scalar < opnd[i]);
+		}
+		break;
+
+	    case GREATER:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(scalar > opnd[i]);
+		}
+		break;
+
+	    case LEQ:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(scalar >= opnd[i]);
+		}
+		break;
+
+	    case GEQ:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(scalar <= opnd[i]);
+		}
+		break;
+
+	    case EQUAL:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] == scalar);
+		}
+		break;
+
+	    case NEQ:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] != scalar);
+		}
+		break;
+
+	    case AND:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] && scalar);
+		}
+		break;
+
+	    case OR:
+		for(i = 0; i < vPtr->length; i++) {
+		    opnd[i] = (double)(opnd[i] || scalar);
+		}
+		break;
+
+	    case LEFT_SHIFT:
+	    case RIGHT_SHIFT:
+		Tcl_AppendResult(interp, "second shift operand must be scalar",
+		    (char *)NULL);
+		goto error;
+
+	    default:
+		Tcl_AppendResult(interp, "unknown operator in expression",
+		    (char *)NULL);
+		goto error;
+	    }
+	} else {
+	    double *opnd1, *opnd2;
+	    /*
+	     * Carry out the function of the specified operator.
+	     */
+	    if (vPtr->length != v2Ptr->length) {
+		Tcl_AppendResult(interp, "vectors are different lengths",
+		    (char *)NULL);
+		goto error;
+	    }
+	    opnd1 = vPtr->valueArr, opnd2 = v2Ptr->valueArr;
+	    switch (operator) {
+	    case MULT:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] *= opnd2[i];
+		}
+		break;
+
+	    case DIVIDE:
+		for (i = 0; i < vPtr->length; i++) {
+		    if (opnd2[i] == 0.0) {
+			Tcl_AppendResult(interp,
+			    "can't divide by 0.0 vector component",
+			    (char *)NULL);
+			goto error;
+		    }
+		    opnd1[i] /= opnd2[i];
+		}
+		break;
+
+	    case PLUS:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] += opnd2[i];
+		}
+		break;
+
+	    case MINUS:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] -= opnd2[i];
+		}
+		break;
+
+	    case MOD:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] = Fmod(opnd1[i], opnd2[i]);
+		}
+		break;
+
+	    case EXPONENT:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] = pow(opnd1[i], opnd2[i]);
+		}
+		break;
+
+	    case LESS:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] = (double)(opnd1[i] < opnd2[i]);
+		}
+		break;
+
+	    case GREATER:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] = (double)(opnd1[i] > opnd2[i]);
+		}
+		break;
+
+	    case LEQ:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] = (double)(opnd1[i] <= opnd2[i]);
+		}
+		break;
+
+	    case GEQ:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] = (double)(opnd1[i] >= opnd2[i]);
+		}
+		break;
+
+	    case EQUAL:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] = (double)(opnd1[i] == opnd2[i]);
+		}
+		break;
+
+	    case NEQ:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] = (double)(opnd1[i] != opnd2[i]);
+		}
+		break;
+
+	    case AND:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] = (double)(opnd1[i] && opnd2[i]);
+		}
+		break;
+
+	    case OR:
+		for (i = 0; i < vPtr->length; i++) {
+		    opnd1[i] = (double)(opnd1[i] || opnd2[i]);
+		}
+		break;
+
+	    case LEFT_SHIFT:
+	    case RIGHT_SHIFT:
+		Tcl_AppendResult(interp, "second shift operand must be scalar",
+		    (char *)NULL);
+		goto error;
+
+	    default:
+		Tcl_AppendResult(interp, "unknown operator in expression",
+		    (char *)NULL);
+		goto error;
+	    }
+	}
+    }
+  done:
+    if (value2.pv.buffer != value2.staticSpace) {
+	free(value2.pv.buffer);
+    }
+    Blt_Vec_Free(v2Ptr);
+    return result;
+
+  error:
+    if (value2.pv.buffer != value2.staticSpace) {
+	free(value2.pv.buffer);
+    }
+    Blt_Vec_Free(v2Ptr);
+    return TCL_ERROR;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * EvaluateExpression --
+ *
+ *	This procedure provides top-level functionality shared by
+ *	procedures like Tcl_ExprInt, Tcl_ExprDouble, etc.
+ *
+ * Results:
+ *	The result is a standard TCL return value.  If an error
+ *	occurs then an error message is left in interp->result.
+ *	The value of the expression is returned in *valuePtr, in
+ *	whatever form it ends up in (could be string or integer
+ *	or double).  Caller may need to convert result.  Caller
+ *	is also responsible for freeing string memory in *valuePtr,
+ *	if any was allocated.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+EvaluateExpression(
+    Tcl_Interp *interp,		/* Context in which to evaluate the
+				 * expression. */
+    char *string,		/* Expression to evaluate. */
+    Value *valuePtr)		/* Where to store result.  Should
+				 * not be initialized by caller. */
+{
+    ParseInfo info;
+    int result;
+    Vector *vPtr;
+    double *vp, *vend;
+
+    info.expr = info.nextPtr = string;
+    valuePtr->pv.buffer = valuePtr->pv.next = valuePtr->staticSpace;
+    valuePtr->pv.end = valuePtr->pv.buffer + STATIC_STRING_SPACE - 1;
+    valuePtr->pv.expandProc = Blt_ExpandParseValue;
+    valuePtr->pv.clientData = NULL;
+
+    result = NextValue(interp, &info, -1, valuePtr);
+    if (result != TCL_OK) {
+	return result;
+    }
+    if (info.token != END) {
+	Tcl_AppendResult(interp, ": syntax error in expression \"",
+	    string, "\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    vPtr = valuePtr->vPtr;
+
+    /* Check for NaN's and overflows. */
+    for (vp = vPtr->valueArr, vend = vp + vPtr->length; vp < vend; vp++) {
+	if (!isfinite(*vp)) {
+	    /*
+	     * IEEE floating-point error.
+	     */
+	    MathError(interp, *vp);
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Math Functions --
+ *
+ *	This page contains the procedures that implement all of the
+ *	built-in math functions for expressions.
+ *
+ * Results:
+ *	Each procedure returns TCL_OK if it succeeds and places result
+ *	information at *resultPtr.  If it fails it returns TCL_ERROR
+ *	and leaves an error message in interp->result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ComponentFunc(
+    ClientData clientData,	/* Contains address of procedure that
+				 * takes one double argument and
+				 * returns a double result. */
+    Tcl_Interp *interp,
+    Vector *vPtr)
+{
+    ComponentProc *procPtr = (ComponentProc *) clientData;
+    double *vp, *vend;
+
+    errno = 0;
+    for(vp = vPtr->valueArr + vPtr->first, 
+	    vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) {
+	*vp = (*procPtr) (*vp);
+	if (errno != 0) {
+	    MathError(interp, *vp);
+	    return TCL_ERROR;
+	}
+	if (!isfinite(*vp)) {
+	    /*
+	     * IEEE floating-point error.
+	     */
+	    MathError(interp, *vp);
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+static int
+ScalarFunc(ClientData clientData, Tcl_Interp *interp, Vector *vPtr)
+{
+    double value;
+    ScalarProc *procPtr = (ScalarProc *) clientData;
+
+    errno = 0;
+    value = (*procPtr) (vPtr);
+    if (errno != 0) {
+	MathError(interp, value);
+	return TCL_ERROR;
+    }
+    if (Blt_Vec_ChangeLength(interp, vPtr, 1) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    vPtr->valueArr[0] = value;
+    return TCL_OK;
+}
+
+/*ARGSUSED*/
+static int
+VectorFunc(ClientData clientData, Tcl_Interp *interp, Vector *vPtr)
+{
+    VectorProc *procPtr = (VectorProc *) clientData;
+
+    return (*procPtr) (vPtr);
+}
+
+
+static MathFunction mathFunctions[] =
+{
+    {"abs",     ComponentFunc, Fabs},
+    {"acos",	ComponentFunc, acos},
+    {"asin",	ComponentFunc, asin},
+    {"atan",	ComponentFunc, atan},
+    {"adev",	ScalarFunc,    AvgDeviation},
+    {"ceil",	ComponentFunc, ceil},
+    {"cos",	ComponentFunc, cos},
+    {"cosh",	ComponentFunc, cosh},
+    {"exp",	ComponentFunc, exp},
+    {"floor",	ComponentFunc, floor},
+    {"kurtosis",ScalarFunc,    Kurtosis},
+    {"length",	ScalarFunc,    Length},
+    {"log",	ComponentFunc, log},
+    {"log10",	ComponentFunc, log10},
+    {"max",	ScalarFunc,    Blt_VecMax},
+    {"mean",	ScalarFunc,    Mean},
+    {"median",	ScalarFunc,    Median},
+    {"min",	ScalarFunc,    Blt_VecMin},
+    {"norm",	VectorFunc,    Norm},
+    {"nz",	ScalarFunc,    Nonzeros},
+    {"q1",	ScalarFunc,    Q1},
+    {"q3",	ScalarFunc,    Q3},
+    {"prod",	ScalarFunc,    Product},
+    {"random",	ComponentFunc, drand48},
+    {"round",	ComponentFunc, Round},
+    {"sdev",	ScalarFunc,    StdDeviation},
+    {"sin",	ComponentFunc, sin},
+    {"sinh",	ComponentFunc, sinh},
+    {"skew",	ScalarFunc,    Skew},
+    {"sort",	VectorFunc,    Sort},
+    {"sqrt",	ComponentFunc, sqrt},
+    {"sum",	ScalarFunc,    Sum},
+    {"tan",	ComponentFunc, tan},
+    {"tanh",	ComponentFunc, tanh},
+    {"var",	ScalarFunc,    Variance},
+    {(char *)NULL,},
+};
+
+void
+Blt_Vec_InstallMathFunctions(Blt_HashTable *tablePtr)
+{
+    MathFunction *mathPtr;
+
+    for (mathPtr = mathFunctions; mathPtr->name != NULL; mathPtr++) {
+	Blt_HashEntry *hPtr;
+	int isNew;
+
+	hPtr = Blt_CreateHashEntry(tablePtr, mathPtr->name, &isNew);
+	Blt_SetHashValue(hPtr, (ClientData)mathPtr);
+    }
+}
+
+void
+Blt_Vec_UninstallMathFunctions(Blt_HashTable *tablePtr)
+{
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch cursor;
+
+    for (hPtr = Blt_FirstHashEntry(tablePtr, &cursor); hPtr != NULL; 
+	hPtr = Blt_NextHashEntry(&cursor)) {
+	MathFunction *mathPtr;
+
+	mathPtr = Blt_GetHashValue(hPtr);
+	if (mathPtr->name == NULL) {
+	    free(mathPtr);
+	}
+    }
+}
+
+
+static void
+InstallIndexProc(
+    Blt_HashTable *tablePtr,
+    const char *string,
+    Blt_VectorIndexProc *procPtr) /* Pointer to function to be called
+				   * when the vector finds the named index.
+				   * If NULL, this indicates to remove
+				   * the index from the table.
+				   */
+{
+    Blt_HashEntry *hPtr;
+    int dummy;
+
+    hPtr = Blt_CreateHashEntry(tablePtr, string, &dummy);
+    if (procPtr == NULL) {
+	Blt_DeleteHashEntry(tablePtr, hPtr);
+    } else {
+	Blt_SetHashValue(hPtr, (ClientData)procPtr);
+    }
+}
+
+void
+Blt_Vec_InstallSpecialIndices(Blt_HashTable *tablePtr)
+{
+    InstallIndexProc(tablePtr, "min",  Blt_VecMin);
+    InstallIndexProc(tablePtr, "max",  Blt_VecMax);
+    InstallIndexProc(tablePtr, "mean", Mean);
+    InstallIndexProc(tablePtr, "sum",  Sum);
+    InstallIndexProc(tablePtr, "prod", Product);
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ExprVector --
+ *
+ *	Evaluates an vector expression and returns its value(s).
+ *
+ * Results:
+ *	Each of the procedures below returns a standard TCL result.
+ *	If an error occurs then an error message is left in
+ *	interp->result.  Otherwise the value of the expression,
+ *	in the appropriate form, is stored at *resultPtr.  If
+ *	the expression had a result that was incompatible with the
+ *	desired form then an error is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_ExprVector(
+    Tcl_Interp *interp,		/* Context in which to evaluate the
+				 * expression. */
+    char *string,		/* Expression to evaluate. */
+    Blt_Vector *vector)		/* Where to store result. */
+{
+    VectorInterpData *dataPtr;	/* Interpreter-specific data. */
+    Vector *vPtr = (Vector *)vector;
+    Value value;
+
+    dataPtr = (vector != NULL) 
+	? vPtr->dataPtr : Blt_Vec_GetInterpData(interp);
+    value.vPtr = Blt_Vec_New(dataPtr);
+    if (EvaluateExpression(interp, string, &value) != TCL_OK) {
+	Blt_Vec_Free(value.vPtr);
+	return TCL_ERROR;
+    }
+    if (vPtr != NULL) {
+	Blt_Vec_Duplicate(vPtr, value.vPtr);
+    } else {
+	Tcl_Obj *listObjPtr;
+	double *vp, *vend;
+
+	/* No result vector.  Put values in interp->result.  */
+	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+	for (vp = value.vPtr->valueArr, vend = vp + value.vPtr->length; 
+	     vp < vend; vp++) {
+	    Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(*vp));
+	}
+	Tcl_SetObjResult(interp, listObjPtr);
+    }
+    Blt_Vec_Free(value.vPtr);
+    return TCL_OK;
+}
diff --git a/tlt3.0/bltVector.c b/tlt3.0/bltVector.c
new file mode 100644
index 0000000..35e2d1a
--- /dev/null
+++ b/tlt3.0/bltVector.c
@@ -0,0 +1,2794 @@
+/*
+ * bltVector.c --
+ *
+ * This module implements vector data objects.
+ *
+ *	Copyright 1995-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * TODO:
+ *	o Add H. Kirsch's vector binary read operation
+ *		x binread file0
+ *		x binread -file file0
+ *
+ *	o Add ASCII/binary file reader
+ *		x read fileName
+ *
+ *	o Allow Tcl-based client notifications.
+ *		vector x
+ *		x notify call Display
+ *		x notify delete Display
+ *		x notify reorder #1 #2
+ */
+
+#include <assert.h>
+#include <float.h>
+#include <math.h>
+#include <time.h>
+
+#include "bltInt.h"
+#include "bltVecInt.h"
+#include "bltOp.h"
+#include "bltNsUtil.h"
+#include "bltSwitch.h"
+
+#define DEF_ARRAY_SIZE		64
+#define TRACE_ALL  (TCL_TRACE_WRITES | TCL_TRACE_READS | TCL_TRACE_UNSETS)
+
+
+#define VECTOR_CHAR(c)	((isalnum((unsigned char)(c))) || \
+	(c == '_') || (c == ':') || (c == '@') || (c == '.'))
+
+/*
+ * VectorClient --
+ *
+ *	A vector can be shared by several clients.  Each client allocates this
+ *	structure that acts as its key for using the vector.  Clients can also
+ *	designate a callback routine that is executed whenever the vector is
+ *	updated or destroyed.
+ *
+ */
+typedef struct {
+    unsigned int magic;		/* Magic value designating whether this really
+				 * is a vector token or not */
+
+    Vector *serverPtr;		/* Pointer to the master record of the vector.
+				 * If NULL, indicates that the vector has been
+				 * destroyed but as of yet, this client hasn't
+				 * recognized it. */
+
+    Blt_VectorChangedProc *proc;/* Routine to call when the contents of the
+				 * vector change or the vector is deleted. */
+
+    ClientData clientData;	/* Data passed whenever the vector change
+				 * procedure is called. */
+
+    Blt_ChainLink link;		/* Used to quickly remove this entry from its
+				 * server's client chain. */
+} VectorClient;
+
+static Tcl_CmdDeleteProc VectorInstDeleteProc;
+static Tcl_ObjCmdProc VectorCmd;
+static Tcl_InterpDeleteProc VectorInterpDeleteProc;
+
+typedef struct {
+    char *varName;		/* Requested variable name. */
+    char *cmdName;		/* Requested command name. */
+    int flush;			/* Flush */
+    int watchUnset;		/* Watch when variable is unset. */
+} CreateSwitches;
+
+static Blt_SwitchSpec createSwitches[] = 
+{
+    {BLT_SWITCH_STRING, "-variable", "varName",
+	Blt_Offset(CreateSwitches, varName), BLT_SWITCH_NULL_OK},
+    {BLT_SWITCH_STRING, "-command", "command",
+	Blt_Offset(CreateSwitches, cmdName), BLT_SWITCH_NULL_OK},
+    {BLT_SWITCH_BOOLEAN, "-watchunset", "bool",
+	Blt_Offset(CreateSwitches, watchUnset), 0},
+    {BLT_SWITCH_BOOLEAN, "-flush", "bool",
+	Blt_Offset(CreateSwitches, flush), 0},
+    {BLT_SWITCH_END}
+};
+
+typedef int (VectorCmdProc)(Vector *vecObjPtr, Tcl_Interp *interp, 
+	int objc, Tcl_Obj *const *objv);
+
+static Vector *
+FindVectorInNamespace(
+    VectorInterpData *dataPtr,	/* Interpreter-specific data. */
+    Blt_ObjectName *objNamePtr)
+{
+    Tcl_DString dString;
+    const char *name;
+    Blt_HashEntry *hPtr;
+
+    name = Blt_MakeQualifiedName(objNamePtr, &dString);
+    hPtr = Blt_FindHashEntry(&dataPtr->vectorTable, name);
+    Tcl_DStringFree(&dString);
+    if (hPtr != NULL) {
+	return Blt_GetHashValue(hPtr);
+    }
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetVectorObject --
+ *
+ *	Searches for the vector associated with the name given.  Allow for a
+ *	range specification.
+ *
+ * Results:
+ *	Returns a pointer to the vector if found, otherwise NULL.
+ *
+ *---------------------------------------------------------------------------
+ */
+static Vector *
+GetVectorObject(
+    VectorInterpData *dataPtr,	/* Interpreter-specific data. */
+    const char *name,
+    int flags)
+{
+    Blt_ObjectName objName;
+    Vector *vPtr;
+    Tcl_Interp *interp;
+
+    interp = dataPtr->interp;
+    if (!Blt_ParseObjectName(interp, name, &objName, 
+		BLT_NO_ERROR_MSG | BLT_NO_DEFAULT_NS)) {
+	return NULL;		/* Can't find namespace. */
+    } 
+    vPtr = NULL;
+    if (objName.nsPtr != NULL) {
+	vPtr = FindVectorInNamespace(dataPtr, &objName);
+    } else {
+	if (flags & NS_SEARCH_CURRENT) {
+	    objName.nsPtr = Tcl_GetCurrentNamespace(interp);
+	    vPtr = FindVectorInNamespace(dataPtr, &objName);
+	}
+	if ((vPtr == NULL) && (flags & NS_SEARCH_GLOBAL)) {
+	    objName.nsPtr = Tcl_GetGlobalNamespace(interp);
+	    vPtr = FindVectorInNamespace(dataPtr, &objName);
+	}
+    }
+    return vPtr;
+}
+
+void
+Blt_Vec_UpdateRange(Vector *vPtr)
+{
+    double min, max;
+    double *vp, *vend;
+
+    vp = vPtr->valueArr + vPtr->first;
+    vend = vPtr->valueArr + vPtr->last;
+    min = max = *vp++;
+    for (/* empty */; vp <= vend; vp++) {
+	if (min > *vp) {
+	    min = *vp; 
+	} else if (max < *vp) { 
+	    max = *vp; 
+	} 
+    } 
+    vPtr->min = min;
+    vPtr->max = max;
+    vPtr->notifyFlags &= ~UPDATE_RANGE;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_GetIndex --
+ *
+ *	Converts the string representing an index in the vector, to its
+ *	numeric value.  A valid index may be an numeric string of the string
+ *	"end" (indicating the last element in the string).
+ *
+ * Results:
+ *	A standard TCL result.  If the string is a valid index, TCL_OK is
+ *	returned.  Otherwise TCL_ERROR is returned and interp->result will
+ *	contain an error message.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_Vec_GetIndex(
+    Tcl_Interp *interp,
+    Vector *vPtr,
+    const char *string,
+    int *indexPtr,
+    int flags,
+    Blt_VectorIndexProc **procPtrPtr)
+{
+    char c;
+    int value;
+
+    c = string[0];
+
+    /* Treat the index "end" like a numeric index.  */
+
+    if ((c == 'e') && (strcmp(string, "end") == 0)) {
+	if (vPtr->length < 1) {
+	    if (interp != NULL) {
+		Tcl_AppendResult(interp, "bad index \"end\": vector is empty", 
+				 (char *)NULL);
+	    }
+	    return TCL_ERROR;
+	}
+	*indexPtr = vPtr->length - 1;
+	return TCL_OK;
+    } else if ((c == '+') && (strcmp(string, "++end") == 0)) {
+	*indexPtr = vPtr->length;
+	return TCL_OK;
+    }
+    if (procPtrPtr != NULL) {
+	Blt_HashEntry *hPtr;
+
+	hPtr = Blt_FindHashEntry(&vPtr->dataPtr->indexProcTable, string);
+	if (hPtr != NULL) {
+	    *indexPtr = SPECIAL_INDEX;
+	    *procPtrPtr = Blt_GetHashValue(hPtr);
+	    return TCL_OK;
+	}
+    }
+    if (Tcl_GetInt(interp, (char *)string, &value) != TCL_OK) {
+	long int lvalue;
+	/*   
+	 * Unlike Tcl_GetInt, Tcl_ExprLong needs a valid interpreter, but the
+	 * interp passed in may be NULL.  So we have to use vPtr->interp and
+	 * then reset the result.
+	 */
+	if (Tcl_ExprLong(vPtr->interp, (char *)string, &lvalue) != TCL_OK) {
+	    Tcl_ResetResult(vPtr->interp);
+	    if (interp != NULL) {
+		Tcl_AppendResult(interp, "bad index \"", string, "\"", 
+				 (char *)NULL);
+	    }
+	    return TCL_ERROR;
+	}
+	value = (int)lvalue;
+    }
+    /*
+     * Correct the index by the current value of the offset. This makes all
+     * the numeric indices non-negative, which is how we distinguish the
+     * special non-numeric indices.
+     */
+    value -= vPtr->offset;
+
+    if ((value < 0) || ((flags & INDEX_CHECK) && (value >= vPtr->length))) {
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "index \"", string, "\" is out of range", 
+			 (char *)NULL);
+	}
+	return TCL_ERROR;
+    }
+    *indexPtr = (int)value;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_GetIndexRange --
+ *
+ *	Converts the string representing an index in the vector, to its
+ *	numeric value.  A valid index may be an numeric string of the string
+ *	"end" (indicating the last element in the string).
+ *
+ * Results:
+ *	A standard TCL result.  If the string is a valid index, TCL_OK is
+ *	returned.  Otherwise TCL_ERROR is returned and interp->result will
+ *	contain an error message.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_Vec_GetIndexRange(
+    Tcl_Interp *interp,
+    Vector *vPtr,
+    const char *string,
+    int flags,
+    Blt_VectorIndexProc **procPtrPtr)
+{
+    int ielem;
+    char *colon;
+
+    colon = NULL;
+    if (flags & INDEX_COLON) {
+	colon = strchr(string, ':');
+    }
+    if (colon != NULL) {
+	if (string == colon) {
+	    vPtr->first = 0;	/* Default to the first index */
+	} else {
+	    int result;
+
+	    *colon = '\0';
+	    result = Blt_Vec_GetIndex(interp, vPtr, string, &ielem, flags,
+		(Blt_VectorIndexProc **) NULL);
+	    *colon = ':';
+	    if (result != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    vPtr->first = ielem;
+	}
+	if (*(colon + 1) == '\0') {
+	    /* Default to the last index */
+	    vPtr->last = (vPtr->length > 0) ? vPtr->length - 1 : 0;
+	} else {
+	    if (Blt_Vec_GetIndex(interp, vPtr, colon + 1, &ielem, flags,
+		    (Blt_VectorIndexProc **) NULL) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    vPtr->last = ielem;
+	}
+	if (vPtr->first > vPtr->last) {
+	    if (interp != NULL) {
+		Tcl_AppendResult(interp, "bad range \"", string,
+			 "\" (first > last)", (char *)NULL);
+	    }
+	    return TCL_ERROR;
+	}
+    } else {
+	if (Blt_Vec_GetIndex(interp, vPtr, string, &ielem, flags, 
+		       procPtrPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	vPtr->last = vPtr->first = ielem;
+    }
+    return TCL_OK;
+}
+
+Vector *
+Blt_Vec_ParseElement(
+    Tcl_Interp *interp,
+    VectorInterpData *dataPtr,	/* Interpreter-specific data. */
+    const char *start,
+    const char **endPtr,
+    int flags)
+{
+    char *p;
+    char saved;
+    Vector *vPtr;
+
+    p = (char *)start;
+    /* Find the end of the vector name */
+    while (VECTOR_CHAR(*p)) {
+	p++;
+    }
+    saved = *p;
+    *p = '\0';
+
+    vPtr = GetVectorObject(dataPtr, start, flags);
+    if (vPtr == NULL) {
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "can't find vector \"", start, "\"", 
+			     (char *)NULL);
+	}
+	*p = saved;
+	return NULL;
+    }
+    *p = saved;
+    vPtr->first = 0;
+    vPtr->last = vPtr->length - 1;
+    if (*p == '(') {
+	int count, result;
+
+	start = p + 1;
+	p++;
+
+	/* Find the matching right parenthesis */
+	count = 1;
+	while (*p != '\0') {
+	    if (*p == ')') {
+		count--;
+		if (count == 0) {
+		    break;
+		}
+	    } else if (*p == '(') {
+		count++;
+	    }
+	    p++;
+	}
+	if (count > 0) {
+	    if (interp != NULL) {
+		Tcl_AppendResult(interp, "unbalanced parentheses \"", start, 
+			"\"", (char *)NULL);
+	    }
+	    return NULL;
+	}
+	*p = '\0';
+	result = Blt_Vec_GetIndexRange(interp, vPtr, start, 
+		(INDEX_COLON | INDEX_CHECK), (Blt_VectorIndexProc **) NULL);
+	*p = ')';
+	if (result != TCL_OK) {
+	    return NULL;
+	}
+	p++;
+    }
+    if (endPtr != NULL) {
+      *endPtr = p;
+    }
+    return vPtr;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_NotifyClients --
+ *
+ *	Notifies each client of the vector that the vector has changed
+ *	(updated or destroyed) by calling the provided function back.  The
+ *	function pointer may be NULL, in that case the client is not notified.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The results depend upon what actions the client callbacks
+ *	take.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Vec_NotifyClients(ClientData clientData)
+{
+    Vector *vPtr = clientData;
+    Blt_ChainLink link, next;
+    Blt_VectorNotify notify;
+
+    notify = (vPtr->notifyFlags & NOTIFY_DESTROYED)
+	? BLT_VECTOR_NOTIFY_DESTROY : BLT_VECTOR_NOTIFY_UPDATE;
+    vPtr->notifyFlags &= ~(NOTIFY_UPDATED | NOTIFY_DESTROYED | NOTIFY_PENDING);
+    for (link = Blt_Chain_FirstLink(vPtr->chain); link != NULL; link = next) {
+	VectorClient *clientPtr;
+
+	next = Blt_Chain_NextLink(link);
+	clientPtr = Blt_Chain_GetValue(link);
+	if ((clientPtr->proc != NULL) && (clientPtr->serverPtr != NULL)) {
+	    (*clientPtr->proc) (vPtr->interp, clientPtr->clientData, notify);
+	}
+    }
+    /*
+     * Some clients may not handle the "destroy" callback properly (they
+     * should call Blt_FreeVectorId to release the client identifier), so mark
+     * any remaining clients to indicate that vector's server has gone away.
+     */
+    if (notify == BLT_VECTOR_NOTIFY_DESTROY) {
+	for (link = Blt_Chain_FirstLink(vPtr->chain); link != NULL;
+	    link = Blt_Chain_NextLink(link)) {
+	    VectorClient *clientPtr;
+
+	    clientPtr = Blt_Chain_GetValue(link);
+	    clientPtr->serverPtr = NULL;
+	}
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_UpdateClients --
+ *
+ *	Notifies each client of the vector that the vector has changed
+ *	(updated or destroyed) by calling the provided function back.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The individual client callbacks are eventually invoked.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Vec_UpdateClients(Vector *vPtr)
+{
+    vPtr->dirty++;
+    vPtr->max = vPtr->min = NAN;
+    if (vPtr->notifyFlags & NOTIFY_NEVER) {
+	return;
+    }
+    vPtr->notifyFlags |= NOTIFY_UPDATED;
+    if (vPtr->notifyFlags & NOTIFY_ALWAYS) {
+	Blt_Vec_NotifyClients(vPtr);
+	return;
+    }
+    if (!(vPtr->notifyFlags & NOTIFY_PENDING)) {
+	vPtr->notifyFlags |= NOTIFY_PENDING;
+	Tcl_DoWhenIdle(Blt_Vec_NotifyClients, vPtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_FlushCache --
+ *
+ *	Unsets all the elements of the TCL array variable associated with the
+ *	vector, freeing memory associated with the variable.  This includes
+ *	both the hash table and the hash keys.  The down side is that this
+ *	effectively flushes the caching of vector elements in the array.  This
+ *	means that the subsequent reads of the array will require a decimal to
+ *	string conversion.
+ *
+ *	This is needed when the vector changes its values, making the array
+ *	variable out-of-sync.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	All elements of array variable (except one) are unset, freeing
+ *	the memory associated with the variable.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Vec_FlushCache(Vector *vPtr)
+{
+    Tcl_Interp *interp = vPtr->interp;
+
+    if (vPtr->arrayName == NULL) {
+	return;			/* Doesn't use the variable API */
+    }
+    /* Turn off the trace temporarily so that we can unset all the
+     * elements in the array.  */
+
+    Tcl_UntraceVar2(interp, vPtr->arrayName, (char *)NULL,
+	TRACE_ALL | vPtr->varFlags, Blt_Vec_VarTrace, vPtr);
+
+    /* Clear all the element entries from the entire array */
+    Tcl_UnsetVar2(interp, vPtr->arrayName, (char *)NULL, vPtr->varFlags);
+
+    /* Restore the "end" index by default and the trace on the entire array */
+    Tcl_SetVar2(interp, vPtr->arrayName, "end", "", vPtr->varFlags);
+    Tcl_TraceVar2(interp, vPtr->arrayName, (char *)NULL,
+	TRACE_ALL | vPtr->varFlags, Blt_Vec_VarTrace, vPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_LookupName --
+ *
+ *	Searches for the vector associated with the name given.  Allow for a
+ *	range specification.
+ *
+ * Results:
+ *	Returns a pointer to the vector if found, otherwise NULL.  If the name
+ *	is not associated with a vector and the TCL_LEAVE_ERR_MSG flag is set,
+ *	and interp->result will contain an error message.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_Vec_LookupName(
+    VectorInterpData *dataPtr,	/* Interpreter-specific data. */
+    const char *vecName,
+    Vector **vPtrPtr)
+{
+    Vector *vPtr;
+    const char *endPtr;
+
+    vPtr = Blt_Vec_ParseElement(dataPtr->interp, dataPtr, vecName, &endPtr, 
+	NS_SEARCH_BOTH);
+    if (vPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (*endPtr != '\0') {
+	Tcl_AppendResult(dataPtr->interp, 
+			 "extra characters after vector name", (char *)NULL);
+	return TCL_ERROR;
+    }
+    *vPtrPtr = vPtr;
+    return TCL_OK;
+}
+
+double
+Blt_Vec_Min(Vector *vecObjPtr)
+{
+    double *vp, *vend;
+    double min;
+
+    vp = vecObjPtr->valueArr + vecObjPtr->first;
+    vend = vecObjPtr->valueArr + vecObjPtr->last;
+    min = *vp++;
+    for (/* empty */; vp <= vend; vp++) {
+	if (min > *vp) {
+	    min = *vp; 
+	} 
+    } 
+    vecObjPtr->min = min;
+    return vecObjPtr->min;
+}
+
+double
+Blt_Vec_Max(Vector *vecObjPtr)
+{
+    double max;
+    double *vp, *vend;
+
+    max = NAN;
+    vp = vecObjPtr->valueArr + vecObjPtr->first;
+    vend = vecObjPtr->valueArr + vecObjPtr->last;
+    max = *vp++;
+    for (/* empty */; vp <= vend; vp++) {
+	if (max < *vp) {
+	    max = *vp; 
+	} 
+    } 
+    vecObjPtr->max = max;
+    return vecObjPtr->max;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DeleteCommand --
+ *
+ *	Deletes the TCL command associated with the vector, without triggering
+ *	a callback to "VectorInstDeleteProc".
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+DeleteCommand(Vector *vPtr) /* Vector associated with the TCL command. */
+{
+    Tcl_Interp *interp = vPtr->interp;
+    char *qualName;		/* Name of TCL command. */
+    Tcl_CmdInfo cmdInfo;
+    Tcl_DString dString;
+    Blt_ObjectName objName;
+
+    Tcl_DStringInit(&dString);
+    objName.name = Tcl_GetCommandName(interp, vPtr->cmdToken);
+    objName.nsPtr = Blt_GetCommandNamespace(vPtr->cmdToken);
+    qualName = Blt_MakeQualifiedName(&objName, &dString);
+    if (Tcl_GetCommandInfo(interp, qualName, &cmdInfo)) {
+	/* Disable the callback before deleting the TCL command.*/	
+	cmdInfo.deleteProc = NULL;	
+	Tcl_SetCommandInfo(interp, qualName, &cmdInfo);
+	Tcl_DeleteCommandFromToken(interp, vPtr->cmdToken);
+    }
+    Tcl_DStringFree(&dString);
+    vPtr->cmdToken = 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * UnmapVariable --
+ *
+ *	Destroys the trace on the current TCL variable designated to access
+ *	the vector.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+UnmapVariable(Vector *vPtr)
+{
+    Tcl_Interp *interp = vPtr->interp;
+
+    /* Unset the entire array */
+    Tcl_UntraceVar2(interp, vPtr->arrayName, (char *)NULL,
+	(TRACE_ALL | vPtr->varFlags), Blt_Vec_VarTrace, vPtr);
+    Tcl_UnsetVar2(interp, vPtr->arrayName, (char *)NULL, vPtr->varFlags);
+
+    if (vPtr->arrayName != NULL) {
+      free((void*)(vPtr->arrayName));
+      vPtr->arrayName = NULL;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_MapVariable --
+ *
+ *	Sets up traces on a TCL variable to access the vector.
+ *
+ *	If another variable is already mapped, it's first untraced and
+ *	removed.  Don't do anything else for variables named "" (even though
+ *	Tcl allows this pathology). Saves the name of the new array variable.
+ *
+ * Results:
+ *	A standard TCL result. If an error occurs setting the variable
+ *	TCL_ERROR is returned and an error message is left in the interpreter.
+ *
+ * Side effects:
+ *	Traces are set for the new variable. The new variable name is saved in
+ *	a malloc'ed string in vPtr->arrayName.  If this variable is non-NULL,
+ *	it indicates that a TCL variable has been mapped to this vector.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_Vec_MapVariable(
+    Tcl_Interp *interp, 
+    Vector *vPtr, 
+    const char *path)
+{
+    Blt_ObjectName objName;
+    char *newPath;
+    const char *result;
+    Tcl_DString dString;
+
+    if (vPtr->arrayName != NULL) {
+	UnmapVariable(vPtr);
+    }
+    if ((path == NULL) || (path[0] == '\0')) {
+	return TCL_OK;		/* If the variable pathname is the empty
+				 * string, simply return after removing any
+				 * existing variable. */
+    }
+    /* Get the variable name (without the namespace qualifier). */
+    if (!Blt_ParseObjectName(interp, path, &objName, BLT_NO_DEFAULT_NS)) {
+	return TCL_ERROR;
+    }
+    if (objName.nsPtr == NULL) {
+	/* 
+	 * If there was no namespace qualifier, try harder to see if the
+	 * variable is non-local.
+	 */
+	objName.nsPtr = Blt_GetVariableNamespace(interp, objName.name);
+    } 
+    Tcl_DStringInit(&dString);
+    vPtr->varFlags = 0;
+    if (objName.nsPtr != NULL) {	/* Global or namespace variable. */
+	newPath = Blt_MakeQualifiedName(&objName, &dString);
+	vPtr->varFlags |= (TCL_GLOBAL_ONLY);
+    } else {			/* Local variable. */
+	newPath = (char *)objName.name;
+    }
+
+    /*
+     * To play it safe, delete the variable first.  This has the benefical
+     * side-effect of unmapping the variable from another vector that may be
+     * currently associated with it.
+     */
+    Tcl_UnsetVar2(interp, newPath, (char *)NULL, 0);
+
+    /* 
+     * Set the index "end" in the array.  This will create the variable
+     * immediately so that we can check its namespace context.
+     */
+    result = Tcl_SetVar2(interp, newPath, "end", "", TCL_LEAVE_ERR_MSG);
+    if (result == NULL) {
+	Tcl_DStringFree(&dString);
+	return TCL_ERROR;
+    }
+    /* Create a full-array trace on reads, writes, and unsets. */
+    Tcl_TraceVar2(interp, newPath, (char *)NULL, TRACE_ALL, Blt_Vec_VarTrace,
+	vPtr);
+    vPtr->arrayName = Blt_Strdup(newPath);
+    Tcl_DStringFree(&dString);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_SetSize --
+ *
+ *	Resizes the vector to the designated new size.
+ *
+ *	If the new size is the same as the old, simply return.  Otherwise
+ *	we're copying the data from one memory location to another.
+ *
+ *	If the storage changed memory locations, free up the old location if
+ *	it was dynamically allocated.
+ *
+ * Results:
+ *	A standard TCL result.  If the reallocation is successful,
+ *	TCL_OK is returned, otherwise TCL_ERROR.
+ *
+ * Side effects:
+ *	Memory for the array is reallocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_Vec_SetSize(
+    Tcl_Interp *interp, 
+    Vector *vPtr, 
+    int newSize)		/* Size of array in elements */
+{
+    if (newSize <= 0) {
+	newSize = DEF_ARRAY_SIZE;
+    }
+    if (newSize == vPtr->size) {
+	/* Same size, use the current array. */
+	return TCL_OK;
+    } 
+    if (vPtr->freeProc == TCL_DYNAMIC) {
+	double *newArr;
+
+	/* Old memory was dynamically allocated, so use realloc. */
+	newArr = realloc(vPtr->valueArr, newSize * sizeof(double));
+	if (newArr == NULL) {
+	    if (interp != NULL) {
+		Tcl_AppendResult(interp, "can't reallocate ", 
+				 Blt_Itoa(newSize), " elements for vector \"", 
+				 vPtr->name, "\"", (char *)NULL); 
+	    }
+	    return TCL_ERROR;
+	}
+	vPtr->size = newSize;
+	vPtr->valueArr = newArr;
+	return TCL_OK;
+    }
+
+    {
+	double *newArr;
+
+	/* Old memory was created specially (static or special allocator).
+	 * Replace with dynamically allocated memory (malloc-ed). */
+
+	newArr = calloc(newSize, sizeof(double));
+	if (newArr == NULL) {
+	    if (interp != NULL) {
+		Tcl_AppendResult(interp, "can't allocate ", 
+				 Blt_Itoa(newSize), " elements for vector \"", 
+				 vPtr->name, "\"", (char *)NULL); 
+	    }
+	    return TCL_ERROR;
+	}
+	{
+	    int used, wanted;
+	    
+	    /* Copy the contents of the old memory into the new. */
+	    used = vPtr->length;
+	    wanted = newSize;
+	    
+	    if (used > wanted) {
+		used = wanted;
+	    }
+	    /* Copy any previous data */
+	    if (used > 0) {
+		memcpy(newArr, vPtr->valueArr, used * sizeof(double));
+	    }
+	}
+	
+	assert(vPtr->valueArr != NULL);
+	
+	/* 
+	 * We're not using the old storage anymore, so free it if it's not
+	 * TCL_STATIC.  It's static because the user previously reset the
+	 * vector with a statically allocated array (setting freeProc to
+	 * TCL_STATIC).
+	 */
+	if (vPtr->freeProc != TCL_STATIC) {
+	    if (vPtr->freeProc == TCL_DYNAMIC) {
+		free(vPtr->valueArr);
+	    } else {
+		(*vPtr->freeProc) ((char *)vPtr->valueArr);
+	    }
+	}
+	vPtr->freeProc = TCL_DYNAMIC; /* Set the type of the new storage */
+	vPtr->valueArr = newArr;
+	vPtr->size = newSize;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_SetSize --
+ *
+ *	Set the length (the number of elements currently in use) of the
+ *	vector.  If the new length is greater than the size (total number of
+ *	slots), then the vector is grown.
+ *
+ * Results:
+ *	A standard TCL result.  If the reallocation is successful, TCL_OK is
+ *	returned, otherwise TCL_ERROR.
+ *
+ * Side effects:
+ *	Memory for the array is possibly reallocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_Vec_SetLength(
+    Tcl_Interp *interp, 
+    Vector *vPtr, 
+    int newLength)		/* Size of array in elements */
+{
+    if (vPtr->size < newLength) {
+	if (Blt_Vec_SetSize(interp, vPtr, newLength) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    vPtr->length = newLength;
+    vPtr->first = 0;
+    vPtr->last = newLength - 1;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_ChangeLength --
+ *
+ *	Resizes the vector to the new size.
+ *
+ *	The new size of the vector is computed by doubling the size of the
+ *	vector until it fits the number of slots needed (designated by
+ *	*length*).
+ *
+ *	If the new size is the same as the old, simply adjust the length of
+ *	the vector.  Otherwise we're copying the data from one memory location
+ *	to another. The trailing elements of the vector need to be reset to
+ *	zero.
+ *
+ *	If the storage changed memory locations, free up the old location if
+ *	it was dynamically allocated.
+ *
+ * Results:
+ *	A standard TCL result.  If the reallocation is successful,
+ *	TCL_OK is returned, otherwise TCL_ERROR.
+ *
+ * Side effects:
+ *	Memory for the array is reallocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Blt_Vec_ChangeLength(
+    Tcl_Interp *interp, 
+    Vector *vPtr, 
+    int newLength)
+{
+    if (newLength < 0) {
+	newLength = 0;
+    } 
+    if (newLength > vPtr->size) {
+	int newSize;		/* Size of array in elements */
+    
+	/* Compute the new size of the array.  It's a multiple of
+	 * DEF_ARRAY_SIZE. */
+	newSize = DEF_ARRAY_SIZE;
+	while (newSize < newLength) {
+	    newSize += newSize;
+	}
+	if (newSize != vPtr->size) {
+	    if (Blt_Vec_SetSize(interp, vPtr, newSize) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+    }
+    vPtr->length = newLength;
+    vPtr->first = 0;
+    vPtr->last = newLength - 1;
+    return TCL_OK;
+    
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_Reset --
+ *
+ *	Resets the vector data.  This is called by a client to indicate that
+ *	the vector data has changed.  The vector does not need to point to
+ *	different memory.  Any clients of the vector will be notified of the
+ *	change.
+ *
+ * Results:
+ *	A standard TCL result.  If the new array size is invalid, TCL_ERROR is
+ *	returned.  Otherwise TCL_OK is returned and the new vector data is
+ *	recorded.
+ *
+ * Side Effects:
+ *	Any client designated callbacks will be posted.  Memory may be changed
+ *	for the vector array.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_Vec_Reset(
+    Vector *vPtr,
+    double *valueArr,		/* Array containing the elements of the
+				 * vector. If NULL, indicates to reset the 
+				 * vector size to the default. */
+    int length,			/* The number of elements that the vector 
+				 * currently holds. */
+    int size,			/* The maximum number of elements that the
+				 * array can hold. */
+    Tcl_FreeProc *freeProc)	/* Address of memory deallocation routine
+				 * for the array of values.  Can also be
+				 * TCL_STATIC, TCL_DYNAMIC, or TCL_VOLATILE. */
+{
+    if (vPtr->valueArr != valueArr) {	/* New array of values resides
+					 * in different memory than
+					 * the current vector.  */
+	if ((valueArr == NULL) || (size == 0)) {
+	    /* Empty array. Set up default values */
+	    valueArr = malloc(sizeof(double) * DEF_ARRAY_SIZE);
+	    size = DEF_ARRAY_SIZE;
+	    if (valueArr == NULL) {
+		Tcl_AppendResult(vPtr->interp, "can't allocate ", 
+			Blt_Itoa(size), " elements for vector \"", 
+			vPtr->name, "\"", (char *)NULL);
+		return TCL_ERROR;
+	    }
+	    freeProc = TCL_DYNAMIC;
+	    length = 0;
+	} else if (freeProc == TCL_VOLATILE) {
+	    double *newArr;
+	    /* Data is volatile. Make a copy of the value array.  */
+	    newArr = malloc(size * sizeof(double));
+	    if (newArr == NULL) {
+		Tcl_AppendResult(vPtr->interp, "can't allocate ", 
+			Blt_Itoa(size), " elements for vector \"", 
+			vPtr->name, "\"", (char *)NULL);
+		return TCL_ERROR;
+	    }
+	    memcpy((char *)newArr, (char *)valueArr, 
+		   sizeof(double) * length);
+	    valueArr = newArr;
+	    freeProc = TCL_DYNAMIC;
+	} 
+
+	if (vPtr->freeProc != TCL_STATIC) {
+	    /* Old data was dynamically allocated. Free it before attaching
+	     * new data.  */
+	    if (vPtr->freeProc == TCL_DYNAMIC) {
+		free(vPtr->valueArr);
+	    } else {
+		(*freeProc) ((char *)vPtr->valueArr);
+	    }
+	}
+	vPtr->freeProc = freeProc;
+	vPtr->valueArr = valueArr;
+	vPtr->size = size;
+    }
+
+    vPtr->length = length;
+    if (vPtr->flush) {
+	Blt_Vec_FlushCache(vPtr);
+    }
+    Blt_Vec_UpdateClients(vPtr);
+    return TCL_OK;
+}
+
+Vector *
+Blt_Vec_New(VectorInterpData *dataPtr) /* Interpreter-specific data. */
+{
+    Vector *vPtr;
+
+    vPtr = calloc(1, sizeof(Vector));
+    vPtr->valueArr = malloc(sizeof(double) * DEF_ARRAY_SIZE);
+    if (vPtr->valueArr == NULL) {
+	free(vPtr);
+	return NULL;
+    }
+    vPtr->size = DEF_ARRAY_SIZE;
+    vPtr->freeProc = TCL_DYNAMIC;
+    vPtr->length = 0;
+    vPtr->interp = dataPtr->interp;
+    vPtr->hashPtr = NULL;
+    vPtr->chain = Blt_Chain_Create();
+    vPtr->flush = FALSE;
+    vPtr->min = vPtr->max = NAN;
+    vPtr->notifyFlags = NOTIFY_WHENIDLE;
+    vPtr->dataPtr = dataPtr;
+    return vPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_Free --
+ *
+ *	Removes the memory and frees resources associated with the vector.
+ *
+ *	o Removes the trace and the TCL array variable and unsets
+ *	  the variable.
+ *	o Notifies clients of the vector that the vector is being
+ *	  destroyed.
+ *	o Removes any clients that are left after notification.
+ *	o Frees the memory (if necessary) allocated for the array.
+ *	o Removes the entry from the hash table of vectors.
+ *	o Frees the memory allocated for the name.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_Vec_Free(Vector *vPtr)
+{
+    Blt_ChainLink link;
+
+    if (vPtr->cmdToken != 0) {
+	DeleteCommand(vPtr);
+    }
+    if (vPtr->arrayName != NULL) {
+	UnmapVariable(vPtr);
+    }
+    vPtr->length = 0;
+
+    /* Immediately notify clients that vector is going away */
+    if (vPtr->notifyFlags & NOTIFY_PENDING) {
+	vPtr->notifyFlags &= ~NOTIFY_PENDING;
+	Tcl_CancelIdleCall(Blt_Vec_NotifyClients, vPtr);
+    }
+    vPtr->notifyFlags |= NOTIFY_DESTROYED;
+    Blt_Vec_NotifyClients(vPtr);
+
+    for (link = Blt_Chain_FirstLink(vPtr->chain); link != NULL;
+	link = Blt_Chain_NextLink(link)) {
+	VectorClient *clientPtr;
+
+	clientPtr = Blt_Chain_GetValue(link);
+	free(clientPtr);
+    }
+    Blt_Chain_Destroy(vPtr->chain);
+    if ((vPtr->valueArr != NULL) && (vPtr->freeProc != TCL_STATIC)) {
+	if (vPtr->freeProc == TCL_DYNAMIC) {
+	    free(vPtr->valueArr);
+	} else {
+	    (*vPtr->freeProc) ((char *)vPtr->valueArr);
+	}
+    }
+    if (vPtr->hashPtr != NULL) {
+	Blt_DeleteHashEntry(&vPtr->dataPtr->vectorTable, vPtr->hashPtr);
+    }
+#ifdef NAMESPACE_DELETE_NOTIFY
+    if (vPtr->nsPtr != NULL) {
+	Blt_DestroyNsDeleteNotify(vPtr->interp, vPtr->nsPtr, vPtr);
+    }
+#endif /* NAMESPACE_DELETE_NOTIFY */
+    free(vPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VectorInstDeleteProc --
+ *
+ *	Deletes the command associated with the vector.  This is called only
+ *	when the command associated with the vector is destroyed.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+VectorInstDeleteProc(ClientData clientData)
+{
+    Vector *vPtr = clientData;
+
+    vPtr->cmdToken = 0;
+    Blt_Vec_Free(vPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Vec_Create --
+ *
+ *	Creates a vector structure and the following items:
+ *
+ *	o TCL command
+ *	o TCL array variable and establishes traces on the variable
+ *	o Adds a  new entry in the vector hash table
+ *
+ * Results:
+ *	A pointer to the new vector structure.  If an error occurred NULL is
+ *	returned and an error message is left in interp->result.
+ *
+ * Side effects:
+ *	A new TCL command and array variable is added to the interpreter.
+ *
+ * ---------------------------------------------------------------------- 
+ */
+Vector *
+Blt_Vec_Create(
+    VectorInterpData *dataPtr,	/* Interpreter-specific data. */
+    const char *vecName,	/* Namespace-qualified name of the vector */
+    const char *cmdName,	/* Name of the TCL command mapped to
+				 * the vector */
+    const char *varName,	/* Name of the TCL array mapped to the
+				 * vector */
+    int *isNewPtr)
+{
+    Tcl_DString dString;
+    Vector *vPtr;
+    int isNew;
+    Blt_ObjectName objName;
+    char *qualName;
+    Blt_HashEntry *hPtr;
+    Tcl_Interp *interp = dataPtr->interp;
+
+    isNew = 0;
+    vPtr = NULL;
+
+    if (!Blt_ParseObjectName(interp, vecName, &objName, 0)) {
+	return NULL;
+    }
+    Tcl_DStringInit(&dString);
+    if ((objName.name[0] == '#') && (strcmp(objName.name, "#auto") == 0)) {
+
+	do {	/* Generate a unique vector name. */
+	    char string[200];
+
+	    sprintf_s(string, 200, "vector%d", dataPtr->nextId++);
+	    objName.name = string;
+	    qualName = Blt_MakeQualifiedName(&objName, &dString);
+	    hPtr = Blt_FindHashEntry(&dataPtr->vectorTable, qualName);
+	} while (hPtr != NULL);
+    } else {
+	const char *p;
+
+	for (p = objName.name; *p != '\0'; p++) {
+	    if (!VECTOR_CHAR(*p)) {
+		Tcl_AppendResult(interp, "bad vector name \"", objName.name,
+		    "\": must contain digits, letters, underscore, or period",
+		    (char *)NULL);
+		goto error;
+	    }
+	}
+	qualName = Blt_MakeQualifiedName(&objName, &dString);
+	vPtr = Blt_Vec_ParseElement((Tcl_Interp *)NULL, dataPtr, qualName, 
+		NULL, NS_SEARCH_CURRENT);
+    }
+    if (vPtr == NULL) {
+	hPtr = Blt_CreateHashEntry(&dataPtr->vectorTable, qualName, &isNew);
+	vPtr = Blt_Vec_New(dataPtr);
+	vPtr->hashPtr = hPtr;
+	vPtr->nsPtr = objName.nsPtr;
+
+	vPtr->name = Blt_GetHashKey(&dataPtr->vectorTable, hPtr);
+#ifdef NAMESPACE_DELETE_NOTIFY
+	Blt_CreateNsDeleteNotify(interp, objName.nsPtr, vPtr, 
+		VectorInstDeleteProc);
+#endif /* NAMESPACE_DELETE_NOTIFY */
+	Blt_SetHashValue(hPtr, vPtr);
+    }
+    if (cmdName != NULL) {
+	Tcl_CmdInfo cmdInfo;
+
+	if ((cmdName == vecName) ||
+	    ((cmdName[0] == '#') && (strcmp(cmdName, "#auto")==0))) {
+	    cmdName = qualName;
+	} 
+	if (Tcl_GetCommandInfo(interp, (char *)cmdName, &cmdInfo)) {
+	    if (vPtr != cmdInfo.objClientData) {
+		Tcl_AppendResult(interp, "command \"", cmdName,
+			 "\" already exists", (char *)NULL);
+		goto error;
+	    }
+	    /* We get here only if the old name is the same as the new. */
+	    goto checkVariable;
+	}
+    }
+    if (vPtr->cmdToken != 0) {
+	DeleteCommand(vPtr);	/* Command already exists, delete old first */
+    }
+    if (cmdName != NULL) {
+	Tcl_DString dString2;
+	
+	Tcl_DStringInit(&dString2);
+	if (cmdName != qualName) {
+	    if (!Blt_ParseObjectName(interp, cmdName, &objName, 0)) {
+		goto error;
+	    }
+	    cmdName = Blt_MakeQualifiedName(&objName, &dString2);
+	}
+	vPtr->cmdToken = Tcl_CreateObjCommand(interp, (char *)cmdName, 
+		Blt_Vec_InstCmd, vPtr, VectorInstDeleteProc);
+	Tcl_DStringFree(&dString2);
+    }
+  checkVariable:
+    if (varName != NULL) {
+	if ((varName[0] == '#') && (strcmp(varName, "#auto") == 0)) {
+	    varName = qualName;
+	}
+	if (Blt_Vec_MapVariable(interp, vPtr, varName) != TCL_OK) {
+	    goto error;
+	}
+    }
+
+    Tcl_DStringFree(&dString);
+    *isNewPtr = isNew;
+    return vPtr;
+
+  error:
+    Tcl_DStringFree(&dString);
+    if (vPtr != NULL) {
+	Blt_Vec_Free(vPtr);
+    }
+    return NULL;
+}
+
+
+int
+Blt_Vec_Duplicate(Vector *destPtr, Vector *srcPtr)
+{
+    size_t nBytes;
+    size_t length;
+
+    if (destPtr == srcPtr) {
+	/* Copying the same vector. */
+    }
+    length = srcPtr->last - srcPtr->first + 1;
+    if (Blt_Vec_ChangeLength(destPtr->interp, destPtr, length) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    nBytes = length * sizeof(double);
+    memcpy(destPtr->valueArr, srcPtr->valueArr + srcPtr->first, nBytes);
+    destPtr->offset = srcPtr->offset;
+    return TCL_OK;
+}
+
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VectorNamesOp --
+ *
+ *	Reports the names of all the current vectors in the interpreter.
+ *
+ * Results:
+ *	A standard TCL result.  interp->result will contain a list of
+ *	all the names of the vector instances.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+VectorNamesOp(
+    ClientData clientData,	/* Interpreter-specific data. */
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    VectorInterpData *dataPtr = clientData;
+    Tcl_Obj *listObjPtr;
+
+    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+    if (objc == 2) {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch cursor;
+
+	for (hPtr = Blt_FirstHashEntry(&dataPtr->vectorTable, &cursor);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	    char *name;
+
+	    name = Blt_GetHashKey(&dataPtr->vectorTable, hPtr);
+	    Tcl_ListObjAppendElement(interp, listObjPtr, 
+		Tcl_NewStringObj(name, -1));
+	}
+    } else {
+	Blt_HashEntry *hPtr;
+	Blt_HashSearch cursor;
+
+	for (hPtr = Blt_FirstHashEntry(&dataPtr->vectorTable, &cursor);
+	     hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	    char *name;
+	    int i;
+
+	    name = Blt_GetHashKey(&dataPtr->vectorTable, hPtr);
+	    for (i = 2; i < objc; i++) {
+		char *pattern;
+
+		pattern = Tcl_GetString(objv[i]);
+		if (Tcl_StringMatch(name, pattern)) {
+		    Tcl_ListObjAppendElement(interp, listObjPtr, 
+				Tcl_NewStringObj(name, -1));
+		    break;
+		}
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VectorCreateOp --
+ *
+ *	Creates a TCL command, and array variable representing an instance of
+ *	a vector.
+ *
+ *	vector a
+ *	vector b(20)
+ *	vector c(-5:14)
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+/*ARGSUSED*/
+static int
+VectorCreate2(
+    ClientData clientData,	/* Interpreter-specific data. */
+    Tcl_Interp *interp,
+    int argStart,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    VectorInterpData *dataPtr = clientData;
+    Vector *vPtr;
+    int count, i;
+    CreateSwitches switches;
+
+    /*
+     * Handle switches to the vector command and collect the vector name
+     * arguments into an array.
+     */
+    count = 0;
+    vPtr = NULL;
+    for (i = argStart; i < objc; i++) {
+	char *string;
+
+	string = Tcl_GetString(objv[i]);
+	if (string[0] == '-') {
+	    break;
+	}
+    }
+    count = i - argStart;
+    if (count == 0) {
+	Tcl_AppendResult(interp, "no vector names supplied", (char *)NULL);
+	return TCL_ERROR;
+    }
+    memset(&switches, 0, sizeof(switches));
+    if (Blt_ParseSwitches(interp, createSwitches, objc - i, objv + i, 
+	&switches, BLT_SWITCH_DEFAULTS) < 0) {
+	return TCL_ERROR;
+    }
+    if (count > 1) {
+	if (switches.cmdName != NULL) {
+	    Tcl_AppendResult(interp, 
+		"can't specify more than one vector with \"-command\" switch",
+		(char *)NULL);
+	    goto error;
+	}
+	if (switches.varName != NULL) {
+	    Tcl_AppendResult(interp,
+		"can't specify more than one vector with \"-variable\" switch",
+		(char *)NULL);
+	    goto error;
+	}
+    }
+    for (i = 0; i < count; i++) {
+	char *leftParen, *rightParen;
+	char *string;
+	int isNew;
+	int size, first, last;
+
+	size = first = last = 0;
+	string = Tcl_GetString(objv[i + argStart]);
+	leftParen = strchr(string, '(');
+	rightParen = strchr(string, ')');
+	if (((leftParen != NULL) && (rightParen == NULL)) ||
+	    ((leftParen == NULL) && (rightParen != NULL)) ||
+	    (leftParen > rightParen)) {
+	    Tcl_AppendResult(interp, "bad vector specification \"", string,
+		"\"", (char *)NULL);
+	    goto error;
+	}
+	if (leftParen != NULL) {
+	    int result;
+	    char *colon;
+
+	    *rightParen = '\0';
+	    colon = strchr(leftParen + 1, ':');
+	    if (colon != NULL) {
+
+		/* Specification is in the form vecName(first:last) */
+		*colon = '\0';
+		result = Tcl_GetInt(interp, leftParen + 1, &first);
+		if ((*(colon + 1) != '\0') && (result == TCL_OK)) {
+		    result = Tcl_GetInt(interp, colon + 1, &last);
+		    if (first > last) {
+			Tcl_AppendResult(interp, "bad vector range \"",
+			    string, "\"", (char *)NULL);
+			result = TCL_ERROR;
+		    }
+		    size = (last - first) + 1;
+		}
+		*colon = ':';
+	    } else {
+		/* Specification is in the form vecName(size) */
+		result = Tcl_GetInt(interp, leftParen + 1, &size);
+	    }
+	    *rightParen = ')';
+	    if (result != TCL_OK) {
+		goto error;
+	    }
+	    if (size < 0) {
+		Tcl_AppendResult(interp, "bad vector size \"", string, "\"",
+		    (char *)NULL);
+		goto error;
+	    }
+	}
+	if (leftParen != NULL) {
+	    *leftParen = '\0';
+	}
+	/*
+	 * By default, we create a TCL command by the name of the vector.
+	 */
+	vPtr = Blt_Vec_Create(dataPtr, string,
+	    (switches.cmdName == NULL) ? string : switches.cmdName,
+	    (switches.varName == NULL) ? string : switches.varName, &isNew);
+	if (leftParen != NULL) {
+	    *leftParen = '(';
+	}
+	if (vPtr == NULL) {
+	    goto error;
+	}
+	vPtr->freeOnUnset = switches.watchUnset;
+	vPtr->flush = switches.flush;
+	vPtr->offset = first;
+	if (size > 0) {
+	    if (Blt_Vec_ChangeLength(interp, vPtr, size) != TCL_OK) {
+		goto error;
+	    }
+	}
+	if (!isNew) {
+	    if (vPtr->flush) {
+		Blt_Vec_FlushCache(vPtr);
+	    }
+	    Blt_Vec_UpdateClients(vPtr);
+	}
+    }
+    Blt_FreeSwitches(createSwitches, (char *)&switches, 0);
+    if (vPtr != NULL) {
+	/* Return the name of the last vector created  */
+	Tcl_SetStringObj(Tcl_GetObjResult(interp), vPtr->name, -1);
+    }
+    return TCL_OK;
+  error:
+    Blt_FreeSwitches(createSwitches, (char *)&switches, 0);
+    return TCL_ERROR;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VectorCreateOp --
+ *
+ *	Creates a TCL command, and array variable representing an instance of
+ *	a vector.
+ *
+ *	vector a
+ *	vector b(20)
+ *	vector c(-5:14)
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+VectorCreateOp(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    return VectorCreate2(clientData, interp, 2, objc, objv);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VectorDestroyOp --
+ *
+ *	Destroys the vector and its related TCL command and array variable (if
+ *	they exist).
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ * Side effects:
+ *	Deletes the vector.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+VectorDestroyOp(
+    ClientData clientData,	/* Interpreter-specific data. */
+    Tcl_Interp *interp,		/* Not used. */
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    VectorInterpData *dataPtr = clientData;
+    Vector *vPtr;
+    int i;
+
+    for (i = 2; i < objc; i++) {
+	if (Blt_Vec_LookupName(dataPtr, Tcl_GetString(objv[i]), &vPtr) 
+		!= TCL_OK) {
+	    return TCL_ERROR;
+	}
+	Blt_Vec_Free(vPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VectorExprOp --
+ *
+ *	Computes the result of the expression which may be either a scalar
+ *	(single value) or vector (list of values).
+ *
+ * Results:
+ *	A standard TCL result.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static int
+VectorExprOp(
+    ClientData clientData,	/* Not Used. */
+    Tcl_Interp *interp,
+    int objc,			/* Not used. */
+    Tcl_Obj *const *objv)
+{
+    return Blt_ExprVector(interp, Tcl_GetString(objv[2]), (Blt_Vector *)NULL);
+}
+
+static Blt_OpSpec vectorCmdOps[] =
+{
+    {"create", 1, VectorCreateOp, 3, 0,
+	"vecName ?vecName...? ?switches...?",},
+    {"destroy", 1, VectorDestroyOp, 3, 0,
+	"vecName ?vecName...?",},
+    {"expr", 1, VectorExprOp, 3, 3, "expression",},
+    {"names", 1, VectorNamesOp, 2, 3, "?pattern?...",},
+};
+
+static int nCmdOps = sizeof(vectorCmdOps) / sizeof(Blt_OpSpec);
+
+/*ARGSUSED*/
+static int
+VectorCmd(
+    ClientData clientData,	/* Interpreter-specific data. */
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    VectorCmdProc *proc;
+    /*
+     * Try to replicate the old vector command's behavior:
+     */
+    if (objc > 1) {
+	char *string;
+	char c;
+	int i;
+	Blt_OpSpec *specPtr;
+
+	string = Tcl_GetString(objv[1]);
+	c = string[0];
+	for (specPtr = vectorCmdOps, i = 0; i < nCmdOps; i++, specPtr++) {
+	    if ((c == specPtr->name[0]) &&
+		(strcmp(string, specPtr->name) == 0)) {
+		goto doOp;
+	    }
+	}
+	/*
+	 * The first argument is not an operation, so assume that its
+	 * actually the name of a vector to be created
+	 */
+	return VectorCreate2(clientData, interp, 1, objc, objv);
+    }
+  doOp:
+    /* Do the usual vector operation lookup now. */
+    proc = Blt_GetOpFromObj(interp, nCmdOps, vectorCmdOps, BLT_OP_ARG1, 
+	objc, objv,0);
+    if (proc == NULL) {
+	return TCL_ERROR;
+    }
+    return (*proc) (clientData, interp, objc, objv);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * VectorInterpDeleteProc --
+ *
+ *	This is called when the interpreter hosting the "vector" command
+ *	is deleted.  
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Destroys the math and index hash tables.  In addition removes
+ *	the hash table managing all vector names.
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static void
+VectorInterpDeleteProc(
+    ClientData clientData,	/* Interpreter-specific data. */
+    Tcl_Interp *interp)
+{
+    VectorInterpData *dataPtr = clientData;
+    Blt_HashEntry *hPtr;
+    Blt_HashSearch cursor;
+    
+    for (hPtr = Blt_FirstHashEntry(&dataPtr->vectorTable, &cursor);
+	 hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
+	Vector *vPtr;
+
+	vPtr = Blt_GetHashValue(hPtr);
+	vPtr->hashPtr = NULL;
+	Blt_Vec_Free(vPtr);
+    }
+    Blt_DeleteHashTable(&dataPtr->vectorTable);
+
+    /* If any user-defined math functions were installed, remove them.  */
+    Blt_Vec_UninstallMathFunctions(&dataPtr->mathProcTable);
+    Blt_DeleteHashTable(&dataPtr->mathProcTable);
+
+    Blt_DeleteHashTable(&dataPtr->indexProcTable);
+    Tcl_DeleteAssocData(interp, VECTOR_THREAD_KEY);
+    free(dataPtr);
+}
+
+VectorInterpData *
+Blt_Vec_GetInterpData(Tcl_Interp *interp)
+{
+    VectorInterpData *dataPtr;
+    Tcl_InterpDeleteProc *proc;
+
+    dataPtr = (VectorInterpData *)
+	Tcl_GetAssocData(interp, VECTOR_THREAD_KEY, &proc);
+    if (dataPtr == NULL) {
+	dataPtr = malloc(sizeof(VectorInterpData));
+	dataPtr->interp = interp;
+	dataPtr->nextId = 0;
+	Tcl_SetAssocData(interp, VECTOR_THREAD_KEY, VectorInterpDeleteProc,
+		 dataPtr);
+	Blt_InitHashTable(&dataPtr->vectorTable, BLT_STRING_KEYS);
+	Blt_InitHashTable(&dataPtr->mathProcTable, BLT_STRING_KEYS);
+	Blt_InitHashTable(&dataPtr->indexProcTable, BLT_STRING_KEYS);
+	Blt_Vec_InstallMathFunctions(&dataPtr->mathProcTable);
+	Blt_Vec_InstallSpecialIndices(&dataPtr->indexProcTable);
+	srand48(time((time_t *) NULL));
+    }
+    return dataPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_VectorCmdInitProc --
+ *
+ *	This procedure is invoked to initialize the "vector" command.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Creates the new command and adds a new entry into a global Tcl
+ *	associative array.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Blt_VectorCmdInitProc(Tcl_Interp *interp)
+{
+    static Blt_InitCmdSpec cmdSpec = {"vector", VectorCmd, };
+    
+    cmdSpec.clientData = Blt_Vec_GetInterpData(interp);
+    return Blt_InitCmd(interp, "::blt", &cmdSpec);
+}
+
+
+
+/* C Application interface to vectors */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_CreateVector --
+ *
+ *	Creates a new vector by the name and size.
+ *
+ * Results:
+ *	A standard TCL result.  If the new array size is invalid or a vector
+ *	already exists by that name, TCL_ERROR is returned.  Otherwise TCL_OK
+ *	is returned and the new vector is created.
+ *
+ * Side Effects:
+ *	Memory will be allocated for the new vector.  A new TCL command and
+ *	Tcl array variable will be created.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+/*LINTLIBRARY*/
+int
+Blt_CreateVector2(
+    Tcl_Interp *interp,
+    const char *vecName, const char *cmdName, const char *varName,
+    int initialSize,
+    Blt_Vector **vecPtrPtr)
+{
+    VectorInterpData *dataPtr;	/* Interpreter-specific data. */
+    Vector *vPtr;
+    int isNew;
+    char *nameCopy;
+
+    if (initialSize < 0) {
+	Tcl_AppendResult(interp, "bad vector size \"", Blt_Itoa(initialSize),
+	    "\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    dataPtr = Blt_Vec_GetInterpData(interp);
+
+    nameCopy = Blt_Strdup(vecName);
+    vPtr = Blt_Vec_Create(dataPtr, nameCopy, cmdName, varName, &isNew);
+    free(nameCopy);
+
+    if (vPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (initialSize > 0) {
+	if (Blt_Vec_ChangeLength(interp, vPtr, initialSize) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    if (vecPtrPtr != NULL) {
+	*vecPtrPtr = (Blt_Vector *) vPtr;
+    }
+    return TCL_OK;
+}
+
+int
+Blt_CreateVector(
+    Tcl_Interp *interp,
+    const char *name,
+    int size,
+    Blt_Vector **vecPtrPtr)
+{
+    return Blt_CreateVector2(interp, name, name, name, size, vecPtrPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DeleteVector --
+ *
+ *	Deletes the vector of the given name.  All clients with designated
+ *	callback routines will be notified.
+ *
+ * Results:
+ *	A standard TCL result.  If no vector exists by that name, TCL_ERROR is
+ *	returned.  Otherwise TCL_OK is returned and vector is deleted.
+ *
+ * Side Effects:
+ *	Memory will be released for the new vector.  Both the TCL command and
+ *	array variable will be deleted.  All clients which set call back
+ *	procedures will be notified.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+int
+Blt_DeleteVector(Blt_Vector *vecPtr)
+{
+    Vector *vPtr = (Vector *)vecPtr;
+
+    Blt_Vec_Free(vPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_DeleteVectorByName --
+ *
+ *	Deletes the vector of the given name.  All clients with designated
+ *	callback routines will be notified.
+ *
+ * Results:
+ *	A standard TCL result.  If no vector exists by that name, TCL_ERROR is
+ *	returned.  Otherwise TCL_OK is returned and vector is deleted.
+ *
+ * Side Effects:
+ *	Memory will be released for the new vector.  Both the TCL command and
+ *	array variable will be deleted.  All clients which set call back
+ *	procedures will be notified.
+ *
+ *---------------------------------------------------------------------------
+ */
+/*LINTLIBRARY*/
+int
+Blt_DeleteVectorByName(Tcl_Interp *interp, const char *name)
+{
+    VectorInterpData *dataPtr;	/* Interpreter-specific data. */
+    Vector *vPtr;
+    char *nameCopy;
+    int result;
+
+    /*
+     * If the vector name was passed via a read-only string (e.g. "x"), the
+     * Blt_Vec_ParseElement routine will segfault when it tries to write into
+     * the string.  Therefore make a writable copy and free it when we're
+     * done.
+     */
+    nameCopy = Blt_Strdup(name);
+    dataPtr = Blt_Vec_GetInterpData(interp);
+    result = Blt_Vec_LookupName(dataPtr, nameCopy, &vPtr);
+    free(nameCopy);
+
+    if (result != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Blt_Vec_Free(vPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_VectorExists2 --
+ *
+ *	Returns whether the vector associated with the client token still
+ *	exists.
+ *
+ * Results:
+ *	Returns 1 is the vector still exists, 0 otherwise.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_VectorExists2(Tcl_Interp *interp, const char *vecName)
+{
+    VectorInterpData *dataPtr;	/* Interpreter-specific data. */
+
+    dataPtr = Blt_Vec_GetInterpData(interp);
+    if (GetVectorObject(dataPtr, vecName, NS_SEARCH_BOTH) != NULL) {
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_VectorExists --
+ *
+ *	Returns whether the vector associated with the client token
+ *	still exists.
+ *
+ * Results:
+ *	Returns 1 is the vector still exists, 0 otherwise.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_VectorExists(Tcl_Interp *interp, const char *vecName)
+{
+    char *nameCopy;
+    int result;
+
+    /*
+     * If the vector name was passed via a read-only string (e.g. "x"), the
+     * Blt_VectorParseName routine will segfault when it tries to write into
+     * the string.  Therefore make a writable copy and free it when we're
+     * done.
+     */
+    nameCopy = Blt_Strdup(vecName);
+    result = Blt_VectorExists2(interp, nameCopy);
+    free(nameCopy);
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetVector --
+ *
+ *	Returns a pointer to the vector associated with the given name.
+ *
+ * Results:
+ *	A standard TCL result.  If there is no vector "name", TCL_ERROR is
+ *	returned.  Otherwise TCL_OK is returned and vecPtrPtr will point to
+ *	the vector.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_GetVector(Tcl_Interp *interp, const char *name, Blt_Vector **vecPtrPtr)
+{
+    VectorInterpData *dataPtr;	/* Interpreter-specific data. */
+    Vector *vPtr;
+    char *nameCopy;
+    int result;
+
+    dataPtr = Blt_Vec_GetInterpData(interp);
+    /*
+     * If the vector name was passed via a read-only string (e.g. "x"), the
+     * Blt_VectorParseName routine will segfault when it tries to write into
+     * the string.  Therefore make a writable copy and free it when we're
+     * done.
+     */
+    nameCopy = Blt_Strdup(name);
+    result = Blt_Vec_LookupName(dataPtr, nameCopy, &vPtr);
+    free(nameCopy);
+    if (result != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Blt_Vec_UpdateRange(vPtr);
+    *vecPtrPtr = (Blt_Vector *) vPtr;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetVectorFromObj --
+ *
+ *	Returns a pointer to the vector associated with the given name.
+ *
+ * Results:
+ *	A standard TCL result.  If there is no vector "name", TCL_ERROR
+ *	is returned.  Otherwise TCL_OK is returned and vecPtrPtr will
+ *	point to the vector.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_GetVectorFromObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr,
+    Blt_Vector **vecPtrPtr)
+{
+    VectorInterpData *dataPtr;	/* Interpreter-specific data. */
+    Vector *vPtr;
+
+    dataPtr = Blt_Vec_GetInterpData(interp);
+    if (Blt_Vec_LookupName(dataPtr, Tcl_GetString(objPtr), &vPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Blt_Vec_UpdateRange(vPtr);
+    *vecPtrPtr = (Blt_Vector *) vPtr;
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ResetVector --
+ *
+ *	Resets the vector data.  This is called by a client to indicate that
+ *	the vector data has changed.  The vector does not need to point to
+ *	different memory.  Any clients of the vector will be notified of the
+ *	change.
+ *
+ * Results:
+ *	A standard TCL result.  If the new array size is invalid,
+ *	TCL_ERROR is returned.  Otherwise TCL_OK is returned and the
+ *	new vector data is recorded.
+ *
+ * Side Effects:
+ *	Any client designated callbacks will be posted.  Memory may
+ *	be changed for the vector array.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_ResetVector(
+    Blt_Vector *vecPtr,
+    double *valueArr,		/* Array containing the elements of the
+				 * vector. If NULL, indicates to reset the 
+				 * vector.*/
+    int length,			/* The number of elements that the vector 
+				 * currently holds. */
+    int size,			/* The maximum number of elements that the
+				 * array can hold. */
+    Tcl_FreeProc *freeProc)	/* Address of memory deallocation routine
+				 * for the array of values.  Can also be
+				 * TCL_STATIC, TCL_DYNAMIC, or TCL_VOLATILE. */
+{
+    Vector *vPtr = (Vector *)vecPtr;
+
+    if (size < 0) {
+	Tcl_AppendResult(vPtr->interp, "bad array size", (char *)NULL);
+	return TCL_ERROR;
+    }
+    return Blt_Vec_Reset(vPtr, valueArr, length, size, freeProc);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_ResizeVector --
+ *
+ *	Changes the size of the vector.  All clients with designated callback
+ *	routines will be notified of the size change.
+ *
+ * Results:
+ *	A standard TCL result.  If no vector exists by that name, TCL_ERROR is
+ *	returned.  Otherwise TCL_OK is returned and vector is resized.
+ *
+ * Side Effects:
+ *	Memory may be reallocated for the new vector size.  All clients which
+ *	set call back procedures will be notified.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_ResizeVector(Blt_Vector *vecPtr, int length)
+{
+    Vector *vPtr = (Vector *)vecPtr;
+
+    if (Blt_Vec_ChangeLength((Tcl_Interp *)NULL, vPtr, length) != TCL_OK) {
+	Tcl_AppendResult(vPtr->interp, "can't resize vector \"", vPtr->name,
+	    "\"", (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (vPtr->flush) {
+	Blt_Vec_FlushCache(vPtr);
+    }
+    Blt_Vec_UpdateClients(vPtr);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_AllocVectorId --
+ *
+ *	Creates an identifier token for an existing vector.  The identifier is
+ *	used by the client routines to get call backs when (and if) the vector
+ *	changes.
+ *
+ * Results:
+ *	A standard TCL result.  If "vecName" is not associated with a vector,
+ *	TCL_ERROR is returned and interp->result is filled with an error
+ *	message.
+ *
+ *---------------------------------------------------------------------------
+ */
+Blt_VectorId
+Blt_AllocVectorId(Tcl_Interp *interp, const char *name)
+{
+    VectorInterpData *dataPtr;	/* Interpreter-specific data. */
+    Vector *vPtr;
+    VectorClient *clientPtr;
+    Blt_VectorId clientId;
+    int result;
+    char *nameCopy;
+
+    dataPtr = Blt_Vec_GetInterpData(interp);
+    /*
+     * If the vector name was passed via a read-only string (e.g. "x"), the
+     * Blt_VectorParseName routine will segfault when it tries to write into
+     * the string.  Therefore make a writable copy and free it when we're
+     * done.
+     */
+    nameCopy = Blt_Strdup(name);
+    result = Blt_Vec_LookupName(dataPtr, nameCopy, &vPtr);
+    free(nameCopy);
+
+    if (result != TCL_OK) {
+	return (Blt_VectorId) 0;
+    }
+    /* Allocate a new client structure */
+    clientPtr = calloc(1, sizeof(VectorClient));
+    clientPtr->magic = VECTOR_MAGIC;
+
+    /* Add the new client to the server's list of clients */
+    clientPtr->link = Blt_Chain_Append(vPtr->chain, clientPtr);
+    clientPtr->serverPtr = vPtr;
+    clientId = (Blt_VectorId) clientPtr;
+    return clientId;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_SetVectorChangedProc --
+ *
+ *	Sets the routine to be called back when the vector is changed or
+ *	deleted.  *clientData* will be provided as an argument. If *proc* is
+ *	NULL, no callback will be made.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	The designated routine will be called when the vector is changed
+ *	or deleted.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_SetVectorChangedProc(
+    Blt_VectorId clientId,	/* Client token identifying the vector */
+    Blt_VectorChangedProc *proc,/* Address of routine to call when the contents
+				 * of the vector change. If NULL, no routine
+				 * will be called */
+    ClientData clientData)	/* One word of information to pass along when
+				 * the above routine is called */
+{
+    VectorClient *clientPtr = (VectorClient *)clientId;
+
+    if (clientPtr->magic != VECTOR_MAGIC) {
+	return;			/* Not a valid token */
+    }
+    clientPtr->clientData = clientData;
+    clientPtr->proc = proc;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FreeVectorId --
+ *
+ *	Releases the token for an existing vector.  This indicates that the
+ *	client is no longer interested the vector.  Any previously specified
+ *	callback routine will no longer be invoked when (and if) the vector
+ *	changes.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Any previously specified callback routine will no longer be
+ *	invoked when (and if) the vector changes.
+ *
+ *---------------------------------------------------------------------------
+ */
+void
+Blt_FreeVectorId(Blt_VectorId clientId)
+{
+    VectorClient *clientPtr = (VectorClient *)clientId;
+
+    if (clientPtr->magic != VECTOR_MAGIC) {
+	return;			/* Not a valid token */
+    }
+    if (clientPtr->serverPtr != NULL) {
+	/* Remove the client from the server's list */
+	Blt_Chain_DeleteLink(clientPtr->serverPtr->chain, clientPtr->link);
+    }
+    free(clientPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_NameOfVectorId --
+ *
+ *	Returns the name of the vector (and array variable).
+ *
+ * Results:
+ *	The name of the array variable is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+const char *
+Blt_NameOfVectorId(Blt_VectorId clientId) 
+{
+    VectorClient *clientPtr = (VectorClient *)clientId;
+
+    if ((clientPtr->magic != VECTOR_MAGIC) || (clientPtr->serverPtr == NULL)) {
+	return NULL;
+    }
+    return clientPtr->serverPtr->name;
+}
+
+const char *
+Blt_NameOfVector(Blt_Vector *vecPtr) /* Vector to query. */
+{
+    Vector *vPtr = (Vector *)vecPtr;
+    return vPtr->name;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_VectorNotifyPending --
+ *
+ *	Returns the name of the vector (and array variable).
+ *
+ * Results:
+ *	The name of the array variable is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_VectorNotifyPending(Blt_VectorId clientId)
+{
+    VectorClient *clientPtr = (VectorClient *)clientId;
+
+    if ((clientPtr == NULL) || (clientPtr->magic != VECTOR_MAGIC) || 
+	(clientPtr->serverPtr == NULL)) {
+	return 0;
+    }
+    return (clientPtr->serverPtr->notifyFlags & NOTIFY_PENDING);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_GetVectorById --
+ *
+ *	Returns a pointer to the vector associated with the client
+ *	token.
+ *
+ * Results:
+ *	A standard TCL result.  If the client token is not associated
+ *	with a vector any longer, TCL_ERROR is returned. Otherwise,
+ *	TCL_OK is returned and vecPtrPtr will point to vector.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Blt_GetVectorById(
+    Tcl_Interp *interp,
+    Blt_VectorId clientId,	/* Client token identifying the vector */
+    Blt_Vector **vecPtrPtr)
+{
+    VectorClient *clientPtr = (VectorClient *)clientId;
+
+    if (clientPtr->magic != VECTOR_MAGIC) {
+	Tcl_AppendResult(interp, "bad vector token", (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (clientPtr->serverPtr == NULL) {
+	Tcl_AppendResult(interp, "vector no longer exists", (char *)NULL);
+	return TCL_ERROR;
+    }
+    Blt_Vec_UpdateRange(clientPtr->serverPtr);
+    *vecPtrPtr = (Blt_Vector *) clientPtr->serverPtr;
+    return TCL_OK;
+}
+
+/*LINTLIBRARY*/
+void
+Blt_InstallIndexProc(Tcl_Interp *interp, const char *string, 
+		     Blt_VectorIndexProc *procPtr) 
+{
+    VectorInterpData *dataPtr;	/* Interpreter-specific data. */
+    Blt_HashEntry *hPtr;
+    int isNew;
+
+    dataPtr = Blt_Vec_GetInterpData(interp);
+    hPtr = Blt_CreateHashEntry(&dataPtr->indexProcTable, string, &isNew);
+    if (procPtr == NULL) {
+	Blt_DeleteHashEntry(&dataPtr->indexProcTable, hPtr);
+    } else {
+	Blt_SetHashValue(hPtr, procPtr);
+    }
+}
+
+/* spinellia at acm.org START */
+
+
+#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
+
+/* routine by Brenner
+ * data is the array of complex data points, perversely
+ * starting at 1
+ * nn is the number of complex points, i.e. half the length of data
+ * isign is 1 for forward, -1 for inverse
+ */
+static void 
+four1(double *data, unsigned long nn, int isign)
+{
+    unsigned long n,mmax,m,j,istep,i;
+    double wtemp,wr,wpr,wpi,wi,theta;
+    double tempr,tempi;
+    
+    n=nn << 1;
+    j=1;
+    for (i = 1;i<n;i+=2) {
+	if (j > i) {
+	    SWAP(data[j],data[i]);
+	    SWAP(data[j+1],data[i+1]);
+	}
+	m=n >> 1;
+	while (m >= 2 && j > m) {
+	    j -= m;
+	    m >>= 1;
+	}
+	j += m;
+    }
+    mmax=2;
+    while (n > mmax) {
+	istep=mmax << 1;
+	theta=isign*(6.28318530717959/mmax);
+	wtemp=sin(0.5*theta);
+	wpr = -2.0*wtemp*wtemp;
+	wpi=sin(theta);
+	wr=1.0;
+	wi=0.0;
+	for (m=1;m<mmax;m+=2) {
+	    for (i=m;i<=n;i+=istep) {
+		j=i+mmax;
+		tempr=wr*data[j]-wi*data[j+1];
+		tempi=wr*data[j+1]+wi*data[j];
+		data[j]=data[i]-tempr;
+		data[j+1]=data[i+1]-tempi;
+		data[i] += tempr;
+		data[i+1] += tempi;
+	    }
+	    wr=(wtemp=wr)*wpr-wi*wpi+wr;
+	    wi=wi*wpr+wtemp*wpi+wi;
+	}
+	mmax=istep;
+    }
+}
+#undef SWAP
+
+static int 
+smallest_power_of_2_not_less_than(int x)
+{
+    int pow2 = 1;
+
+    while (pow2 < x){
+	pow2 <<= 1;
+    }
+    return pow2;
+}
+
+
+int
+Blt_Vec_FFT(
+    Tcl_Interp *interp,		/* Interpreter to report errors to */
+    Vector *realPtr,	/* If non-NULL, indicates to compute and
+				   store the real values in this vector.  */
+    Vector *phasesPtr,	/* If non-NULL, indicates to compute
+				 * and store the imaginary values in
+				 * this vector. */
+    Vector *freqPtr,	/* If non-NULL, indicates to compute
+				 * and store the frequency values in
+				 * this vector.  */
+    double delta,		/*  */
+    int flags,			/* Bit mask representing various
+				 * flags: FFT_NO_constANT,
+				 * FFT_SPECTRUM, and FFT_BARTLETT. */
+    Vector *srcPtr) 
+{
+    int length;
+    int pow2len;
+    double *paddedData;
+    int i;
+    double Wss = 0.0;
+    /* TENTATIVE */
+    int middle = 1;
+    int noconstant;
+
+    noconstant = (flags & FFT_NO_CONSTANT) ? 1 : 0;
+
+    /* Length of the original vector. */
+    length = srcPtr->last - srcPtr->first + 1;
+    /* new length */
+    pow2len = smallest_power_of_2_not_less_than( length );
+
+    /* We do not do in-place FFTs */
+    if (realPtr == srcPtr) {
+	Tcl_AppendResult(interp, "real vector \"", realPtr->name, 
+		 "\" can't be the same as the source", (char *)NULL);
+	return TCL_ERROR;
+    }
+    if (phasesPtr != NULL) {
+	if (phasesPtr == srcPtr) {
+	    Tcl_AppendResult(interp, "imaginary vector \"", phasesPtr->name, 
+			"\" can't be the same as the source", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	if (Blt_Vec_ChangeLength(interp, phasesPtr, 
+		pow2len/2-noconstant+middle) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    if (freqPtr != NULL) {
+	if (freqPtr == srcPtr) {
+	    Tcl_AppendResult(interp, "frequency vector \"", freqPtr->name, 
+		     "\" can't be the same as the source", (char *)NULL);
+	    return TCL_ERROR;
+	}
+	if (Blt_Vec_ChangeLength(interp, freqPtr, 
+			   pow2len/2-noconstant+middle) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /* Allocate memory zero-filled array. */
+    paddedData = calloc(pow2len * 2, sizeof(double));
+    if (paddedData == NULL) {
+	Tcl_AppendResult(interp, "can't allocate memory for padded data",
+		 (char *)NULL);
+	return TCL_ERROR;
+    }
+    
+    /*
+     * Since we just do real transforms, only even locations will be
+     * filled with data.
+     */
+    if (flags & FFT_BARTLETT) {	/* Bartlett window 1 - ( (x - N/2) / (N/2) ) */
+	double Nhalf = pow2len*0.5;
+	double Nhalf_1 = 1.0 / Nhalf;
+	double w;
+
+	for (i = 0; i < length; i++) {
+	    w = 1.0 - fabs( (i-Nhalf) * Nhalf_1 );
+	    Wss += w;
+	    paddedData[2*i] = w * srcPtr->valueArr[i];
+	}
+	for(/*empty*/; i < pow2len; i++) {
+	    w = 1.0 - fabs((i-Nhalf) * Nhalf_1);
+	    Wss += w;
+	}
+    } else {			/* Squared window, i.e. no data windowing. */
+	for (i = 0; i < length; i++) { 
+	    paddedData[2*i] = srcPtr->valueArr[i]; 
+	}
+	Wss = pow2len;
+    }
+    
+    /* Fourier */
+    four1(paddedData-1, pow2len, 1);
+    
+    /*
+      for(i=0;i<pow2len;i++){
+      printf( "(%f %f) ", paddedData[2*i], paddedData[2*i+1] );
+      }
+    */
+    
+    /* the spectrum is the modulus of the transforms, scaled by 1/N^2 */
+    /* or 1/(N * Wss) for windowed data */
+    if (flags & FFT_SPECTRUM) {
+	double re, im, reS, imS;
+	double factor = 1.0 / (pow2len*Wss);
+	double *v = realPtr->valueArr;
+	
+	for (i = 0 + noconstant; i < pow2len / 2; i++) {
+	    re = paddedData[2*i];
+	    im = paddedData[2*i+1];
+	    reS = paddedData[2*pow2len-2*i-2];
+	    imS = paddedData[2*pow2len-2*i-1];
+	    v[i - noconstant] = factor * (
+# if 0
+			  hypot( paddedData[2*i], paddedData[2*i+1] )
+			  + hypot(
+				  paddedData[pow2len*2-2*i-2],
+				  paddedData[pow2len*2-2*i-1]
+			)
+# else
+			  sqrt( re*re + im* im ) + sqrt( reS*reS + imS*imS )
+# endif
+		   );
+	}
+    } else {
+	for(i = 0 + noconstant; i < pow2len / 2 + middle; i++) {
+	    realPtr->valueArr[i - noconstant] = paddedData[2*i];
+	}
+    }
+    if( phasesPtr != NULL ){
+        for (i = 0 + noconstant; i < pow2len / 2 + middle; i++) {
+	    phasesPtr->valueArr[i-noconstant] = paddedData[2*i+1];
+	}
+    }
+    
+    /* Compute frequencies */
+    if (freqPtr != NULL) {
+        double N = pow2len;
+	double denom = 1.0 / N / delta;
+        for( i=0+noconstant; i<pow2len/2+middle; i++ ){
+	    freqPtr->valueArr[i-noconstant] = ((double) i) * denom;
+	}
+    }
+    
+    /* Memory is necessarily dynamic, because nobody touched it ! */
+    free(paddedData);
+    
+    realPtr->offset = 0;
+    return TCL_OK;
+}
+
+
+int
+Blt_Vec_InverseFFT(Tcl_Interp *interp, Vector *srcImagPtr, Vector *destRealPtr, 
+    Vector *destImagPtr, Vector *srcPtr)
+{
+    int length;
+    int pow2len;
+    double *paddedData;
+    int i;
+    double oneOverN;
+
+    if ((destRealPtr == srcPtr) || (destImagPtr == srcPtr )){
+/* we do not do in-place FFTs */
+	return TCL_ERROR;
+    }
+    length = srcPtr->last - srcPtr->first + 1;
+
+/* minus one because of the magical middle element! */
+    pow2len = smallest_power_of_2_not_less_than( (length-1)*2 );
+    oneOverN = 1.0 / pow2len;
+
+    if (Blt_Vec_ChangeLength(interp, destRealPtr, pow2len) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Blt_Vec_ChangeLength(interp, destImagPtr, pow2len) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if( length != (srcImagPtr->last - srcImagPtr->first + 1) ){
+	Tcl_AppendResult(srcPtr->interp,
+		"the length of the imagPart vector must ",
+		"be the same as the real one", (char *)NULL);
+	return TCL_ERROR;
+    }
+
+    paddedData = malloc( pow2len*2*sizeof(double) );
+    if( paddedData == NULL ){
+	if (interp != NULL) {
+	    Tcl_AppendResult(interp, "memory allocation failed", (char *)NULL);
+	}
+	return TCL_ERROR;
+    }
+    for(i=0;i<pow2len*2;i++) { paddedData[i] = 0.0; }
+    for(i=0;i<length-1;i++){
+	paddedData[2*i] = srcPtr->valueArr[i];
+	paddedData[2*i+1] = srcImagPtr->valueArr[i];
+	paddedData[pow2len*2 - 2*i - 2 ] = srcPtr->valueArr[i+1];
+	paddedData[pow2len*2 - 2*i - 1 ] = - srcImagPtr->valueArr[i+1];
+    }
+/* mythical middle element */
+    paddedData[(length-1)*2] = srcPtr->valueArr[length-1];
+    paddedData[(length-1)*2+1] = srcImagPtr->valueArr[length-1];
+
+/*
+for(i=0;i<pow2len;i++){
+	printf( "(%f %f) ", paddedData[2*i], paddedData[2*i+1] );
+}
+ */
+
+/* fourier */
+    four1( paddedData-1, pow2len, -1 );
+
+/* put values in their places, normalising by 1/N */
+    for(i=0;i<pow2len;i++){
+	destRealPtr->valueArr[i] = paddedData[2*i] * oneOverN;
+	destImagPtr->valueArr[i] = paddedData[2*i+1] * oneOverN;
+    }
+
+/* memory is necessarily dynamic, because nobody touched it ! */
+    free( paddedData );
+
+    return TCL_OK;
+}
+
+
+/* spinellia at acm.org STOP */
+
+
+
+static double
+FindSplit(Point2d *points, int i, int j, int *split)	
+{    
+    double maxDist2;
+    
+    maxDist2 = -1.0;
+    if ((i + 1) < j) {
+	int k;
+	double a, b, c;	
+
+	/* 
+	 * 
+	 *  dist2 P(k) =  |  1  P(i).x  P(i).y  |
+	 *		  |  1  P(j).x  P(j).y  |
+	 *                |  1  P(k).x  P(k).y  |
+	 *       ------------------------------------------
+ 	 *       (P(i).x - P(j).x)^2 + (P(i).y - P(j).y)^2
+	 */
+
+	a = points[i].y - points[j].y;
+	b = points[j].x - points[i].x;
+	c = (points[i].x * points[j].y) - (points[i].y * points[j].x);
+	for (k = (i + 1); k < j; k++) {
+	    double dist2;
+
+	    dist2 = (points[k].x * a) + (points[k].y * b) + c;
+	    if (dist2 < 0.0) {
+		dist2 = -dist2;	
+	    }
+	    if (dist2 > maxDist2) {
+		maxDist2 = dist2;	/* Track the maximum. */
+		*split = k;
+	    }
+	}
+	/* Correction for segment length---should be redone if can == 0 */
+	maxDist2 *= maxDist2 / (a * a + b * b);
+    } 
+    return maxDist2;
+}
+
+
+/* Douglas-Peucker line simplification algorithm */
+int
+Blt_SimplifyLine(Point2d *inputPts, int low, int high, double tolerance,
+		 int *indices)
+{
+#define StackPush(a)	s++, stack[s] = (a)
+#define StackPop(a)	(a) = stack[s], s--
+#define StackEmpty()	(s < 0)
+#define StackTop()	stack[s]
+    int *stack;
+    int split = -1; 
+    double dist2, tolerance2;
+    int s = -1;			/* Points to top stack item. */
+    int count;
+
+    stack = malloc(sizeof(int) * (high - low + 1));
+    StackPush(high);
+    count = 0;
+    indices[count++] = 0;
+    tolerance2 = tolerance * tolerance;
+    while (!StackEmpty()) {
+	dist2 = FindSplit(inputPts, low, StackTop(), &split);
+	if (dist2 > tolerance2) {
+	    StackPush(split);
+	} else {
+	    indices[count++] = StackTop();
+	    StackPop(low);
+	}
+    } 
+    free(stack);
+    return count;
+}
diff --git a/tlt3.0/bltVector.h b/tlt3.0/bltVector.h
new file mode 100644
index 0000000..2ec03bc
--- /dev/null
+++ b/tlt3.0/bltVector.h
@@ -0,0 +1,137 @@
+
+/*
+ * bltVector.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_VECTOR_H
+#define _BLT_VECTOR_H
+
+typedef enum {
+    BLT_VECTOR_NOTIFY_UPDATE = 1, /* The vector's values has been updated */
+    BLT_VECTOR_NOTIFY_DESTROY	/* The vector has been destroyed and the client
+				 * should no longer use its data (calling
+				 * Blt_FreeVectorId) */
+} Blt_VectorNotify;
+
+typedef struct _Blt_VectorId *Blt_VectorId;
+
+typedef void (Blt_VectorChangedProc)(Tcl_Interp *interp, ClientData clientData,
+	Blt_VectorNotify notify);
+
+typedef struct {
+    double *valueArr;		/* Array of values (possibly malloc-ed) */
+    int numValues;		/* Number of values in the array */
+    int arraySize;		/* Size of the allocated space */
+    double min, max;		/* Minimum and maximum values in the vector */
+    int dirty;			/* Indicates if the vector has been updated */
+    int reserved;		/* Reserved for future use */
+
+} Blt_Vector;
+
+typedef double (Blt_VectorIndexProc)(Blt_Vector * vecPtr);
+
+typedef enum {
+    BLT_MATH_FUNC_SCALAR = 1,	/* The function returns a single double
+				 * precision value. */
+    BLT_MATH_FUNC_VECTOR	/* The function processes the entire vector. */
+} Blt_MathFuncType;
+
+/*
+ * To be safe, use the macros below, rather than the fields of the
+ * structure directly.
+ *
+ * The Blt_Vector is basically an opaque type.  But it's also the
+ * actual memory address of the vector itself.  I wanted to make the
+ * API as unobtrusive as possible.  So instead of giving you a copy of
+ * the vector, providing various functions to access and update the
+ * vector, you get your hands on the actual memory (array of doubles)
+ * shared by all the vector's clients.
+ *
+ * The trade-off for speed and convenience is safety.  You can easily
+ * break things by writing into the vector when other clients are
+ * using it.  Use Blt_ResetVector to get around this.  At least the
+ * macros are a reminder it isn't really safe to reset the data
+ * fields, except by the API routines.  
+ */
+#define Blt_VecData(v)		((v)->valueArr)
+#define Blt_VecLength(v)	((v)->numValues)
+#define Blt_VecSize(v)		((v)->arraySize)
+#define Blt_VecDirty(v)		((v)->dirty)
+
+extern double Blt_VecMin(Blt_Vector *vPtr);
+extern double Blt_VecMax(Blt_Vector *vPtr);
+
+extern Blt_VectorId Blt_AllocVectorId(Tcl_Interp *interp, 
+	const char *vecName);
+
+extern void Blt_SetVectorChangedProc(Blt_VectorId clientId, 
+	Blt_VectorChangedProc *proc, ClientData clientData);
+
+extern void Blt_FreeVectorId(Blt_VectorId clientId);
+
+extern int Blt_GetVectorById(Tcl_Interp *interp, Blt_VectorId clientId, 
+	Blt_Vector **vecPtrPtr);
+
+extern const char *Blt_NameOfVectorId(Blt_VectorId clientId);
+
+extern const char *Blt_NameOfVector(Blt_Vector *vecPtr);
+
+extern int Blt_VectorNotifyPending(Blt_VectorId clientId);
+
+extern int Blt_CreateVector(Tcl_Interp *interp, const char *vecName, 
+	int size, Blt_Vector ** vecPtrPtr);
+
+extern int Blt_CreateVector2(Tcl_Interp *interp, const char *vecName, 
+	const char *cmdName, const char *varName, int initialSize, 
+	Blt_Vector **vecPtrPtr);
+
+extern int Blt_GetVector(Tcl_Interp *interp, const char *vecName, 
+	Blt_Vector **vecPtrPtr);
+
+extern int Blt_GetVectorFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
+	Blt_Vector **vecPtrPtr);
+
+extern int Blt_VectorExists(Tcl_Interp *interp, const char *vecName);
+
+extern int Blt_ResetVector(Blt_Vector *vecPtr, double *dataArr, int n, 
+	int arraySize, Tcl_FreeProc *freeProc);
+
+extern int Blt_ResizeVector(Blt_Vector *vecPtr, int n);
+
+extern int Blt_DeleteVectorByName(Tcl_Interp *interp, const char *vecName);
+
+extern int Blt_DeleteVector(Blt_Vector *vecPtr);
+
+extern int Blt_ExprVector(Tcl_Interp *interp, char *expr, 
+	Blt_Vector *vecPtr);
+
+extern void Blt_InstallIndexProc(Tcl_Interp *interp, const char *indexName,
+	Blt_VectorIndexProc * procPtr);
+
+extern int Blt_VectorExists2(Tcl_Interp *interp, const char *vecName);
+
+#endif /* _BLT_VECTOR_H */
diff --git a/tlt3.0/bltWindow.c b/tlt3.0/bltWindow.c
new file mode 100644
index 0000000..be0255b
--- /dev/null
+++ b/tlt3.0/bltWindow.c
@@ -0,0 +1,247 @@
+/*
+ * bltWindow.c --
+ *
+ * This module implements additional window functions for the BLT
+ * toolkit.
+ *
+ *	Copyright 1991-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person
+ *	obtaining a copy of this software and associated documentation
+ *	files (the "Software"), to deal in the Software without
+ *	restriction, including without limitation the rights to use,
+ *	copy, modify, merge, publish, distribute, sublicense, and/or
+ *	sell copies of the Software, and to permit persons to whom the
+ *	Software is furnished to do so, subject to the following
+ *	conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the
+ *	Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ *	KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ *	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ *	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ *	OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *	OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ *	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ *	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+
+#include <tkPort.h>
+#include <tkInt.h>
+
+#include "bltInt.h"
+#include "bltWindow.h"
+#include "bltHash.h"
+
+/* 
+ * Cache drawable information.
+ *
+ * There are specific times when we need information about the drawable
+ * that is not available via the normal argument passing.  For example,
+ * XFT font rendering requires that the correct depth XftDraw be used.
+ * If we create a painter from a drawable, we need to know its depth,
+ * colormap, and visual also.
+ * 
+ * We can usually get this information using XGetWindowAttributes at
+ * the cost of a round-trip to the X server.  Instead we'll cache it
+ * in a hash table.  We don't have to cache every window. We need to
+ * watch destroy events and freeing pixmaps.
+ */
+
+typedef struct {
+  Display *display;
+  Drawable drawable;
+} DrawableKey;
+
+static Blt_HashTable attribTable;
+static int initialized = FALSE;
+
+Blt_DrawableAttributes* Blt_GetDrawableAttribs(Display *display, 
+					       Drawable drawable)
+{
+  if (drawable != None) {
+    Blt_HashEntry *hPtr;
+    DrawableKey key;
+
+    if (!initialized) {
+      Blt_InitHashTable(&attribTable, sizeof(DrawableKey)/sizeof(int));
+      initialized = TRUE;
+    }
+    memset(&key, 0, sizeof(key));
+    key.drawable = drawable;
+    key.display = display;
+    hPtr = Blt_FindHashEntry(&attribTable, &key);
+    if (hPtr != NULL) {
+      return Blt_GetHashValue(hPtr);
+    }
+  }
+  return NULL;		/* Don't have any information about this
+			 * drawable. */
+}
+
+void Blt_SetDrawableAttribs(Display *display, Drawable drawable, int depth,
+			    int width, int height, Colormap colormap,
+			    Visual *visual)
+{
+  if (drawable != None) {
+    Blt_DrawableAttributes *attrPtr;
+    Blt_HashEntry *hPtr;
+    int isNew;
+    DrawableKey key;
+
+    if (!initialized) {
+      Blt_InitHashTable(&attribTable, sizeof(DrawableKey)/sizeof(int));
+      initialized = TRUE;
+    }
+    memset(&key, 0, sizeof(key));
+    key.drawable = drawable;
+    key.display = display;
+    hPtr = Blt_CreateHashEntry(&attribTable, &key, &isNew);
+    if (isNew) {
+      attrPtr = malloc(sizeof(Blt_DrawableAttributes));
+      Blt_SetHashValue(hPtr, attrPtr);
+    }  else {
+      attrPtr = Blt_GetHashValue(hPtr);
+    }
+    /* Set or reset information for drawable. */
+    attrPtr->id = drawable;
+    attrPtr->depth = depth;
+    attrPtr->colormap = colormap;
+    attrPtr->visual = visual;
+    attrPtr->width = width;
+    attrPtr->height = height;
+  }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FindChild --
+ *
+ *      Performs a linear search for the named child window in a given
+ *	parent window.
+ *
+ *	This can be done via Tcl, but not through Tk's C API.  It's 
+ *	simple enough, if you peek into the Tk_Window structure.
+ *
+ * Results:
+ *      The child Tk_Window. If the named child can't be found, NULL
+ *	is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tk_Window Blt_FindChild(Tk_Window parent, char *name)
+{
+  TkWindow *winPtr;
+  TkWindow *parentPtr = (TkWindow *)parent;
+
+  for (winPtr = parentPtr->childList; winPtr != NULL; 
+       winPtr = winPtr->nextPtr) {
+    if (strcmp(name, winPtr->nameUid) == 0) {
+      return (Tk_Window)winPtr;
+    }
+  }
+  return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FirstChildWindow --
+ *
+ *      Performs a linear search for the named child window in a given
+ *	parent window.
+ *
+ *	This can be done via Tcl, but not through Tk's C API.  It's 
+ *	simple enough, if you peek into the Tk_Window structure.
+ *
+ * Results:
+ *      The child Tk_Window. If the named child can't be found, NULL
+ *	is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tk_Window Blt_FirstChild(Tk_Window parent)
+{
+  TkWindow *parentPtr = (TkWindow *)parent;
+  return (Tk_Window)parentPtr->childList;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_FindChild --
+ *
+ *      Performs a linear search for the named child window in a given
+ *	parent window.
+ *
+ *	This can be done via Tcl, but not through Tk's C API.  It's 
+ *	simple enough, if you peek into the Tk_Window structure.
+ *
+ * Results:
+ *      The child Tk_Window. If the named child can't be found, NULL
+ *	is returned.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tk_Window Blt_NextChild(Tk_Window tkwin)
+{
+  TkWindow *winPtr = (TkWindow *)tkwin;
+
+  if (winPtr == NULL) {
+    return NULL;
+  }
+  return (Tk_Window)winPtr->nextPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Blt_Toplevel --
+ *
+ *      Climbs up the widget hierarchy to find the top level window of
+ *      the window given.
+ *
+ * Results:
+ *      Returns the Tk_Window of the toplevel widget.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tk_Window Blt_Toplevel(Tk_Window tkwin)
+{
+  while (!Tk_IsTopLevel(tkwin)) {
+    tkwin = Tk_Parent(tkwin);
+  }
+  return tkwin;
+}
+
+void Blt_SetWindowInstanceData(Tk_Window tkwin, ClientData instanceData)
+{
+  TkWindow *winPtr = (TkWindow *)tkwin;
+
+  winPtr->instanceData = instanceData;
+}
+
+ClientData Blt_GetWindowInstanceData(Tk_Window tkwin)
+{
+  TkWindow *winPtr;
+
+  while (tkwin != NULL) {
+    winPtr = (TkWindow *)tkwin;
+    if (winPtr->instanceData != NULL) {
+      return (ClientData)winPtr->instanceData;
+    }
+    tkwin = Tk_Parent(tkwin);
+  }
+  return NULL;
+}
diff --git a/tlt3.0/bltWindow.h b/tlt3.0/bltWindow.h
new file mode 100644
index 0000000..503b4cf
--- /dev/null
+++ b/tlt3.0/bltWindow.h
@@ -0,0 +1,58 @@
+/*
+ * bltWindow.h --
+ *
+ *	Copyright 1993-2004 George A Howlett.
+ *
+ *	Permission is hereby granted, free of charge, to any person obtaining
+ *	a copy of this software and associated documentation files (the
+ *	"Software"), to deal in the Software without restriction, including
+ *	without limitation the rights to use, copy, modify, merge, publish,
+ *	distribute, sublicense, and/or sell copies of the Software, and to
+ *	permit persons to whom the Software is furnished to do so, subject to
+ *	the following conditions:
+ *
+ *	The above copyright notice and this permission notice shall be
+ *	included in all copies or substantial portions of the Software.
+ *
+ *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_WINDOW_H
+#define _BLT_WINDOW_H
+
+#include <tk.h>
+
+typedef struct {
+    Drawable id;
+    unsigned short int width, height;
+    int depth;
+    Colormap colormap;
+    Visual *visual;
+} Blt_DrawableAttributes;
+
+extern Blt_DrawableAttributes *Blt_GetDrawableAttribs(Display *display,
+	Drawable drawable);
+
+extern void Blt_SetDrawableAttribs(Display *display, Drawable drawable,
+	int width, int height, int depth, Colormap colormap, Visual *visual);
+
+extern Tk_Window Blt_FindChild(Tk_Window parent, char *name);
+
+extern Tk_Window Blt_FirstChild(Tk_Window parent);
+
+extern Tk_Window Blt_NextChild(Tk_Window tkwin);
+
+extern Tk_Window Blt_Toplevel(Tk_Window tkwin);
+
+extern ClientData Blt_GetWindowInstanceData (Tk_Window tkwin);
+
+extern void Blt_SetWindowInstanceData (Tk_Window tkwin, 
+	ClientData instanceData);
+
+#endif
diff --git a/tlt3.0/configure b/tlt3.0/configure
new file mode 100755
index 0000000..04e3aa3
--- /dev/null
+++ b/tlt3.0/configure
@@ -0,0 +1,10699 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for tlt 3.0.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='tlt'
+PACKAGE_TARNAME='tlt'
+PACKAGE_VERSION='3.0'
+PACKAGE_STRING='tlt 3.0'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+TCLSH_PROG
+XFT_LIBS
+XFT_CFLAGS
+XMKMF
+VC_MANIFEST_EMBED_EXE
+VC_MANIFEST_EMBED_DLL
+RANLIB_STUB
+MAKE_STUB_LIB
+MAKE_STATIC_LIB
+MAKE_SHARED_LIB
+MAKE_LIB
+TCL_DBGX
+LDFLAGS_DEFAULT
+CFLAGS_DEFAULT
+LD_LIBRARY_PATH_VAR
+SHLIB_CFLAGS
+SHLIB_LD_LIBS
+SHLIB_LD
+STLIB_LD
+CFLAGS_WARNING
+CFLAGS_OPTIMIZE
+CFLAGS_DEBUG
+RC
+CELIB_DIR
+AR
+SHARED_BUILD
+TCL_THREADS
+TK_XLIB_DIR_NATIVE
+TK_TOP_DIR_NATIVE
+TK_INCLUDES
+TCL_TOP_DIR_NATIVE
+TCL_INCLUDES
+PKG_OBJECTS
+PKG_SOURCES
+MATH_LIBS
+EGREP
+GREP
+RANLIB
+SET_MAKE
+INSTALL
+CPP
+TK_XINCLUDES
+TK_LIBS
+TK_STUB_LIB_SPEC
+TK_STUB_LIB_FLAG
+TK_STUB_LIB_FILE
+TK_LIB_SPEC
+TK_LIB_FLAG
+TK_LIB_FILE
+TK_SRC_DIR
+TK_BIN_DIR
+TK_VERSION
+TCL_SHLIB_LD_LIBS
+TCL_LD_FLAGS
+TCL_EXTRA_CFLAGS
+TCL_DEFS
+TCL_LIBS
+CLEANFILES
+OBJEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+TCL_STUB_LIB_SPEC
+TCL_STUB_LIB_FLAG
+TCL_STUB_LIB_FILE
+TCL_LIB_SPEC
+TCL_LIB_FLAG
+TCL_LIB_FILE
+TCL_SRC_DIR
+TCL_BIN_DIR
+TCL_PATCH_LEVEL
+TCL_VERSION
+PKG_CFLAGS
+PKG_LIBS
+PKG_INCLUDES
+PKG_HEADERS
+PKG_TCL_SOURCES
+PKG_STUB_OBJECTS
+PKG_STUB_SOURCES
+PKG_STUB_LIB_FILE
+PKG_LIB_FILE
+EXEEXT
+CYGPATH
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_tcl
+with_tk
+with_tclinclude
+with_tkinclude
+enable_threads
+enable_shared
+enable_64bit
+enable_64bit_vis
+enable_rpath
+enable_wince
+with_celib
+enable_symbols
+with_x
+enable_xft
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+XMKMF'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures tlt 3.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/tlt]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+X features:
+  --x-includes=DIR    X include files are in DIR
+  --x-libraries=DIR   X library files are in DIR
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of tlt 3.0:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-threads        build with threads
+  --enable-shared         build and link with shared libraries (default: on)
+  --enable-64bit          enable 64bit support (default: off)
+  --enable-64bit-vis      enable 64bit Sparc VIS support (default: off)
+  --disable-rpath         disable rpath support (default: on)
+  --enable-wince          enable Win/CE support (where applicable)
+  --enable-symbols        build with debugging symbols (default: off)
+  --enable-xft            use freetype/fontconfig/xft (default: on)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-tcl              directory containing tcl configuration
+                          (tclConfig.sh)
+  --with-tk               directory containing tk configuration (tkConfig.sh)
+  --with-tclinclude       directory containing the public Tcl header files
+  --with-tkinclude        directory containing the public Tk header files
+  --with-celib=DIR        use Windows/CE support library from DIR
+  --with-x                use the X Window System
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+  XMKMF       Path to xmkmf, Makefile generator for X Window System
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+tlt configure 3.0
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by tlt $as_me 3.0, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.9"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
+$as_echo_n "checking for correct TEA configuration... " >&6; }
+    if test x"${PACKAGE_NAME}" = x ; then
+	as_fn_error $? "
+The PACKAGE_NAME variable must be defined by your TEA configure.in" "$LINENO" 5
+    fi
+    if test x"3.9" = x ; then
+	as_fn_error $? "
+TEA version not specified." "$LINENO" 5
+    elif test "3.9" != "${TEA_VERSION}" ; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&5
+$as_echo "warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&6; }
+    else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (TEA ${TEA_VERSION})" >&5
+$as_echo "ok (TEA ${TEA_VERSION})" >&6; }
+    fi
+
+    # If the user did not set CFLAGS, set it now to keep macros
+    # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+	CFLAGS=""
+    fi
+
+    case "`uname -s`" in
+	*win32*|*WIN32*|*MINGW32_*)
+	    # Extract the first word of "cygpath", so it can be a program name with args.
+set dummy cygpath; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CYGPATH+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CYGPATH"; then
+  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CYGPATH="cygpath -w"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
+fi
+fi
+CYGPATH=$ac_cv_prog_CYGPATH
+if test -n "$CYGPATH"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
+$as_echo "$CYGPATH" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+	    EXEEXT=".exe"
+	    TEA_PLATFORM="windows"
+	    ;;
+	*CYGWIN_*)
+	    CYGPATH=echo
+	    EXEEXT=".exe"
+	    # TEA_PLATFORM is determined later in LOAD_TCLCONFIG
+	    ;;
+	*)
+	    CYGPATH=echo
+	    # Maybe we are cross-compiling....
+	    case ${host_alias} in
+		*mingw32*)
+		EXEEXT=".exe"
+		TEA_PLATFORM="windows"
+		;;
+	    *)
+		EXEEXT=""
+		TEA_PLATFORM="unix"
+		;;
+	    esac
+	    ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+	exec_prefix_default=yes
+	exec_prefix=$prefix
+    fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&5
+$as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
+
+
+
+
+    # This package name must be replaced statically for AC_SUBST to work
+
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in tclconfig "$srcdir"/tclconfig; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in tclconfig \"$srcdir\"/tclconfig" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+
+
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+	# we reset no_tcl in case something fails here
+	no_tcl=true
+
+# Check whether --with-tcl was given.
+if test "${with_tcl+set}" = set; then :
+  withval=$with_tcl; with_tclconfig="${withval}"
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
+$as_echo_n "checking for Tcl configuration... " >&6; }
+	if ${ac_cv_c_tclconfig+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+
+	    # First check to see if --with-tcl was specified.
+	    if test x"${with_tclconfig}" != x ; then
+		case "${with_tclconfig}" in
+		    */tclConfig.sh )
+			if test -f "${with_tclconfig}"; then
+			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
+$as_echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
+			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
+			fi ;;
+		esac
+		if test -f "${with_tclconfig}/tclConfig.sh" ; then
+		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
+		else
+		    as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5
+		fi
+	    fi
+
+	    # then check for a private Tcl installation
+	    if test x"${ac_cv_c_tclconfig}" = x ; then
+		for i in \
+			../tcl \
+			`ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+			`ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \
+			`ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
+			../../tcl \
+			`ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+			`ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \
+			`ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
+			../../../tcl \
+			`ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+			`ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \
+			`ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do
+		    if test "${TEA_PLATFORM}" = "windows" \
+			    -a -f "$i/win/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+			break
+		    fi
+		    if test -f "$i/unix/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # on Darwin, check in Framework installation locations
+	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+			`ls -d /Library/Frameworks 2>/dev/null` \
+			`ls -d /Network/Library/Frameworks 2>/dev/null` \
+			`ls -d /System/Library/Frameworks 2>/dev/null` \
+			; do
+		    if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # TEA specific: on Windows, check in common installation locations
+	    if test "${TEA_PLATFORM}" = "windows" \
+		-a x"${ac_cv_c_tclconfig}" = x ; then
+		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+			; do
+		    if test -f "$i/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # check in a few common install locations
+	    if test x"${ac_cv_c_tclconfig}" = x ; then
+		for i in `ls -d ${libdir} 2>/dev/null` \
+			`ls -d ${exec_prefix}/lib 2>/dev/null` \
+			`ls -d ${prefix}/lib 2>/dev/null` \
+			`ls -d /usr/local/lib 2>/dev/null` \
+			`ls -d /usr/contrib/lib 2>/dev/null` \
+			`ls -d /usr/lib 2>/dev/null` \
+			`ls -d /usr/lib64 2>/dev/null` \
+			; do
+		    if test -f "$i/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # check in a few other private locations
+	    if test x"${ac_cv_c_tclconfig}" = x ; then
+		for i in \
+			${srcdir}/../tcl \
+			`ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+			`ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \
+			`ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
+		    if test "${TEA_PLATFORM}" = "windows" \
+			    -a -f "$i/win/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+			break
+		    fi
+		    if test -f "$i/unix/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+fi
+
+
+	if test x"${ac_cv_c_tclconfig}" = x ; then
+	    TCL_BIN_DIR="# no Tcl configs found"
+	    as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5
+	else
+	    no_tcl=
+	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
+$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
+	fi
+    fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
+$as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; }
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
+$as_echo "loading" >&6; }
+	. "${TCL_BIN_DIR}/tclConfig.sh"
+    else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
+$as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
+        TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
+        TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
+    elif test "`uname -s`" = "Darwin"; then
+	# If Tcl was built as a framework, attempt to use the libraries
+	# from the framework at the given location so that linking works
+	# against Tcl.framework installed in an arbitrary location.
+	case ${TCL_DEFS} in
+	    *TCL_FRAMEWORK*)
+		if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+		    for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
+			     "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
+			if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+			    TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
+			    break
+			fi
+		    done
+		fi
+		if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+		    TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
+		    TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+		fi
+		;;
+	esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking platform" >&5
+$as_echo_n "checking platform... " >&6; }
+    hold_cc=$CC; CC="$TCL_CC"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+	    #ifdef _WIN32
+		#error win32
+	    #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  TEA_PLATFORM="unix"
+else
+  TEA_PLATFORM="windows"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    CC=$hold_cc
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEA_PLATFORM" >&5
+$as_echo "$TEA_PLATFORM" >&6; }
+
+    # The BUILD_$pkg is to define the correct extern storage class
+    # handling when making this package
+
+cat >>confdefs.h <<_ACEOF
+#define BUILD_${PACKAGE_NAME} /**/
+_ACEOF
+
+    # Do this here as we have fully defined TEA_PLATFORM now
+    if test "${TEA_PLATFORM}" = "windows" ; then
+	EXEEXT=".exe"
+	CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
+    fi
+
+    # TEA specific:
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# Load the tkConfig.sh file if necessary (Tk extension)
+#--------------------------------------------------------------------
+
+
+    #
+    # Ok, lets find the tk configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tk
+    #
+
+    if test x"${no_tk}" = x ; then
+	# we reset no_tk in case something fails here
+	no_tk=true
+
+# Check whether --with-tk was given.
+if test "${with_tk+set}" = set; then :
+  withval=$with_tk; with_tkconfig="${withval}"
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk configuration" >&5
+$as_echo_n "checking for Tk configuration... " >&6; }
+	if ${ac_cv_c_tkconfig+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+
+	    # First check to see if --with-tkconfig was specified.
+	    if test x"${with_tkconfig}" != x ; then
+		case "${with_tkconfig}" in
+		    */tkConfig.sh )
+			if test -f "${with_tkconfig}"; then
+			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&5
+$as_echo "$as_me: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&2;}
+			    with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
+			fi ;;
+		esac
+		if test -f "${with_tkconfig}/tkConfig.sh" ; then
+		    ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
+		else
+		    as_fn_error $? "${with_tkconfig} directory doesn't contain tkConfig.sh" "$LINENO" 5
+		fi
+	    fi
+
+	    # then check for a private Tk library
+	    if test x"${ac_cv_c_tkconfig}" = x ; then
+		for i in \
+			../tk \
+			`ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \
+			`ls -dr ../tk[8-9].[0-9] 2>/dev/null` \
+			`ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \
+			../../tk \
+			`ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \
+			`ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \
+			`ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \
+			../../../tk \
+			`ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \
+			`ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \
+			`ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do
+		    if test "${TEA_PLATFORM}" = "windows" \
+			    -a -f "$i/win/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+			break
+		    fi
+		    if test -f "$i/unix/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # on Darwin, check in Framework installation locations
+	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+			`ls -d /Library/Frameworks 2>/dev/null` \
+			`ls -d /Network/Library/Frameworks 2>/dev/null` \
+			`ls -d /System/Library/Frameworks 2>/dev/null` \
+			; do
+		    if test -f "$i/Tk.framework/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # check in a few common install locations
+	    if test x"${ac_cv_c_tkconfig}" = x ; then
+		for i in `ls -d ${libdir} 2>/dev/null` \
+			`ls -d ${exec_prefix}/lib 2>/dev/null` \
+			`ls -d ${prefix}/lib 2>/dev/null` \
+			`ls -d /usr/local/lib 2>/dev/null` \
+			`ls -d /usr/contrib/lib 2>/dev/null` \
+			`ls -d /usr/lib 2>/dev/null` \
+			`ls -d /usr/lib64 2>/dev/null` \
+			; do
+		    if test -f "$i/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # TEA specific: on Windows, check in common installation locations
+	    if test "${TEA_PLATFORM}" = "windows" \
+		-a x"${ac_cv_c_tkconfig}" = x ; then
+		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+			; do
+		    if test -f "$i/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # check in a few other private locations
+	    if test x"${ac_cv_c_tkconfig}" = x ; then
+		for i in \
+			${srcdir}/../tk \
+			`ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \
+			`ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \
+			`ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do
+		    if test "${TEA_PLATFORM}" = "windows" \
+			    -a -f "$i/win/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+			break
+		    fi
+		    if test -f "$i/unix/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+fi
+
+
+	if test x"${ac_cv_c_tkconfig}" = x ; then
+	    TK_BIN_DIR="# no Tk configs found"
+	    as_fn_error $? "Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh" "$LINENO" 5
+	else
+	    no_tk=
+	    TK_BIN_DIR="${ac_cv_c_tkconfig}"
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TK_BIN_DIR}/tkConfig.sh" >&5
+$as_echo "found ${TK_BIN_DIR}/tkConfig.sh" >&6; }
+	fi
+    fi
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5
+$as_echo_n "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... " >&6; }
+
+    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
+$as_echo "loading" >&6; }
+	. "${TK_BIN_DIR}/tkConfig.sh"
+    else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5
+$as_echo "could not find ${TK_BIN_DIR}/tkConfig.sh" >&6; }
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+    eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+    # If the TK_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TK_LIB_SPEC will be set to the value
+    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+    # instead of TK_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
+        TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
+        TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
+    elif test "`uname -s`" = "Darwin"; then
+	# If Tk was built as a framework, attempt to use the libraries
+	# from the framework at the given location so that linking works
+	# against Tk.framework installed in an arbitrary location.
+	case ${TK_DEFS} in
+	    *TK_FRAMEWORK*)
+		if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+		    for i in "`cd "${TK_BIN_DIR}"; pwd`" \
+			     "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
+			if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+			    TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
+			    break
+			fi
+		    done
+		fi
+		if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+		    TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
+		    TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+		fi
+		;;
+	esac
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+    # TEA specific: Ensure windowingsystem is defined
+    if test "${TEA_PLATFORM}" = "unix" ; then
+	case ${TK_DEFS} in
+	    *MAC_OSX_TK*)
+
+$as_echo "#define MAC_OSX_TK 1" >>confdefs.h
+
+		TEA_WINDOWINGSYSTEM="aqua"
+		;;
+	    *)
+		TEA_WINDOWINGSYSTEM="x11"
+		;;
+	esac
+    elif test "${TEA_PLATFORM}" = "windows" ; then
+	TEA_WINDOWINGSYSTEM="win32"
+    fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # TEA specific:
+
+
+
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+
+    if test "${prefix}" = "NONE"; then
+	prefix_default=yes
+	if test x"${TCL_PREFIX}" != x; then
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5
+$as_echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;}
+	    prefix=${TCL_PREFIX}
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: --prefix defaulting to /usr/local" >&5
+$as_echo "$as_me: --prefix defaulting to /usr/local" >&6;}
+	    prefix=/usr/local
+	fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+	-o x"${exec_prefix_default}" = x"yes" ; then
+	if test x"${TCL_EXEC_PREFIX}" != x; then
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5
+$as_echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;}
+	    exec_prefix=${TCL_EXEC_PREFIX}
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: --exec-prefix defaulting to ${prefix}" >&5
+$as_echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;}
+	    exec_prefix=$prefix
+	fi
+    fi
+
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC and a few others to create the basic setup
+# necessary to compile executables.
+#-----------------------------------------------------------------------
+
+
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+    INSTALL="\$(SHELL) \$(srcdir)/tclconfig/install-sh -c"
+
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -pipe" >&5
+$as_echo_n "checking if the compiler understands -pipe... " >&6; }
+if ${tcl_cv_cc_pipe+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_cc_pipe=yes
+else
+  tcl_cv_cc_pipe=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+	    CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_pipe" >&5
+$as_echo "$tcl_cv_cc_pipe" >&6; }
+	if test $tcl_cv_cc_pipe = yes; then
+	    CFLAGS="$CFLAGS -pipe"
+	fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __APPLE_CC__
+	       not a universal capable compiler
+	     #endif
+	     typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+	# Check for potential -arch flags.  It is not universal unless
+	# there are at least two -arch flags with different values.
+	ac_arch=
+	ac_prev=
+	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+	 if test -n "$ac_prev"; then
+	   case $ac_word in
+	     i?86 | x86_64 | ppc | ppc64)
+	       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+		 ac_arch=$ac_word
+	       else
+		 ac_cv_c_bigendian=universal
+		 break
+	       fi
+	       ;;
+	   esac
+	   ac_prev=
+	 elif test "x$ac_word" = "x-arch"; then
+	   ac_prev=arch
+	 fi
+       done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+	     #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+		     && LITTLE_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+		#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to _BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # Compile a test program.
+      if test "$cross_compiling" = yes; then :
+  # Try to guess by grepping values from an object file.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+short int ascii_mm[] =
+		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+		short int ascii_ii[] =
+		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+		int use_ascii (int i) {
+		  return ascii_mm[i] + ascii_ii[i];
+		}
+		short int ebcdic_ii[] =
+		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+		short int ebcdic_mm[] =
+		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+		int use_ebcdic (int i) {
+		  return ebcdic_mm[i] + ebcdic_ii[i];
+		}
+		extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+	      ac_cv_c_bigendian=yes
+	    fi
+	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+	      if test "$ac_cv_c_bigendian" = unknown; then
+		ac_cv_c_bigendian=no
+	      else
+		# finding both strings is unlikely to happen, but who knows?
+		ac_cv_c_bigendian=unknown
+	      fi
+	    fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+	     /* Are we little or big endian?  From Harbison&Steele.  */
+	     union
+	     {
+	       long int l;
+	       char c[sizeof (long int)];
+	     } u;
+	     u.l = 1;
+	     return u.c[sizeof (long int) - 1] == 1;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_bigendian=no
+else
+  ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+    fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+   yes)
+     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+   no)
+      ;; #(
+   universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+     ;; #(
+   *)
+     as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+    if test "${TEA_PLATFORM}" = "unix" ; then
+
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    ac_fn_c_check_func "$LINENO" "sin" "ac_cv_func_sin"
+if test "x$ac_cv_func_sin" = xyes; then :
+  MATH_LIBS=""
+else
+  MATH_LIBS="-lm"
+fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lieee" >&5
+$as_echo_n "checking for main in -lieee... " >&6; }
+if ${ac_cv_lib_ieee_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lieee  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_ieee_main=yes
+else
+  ac_cv_lib_ieee_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee_main" >&5
+$as_echo "$ac_cv_lib_ieee_main" >&6; }
+if test "x$ac_cv_lib_ieee_main" = xyes; then :
+  MATH_LIBS="-lieee $MATH_LIBS"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -linet" >&5
+$as_echo_n "checking for main in -linet... " >&6; }
+if ${ac_cv_lib_inet_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_inet_main=yes
+else
+  ac_cv_lib_inet_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_main" >&5
+$as_echo "$ac_cv_lib_inet_main" >&6; }
+if test "x$ac_cv_lib_inet_main" = xyes; then :
+  LIBS="$LIBS -linet"
+fi
+
+    ac_fn_c_check_header_mongrel "$LINENO" "net/errno.h" "ac_cv_header_net_errno_h" "$ac_includes_default"
+if test "x$ac_cv_header_net_errno_h" = xyes; then :
+
+
+$as_echo "#define HAVE_NET_ERRNO_H 1" >>confdefs.h
+
+fi
+
+
+
+    #--------------------------------------------------------------------
+    #	Check for the existence of the -lsocket and -lnsl libraries.
+    #	The order here is important, so that they end up in the right
+    #	order in the command line generated by make.  Here are some
+    #	special considerations:
+    #	1. Use "connect" and "accept" to check for -lsocket, and
+    #	   "gethostbyname" to check for -lnsl.
+    #	2. Use each function name only once:  can't redo a check because
+    #	   autoconf caches the results of the last check and won't redo it.
+    #	3. Use -lnsl and -lsocket only if they supply procedures that
+    #	   aren't already present in the normal libraries.  This is because
+    #	   IRIX 5.2 has libraries, but they aren't needed and they're
+    #	   bogus:  they goof up name resolution if used.
+    #	4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #	   To get around this problem, check for both libraries together
+    #	   if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect"
+if test "x$ac_cv_func_connect" = xyes; then :
+  tcl_checkSocket=0
+else
+  tcl_checkSocket=1
+fi
+
+    if test "$tcl_checkSocket" = 1; then
+	ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt"
+if test "x$ac_cv_func_setsockopt" = xyes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5
+$as_echo_n "checking for setsockopt in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_setsockopt+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_socket_setsockopt=yes
+else
+  ac_cv_lib_socket_setsockopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5
+$as_echo "$ac_cv_lib_socket_setsockopt" >&6; }
+if test "x$ac_cv_lib_socket_setsockopt" = xyes; then :
+  LIBS="$LIBS -lsocket"
+else
+  tcl_checkBoth=1
+fi
+
+fi
+
+    fi
+    if test "$tcl_checkBoth" = 1; then
+	tk_oldLibs=$LIBS
+	LIBS="$LIBS -lsocket -lnsl"
+	ac_fn_c_check_func "$LINENO" "accept" "ac_cv_func_accept"
+if test "x$ac_cv_func_accept" = xyes; then :
+  tcl_checkNsl=0
+else
+  LIBS=$tk_oldLibs
+fi
+
+    fi
+    ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
+$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
+$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
+  LIBS="$LIBS -lnsl"
+fi
+
+fi
+
+
+    # TEA specific: Don't perform the eval of the libraries here because
+    # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dirent.h" >&5
+$as_echo_n "checking dirent.h... " >&6; }
+if ${tcl_cv_dirent_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <dirent.h>
+int
+main ()
+{
+
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+	/*
+	 * Generate compilation error to make the test fail:  Lynx headers
+	 * are only valid if really in the POSIX environment.
+	 */
+
+	missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_dirent_h=yes
+else
+  tcl_cv_dirent_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_dirent_h" >&5
+$as_echo "$tcl_cv_dirent_h" >&6; }
+
+    if test $tcl_cv_dirent_h = no; then
+
+$as_echo "#define NO_DIRENT_H 1" >>confdefs.h
+
+    fi
+
+    # TEA specific:
+    ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
+if test "x$ac_cv_header_errno_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_ERRNO_H 1" >>confdefs.h
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default"
+if test "x$ac_cv_header_float_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_FLOAT_H 1" >>confdefs.h
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "values.h" "ac_cv_header_values_h" "$ac_includes_default"
+if test "x$ac_cv_header_values_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_VALUES_H 1" >>confdefs.h
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = xyes; then :
+
+$as_echo "#define HAVE_LIMITS_H 1" >>confdefs.h
+
+else
+
+$as_echo "#define NO_LIMITS_H 1" >>confdefs.h
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtol" >/dev/null 2>&1; then :
+
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtoul" >/dev/null 2>&1; then :
+
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtod" >/dev/null 2>&1; then :
+
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    if test $tcl_ok = 0; then
+
+$as_echo "#define NO_STDLIB_H 1" >>confdefs.h
+
+    fi
+    ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes; then :
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strstr" >/dev/null 2>&1; then :
+
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strerror" >/dev/null 2>&1; then :
+
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+
+$as_echo "#define NO_STRING_H 1" >>confdefs.h
+
+    fi
+
+    ac_fn_c_check_header_mongrel "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_wait_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+
+    ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_DLFCN_H 1" >>confdefs.h
+
+fi
+
+
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+    for ac_header in sys/param.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_param_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_PARAM_H 1
+_ACEOF
+
+fi
+
+done
+
+
+	# Let the user call this, because if it triggers, they will
+	# need a compat/strtod.c that is correct.  Users can also
+	# use Tcl_GetDouble(FromObj) instead.
+	#TEA_BUGGY_STRTOD
+    fi
+
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+    vars="
+	bltBase64.c
+	bltBgStyle.c
+	bltBind.c
+	bltBitmap.c
+	bltChain.c
+	bltConfig.c
+	bltDBuffer.c
+	bltGrAxis.c
+	bltGrBar.c
+	bltGrElem.c
+	bltGrHairs.c
+	bltGrLegd.c
+	bltGrLine.c
+	bltGrMarker.c
+	bltGrMisc.c
+	bltGrPen.c
+	bltGrPs.c
+	bltGraph.c
+	bltHash.c
+	bltImage.c
+	bltInt.c
+	bltInit.c
+	bltList.c
+	bltNsUtil.c
+	bltParse.c
+	bltPool.c
+	bltPs.c
+	bltPsAfm.c
+	bltSpline.c
+	bltSwitch.c
+	bltText.c
+	bltUnixFont.c
+	bltUnixWindow.c
+	bltUtil.c
+	bltVecCmd.c
+	bltVecMath.c
+	bltVector.c
+	bltWindow.c
+	"
+    for i in $vars; do
+	case $i in
+	    \$*)
+		# allow $-var names
+		PKG_SOURCES="$PKG_SOURCES $i"
+		PKG_OBJECTS="$PKG_OBJECTS $i"
+		;;
+	    *)
+		# check for existence - allows for generic/win/unix VPATH
+		# To add more dirs here (like 'src'), you have to update VPATH
+		# in Makefile.in as well
+		if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+		    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+		    -a ! -f "${srcdir}/macosx/$i" \
+		    ; then
+		    as_fn_error $? "could not find source file '$i'" "$LINENO" 5
+		fi
+		PKG_SOURCES="$PKG_SOURCES $i"
+		# this assumes it is in a VPATH dir
+		i=`basename $i`
+		# handle user calling this before or after TEA_SETUP_COMPILER
+		if test x"${OBJEXT}" != x ; then
+		    j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+		else
+		    j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+		fi
+		PKG_OBJECTS="$PKG_OBJECTS $j"
+		;;
+	esac
+    done
+
+
+
+
+    vars="bltVector.h"
+    for i in $vars; do
+	# check for existence, be strict because it is installed
+	if test ! -f "${srcdir}/$i" ; then
+	    as_fn_error $? "could not find header file '${srcdir}/$i'" "$LINENO" 5
+	fi
+	PKG_HEADERS="$PKG_HEADERS $i"
+    done
+
+
+
+    vars="-I. -I\"`${CYGPATH} ${srcdir}`\""
+    for i in $vars; do
+	PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+
+
+
+    vars=""
+    for i in $vars; do
+	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+	    # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+	    i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+	fi
+	PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+
+    PKG_CFLAGS="$PKG_CFLAGS -Wunused"
+
+
+
+    vars=""
+    for i in $vars; do
+	# check for existence - allows for generic/win/unix VPATH
+	if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+	    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+	    -a ! -f "${srcdir}/macosx/$i" \
+	    ; then
+	    as_fn_error $? "could not find stub source file '$i'" "$LINENO" 5
+	fi
+	PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+	# this assumes it is in a VPATH dir
+	i=`basename $i`
+	# handle user calling this before or after TEA_SETUP_COMPILER
+	if test x"${OBJEXT}" != x ; then
+	    j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+	else
+	    j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+	fi
+	PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+
+
+
+
+    vars="library/graph.tcl library/bltGraph.pro"
+    for i in $vars; do
+	# check for existence, be strict because it is installed
+	if test ! -f "${srcdir}/$i" ; then
+	    as_fn_error $? "could not find tcl source file '${srcdir}/$i'" "$LINENO" 5
+	fi
+	PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+
+
+
+#--------------------------------------------------------------------
+# __CHANGE__
+#
+# You can add more files to clean if your extension creates any extra
+# files by extending CLEANFILES.
+# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
+# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
+#
+# A few miscellaneous platform-specific items:
+# TEA_ADD_* any platform specific compiler/build info here.
+#--------------------------------------------------------------------
+
+CLEANFILES="$CLEANFILES config.status config.log Makefile"
+if test "${TEA_PLATFORM}" = "windows" ; then
+    # Ensure no empty if clauses
+    :
+    #TEA_ADD_SOURCES([win/winFile.c])
+    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+    # Ensure no empty else clauses
+    :
+    #TEA_ADD_SOURCES([unix/unixFile.c])
+    #TEA_ADD_LIBS([-lsuperfly])
+fi
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# Choose which headers you need.  Extension authors should try very
+# hard to only rely on the Tcl public header files.  Internal headers
+# contain private data structures and are subject to change without
+# notice.
+# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
+#--------------------------------------------------------------------
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl public headers" >&5
+$as_echo_n "checking for Tcl public headers... " >&6; }
+
+
+# Check whether --with-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then :
+  withval=$with_tclinclude; with_tclinclude=${withval}
+fi
+
+
+    if ${ac_cv_c_tclh+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	# Use the value from --with-tclinclude, if it was given
+
+	if test x"${with_tclinclude}" != x ; then
+	    if test -f "${with_tclinclude}/tcl.h" ; then
+		ac_cv_c_tclh=${with_tclinclude}
+	    else
+		as_fn_error $? "${with_tclinclude} directory does not contain tcl.h" "$LINENO" 5
+	    fi
+	else
+	    list=""
+	    if test "`uname -s`" = "Darwin"; then
+		# If Tcl was built as a framework, attempt to use
+		# the framework's Headers directory
+		case ${TCL_DEFS} in
+		    *TCL_FRAMEWORK*)
+			list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+			;;
+		esac
+	    fi
+
+	    # Look in the source dir only if Tcl is not installed,
+	    # and in that situation, look there before installed locations.
+	    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+		list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+	    fi
+
+	    # Check order: pkg --prefix location, Tcl's --prefix location,
+	    # relative to directory of tclConfig.sh.
+
+	    eval "temp_includedir=${includedir}"
+	    list="$list \
+		`ls -d ${temp_includedir}        2>/dev/null` \
+		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+		list="$list /usr/local/include /usr/include"
+		if test x"${TCL_INCLUDE_SPEC}" != x ; then
+		    d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+		    list="$list `ls -d ${d} 2>/dev/null`"
+		fi
+	    fi
+	    for i in $list ; do
+		if test -f "$i/tcl.h" ; then
+		    ac_cv_c_tclh=$i
+		    break
+		fi
+	    done
+	fi
+
+fi
+
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+	as_fn_error $? "tcl.h not found.  Please specify its location with --with-tclinclude" "$LINENO" 5
+    else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_cv_c_tclh}" >&5
+$as_echo "${ac_cv_c_tclh}" >&6; }
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+
+
+
+    # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl private include files" >&5
+$as_echo_n "checking for Tcl private include files... " >&6; }
+
+    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+    # Check to see if tcl<Plat>Port.h isn't already with the public headers
+    # Don't look for tclInt.h because that resides with tcl.h in the core
+    # sources, but the <plat>Port headers are in a different directory
+    if test "${TEA_PLATFORM}" = "windows" -a \
+	-f "${ac_cv_c_tclh}/tclWinPort.h"; then
+	result="private headers found with public headers"
+    elif test "${TEA_PLATFORM}" = "unix" -a \
+	-f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+	result="private headers found with public headers"
+    else
+	TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+	if test "${TEA_PLATFORM}" = "windows"; then
+	    TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+	else
+	    TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+	fi
+	# Overwrite the previous TCL_INCLUDES as this should capture both
+	# public and private headers in the same set.
+	# We want to ensure these are substituted so as not to require
+	# any *_NATIVE vars be defined in the Makefile
+	TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+	if test "`uname -s`" = "Darwin"; then
+            # If Tcl was built as a framework, attempt to use
+            # the framework's Headers and PrivateHeaders directories
+            case ${TCL_DEFS} in
+	    	*TCL_FRAMEWORK*)
+		    if test -d "${TCL_BIN_DIR}/Headers" -a \
+			    -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+			TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+		    else
+			TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+		    fi
+	            ;;
+	    esac
+	    result="Using ${TCL_INCLUDES}"
+	else
+	    if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+		as_fn_error $? "Cannot find private header tclInt.h in ${TCL_SRC_DIR}" "$LINENO" 5
+	    fi
+	    result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+	fi
+    fi
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${result}" >&5
+$as_echo "${result}" >&6; }
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk public headers" >&5
+$as_echo_n "checking for Tk public headers... " >&6; }
+
+
+# Check whether --with-tkinclude was given.
+if test "${with_tkinclude+set}" = set; then :
+  withval=$with_tkinclude; with_tkinclude=${withval}
+fi
+
+
+    if ${ac_cv_c_tkh+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	# Use the value from --with-tkinclude, if it was given
+
+	if test x"${with_tkinclude}" != x ; then
+	    if test -f "${with_tkinclude}/tk.h" ; then
+		ac_cv_c_tkh=${with_tkinclude}
+	    else
+		as_fn_error $? "${with_tkinclude} directory does not contain tk.h" "$LINENO" 5
+	    fi
+	else
+	    list=""
+	    if test "`uname -s`" = "Darwin"; then
+		# If Tk was built as a framework, attempt to use
+		# the framework's Headers directory.
+		case ${TK_DEFS} in
+		    *TK_FRAMEWORK*)
+			list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+			;;
+		esac
+	    fi
+
+	    # Look in the source dir only if Tk is not installed,
+	    # and in that situation, look there before installed locations.
+	    if test -f "${TK_BIN_DIR}/Makefile" ; then
+		list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+	    fi
+
+	    # Check order: pkg --prefix location, Tk's --prefix location,
+	    # relative to directory of tkConfig.sh, Tcl's --prefix location,
+	    # relative to directory of tclConfig.sh.
+
+	    eval "temp_includedir=${includedir}"
+	    list="$list \
+		`ls -d ${temp_includedir}        2>/dev/null` \
+		`ls -d ${TK_PREFIX}/include      2>/dev/null` \
+		`ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
+		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+		list="$list /usr/local/include /usr/include"
+		if test x"${TK_INCLUDE_SPEC}" != x ; then
+		    d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+		    list="$list `ls -d ${d} 2>/dev/null`"
+		fi
+	    fi
+	    for i in $list ; do
+		if test -f "$i/tk.h" ; then
+		    ac_cv_c_tkh=$i
+		    break
+		fi
+	    done
+	fi
+
+fi
+
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tkh}" = x ; then
+	as_fn_error $? "tk.h not found.  Please specify its location with --with-tkinclude" "$LINENO" 5
+    else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_cv_c_tkh}" >&5
+$as_echo "${ac_cv_c_tkh}" >&6; }
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+    TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+
+
+    if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+	# On Windows and Aqua, we need the X compat headers
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11 header files" >&5
+$as_echo_n "checking for X11 header files... " >&6; }
+	if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+	    INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+	    TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${INCLUDE_DIR_NATIVE}" >&5
+$as_echo "${INCLUDE_DIR_NATIVE}" >&6; }
+    fi
+
+
+    # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk private include files" >&5
+$as_echo_n "checking for Tk private include files... " >&6; }
+
+    TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+    TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+
+    # Check to see if tk<Plat>Port.h isn't already with the public headers
+    # Don't look for tkInt.h because that resides with tk.h in the core
+    # sources, but the <plat>Port headers are in a different directory
+    if test "${TEA_PLATFORM}" = "windows" -a \
+	-f "${ac_cv_c_tkh}/tkWinPort.h"; then
+	result="private headers found with public headers"
+    elif test "${TEA_PLATFORM}" = "unix" -a \
+	-f "${ac_cv_c_tkh}/tkUnixPort.h"; then
+	result="private headers found with public headers"
+    else
+	TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+	TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+	if test "${TEA_PLATFORM}" = "windows"; then
+	    TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+	else
+	    TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+	fi
+	# Overwrite the previous TK_INCLUDES as this should capture both
+	# public and private headers in the same set.
+	# We want to ensure these are substituted so as not to require
+	# any *_NATIVE vars be defined in the Makefile
+	TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+	# Detect and add ttk subdir
+	if test -d "${TK_SRC_DIR}/generic/ttk"; then
+	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
+	fi
+	if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+	fi
+	if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+	fi
+	if test "`uname -s`" = "Darwin"; then
+	    # If Tk was built as a framework, attempt to use
+	    # the framework's Headers and PrivateHeaders directories
+	    case ${TK_DEFS} in
+		*TK_FRAMEWORK*)
+			if test -d "${TK_BIN_DIR}/Headers" -a \
+				-d "${TK_BIN_DIR}/PrivateHeaders"; then
+			    TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
+			else
+			    TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+			fi
+			;;
+	    esac
+	    result="Using ${TK_INCLUDES}"
+	else
+	    if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+	       as_fn_error $? "Cannot find private header tkInt.h in ${TK_SRC_DIR}" "$LINENO" 5
+	    fi
+	    result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
+	fi
+    fi
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${result}" >&5
+$as_echo "${result}" >&6; }
+
+#TEA_PATH_X
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+
+    # Check whether --enable-threads was given.
+if test "${enable_threads+set}" = set; then :
+  enableval=$enable_threads; tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi
+
+
+    if test "${enable_threads+set}" = set; then
+	enableval="$enable_threads"
+	tcl_ok=$enableval
+    else
+	tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+	TCL_THREADS=1
+
+	if test "${TEA_PLATFORM}" != "windows" ; then
+	    # We are always OK on Windows, so check what this platform wants:
+
+	    # USE_THREAD_ALLOC tells us to try the special thread-based
+	    # allocator that significantly reduces lock contention
+
+$as_echo "#define USE_THREAD_ALLOC 1" >>confdefs.h
+
+
+$as_echo "#define _REENTRANT 1" >>confdefs.h
+
+	    if test "`uname -s`" = "SunOS" ; then
+
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+	    fi
+
+$as_echo "#define _THREAD_SAFE 1" >>confdefs.h
+
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5
+$as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_pthread_mutex_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pthread_pthread_mutex_init=yes
+else
+  ac_cv_lib_pthread_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then :
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+	    if test "$tcl_ok" = "no"; then
+		# Check a little harder for __pthread_mutex_init in the same
+		# library, as some systems hide it there until pthread.h is
+		# defined.  We could alternatively do an AC_TRY_COMPILE with
+		# pthread.h, but that will work with libpthread really doesn't
+		# exist, like AIX 4.2.  [Bug: 4359]
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_mutex_init in -lpthread" >&5
+$as_echo_n "checking for __pthread_mutex_init in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread___pthread_mutex_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __pthread_mutex_init ();
+int
+main ()
+{
+return __pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pthread___pthread_mutex_init=yes
+else
+  ac_cv_lib_pthread___pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthread___pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthread___pthread_mutex_init" = xyes; then :
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+	    fi
+
+	    if test "$tcl_ok" = "yes"; then
+		# The space is needed
+		THREADS_LIBS=" -lpthread"
+	    else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthreads" >&5
+$as_echo_n "checking for pthread_mutex_init in -lpthreads... " >&6; }
+if ${ac_cv_lib_pthreads_pthread_mutex_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pthreads_pthread_mutex_init=yes
+else
+  ac_cv_lib_pthreads_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthreads_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthreads_pthread_mutex_init" = xyes; then :
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+		if test "$tcl_ok" = "yes"; then
+		    # The space is needed
+		    THREADS_LIBS=" -lpthreads"
+		else
+		    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc" >&5
+$as_echo_n "checking for pthread_mutex_init in -lc... " >&6; }
+if ${ac_cv_lib_c_pthread_mutex_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_c_pthread_mutex_init=yes
+else
+  ac_cv_lib_c_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_c_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_c_pthread_mutex_init" = xyes; then :
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+		    if test "$tcl_ok" = "no"; then
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc_r" >&5
+$as_echo_n "checking for pthread_mutex_init in -lc_r... " >&6; }
+if ${ac_cv_lib_c_r_pthread_mutex_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc_r  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_c_r_pthread_mutex_init=yes
+else
+  ac_cv_lib_c_r_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_c_r_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_c_r_pthread_mutex_init" = xyes; then :
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+			if test "$tcl_ok" = "yes"; then
+			    # The space is needed
+			    THREADS_LIBS=" -pthread"
+			else
+			    TCL_THREADS=0
+			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&5
+$as_echo "$as_me: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&2;}
+			fi
+		    fi
+		fi
+	    fi
+	fi
+    else
+	TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with threads" >&5
+$as_echo_n "checking for building with threads... " >&6; }
+    if test "${TCL_THREADS}" = 1; then
+
+$as_echo "#define TCL_THREADS 1" >>confdefs.h
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (default)" >&5
+$as_echo "yes (default)" >&6; }
+    else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+	*THREADS=1*)
+	    if test "${TCL_THREADS}" = "0"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&5
+$as_echo "$as_me: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&2;}
+	    fi
+	    ;;
+	*)
+	    if test "${TCL_THREADS}" = "1"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core." >&5
+$as_echo "$as_me: WARNING:
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core." >&2;}
+	    fi
+	    ;;
+    esac
+
+
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
+$as_echo_n "checking how to build libraries... " >&6; }
+    # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi
+
+
+    if test "${enable_shared+set}" = set; then
+	enableval="$enable_shared"
+	tcl_ok=$enableval
+    else
+	tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5
+$as_echo "shared" >&6; }
+	SHARED_BUILD=1
+    else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
+$as_echo "static" >&6; }
+	SHARED_BUILD=0
+
+$as_echo "#define STATIC_BUILD 1" >>confdefs.h
+
+    fi
+
+
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects.  This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+
+
+    # Step 0.a: Enable 64 bit support?
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5
+$as_echo_n "checking if 64bit support is requested... " >&6; }
+    # Check whether --enable-64bit was given.
+if test "${enable_64bit+set}" = set; then :
+  enableval=$enable_64bit; do64bit=$enableval
+else
+  do64bit=no
+fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
+$as_echo "$do64bit" >&6; }
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit Sparc VIS support is requested" >&5
+$as_echo_n "checking if 64bit Sparc VIS support is requested... " >&6; }
+    # Check whether --enable-64bit-vis was given.
+if test "${enable_64bit_vis+set}" = set; then :
+  enableval=$enable_64bit_vis; do64bitVIS=$enableval
+else
+  do64bitVIS=no
+fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bitVIS" >&5
+$as_echo "$do64bitVIS" >&6; }
+    # Force 64bit on with VIS
+    if test "$do64bitVIS" = "yes"; then :
+  do64bit=yes
+fi
+
+    # Step 0.c: Check if visibility support is available. Do this here so
+    # that platform specific alternatives can be used below if this fails.
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports visibility \"hidden\"" >&5
+$as_echo_n "checking if compiler supports visibility \"hidden\"... " >&6; }
+if ${tcl_cv_cc_visibility_hidden+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+	    extern __attribute__((__visibility__("hidden"))) void f(void);
+	    void f(void) {}
+int
+main ()
+{
+f();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_cc_visibility_hidden=yes
+else
+  tcl_cv_cc_visibility_hidden=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_visibility_hidden" >&5
+$as_echo "$tcl_cv_cc_visibility_hidden" >&6; }
+    if test $tcl_cv_cc_visibility_hidden = yes; then :
+
+
+$as_echo "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h
+
+
+$as_echo "#define HAVE_HIDDEN 1" >>confdefs.h
+
+
+fi
+
+    # Step 0.d: Disable -rpath support?
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if rpath support is requested" >&5
+$as_echo_n "checking if rpath support is requested... " >&6; }
+    # Check whether --enable-rpath was given.
+if test "${enable_rpath+set}" = set; then :
+  enableval=$enable_rpath; doRpath=$enableval
+else
+  doRpath=yes
+fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doRpath" >&5
+$as_echo "$doRpath" >&6; }
+
+    # TEA specific: Cross-compiling options for Windows/CE builds?
+
+    if test "${TEA_PLATFORM}" = windows; then :
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if Windows/CE build is requested" >&5
+$as_echo_n "checking if Windows/CE build is requested... " >&6; }
+	# Check whether --enable-wince was given.
+if test "${enable_wince+set}" = set; then :
+  enableval=$enable_wince; doWince=$enableval
+else
+  doWince=no
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $doWince" >&5
+$as_echo "$doWince" >&6; }
+
+fi
+
+    # Set the variable "system" to hold the name and version number
+    # for the system.
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5
+$as_echo_n "checking system version... " >&6; }
+if ${tcl_cv_sys_version+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	# TEA specific:
+	if test "${TEA_PLATFORM}" = "windows" ; then
+	    tcl_cv_sys_version=windows
+	else
+	    tcl_cv_sys_version=`uname -s`-`uname -r`
+	    if test "$?" -ne 0 ; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5
+$as_echo "$as_me: WARNING: can't find uname command" >&2;}
+		tcl_cv_sys_version=unknown
+	    else
+		if test "`uname -s`" = "AIX" ; then
+		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+		fi
+	    fi
+	fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5
+$as_echo "$tcl_cv_sys_version" >&6; }
+    system=$tcl_cv_sys_version
+
+
+    # Require ranlib early so we can override it in special cases below.
+
+
+
+    # Set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case and removed some core-only vars.
+
+    do64bit_ok=no
+    # default to '{$LIBS}' and set to "" on per-platform necessary basis
+    SHLIB_LD_LIBS='${LIBS}'
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    UNSHARED_LIB_SUFFIX=""
+    # TEA specific: use PACKAGE_VERSION instead of VERSION
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    if test "$GCC" = yes; then :
+
+	CFLAGS_OPTIMIZE=-O2
+	CFLAGS_WARNING="-Wall"
+
+else
+
+	CFLAGS_OPTIMIZE=-O
+	CFLAGS_WARNING=""
+
+fi
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_AR" = x; then
+    AR=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    if test "x$SHLIB_VERSION" = x; then :
+  SHLIB_VERSION="1.0"
+fi
+    case $system in
+	# TEA specific:
+	windows)
+	    # This is a 2-stage check to make sure we have the 64-bit SDK
+	    # We have to know where the SDK is installed.
+	    # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+	    # MACHINE is IX86 for LINK, but this is used by the manifest,
+	    # which requires x86|amd64|ia64.
+	    MACHINE="X86"
+	    if test "$do64bit" != "no" ; then
+		if test "x${MSSDK}x" = "xx" ; then
+		    MSSDK="C:/Progra~1/Microsoft Platform SDK"
+		fi
+		MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+		PATH64=""
+		case "$do64bit" in
+		    amd64|x64|yes)
+			MACHINE="AMD64" ; # default to AMD64 64-bit build
+			PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+			;;
+		    ia64)
+			MACHINE="IA64"
+			PATH64="${MSSDK}/Bin/Win64"
+			;;
+		esac
+		if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then
+		    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
+$as_echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
+		    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ensure latest Platform SDK is installed" >&5
+$as_echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
+		    do64bit="no"
+		else
+		    { $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
+$as_echo "   Using 64-bit $MACHINE mode" >&6; }
+		    do64bit_ok="yes"
+		fi
+	    fi
+
+	    if test "$doWince" != "no" ; then
+		if test "$do64bit" != "no" ; then
+		    as_fn_error $? "Windows/CE and 64-bit builds incompatible" "$LINENO" 5
+		fi
+		if test "$GCC" = "yes" ; then
+		    as_fn_error $? "Windows/CE and GCC builds incompatible" "$LINENO" 5
+		fi
+
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+	# we reset no_celib in case something fails here
+	no_celib=true
+
+# Check whether --with-celib was given.
+if test "${with_celib+set}" = set; then :
+  withval=$with_celib; with_celibconfig=${withval}
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Windows/CE celib directory" >&5
+$as_echo_n "checking for Windows/CE celib directory... " >&6; }
+	if ${ac_cv_c_celibconfig+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	    # First check to see if --with-celibconfig was specified.
+	    if test x"${with_celibconfig}" != x ; then
+		if test -d "${with_celibconfig}/inc" ; then
+		    ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+		else
+		    as_fn_error $? "${with_celibconfig} directory doesn't contain inc directory" "$LINENO" 5
+		fi
+	    fi
+
+	    # then check for a celib library
+	    if test x"${ac_cv_c_celibconfig}" = x ; then
+		for i in \
+			../celib-palm-3.0 \
+			../celib \
+			../../celib-palm-3.0 \
+			../../celib \
+			`ls -dr ../celib-*3.[0-9]* 2>/dev/null` \
+			${srcdir}/../celib-palm-3.0 \
+			${srcdir}/../celib \
+			`ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \
+			; do
+		    if test -d "$i/inc" ; then
+			ac_cv_c_celibconfig=`(cd $i; pwd)`
+			break
+		    fi
+		done
+	    fi
+
+fi
+
+	if test x"${ac_cv_c_celibconfig}" = x ; then
+	    as_fn_error $? "Cannot find celib support library directory" "$LINENO" 5
+	else
+	    no_celib=
+	    CELIB_DIR=${ac_cv_c_celibconfig}
+	    CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $CELIB_DIR" >&5
+$as_echo "found $CELIB_DIR" >&6; }
+	fi
+    fi
+
+		# Set defaults for common evc4/PPC2003 setup
+		# Currently Tcl requires 300+, possibly 420+ for sockets
+		CEVERSION=420; 		# could be 211 300 301 400 420 ...
+		TARGETCPU=ARMV4;	# could be ARMV4 ARM MIPS SH3 X86 ...
+		ARCH=ARM;		# could be ARM MIPS X86EM ...
+		PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+		if test "$doWince" != "yes"; then
+		    # If !yes then the user specified something
+		    # Reset ARCH to allow user to skip specifying it
+		    ARCH=
+		    eval `echo $doWince | awk -F, '{ \
+	    if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \
+	    if ($1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+	    if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \
+	    if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \
+	    if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \
+		    }'`
+		    if test "x${ARCH}" = "x" ; then
+			ARCH=$TARGETCPU;
+		    fi
+		fi
+		OSVERSION=WCE$CEVERSION;
+	    	if test "x${WCEROOT}" = "x" ; then
+			WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+		    if test ! -d "${WCEROOT}" ; then
+			WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+		    fi
+		fi
+		if test "x${SDKROOT}" = "x" ; then
+		    SDKROOT="C:/Program Files/Windows CE Tools"
+		    if test ! -d "${SDKROOT}" ; then
+			SDKROOT="C:/Windows CE Tools"
+		    fi
+		fi
+		WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+		SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+		if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+		    -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+		    as_fn_error $? "could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" "$LINENO" 5
+		    doWince="no"
+		else
+		    # We could PATH_NOSPACE these, but that's not important,
+		    # as long as we quote them when used.
+		    CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+		    if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+			CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+		    fi
+		    CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+    		fi
+	    fi
+
+	    if test "$GCC" != "yes" ; then
+	        if test "${SHARED_BUILD}" = "0" ; then
+		    runtime=-MT
+	        else
+		    runtime=-MD
+	        fi
+
+                if test "$do64bit" != "no" ; then
+		    # All this magic is necessary for the Win64 SDK RC1 - hobbs
+		    CC="\"${PATH64}/cl.exe\""
+		    CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+		    RC="\"${MSSDK}/bin/rc.exe\""
+		    lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+		    LINKBIN="\"${PATH64}/link.exe\""
+		    CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+		    # Avoid 'unresolved external symbol __security_cookie'
+		    # errors, c.f. http://support.microsoft.com/?id=894573
+
+    vars="bufferoverflowU.lib"
+    for i in $vars; do
+	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+	    # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+	    i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+	fi
+	PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+		elif test "$doWince" != "no" ; then
+		    CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+		    if test "${TARGETCPU}" = "X86"; then
+			CC="\"${CEBINROOT}/cl.exe\""
+		    else
+			CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+		    fi
+		    CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+		    RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+		    arch=`echo ${ARCH} | awk '{print tolower($0)}'`
+		    defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+		    if test "${SHARED_BUILD}" = "1" ; then
+			# Static CE builds require static celib as well
+		    	defs="${defs} _DLL"
+		    fi
+		    for i in $defs ; do
+
+cat >>confdefs.h <<_ACEOF
+#define $i 1
+_ACEOF
+
+		    done
+
+cat >>confdefs.h <<_ACEOF
+#define _WIN32_WCE $CEVERSION
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNDER_CE $CEVERSION
+_ACEOF
+
+		    CFLAGS_DEBUG="-nologo -Zi -Od"
+		    CFLAGS_OPTIMIZE="-nologo -Ox"
+		    lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+		    lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+		    LINKBIN="\"${CEBINROOT}/link.exe\""
+
+		else
+		    RC="rc"
+		    lflags="-nologo"
+    		    LINKBIN="link"
+		    CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+		fi
+	    fi
+
+	    if test "$GCC" = "yes"; then
+		# mingw gcc mode
+		if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
+set dummy ${ac_tool_prefix}windres; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RC"; then
+  ac_cv_prog_RC="$RC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RC="${ac_tool_prefix}windres"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RC=$ac_cv_prog_RC
+if test -n "$RC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
+$as_echo "$RC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RC"; then
+  ac_ct_RC=$RC
+  # Extract the first word of "windres", so it can be a program name with args.
+set dummy windres; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RC"; then
+  ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RC="windres"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RC=$ac_cv_prog_ac_ct_RC
+if test -n "$ac_ct_RC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
+$as_echo "$ac_ct_RC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RC" = x; then
+    RC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RC=$ac_ct_RC
+  fi
+else
+  RC="$ac_cv_prog_RC"
+fi
+
+		CFLAGS_DEBUG="-g"
+		CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+		SHLIB_LD='${CC} -shared'
+		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+		LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+		LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cross-compile version of gcc" >&5
+$as_echo_n "checking for cross-compile version of gcc... " >&6; }
+if ${ac_cv_cross+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+			    #ifdef __WIN32__
+				#error cross-compiler
+			    #endif
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_cross=yes
+else
+  ac_cv_cross=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cross" >&5
+$as_echo "$ac_cv_cross" >&6; }
+		      if test "$ac_cv_cross" = "yes"; then
+			case "$do64bit" in
+			    amd64|x64|yes)
+				CC="x86_64-w64-mingw32-gcc"
+				LD="x86_64-w64-mingw32-ld"
+				AR="x86_64-w64-mingw32-ar"
+				RANLIB="x86_64-w64-mingw32-ranlib"
+				RC="x86_64-w64-mingw32-windres"
+			    ;;
+			    *)
+				CC="i686-w64-mingw32-gcc"
+				LD="i686-w64-mingw32-ld"
+				AR="i686-w64-mingw32-ar"
+				RANLIB="i686-w64-mingw32-ranlib"
+				RC="i686-w64-mingw32-windres"
+			    ;;
+			esac
+		fi
+
+	    else
+		SHLIB_LD="${LINKBIN} -dll ${lflags}"
+		# link -lib only works when -lib is the first arg
+		STLIB_LD="${LINKBIN} -lib ${lflags}"
+		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+		PATHTYPE=-w
+		# For information on what debugtype is most useful, see:
+		# http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+		# and also
+		# http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
+		# This essentially turns it all on.
+		LDFLAGS_DEBUG="-debug -debugtype:cv"
+		LDFLAGS_OPTIMIZE="-release"
+		if test "$doWince" != "no" ; then
+		    LDFLAGS_CONSOLE="-link ${lflags}"
+		    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+		else
+		    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+		    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+		fi
+	    fi
+
+	    SHLIB_SUFFIX=".dll"
+	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+	    TCL_LIB_VERSIONS_OK=nodots
+    	    ;;
+	AIX-*)
+	    if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then :
+
+		# AIX requires the _r compiler when gcc isn't being used
+		case "${CC}" in
+		    *_r|*_r\ *)
+			# ok ...
+			;;
+		    *)
+			# Make sure only first arg gets _r
+		    	CC=`echo "$CC" | sed -e 's/^\([^ ]*\)/\1_r/'`
+			;;
+		esac
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Using $CC for compiling with threads" >&5
+$as_echo "Using $CC for compiling with threads" >&6; }
+
+fi
+	    LIBS="$LIBS -lc"
+	    SHLIB_CFLAGS=""
+	    SHLIB_SUFFIX=".so"
+
+	    LD_LIBRARY_PATH_VAR="LIBPATH"
+
+	    # Check to enable 64-bit flags for compiler/linker
+	    if test "$do64bit" = yes; then :
+
+		if test "$GCC" = yes; then :
+
+		    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+
+else
+
+		    do64bit_ok=yes
+		    CFLAGS="$CFLAGS -q64"
+		    LDFLAGS_ARCH="-q64"
+		    RANLIB="${RANLIB} -X64"
+		    AR="${AR} -X64"
+		    SHLIB_LD_FLAGS="-b64"
+
+fi
+
+fi
+
+	    if test "`uname -m`" = ia64; then :
+
+		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+		if test "$GCC" = yes; then :
+
+		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+
+else
+
+		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+
+fi
+		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+
+else
+
+		if test "$GCC" = yes; then :
+
+		    SHLIB_LD='${CC} -shared -Wl,-bexpall'
+
+else
+
+		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
+		    LDFLAGS="$LDFLAGS -brtl"
+
+fi
+		SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+		CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+fi
+	    ;;
+	BeOS*)
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_LD='${CC} -nostart'
+	    SHLIB_SUFFIX=".so"
+
+	    #-----------------------------------------------------------
+	    # Check for inet_ntoa in -lbind, for BeOS (which also needs
+	    # -lsocket, even if the network functions are in -lnet which
+	    # is always linked to, for compatibility.
+	    #-----------------------------------------------------------
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lbind" >&5
+$as_echo_n "checking for inet_ntoa in -lbind... " >&6; }
+if ${ac_cv_lib_bind_inet_ntoa+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbind  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntoa ();
+int
+main ()
+{
+return inet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_bind_inet_ntoa=yes
+else
+  ac_cv_lib_bind_inet_ntoa=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bind_inet_ntoa" >&5
+$as_echo "$ac_cv_lib_bind_inet_ntoa" >&6; }
+if test "x$ac_cv_lib_bind_inet_ntoa" = xyes; then :
+  LIBS="$LIBS -lbind -lsocket"
+fi
+
+	    ;;
+	BSD/OS-4.*)
+	    SHLIB_CFLAGS="-export-dynamic -fPIC"
+	    SHLIB_LD='${CC} -shared'
+	    SHLIB_SUFFIX=".so"
+	    LDFLAGS="$LDFLAGS -export-dynamic"
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    ;;
+	CYGWIN_*)
+	    SHLIB_CFLAGS=""
+	    SHLIB_LD='${CC} -shared'
+	    SHLIB_SUFFIX=".dll"
+	    EXEEXT=".exe"
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    ;;
+	Haiku*)
+	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_SUFFIX=".so"
+	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnetwork" >&5
+$as_echo_n "checking for inet_ntoa in -lnetwork... " >&6; }
+if ${ac_cv_lib_network_inet_ntoa+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetwork  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntoa ();
+int
+main ()
+{
+return inet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_network_inet_ntoa=yes
+else
+  ac_cv_lib_network_inet_ntoa=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_inet_ntoa" >&5
+$as_echo "$ac_cv_lib_network_inet_ntoa" >&6; }
+if test "x$ac_cv_lib_network_inet_ntoa" = xyes; then :
+  LIBS="$LIBS -lnetwork"
+fi
+
+	    ;;
+	HP-UX-*.11.*)
+	    # Use updated header definitions where possible
+
+$as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h
+
+	    # TEA specific: Needed by Tcl, but not most extensions
+	    #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+	    #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+	    if test "`uname -m`" = ia64; then :
+
+		SHLIB_SUFFIX=".so"
+		# Use newer C++ library for C++ extensions
+		#if test "$GCC" != "yes" ; then
+		#   CPPFLAGS="-AA"
+		#fi
+
+else
+
+		SHLIB_SUFFIX=".sl"
+
+fi
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+	    if test "$tcl_ok" = yes; then :
+
+		LDFLAGS="$LDFLAGS -Wl,-E"
+		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+
+fi
+	    if test "$GCC" = yes; then :
+
+		SHLIB_LD='${CC} -shared'
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+else
+
+		CFLAGS="$CFLAGS -z"
+		# Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+		#CFLAGS="$CFLAGS +DAportable"
+		SHLIB_CFLAGS="+z"
+		SHLIB_LD="ld -b"
+
+fi
+
+	    # Check to enable 64-bit flags for compiler/linker
+	    if test "$do64bit" = "yes"; then :
+
+		if test "$GCC" = yes; then :
+
+		    case `${CC} -dumpmachine` in
+			hppa64*)
+			    # 64-bit gcc in use.  Fix flags for GNU ld.
+			    do64bit_ok=yes
+			    SHLIB_LD='${CC} -shared'
+			    if test $doRpath = yes; then :
+
+				CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+			    ;;
+			*)
+			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+			    ;;
+		    esac
+
+else
+
+		    do64bit_ok=yes
+		    CFLAGS="$CFLAGS +DD64"
+		    LDFLAGS_ARCH="+DD64"
+
+fi
+
+fi ;;
+	IRIX-6.*)
+	    SHLIB_CFLAGS=""
+	    SHLIB_LD="ld -n32 -shared -rdata_shared"
+	    SHLIB_SUFFIX=".so"
+	    if test $doRpath = yes; then :
+
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+	    if test "$GCC" = yes; then :
+
+		CFLAGS="$CFLAGS -mabi=n32"
+		LDFLAGS="$LDFLAGS -mabi=n32"
+
+else
+
+		case $system in
+		    IRIX-6.3)
+			# Use to build 6.2 compatible binaries on 6.3.
+			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+			;;
+		    *)
+			CFLAGS="$CFLAGS -n32"
+			;;
+		esac
+		LDFLAGS="$LDFLAGS -n32"
+
+fi
+	    ;;
+	IRIX64-6.*)
+	    SHLIB_CFLAGS=""
+	    SHLIB_LD="ld -n32 -shared -rdata_shared"
+	    SHLIB_SUFFIX=".so"
+	    if test $doRpath = yes; then :
+
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+	    # Check to enable 64-bit flags for compiler/linker
+
+	    if test "$do64bit" = yes; then :
+
+	        if test "$GCC" = yes; then :
+
+	            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported by gcc" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
+
+else
+
+	            do64bit_ok=yes
+	            SHLIB_LD="ld -64 -shared -rdata_shared"
+	            CFLAGS="$CFLAGS -64"
+	            LDFLAGS_ARCH="-64"
+
+fi
+
+fi
+	    ;;
+	Linux*|GNU*|NetBSD-Debian)
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_SUFFIX=".so"
+
+	    # TEA specific:
+	    CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+
+	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+	    if test $doRpath = yes; then :
+
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+	    if test "`uname -m`" = "alpha"; then :
+  CFLAGS="$CFLAGS -mieee"
+fi
+	    if test $do64bit = yes; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -m64 flag" >&5
+$as_echo_n "checking if compiler accepts -m64 flag... " >&6; }
+if ${tcl_cv_cc_m64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+		    hold_cflags=$CFLAGS
+		    CFLAGS="$CFLAGS -m64"
+		    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_cc_m64=yes
+else
+  tcl_cv_cc_m64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+		    CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_m64" >&5
+$as_echo "$tcl_cv_cc_m64" >&6; }
+		if test $tcl_cv_cc_m64 = yes; then :
+
+		    CFLAGS="$CFLAGS -m64"
+		    do64bit_ok=yes
+
+fi
+
+fi
+
+	    # The combo of gcc + glibc has a bug related to inlining of
+	    # functions like strtod(). The -fno-builtin flag should address
+	    # this problem but it does not work. The -fno-inline flag is kind
+	    # of overkill but it works. Disable inlining only when one of the
+	    # files in compat/*.c is being linked in.
+
+	    if test x"${USE_COMPAT}" != x; then :
+  CFLAGS="$CFLAGS -fno-inline"
+fi
+	    ;;
+	Lynx*)
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_SUFFIX=".so"
+	    CFLAGS_OPTIMIZE=-02
+	    SHLIB_LD='${CC} -shared'
+	    LD_FLAGS="-Wl,--export-dynamic"
+	    if test $doRpath = yes; then :
+
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+	    ;;
+	OpenBSD-*)
+	    arch=`arch -s`
+	    case "$arch" in
+	    vax)
+		SHLIB_SUFFIX=""
+		SHARED_LIB_SUFFIX=""
+		LDFLAGS=""
+		;;
+	    *)
+		SHLIB_CFLAGS="-fPIC"
+		SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+		SHLIB_SUFFIX=".so"
+		if test $doRpath = yes; then :
+
+		    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+		LDFLAGS="-Wl,-export-dynamic"
+		;;
+	    esac
+	    case "$arch" in
+	    vax)
+		CFLAGS_OPTIMIZE="-O1"
+		;;
+	    *)
+		CFLAGS_OPTIMIZE="-O2"
+		;;
+	    esac
+	    if test "${TCL_THREADS}" = "1"; then :
+
+		# On OpenBSD:	Compile with -pthread
+		#		Don't link with -lpthread
+		LIBS=`echo $LIBS | sed s/-lpthread//`
+		CFLAGS="$CFLAGS -pthread"
+
+fi
+	    # OpenBSD doesn't do version numbers with dots.
+	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+	    TCL_LIB_VERSIONS_OK=nodots
+	    ;;
+	NetBSD-*)
+	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+	    SHLIB_SUFFIX=".so"
+	    LDFLAGS="$LDFLAGS -export-dynamic"
+	    if test $doRpath = yes; then :
+
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+	    if test "${TCL_THREADS}" = "1"; then :
+
+		# The -pthread needs to go in the CFLAGS, not LIBS
+		LIBS=`echo $LIBS | sed s/-pthread//`
+		CFLAGS="$CFLAGS -pthread"
+	    	LDFLAGS="$LDFLAGS -pthread"
+
+fi
+	    ;;
+	FreeBSD-*)
+	    # This configuration from FreeBSD Ports.
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_LD="${CC} -shared"
+	    TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$@"
+	    SHLIB_SUFFIX=".so"
+	    LDFLAGS=""
+	    if test $doRpath = yes; then :
+
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+	    if test "${TCL_THREADS}" = "1"; then :
+
+		# The -pthread needs to go in the LDFLAGS, not LIBS
+		LIBS=`echo $LIBS | sed s/-pthread//`
+		CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+		LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
+fi
+	    # Version numbers are dot-stripped by system policy.
+	    TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .`
+	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
+	    TCL_LIB_VERSIONS_OK=nodots
+	    ;;
+	Darwin-*)
+	    CFLAGS_OPTIMIZE="-Os"
+	    SHLIB_CFLAGS="-fno-common"
+	    # To avoid discrepancies between what headers configure sees during
+	    # preprocessing tests and compiling tests, move any -isysroot and
+	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+		if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`"
+	    CFLAGS="`echo " ${CFLAGS}" | \
+		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+		if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`"
+	    if test $do64bit = yes; then :
+
+		case `arch` in
+		    ppc)
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch ppc64 flag" >&5
+$as_echo_n "checking if compiler accepts -arch ppc64 flag... " >&6; }
+if ${tcl_cv_cc_arch_ppc64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+			    hold_cflags=$CFLAGS
+			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_cc_arch_ppc64=yes
+else
+  tcl_cv_cc_arch_ppc64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+			    CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_ppc64" >&5
+$as_echo "$tcl_cv_cc_arch_ppc64" >&6; }
+			if test $tcl_cv_cc_arch_ppc64 = yes; then :
+
+			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+			    do64bit_ok=yes
+
+fi;;
+		    i386)
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch x86_64 flag" >&5
+$as_echo_n "checking if compiler accepts -arch x86_64 flag... " >&6; }
+if ${tcl_cv_cc_arch_x86_64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+			    hold_cflags=$CFLAGS
+			    CFLAGS="$CFLAGS -arch x86_64"
+			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_cc_arch_x86_64=yes
+else
+  tcl_cv_cc_arch_x86_64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+			    CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_x86_64" >&5
+$as_echo "$tcl_cv_cc_arch_x86_64" >&6; }
+			if test $tcl_cv_cc_arch_x86_64 = yes; then :
+
+			    CFLAGS="$CFLAGS -arch x86_64"
+			    do64bit_ok=yes
+
+fi;;
+		    *)
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
+$as_echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
+		esac
+
+else
+
+		# Check for combined 32-bit and 64-bit fat build
+		if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then :
+
+		    fat_32_64=yes
+fi
+
+fi
+	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -single_module flag" >&5
+$as_echo_n "checking if ld accepts -single_module flag... " >&6; }
+if ${tcl_cv_ld_single_module+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+		hold_ldflags=$LDFLAGS
+		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_ld_single_module=yes
+else
+  tcl_cv_ld_single_module=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+		LDFLAGS=$hold_ldflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_single_module" >&5
+$as_echo "$tcl_cv_ld_single_module" >&6; }
+	    if test $tcl_cv_ld_single_module = yes; then :
+
+		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+
+fi
+	    # TEA specific: link shlib with current and compatibility version flags
+	    vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([0-9]\{1,5\}\)\(\(\.[0-9]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
+	    SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
+	    SHLIB_SUFFIX=".dylib"
+	    # Don't use -prebind when building for Mac OS X 10.4 or later only:
+	    if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \
+		"`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then :
+
+		LDFLAGS="$LDFLAGS -prebind"
+fi
+	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5
+$as_echo_n "checking if ld accepts -search_paths_first flag... " >&6; }
+if ${tcl_cv_ld_search_paths_first+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+		hold_ldflags=$LDFLAGS
+		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_ld_search_paths_first=yes
+else
+  tcl_cv_ld_search_paths_first=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+		LDFLAGS=$hold_ldflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_search_paths_first" >&5
+$as_echo "$tcl_cv_ld_search_paths_first" >&6; }
+	    if test $tcl_cv_ld_search_paths_first = yes; then :
+
+		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+
+fi
+	    if test "$tcl_cv_cc_visibility_hidden" != yes; then :
+
+
+$as_echo "#define MODULE_SCOPE __private_extern__" >>confdefs.h
+
+		tcl_cv_cc_visibility_hidden=yes
+
+fi
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+	    # TEA specific: for combined 32 & 64 bit fat builds of Tk
+	    # extensions, verify that 64-bit build is possible.
+	    if test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"; then :
+
+		if test "${TEA_WINDOWINGSYSTEM}" = x11; then :
+
+		    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit X11" >&5
+$as_echo_n "checking for 64-bit X11... " >&6; }
+if ${tcl_cv_lib_x11_64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+			for v in CFLAGS CPPFLAGS LDFLAGS; do
+			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+			done
+			CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+			LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_lib_x11_64=yes
+else
+  tcl_cv_lib_x11_64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+			for v in CFLAGS CPPFLAGS LDFLAGS; do
+			    eval $v'="$hold_'$v'"'
+			done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_x11_64" >&5
+$as_echo "$tcl_cv_lib_x11_64" >&6; }
+
+fi
+		if test "${TEA_WINDOWINGSYSTEM}" = aqua; then :
+
+		    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit Tk" >&5
+$as_echo_n "checking for 64-bit Tk... " >&6; }
+if ${tcl_cv_lib_tk_64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+			for v in CFLAGS CPPFLAGS LDFLAGS; do
+			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+			done
+			CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
+			LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
+			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <tk.h>
+int
+main ()
+{
+Tk_InitStubs(NULL, "", 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_lib_tk_64=yes
+else
+  tcl_cv_lib_tk_64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+			for v in CFLAGS CPPFLAGS LDFLAGS; do
+			    eval $v'="$hold_'$v'"'
+			done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_tk_64" >&5
+$as_echo "$tcl_cv_lib_tk_64" >&6; }
+
+fi
+		# remove 64-bit arch flags from CFLAGS et al. if configuration
+		# does not support 64-bit.
+		if test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no; then :
+
+		    { $as_echo "$as_me:${as_lineno-$LINENO}: Removing 64-bit architectures from compiler & linker flags" >&5
+$as_echo "$as_me: Removing 64-bit architectures from compiler & linker flags" >&6;}
+		    for v in CFLAGS CPPFLAGS LDFLAGS; do
+			eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+		    done
+fi
+
+fi
+	    ;;
+	OS/390-*)
+	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy
+
+$as_echo "#define _OE_SOCKETS 1" >>confdefs.h
+
+	    ;;
+	OSF1-V*)
+	    # Digital OSF/1
+	    SHLIB_CFLAGS=""
+	    if test "$SHARED_BUILD" = 1; then :
+
+	        SHLIB_LD='ld -shared -expect_unresolved "*"'
+
+else
+
+	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+
+fi
+	    SHLIB_SUFFIX=".so"
+	    if test $doRpath = yes; then :
+
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+	    if test "$GCC" = yes; then :
+  CFLAGS="$CFLAGS -mieee"
+else
+
+		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
+fi
+	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
+	    if test "${TCL_THREADS}" = 1; then :
+
+		CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+		CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+		LIBS=`echo $LIBS | sed s/-lpthreads//`
+		if test "$GCC" = yes; then :
+
+		    LIBS="$LIBS -lpthread -lmach -lexc"
+
+else
+
+		    CFLAGS="$CFLAGS -pthread"
+		    LDFLAGS="$LDFLAGS -pthread"
+
+fi
+
+fi
+	    ;;
+	QNX-6*)
+	    # QNX RTP
+	    # This may work for all QNX, but it was only reported for v6.
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_LD="ld -Bshareable -x"
+	    SHLIB_LD_LIBS=""
+	    SHLIB_SUFFIX=".so"
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    ;;
+	SCO_SV-3.2*)
+	    if test "$GCC" = yes; then :
+
+		SHLIB_CFLAGS="-fPIC -melf"
+		LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+
+else
+
+	       SHLIB_CFLAGS="-Kpic -belf"
+	       LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+
+fi
+	    SHLIB_LD="ld -G"
+	    SHLIB_LD_LIBS=""
+	    SHLIB_SUFFIX=".so"
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    ;;
+	SunOS-5.[0-6])
+	    # Careful to not let 5.10+ fall into this case
+
+	    # Note: If _REENTRANT isn't defined, then Solaris
+	    # won't define thread-safe library routines.
+
+
+$as_echo "#define _REENTRANT 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+
+	    SHLIB_CFLAGS="-KPIC"
+	    SHLIB_SUFFIX=".so"
+	    if test "$GCC" = yes; then :
+
+		SHLIB_LD='${CC} -shared'
+		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+else
+
+		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+		CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+fi
+	    ;;
+	SunOS-5*)
+	    # Note: If _REENTRANT isn't defined, then Solaris
+	    # won't define thread-safe library routines.
+
+
+$as_echo "#define _REENTRANT 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+
+	    SHLIB_CFLAGS="-KPIC"
+
+	    # Check to enable 64-bit flags for compiler/linker
+	    if test "$do64bit" = yes; then :
+
+		arch=`isainfo`
+		if test "$arch" = "sparcv9 sparc"; then :
+
+		    if test "$GCC" = yes; then :
+
+			if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then :
+
+			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
+
+else
+
+			    do64bit_ok=yes
+			    CFLAGS="$CFLAGS -m64 -mcpu=v9"
+			    LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+			    SHLIB_CFLAGS="-fPIC"
+
+fi
+
+else
+
+			do64bit_ok=yes
+			if test "$do64bitVIS" = yes; then :
+
+			    CFLAGS="$CFLAGS -xarch=v9a"
+			    LDFLAGS_ARCH="-xarch=v9a"
+
+else
+
+			    CFLAGS="$CFLAGS -xarch=v9"
+			    LDFLAGS_ARCH="-xarch=v9"
+
+fi
+			# Solaris 64 uses this as well
+			#LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+
+fi
+
+else
+  if test "$arch" = "amd64 i386"; then :
+
+		    if test "$GCC" = yes; then :
+
+			case $system in
+			    SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
+				do64bit_ok=yes
+				CFLAGS="$CFLAGS -m64"
+				LDFLAGS="$LDFLAGS -m64";;
+			    *)
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};;
+			esac
+
+else
+
+			do64bit_ok=yes
+			case $system in
+			    SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
+				CFLAGS="$CFLAGS -m64"
+				LDFLAGS="$LDFLAGS -m64";;
+			    *)
+				CFLAGS="$CFLAGS -xarch=amd64"
+				LDFLAGS="$LDFLAGS -xarch=amd64";;
+			esac
+
+fi
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported for $arch" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
+fi
+fi
+
+fi
+
+	    SHLIB_SUFFIX=".so"
+	    if test "$GCC" = yes; then :
+
+		SHLIB_LD='${CC} -shared'
+		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+		if test "$do64bit_ok" = yes; then :
+
+		    if test "$arch" = "sparcv9 sparc"; then :
+
+			# We need to specify -static-libgcc or we need to
+			# add the path to the sparv9 libgcc.
+			# JH: static-libgcc is necessary for core Tcl, but may
+			# not be necessary for extensions.
+			SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+			# for finding sparcv9 libgcc, get the regular libgcc
+			# path, remove so name and append 'sparcv9'
+			#v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+			#CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+
+else
+  if test "$arch" = "amd64 i386"; then :
+
+			# JH: static-libgcc is necessary for core Tcl, but may
+			# not be necessary for extensions.
+			SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+
+fi
+fi
+
+fi
+
+else
+
+		case $system in
+		    SunOS-5.[1-9][0-9]*)
+			# TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+			SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
+		    *)
+			SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+		esac
+		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+
+fi
+	    ;;
+	UNIX_SV* | UnixWare-5*)
+	    SHLIB_CFLAGS="-KPIC"
+	    SHLIB_LD='${CC} -G'
+	    SHLIB_LD_LIBS=""
+	    SHLIB_SUFFIX=".so"
+	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+	    # that don't grok the -Bexport option.  Test that it does.
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld accepts -Bexport flag" >&5
+$as_echo_n "checking for ld accepts -Bexport flag... " >&6; }
+if ${tcl_cv_ld_Bexport+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+		hold_ldflags=$LDFLAGS
+		LDFLAGS="$LDFLAGS -Wl,-Bexport"
+		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  tcl_cv_ld_Bexport=yes
+else
+  tcl_cv_ld_Bexport=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	        LDFLAGS=$hold_ldflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_Bexport" >&5
+$as_echo "$tcl_cv_ld_Bexport" >&6; }
+	    if test $tcl_cv_ld_Bexport = yes; then :
+
+		LDFLAGS="$LDFLAGS -Wl,-Bexport"
+
+fi
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    ;;
+    esac
+
+    if test "$do64bit" = yes -a "$do64bit_ok" = no; then :
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
+$as_echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
+
+fi
+
+
+
+    # Add in the arch flags late to ensure it wasn't removed.
+    # Not necessary in TEA, but this is aligned with core
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    if test "$GCC" = yes; then :
+
+	case $system in
+	    AIX-*) ;;
+	    BSD/OS*) ;;
+	    CYGWIN_*|MINGW32_*) ;;
+	    IRIX*) ;;
+	    NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+	    Darwin-*) ;;
+	    SCO_SV-3.2*) ;;
+	    windows) ;;
+	    *) SHLIB_CFLAGS="-fPIC" ;;
+	esac
+fi
+
+    if test "$tcl_cv_cc_visibility_hidden" != yes; then :
+
+
+$as_echo "#define MODULE_SCOPE extern" >>confdefs.h
+
+
+fi
+
+    if test "$SHARED_LIB_SUFFIX" = ""; then :
+
+    # TEA specific: use PACKAGE_VERSION instead of VERSION
+    SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+fi
+    if test "$UNSHARED_LIB_SUFFIX" = ""; then :
+
+    # TEA specific: use PACKAGE_VERSION instead of VERSION
+    UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+fi
+
+    if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SEH support in compiler" >&5
+$as_echo_n "checking for SEH support in compiler... " >&6; }
+if ${tcl_cv_seh+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  tcl_cv_seh=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+	    int main(int argc, char** argv) {
+		int a, b = 0;
+		__try {
+		    a = 666 / b;
+		}
+		__except (EXCEPTION_EXECUTE_HANDLER) {
+		    return 0;
+		}
+		return 1;
+	    }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  tcl_cv_seh=yes
+else
+  tcl_cv_seh=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_seh" >&5
+$as_echo "$tcl_cv_seh" >&6; }
+	if test "$tcl_cv_seh" = "no" ; then
+
+$as_echo "#define HAVE_NO_SEH 1" >>confdefs.h
+
+	fi
+
+	#
+	# Check to see if the excpt.h include file provided contains the
+	# definition for EXCEPTION_DISPOSITION; if not, which is the case
+	# with Cygwin's version as of 2002-04-10, define it to be int,
+	# sufficient for getting the current code to work.
+	#
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EXCEPTION_DISPOSITION support in include files" >&5
+$as_echo_n "checking for EXCEPTION_DISPOSITION support in include files... " >&6; }
+if ${tcl_cv_eh_disposition+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#	    define WIN32_LEAN_AND_MEAN
+#	    include <windows.h>
+#	    undef WIN32_LEAN_AND_MEAN
+
+int
+main ()
+{
+
+		EXCEPTION_DISPOSITION x;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_eh_disposition=yes
+else
+  tcl_cv_eh_disposition=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_eh_disposition" >&5
+$as_echo "$tcl_cv_eh_disposition" >&6; }
+	if test "$tcl_cv_eh_disposition" = "no" ; then
+
+$as_echo "#define EXCEPTION_DISPOSITION int" >>confdefs.h
+
+	fi
+
+	# Check to see if winnt.h defines CHAR, SHORT, and LONG
+	# even if VOID has already been #defined. The win32api
+	# used by mingw and cygwin is known to do this.
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for winnt.h that ignores VOID define" >&5
+$as_echo_n "checking for winnt.h that ignores VOID define... " >&6; }
+if ${tcl_cv_winnt_ignore_void+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define VOID void
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+int
+main ()
+{
+
+		CHAR c;
+		SHORT s;
+		LONG l;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_winnt_ignore_void=yes
+else
+  tcl_cv_winnt_ignore_void=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_winnt_ignore_void" >&5
+$as_echo "$tcl_cv_winnt_ignore_void" >&6; }
+	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
+
+$as_echo "#define HAVE_WINNT_IGNORE_VOID 1" >>confdefs.h
+
+	fi
+    fi
+
+	# See if the compiler supports casting to a union type.
+	# This is used to stop gcc from printing a compiler
+	# warning when initializing a union member.
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
+$as_echo_n "checking for cast to union support... " >&6; }
+if ${tcl_cv_cast_to_union+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+		  union foo { int i; double d; };
+		  union foo f = (union foo) (int) 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_cast_to_union=yes
+else
+  tcl_cv_cast_to_union=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
+$as_echo "$tcl_cv_cast_to_union" >&6; }
+	if test "$tcl_cv_cast_to_union" = "yes"; then
+
+$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h
+
+	fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for required early compiler flags" >&5
+$as_echo_n "checking for required early compiler flags... " >&6; }
+    tcl_flags=""
+
+    if ${tcl_cv_flag__isoc99_source+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__isoc99_source=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define _ISOC99_SOURCE 1
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__isoc99_source=yes
+else
+  tcl_cv_flag__isoc99_source=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then
+
+$as_echo "#define _ISOC99_SOURCE 1" >>confdefs.h
+
+	tcl_flags="$tcl_flags _ISOC99_SOURCE"
+    fi
+
+
+    if ${tcl_cv_flag__largefile64_source+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__largefile64_source=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define _LARGEFILE64_SOURCE 1
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__largefile64_source=yes
+else
+  tcl_cv_flag__largefile64_source=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then
+
+$as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h
+
+	tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
+    fi
+
+
+    if ${tcl_cv_flag__largefile_source64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__largefile_source64=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define _LARGEFILE_SOURCE64 1
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_flag__largefile_source64=yes
+else
+  tcl_cv_flag__largefile_source64=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then
+
+$as_echo "#define _LARGEFILE_SOURCE64 1" >>confdefs.h
+
+	tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
+    fi
+
+    if test "x${tcl_flags}" = "x" ; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+    else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5
+$as_echo "${tcl_flags}" >&6; }
+    fi
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit integer type" >&5
+$as_echo_n "checking for 64-bit integer type... " >&6; }
+    if ${tcl_cv_type_64bit+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	tcl_cv_type_64bit=none
+	# See if the compiler knows natively about __int64
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__int64 value = (__int64) 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_type_64bit=__int64
+else
+  tcl_type_64bit="long long"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+	# See if we should use long anyway  Note that we substitute in the
+	# type that is our current guess for a 64-bit type inside this check
+	# program, so it should be modified only carefully...
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+switch (0) {
+            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
+        }
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_type_64bit=${tcl_type_64bit}
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "${tcl_cv_type_64bit}" = none ; then
+
+$as_echo "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using long" >&5
+$as_echo "using long" >&6; }
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+		-a "${TEA_PLATFORM}" = "windows" ; then
+	# TEA specific: We actually want to use the default tcl.h checks in
+	# this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using Tcl header defaults" >&5
+$as_echo "using Tcl header defaults" >&6; }
+    else
+
+cat >>confdefs.h <<_ACEOF
+#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
+_ACEOF
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_cv_type_64bit}" >&5
+$as_echo "${tcl_cv_type_64bit}" >&6; }
+
+	# Now check for auxiliary declarations
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5
+$as_echo_n "checking for struct dirent64... " >&6; }
+if ${tcl_cv_struct_dirent64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <dirent.h>
+int
+main ()
+{
+struct dirent64 p;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_struct_dirent64=yes
+else
+  tcl_cv_struct_dirent64=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5
+$as_echo "$tcl_cv_struct_dirent64" >&6; }
+	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+
+$as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h
+
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5
+$as_echo_n "checking for struct stat64... " >&6; }
+if ${tcl_cv_struct_stat64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 p;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_struct_stat64=yes
+else
+  tcl_cv_struct_stat64=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_stat64" >&5
+$as_echo "$tcl_cv_struct_stat64" >&6; }
+	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+
+$as_echo "#define HAVE_STRUCT_STAT64 1" >>confdefs.h
+
+	fi
+
+	for ac_func in open64 lseek64
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5
+$as_echo_n "checking for off64_t... " >&6; }
+	if ${tcl_cv_type_off64_t+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+off64_t offset;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tcl_cv_type_off64_t=yes
+else
+  tcl_cv_type_off64_t=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+			if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+	        test "x${ac_cv_func_lseek64}" = "xyes" && \
+	        test "x${ac_cv_func_open64}" = "xyes" ; then
+
+$as_echo "#define HAVE_TYPE_OFF64_T 1" >>confdefs.h
+
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	fi
+    fi
+
+
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
+$as_echo_n "checking for build with symbols... " >&6; }
+    # Check whether --enable-symbols was given.
+if test "${enable_symbols+set}" = set; then :
+  enableval=$enable_symbols; tcl_ok=$enableval
+else
+  tcl_ok=no
+fi
+
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+	CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
+	LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    else
+	CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+	LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+	if test "$tcl_ok" = "yes"; then
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
+$as_echo "yes (standard debugging)" >&6; }
+	fi
+    fi
+    # TEA specific:
+    if test "${TEA_PLATFORM}" != "windows" ; then
+	LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+
+
+
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+
+$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h
+
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+	if test "$tcl_ok" = "all"; then
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem debugging" >&5
+$as_echo "enabled symbols mem debugging" >&6; }
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
+$as_echo "enabled $tcl_ok debugging" >&6; }
+	fi
+    fi
+
+
+#--------------------------------------------------------------------
+# Everyone should be linking against the Tcl stub library.  If you
+# can't for some reason, remove this definition.  If you aren't using
+# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
+# link against the non-stubbed Tcl library.  Add Tk too if necessary.
+#--------------------------------------------------------------------
+
+
+$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
+
+
+$as_echo "#define USE_TK_STUBS 1" >>confdefs.h
+
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library.  It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+	MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)"
+	MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)"
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+print("manifest needed")
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "manifest needed" >/dev/null 2>&1; then :
+
+	# Could do a CHECK_PROG for mt, but should always be with MSVC8+
+	VC_MANIFEST_EMBED_DLL="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;2 ; fi"
+	VC_MANIFEST_EMBED_EXE="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;1 ; fi"
+	MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
+
+    CLEANFILES="$CLEANFILES *.manifest"
+
+
+fi
+rm -f conftest*
+
+	MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)"
+    else
+	MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)"
+	MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+	MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+	MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+	MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+	if test "${SHARED_BUILD}" = "1" ; then
+	    # We force the unresolved linking of symbols that are really in
+	    # the private libraries of Tcl and Tk.
+	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+	    if test x"${TK_BIN_DIR}" != x ; then
+		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+	    fi
+	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+	else
+	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+	fi
+	# Some packages build their own stubs libraries
+	eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+	if test "$GCC" = "yes"; then
+	    PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+	fi
+	# These aren't needed on Windows (either MSVC or gcc)
+	RANLIB=:
+	RANLIB_STUB=:
+    else
+	RANLIB_STUB="${RANLIB}"
+	if test "${SHARED_BUILD}" = "1" ; then
+	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+	    if test x"${TK_BIN_DIR}" != x ; then
+		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+	    fi
+	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+	    RANLIB=:
+	else
+	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+	fi
+	# Some packages build their own stubs libraries
+	eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+	CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+#	Locate the X11 header files and the X11 library archive.
+#--------------------------------------------------------------------
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5
+$as_echo_n "checking for X... " >&6; }
+
+
+# Check whether --with-x was given.
+if test "${with_x+set}" = set; then :
+  withval=$with_x;
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+  # The user explicitly disabled X.
+  have_x=disabled
+else
+  case $x_includes,$x_libraries in #(
+    *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #(
+    *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=no ac_x_libraries=no
+rm -f -r conftest.dir
+if mkdir conftest.dir; then
+  cd conftest.dir
+  cat >Imakefile <<'_ACEOF'
+incroot:
+	@echo incroot='${INCROOT}'
+usrlibdir:
+	@echo usrlibdir='${USRLIBDIR}'
+libdir:
+	@echo libdir='${LIBDIR}'
+_ACEOF
+  if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then
+    # GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+    for ac_var in incroot usrlibdir libdir; do
+      eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`"
+    done
+    # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+    for ac_extension in a so sl dylib la dll; do
+      if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" &&
+	 test -f "$ac_im_libdir/libX11.$ac_extension"; then
+	ac_im_usrlibdir=$ac_im_libdir; break
+      fi
+    done
+    # Screen out bogus values from the imake configuration.  They are
+    # bogus both because they are the default anyway, and because
+    # using them would break gcc on systems where it needs fixed includes.
+    case $ac_im_incroot in
+	/usr/include) ac_x_includes= ;;
+	*) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;;
+    esac
+    case $ac_im_usrlibdir in
+	/usr/lib | /usr/lib64 | /lib | /lib64) ;;
+	*) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;;
+    esac
+  fi
+  cd ..
+  rm -f -r conftest.dir
+fi
+
+# Standard set of common directories for X headers.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ac_x_header_dirs='
+/usr/X11/include
+/usr/X11R7/include
+/usr/X11R6/include
+/usr/X11R5/include
+/usr/X11R4/include
+
+/usr/include/X11
+/usr/include/X11R7
+/usr/include/X11R6
+/usr/include/X11R5
+/usr/include/X11R4
+
+/usr/local/X11/include
+/usr/local/X11R7/include
+/usr/local/X11R6/include
+/usr/local/X11R5/include
+/usr/local/X11R4/include
+
+/usr/local/include/X11
+/usr/local/include/X11R7
+/usr/local/include/X11R6
+/usr/local/include/X11R5
+/usr/local/include/X11R4
+
+/usr/X386/include
+/usr/x386/include
+/usr/XFree86/include/X11
+
+/usr/include
+/usr/local/include
+/usr/unsupported/include
+/usr/athena/include
+/usr/local/x11r5/include
+/usr/lpp/Xamples/include
+
+/usr/openwin/include
+/usr/openwin/share/include'
+
+if test "$ac_x_includes" = no; then
+  # Guess where to find include files, by looking for Xlib.h.
+  # First, try using that file with no special directory specified.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+  for ac_dir in $ac_x_header_dirs; do
+  if test -r "$ac_dir/X11/Xlib.h"; then
+    ac_x_includes=$ac_dir
+    break
+  fi
+done
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+fi # $ac_x_includes = no
+
+if test "$ac_x_libraries" = no; then
+  # Check for the libraries.
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS=$LIBS
+  LIBS="-lX11 $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize ()
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  LIBS=$ac_save_LIBS
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+  LIBS=$ac_save_LIBS
+for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
+do
+  # Don't even attempt the hair of trying to link an X program!
+  for ac_extension in a so sl dylib la dll; do
+    if test -r "$ac_dir/libX11.$ac_extension"; then
+      ac_x_libraries=$ac_dir
+      break 2
+    fi
+  done
+done
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi # $ac_x_libraries = no
+
+case $ac_x_includes,$ac_x_libraries in #(
+  no,* | *,no | *\'*)
+    # Didn't find X, or a directory has "'" in its name.
+    ac_cv_have_x="have_x=no";; #(
+  *)
+    # Record where we found X for the cache.
+    ac_cv_have_x="have_x=yes\
+	ac_x_includes='$ac_x_includes'\
+	ac_x_libraries='$ac_x_libraries'"
+esac
+fi
+;; #(
+    *) have_x=yes;;
+  esac
+  eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5
+$as_echo "$have_x" >&6; }
+  no_x=yes
+else
+  # If each of the values was on the command line, it overrides each guess.
+  test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+  test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+  # Update the cache value to reflect the command line values.
+  ac_cv_have_x="have_x=yes\
+	ac_x_includes='$x_includes'\
+	ac_x_libraries='$x_libraries'"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5
+$as_echo "libraries $x_libraries, headers $x_includes" >&6; }
+fi
+
+    not_really_there=""
+    if test "$no_x" = ""; then
+	if test "$x_includes" = ""; then
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <X11/XIntrinsic.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  not_really_there="yes"
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+	else
+	    if test ! -r $x_includes/X11/Intrinsic.h; then
+		not_really_there="yes"
+	    fi
+	fi
+    fi
+    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11 header files" >&5
+$as_echo_n "checking for X11 header files... " >&6; }
+	found_xincludes="no"
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <X11/Intrinsic.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  found_xincludes="yes"
+else
+  found_xincludes="no"
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+	if test "$found_xincludes" = "no"; then
+	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+	    for i in $dirs ; do
+		if test -r $i/X11/Intrinsic.h; then
+		    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $i" >&5
+$as_echo "$i" >&6; }
+		    XINCLUDES=" -I$i"
+		    found_xincludes="yes"
+		    break
+		fi
+	    done
+	fi
+    else
+	if test "$x_includes" != ""; then
+	    XINCLUDES="-I$x_includes"
+	    found_xincludes="yes"
+	fi
+    fi
+    if test "$found_xincludes" = "no"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: couldn't find any!" >&5
+$as_echo "couldn't find any!" >&6; }
+    fi
+
+    if test "$no_x" = yes; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11 libraries" >&5
+$as_echo_n "checking for X11 libraries... " >&6; }
+	XLIBSW=nope
+	dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+	for i in $dirs ; do
+	    if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $i" >&5
+$as_echo "$i" >&6; }
+		XLIBSW="-L$i -lX11"
+		x_libraries="$i"
+		break
+	    fi
+	done
+    else
+	if test "$x_libraries" = ""; then
+	    XLIBSW=-lX11
+	else
+	    XLIBSW="-L$x_libraries -lX11"
+	fi
+    fi
+    if test "$XLIBSW" = nope ; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XCreateWindow in -lXwindow" >&5
+$as_echo_n "checking for XCreateWindow in -lXwindow... " >&6; }
+if ${ac_cv_lib_Xwindow_XCreateWindow+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXwindow  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XCreateWindow ();
+int
+main ()
+{
+return XCreateWindow ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_Xwindow_XCreateWindow=yes
+else
+  ac_cv_lib_Xwindow_XCreateWindow=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xwindow_XCreateWindow" >&5
+$as_echo "$ac_cv_lib_Xwindow_XCreateWindow" >&6; }
+if test "x$ac_cv_lib_Xwindow_XCreateWindow" = xyes; then :
+  XLIBSW=-lXwindow
+fi
+
+    fi
+    if test "$XLIBSW" = nope ; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find any!  Using -lX11." >&5
+$as_echo "could not find any!  Using -lX11." >&6; }
+	XLIBSW=-lX11
+    fi
+
+
+#--------------------------------------------------------------------
+#	Check for freetype / fontconfig / Xft support.
+#--------------------------------------------------------------------
+
+if test "${TEA_WINDOWINGSYSTEM}" = "x11"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use xft" >&5
+$as_echo_n "checking whether to use xft... " >&6; }
+    # Check whether --enable-xft was given.
+if test "${enable_xft+set}" = set; then :
+  enableval=$enable_xft; enable_xft=$enableval
+else
+  enable_xft="default"
+fi
+
+    XFT_CFLAGS=""
+    XFT_LIBS=""
+    if test "$enable_xft" = "no" ; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_xft" >&5
+$as_echo "$enable_xft" >&6; }
+    else
+	found_xft="yes"
+			XFT_CFLAGS=`xft-config --cflags 2>/dev/null` || found_xft="no"
+	XFT_LIBS=`xft-config --libs 2>/dev/null` || found_xft="no"
+	if test "$found_xft" = "no" ; then
+	    found_xft=yes
+	    XFT_CFLAGS=`pkg-config --cflags xft 2>/dev/null` || found_xft="no"
+	    XFT_LIBS=`pkg-config --libs xft 2>/dev/null` || found_xft="no"
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $found_xft" >&5
+$as_echo "$found_xft" >&6; }
+		if test "$found_xft" = "yes" ; then
+	    tk_oldCFlags=$CFLAGS
+	    CFLAGS="$XINCLUDES $XFT_CFLAGS"
+	    tk_oldLibs=$LIBS
+	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
+	    ac_fn_c_check_header_compile "$LINENO" "X11/Xft/Xft.h" "ac_cv_header_X11_Xft_Xft_h" "#include <X11/Xlib.h>
+"
+if test "x$ac_cv_header_X11_Xft_Xft_h" = xyes; then :
+
+else
+
+		found_xft=no
+
+fi
+
+
+	    CFLAGS=$tk_oldCFlags
+	    LIBS=$tk_oldLibs
+	fi
+		if test "$found_xft" = "yes" ; then
+	    tk_oldCFlags=$CFLAGS
+	    CFLAGS="$XINCLUDES $XFT_CFLAGS"
+	    tk_oldLibs=$LIBS
+	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XftFontOpen in -lXft" >&5
+$as_echo_n "checking for XftFontOpen in -lXft... " >&6; }
+if ${ac_cv_lib_Xft_XftFontOpen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXft  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XftFontOpen ();
+int
+main ()
+{
+return XftFontOpen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_Xft_XftFontOpen=yes
+else
+  ac_cv_lib_Xft_XftFontOpen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xft_XftFontOpen" >&5
+$as_echo "$ac_cv_lib_Xft_XftFontOpen" >&6; }
+if test "x$ac_cv_lib_Xft_XftFontOpen" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBXFT 1
+_ACEOF
+
+  LIBS="-lXft $LIBS"
+
+else
+
+		found_xft=no
+
+fi
+
+	    CFLAGS=$tk_oldCFlags
+	    LIBS=$tk_oldLibs
+	fi
+		if test "$found_xft" = "no" ; then
+	    if test "$enable_xft" = "yes" ; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find xft configuration, or xft is unusable" >&5
+$as_echo "$as_me: WARNING: Can't find xft configuration, or xft is unusable" >&2;}
+	    fi
+	    enable_xft=no
+	    XFT_CFLAGS=""
+	    XFT_LIBS=""
+	else
+            enable_xft=yes
+	fi
+    fi
+    if test $enable_xft = "yes" ; then
+
+$as_echo "#define HAVE_XFT 1" >>confdefs.h
+
+    fi
+
+
+fi
+
+#--------------------------------------------------------------------
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
+#--------------------------------------------------------------------
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
+$as_echo_n "checking for tclsh... " >&6; }
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${TCLSH_PROG}" >&5
+$as_echo "${TCLSH_PROG}" >&6; }
+
+
+#TEA_PROG_WISH
+
+#--------------------------------------------------------------------
+# Finally, substitute all of the various values into the Makefile.
+# You may alternatively have a special pkgIndex.tcl.in or other files
+# which require substituting th AC variables in.  Include these here.
+#--------------------------------------------------------------------
+
+ac_config_files="$ac_config_files Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+	g
+	s/^\n//
+	s/\n/ /g
+	p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by tlt $as_me 3.0, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+tlt config.status 3.0
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h |  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X "  :F $CONFIG_FILES      "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/tlt3.0/configure.in b/tlt3.0/configure.in
new file mode 100755
index 0000000..bfa0d48
--- /dev/null
+++ b/tlt3.0/configure.in
@@ -0,0 +1,299 @@
+#!/bin/bash -norc
+dnl	This file is an input file used by the GNU "autoconf" program to
+dnl	generate the file "configure", which is run during Tcl installation
+dnl	to configure the system for the local environment.
+
+#-----------------------------------------------------------------------
+# Sample configure.in for Tcl Extensions.  The only places you should
+# need to modify this file are marked by the string __CHANGE__
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Set your package name and version numbers here.
+#
+# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
+# set as provided.  These will also be added as -D defs in your Makefile
+# so you can encode the package version directly into the source files.
+# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
+# so that we create the export library with the dll.
+#-----------------------------------------------------------------------
+
+AC_INIT([tlt], [3.0])
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+TEA_INIT([3.9])
+
+AC_CONFIG_AUX_DIR(tclconfig)
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+TEA_PATH_TCLCONFIG
+TEA_LOAD_TCLCONFIG
+
+#--------------------------------------------------------------------
+# Load the tkConfig.sh file if necessary (Tk extension)
+#--------------------------------------------------------------------
+
+TEA_PATH_TKCONFIG
+TEA_LOAD_TKCONFIG
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+TEA_PREFIX
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC and a few others to create the basic setup
+# necessary to compile executables.
+#-----------------------------------------------------------------------
+
+TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+TEA_ADD_SOURCES([
+	bltBase64.c 
+	bltBgStyle.c
+	bltBind.c
+	bltBitmap.c
+	bltChain.c 
+	bltConfig.c
+	bltDBuffer.c 
+	bltGrAxis.c
+	bltGrBar.c
+	bltGrElem.c
+	bltGrHairs.c
+	bltGrLegd.c
+	bltGrLine.c
+	bltGrMarker.c
+	bltGrMisc.c
+	bltGrPen.c
+	bltGrPs.c
+	bltGraph.c
+	bltHash.c 
+	bltImage.c
+	bltInt.c 
+	bltInit.c 
+	bltList.c
+	bltNsUtil.c
+	bltParse.c
+	bltPool.c
+	bltPs.c
+	bltPsAfm.c
+	bltSpline.c
+	bltSwitch.c
+	bltText.c
+	bltUnixFont.c
+	bltUnixWindow.c
+	bltUtil.c
+	bltVecCmd.c
+	bltVecMath.c
+	bltVector.c
+	bltWindow.c
+	])
+TEA_ADD_HEADERS([bltVector.h])
+TEA_ADD_INCLUDES([-I. -I\"`${CYGPATH} ${srcdir}`\"])
+TEA_ADD_LIBS([])
+TEA_ADD_CFLAGS([-Wunused])
+TEA_ADD_STUB_SOURCES([])
+TEA_ADD_TCL_SOURCES([library/graph.tcl library/bltGraph.pro])
+
+#--------------------------------------------------------------------
+# __CHANGE__
+#
+# You can add more files to clean if your extension creates any extra
+# files by extending CLEANFILES.
+# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
+# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
+#
+# A few miscellaneous platform-specific items:
+# TEA_ADD_* any platform specific compiler/build info here.
+#--------------------------------------------------------------------
+
+CLEANFILES="$CLEANFILES config.status config.log Makefile"
+if test "${TEA_PLATFORM}" = "windows" ; then
+    # Ensure no empty if clauses
+    :
+    #TEA_ADD_SOURCES([win/winFile.c])
+    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+    # Ensure no empty else clauses
+    :
+    #TEA_ADD_SOURCES([unix/unixFile.c])
+    #TEA_ADD_LIBS([-lsuperfly])
+fi
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# Choose which headers you need.  Extension authors should try very
+# hard to only rely on the Tcl public header files.  Internal headers
+# contain private data structures and are subject to change without
+# notice.
+# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
+#--------------------------------------------------------------------
+
+TEA_PUBLIC_TCL_HEADERS
+TEA_PRIVATE_TCL_HEADERS
+
+TEA_PUBLIC_TK_HEADERS
+TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_THREADS
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SHARED
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects.  This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+TEA_CONFIG_CFLAGS
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SYMBOLS
+
+#--------------------------------------------------------------------
+# Everyone should be linking against the Tcl stub library.  If you
+# can't for some reason, remove this definition.  If you aren't using
+# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
+# link against the non-stubbed Tcl library.  Add Tk too if necessary.
+#--------------------------------------------------------------------
+
+AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
+AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library.  It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+TEA_MAKE_LIB
+
+#--------------------------------------------------------------------
+#	Locate the X11 header files and the X11 library archive.
+#--------------------------------------------------------------------
+
+SC_PATH_X
+
+#--------------------------------------------------------------------
+#	Check for freetype / fontconfig / Xft support.
+#--------------------------------------------------------------------
+
+if test "${TEA_WINDOWINGSYSTEM}" = "x11"; then
+    AC_MSG_CHECKING([whether to use xft])
+    AC_ARG_ENABLE(xft,
+	AC_HELP_STRING([--enable-xft],
+	    [use freetype/fontconfig/xft (default: on)]),
+	[enable_xft=$enableval], [enable_xft="default"])
+    XFT_CFLAGS=""
+    XFT_LIBS=""
+    if test "$enable_xft" = "no" ; then
+	AC_MSG_RESULT([$enable_xft])
+    else
+	found_xft="yes"
+	dnl make sure package configurator (xft-config or pkg-config
+	dnl says that xft is present.
+	XFT_CFLAGS=`xft-config --cflags 2>/dev/null` || found_xft="no"
+	XFT_LIBS=`xft-config --libs 2>/dev/null` || found_xft="no"
+	if test "$found_xft" = "no" ; then
+	    found_xft=yes
+	    XFT_CFLAGS=`pkg-config --cflags xft 2>/dev/null` || found_xft="no"
+	    XFT_LIBS=`pkg-config --libs xft 2>/dev/null` || found_xft="no"
+	fi
+	AC_MSG_RESULT([$found_xft])
+	dnl make sure that compiling against Xft header file doesn't bomb
+	if test "$found_xft" = "yes" ; then
+	    tk_oldCFlags=$CFLAGS
+	    CFLAGS="$XINCLUDES $XFT_CFLAGS"
+	    tk_oldLibs=$LIBS
+	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
+	    AC_CHECK_HEADER(X11/Xft/Xft.h, [], [
+		found_xft=no
+	    ],[#include <X11/Xlib.h>])
+	    CFLAGS=$tk_oldCFlags
+	    LIBS=$tk_oldLibs
+	fi
+	dnl make sure that linking against Xft libraries finds freetype
+	if test "$found_xft" = "yes" ; then
+	    tk_oldCFlags=$CFLAGS
+	    CFLAGS="$XINCLUDES $XFT_CFLAGS"
+	    tk_oldLibs=$LIBS
+	    LIBS="$tk_oldLIBS $XFT_LIBS $XLIBSW"
+	    AC_CHECK_LIB(Xft, XftFontOpen, [], [
+		found_xft=no
+	    ])
+	    CFLAGS=$tk_oldCFlags
+	    LIBS=$tk_oldLibs
+	fi
+	dnl print a warning if xft is unusable and was specifically requested
+	if test "$found_xft" = "no" ; then
+	    if test "$enable_xft" = "yes" ; then
+		AC_MSG_WARN([Can't find xft configuration, or xft is unusable])
+	    fi
+	    enable_xft=no
+	    XFT_CFLAGS=""
+	    XFT_LIBS=""
+	else
+            enable_xft=yes
+	fi
+    fi
+    if test $enable_xft = "yes" ; then
+	AC_DEFINE(HAVE_XFT, 1, [Have we turned on XFT (antialiased fonts)?])
+    fi
+    AC_SUBST(XFT_CFLAGS)
+    AC_SUBST(XFT_LIBS)
+fi
+
+#--------------------------------------------------------------------
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
+#--------------------------------------------------------------------
+
+TEA_PROG_TCLSH
+#TEA_PROG_WISH
+
+#--------------------------------------------------------------------
+# Finally, substitute all of the various values into the Makefile.
+# You may alternatively have a special pkgIndex.tcl.in or other files
+# which require substituting th AC variables in.  Include these here.
+#--------------------------------------------------------------------
+
+AC_OUTPUT([Makefile])
diff --git a/tlt3.0/doc/BLT.n b/tlt3.0/doc/BLT.n
new file mode 100644
index 0000000..1593029
--- /dev/null
+++ b/tlt3.0/doc/BLT.n
@@ -0,0 +1,153 @@
+'\"
+'\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies.
+'\"
+'\" Permission to use, copy, modify, and distribute this software and its
+'\" documentation for any purpose and without fee is hereby granted, provided
+'\" that the above copyright notice appear in all copies and that both that the
+'\" copyright notice and warranty disclaimer appear in supporting documentation,
+'\" and that the names of Lucent Technologies any of their entities not be used
+'\" in advertising or publicity pertaining to distribution of the software
+'\" without specific, written prior permission.
+'\"
+'\" Lucent Technologies disclaims all warranties with regard to this software,
+'\" including all implied warranties of merchantability and fitness.  In no event
+'\" shall Lucent Technologies be liable for any special, indirect or
+'\" consequential damages or any damages whatsoever resulting from loss of use,
+'\" data or profits, whether in an action of contract, negligence or other
+'\" tortuous action, arising out of or in connection with the use or performance
+'\" of this software.  
+'\"
+.so man.macros
+.TH intro n BLT_VERSION BLT "BLT Built-In Commands"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+BLT \- Introduction to the BLT library
+.BE
+.SH DESCRIPTION
+BLT is a library of extensions to the Tk library.  It adds new
+commands and variables to the application's interpreter.
+.LP
+.SH COMMANDS
+The following commands are added to the interpreter from the BLT library:
+.TP 15
+\fBtable\fR 
+A table geometry manager for Tk.  You specify window placements as table 
+row,column positions and windows can also span multiple rows or columns. 
+It also has many options for setting and/or bounding window sizes.
+.TP 15
+\fBgraph\fR 
+A 2D plotting widget.  Plots two variable data in a window with an optional 
+legend and annotations.   It has of several components; coordinate axes, 
+crosshairs, a legend, and a collection of elements and tags.
+.TP 15
+\fBbarchart\fR 
+A barchart widget.  Plots two-variable data as rectangular bars in a 
+window.  The x-coordinate values designate the position of the bar along 
+the x-axis, while the y-coordinate values designate the magnitude.
+The \fBbarchart\fR widget has of several components; coordinate axes, 
+crosshairs, a legend, and a collection of elements and tags.
+.TP 15
+\fBvector\fR 
+Creates a vector of floating point values.  The vector's components
+can be manipulated in three ways: through a Tcl array variable, a Tcl
+command, or the C API.
+.TP
+\fBspline\fR
+Computes a spline fitting a set of data points (x and y vectors) and
+produces a vector of the interpolated images (y-coordinates) at a
+given set of x-coordinates.
+.TP 15
+\fBbgexec\fR 
+Like Tcl's \fBexec\fR command, \fBbgexec\fR runs a pipeline of Unix 
+commands in the background.  Unlike \fBexec\fR, the output of the last
+process is collected and a global Tcl variable is set upon its completion.
+\fBbgexec\fR can be used with \fBtkwait\fR to wait for Unix commands
+to finish while still handling expose events.  Intermediate output is
+also available while the pipeline is active.
+.TP 15
+\fBbusy\fR 
+Creates a "busy window" which prevents user-interaction when an
+application is busy.  The busy window also provides an easy way 
+to have temporary busy cursors (such as a watch or hourglass).
+.TP 15
+\fBbitmap\fR 
+Reads and writes bitmaps from Tcl.  New X bitmaps can be defined
+on-the-fly from Tcl, obviating the need to copy around bitmap files.  
+Other options query loaded X bitmap's dimensions and data.
+.TP 15
+\fBdrag&drop\fR 
+Provides a drag-and-drop facility for Tk.  Information (represented
+by a token window) can be dragged to and from any Tk window, including
+those of another Tk application.  \fBdrag&drop\fR acts as a 
+coordinator, directing Tk \fBsend\fR commands between (or within) TCL/Tk 
+applications. 
+.TP 15
+\fBhtext\fR 
+A simple hypertext widget.  Combines text and Tk widgets into a single
+scroll-able window.  Tcl commands can be embedded into text, which are
+invoked as the text is parsed.  In addition, Tk widgets can be
+appended to the window at the current point in the text.  \fBHtext\fR
+can be also used to create scrolled windows of Tk widgets.
+.TP 15
+\fBwinop\fR 
+Raise, lower, map, or, unmap any window.  The raise and lower functions
+are useful for stacking windows above or below "busy windows".
+.TP 15
+\fBwatch\fR 
+Arranges for Tcl procedures to be called before and/or after the execution
+of every Tcl command. This command
+may be used in the logging, profiling, or tracing of Tcl code.
+.TP 15
+\fBbltdebug\fR 
+A simple Tcl command tracing facility useful for debugging Tcl code.  
+Displays each Tcl command before and after substitution along its level 
+in the interpreter on standard error.
+.SH VARIABLES
+.PP
+The following Tcl variables are either set or used by BLT at various times
+in its execution:
+.TP 15
+\fBblt_library\fR
+This variable contains the name of a directory containing a library
+of Tcl scripts and other files related to BLT.  Currently, this 
+directory contains the \fBdrag&drop\fR protocol scripts and the 
+PostScript prolog
+used by \fBgraph\fR and \fBbarchart\fR.
+The value of this variable is taken from the BLT_LIBRARY environment
+variable, if one exists, or else from a default value compiled into
+the \fBBLT\fR library.
+.TP 15
+\fBblt_versions\fR 
+This variable is set in the interpreter for each application. It is an 
+array of the current version numbers for each 
+of the BLT commands in the form \fImajor\fR.\fIminor\fR.  \fIMajor\fR and
+\fIminor\fR are integers.  The major version number increases in
+any command that includes changes that are not backward compatible
+(i.e. whenever existing applications and scripts may have to change to
+work with the new release).  The minor version number increases with
+each new release of a command, except that it resets to zero whenever the
+major version number changes.  The array is indexed by the individual 
+command name.
+.SH ADDING BLT TO YOUR APPLICATIONS
+It's easy to add BLT to an existing Tk application.  BLT requires no 
+patches or edits to the Tcl or Tk libraries.  To add BLT, simply add the 
+following code snippet to your application's tkAppInit.c file.  
+.CS
+if (Blt_Init(interp) != TCL_OK) {
+    return TCL_ERROR;
+}
+.CE
+Recompile and link with the BLT library (libBLT.a) and that's it.
+.PP
+Alternately, you can dynamically load BLT, simply by invoking the
+command
+.CS
+package require BLT
+.CE
+from your Tcl script.
+.SH BUGS
+Send bug reports, requests, suggestions, etc. to 
+gah at siliconmetrics.com or ghowlett at grandecom.net
+.SH KEYWORDS
+BLT
diff --git a/tlt3.0/doc/barchart.n b/tlt3.0/doc/barchart.n
new file mode 100644
index 0000000..ec2b5f4
--- /dev/null
+++ b/tlt3.0/doc/barchart.n
@@ -0,0 +1,2236 @@
+'\"
+'\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies.
+'\"
+'\" Permission to use, copy, modify, and distribute this software and its
+'\" documentation for any purpose and without fee is hereby granted, provided
+'\" that the above copyright notice appear in all copies and that both that the
+'\" copyright notice and warranty disclaimer appear in supporting documentation,
+'\" and that the names of Lucent Technologies any of their entities not be used
+'\" in advertising or publicity pertaining to distribution of the software
+'\" without specific, written prior permission.
+'\"
+'\" Lucent Technologies disclaims all warranties with regard to this software,
+'\" including all implied warranties of merchantability and fitness.  In no event
+'\" shall Lucent Technologies be liable for any special, indirect or
+'\" consequential damages or any damages whatsoever resulting from loss of use,
+'\" data or profits, whether in an action of contract, negligence or other
+'\" tortuous action, arising out of or in connection with the use or performance
+'\" of this software.  
+'\"
+'\" Barchart widget created by Sani Nassif and George Howlett.
+'\"
+.so man.macros
+.TH barchart n BLT_VERSION BLT "BLT Built-In Commands"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+barchart \-  Bar chart for plotting X-Y coordinate data.
+.SH SYNOPSIS
+\fBbarchart\fI \fIpathName \fR?\fIoption value\fR?...
+.BE
+.SH DESCRIPTION
+The \fBbarchart\fR command creates a bar chart for plotting
+two-dimensional data (X-Y coordinates). A bar chart is a graphic means
+of comparing numbers by displaying bars of lengths proportional to the
+y-coordinates of the points they represented.  The bar chart has many
+configurable components: coordinate axes, elements, legend, grid
+lines, cross hairs, etc.  They allow you to customize the look and
+feel of the graph.
+.SH INTRODUCTION
+The \fBbarchart\fR command creates a new window for plotting
+two-dimensional data (X-Y coordinates), using bars of
+various lengths to represent the data points.  The bars are drawn in a
+rectangular area displayed in the center of the new window.  This is the
+\fIplotting area\fR.  The coordinate axes are drawn in
+the margins surrounding the plotting area.  By default, the legend is
+drawn in the right margin.  The title is displayed in top margin.
+.PP
+A \fBbarchart\fR widget has several configurable components:
+coordinate axes, data elements, legend, grid, cross hairs, pens,
+postscript, and annotation markers.  Each component can be queried or
+modified.
+.TP 1i
+\f(CWaxis\fR 
+
+Up to four coordinate axes (two X\-coordinate and two Y\-coordinate
+axes) can be displayed, but you can create and use any number of
+axes. Axes control what region of data is displayed and how the data
+is scaled. Each axis consists of the axis line, title, major and minor
+ticks, and tick labels. Tick labels display the value at each major
+tick.
+.TP 1i
+\f(CWcrosshairs\fR 
+Cross hairs are used to position the mouse pointer relative to the X
+and Y coordinate axes. Two perpendicular lines, intersecting at the
+current location of the mouse, extend across the plotting area to the
+coordinate axes.
+.TP 1i
+\f(CWelement\fR 
+An element represents a set of data to be plotted.  It contains an x
+and y vector of values representing the data points.  Each
+data point is displayed as a bar where the length of the bar is
+proportional to the ordinate (Y-coordinate) of the data point.
+The appearance of the bar, such as its color, stipple, or relief
+is configurable.
+.sp
+A special case exists when two or more data points have the same
+abscissa (X-coordinate).  By default, the bars are overlayed, one on
+top of the other.  The bars are drawn in the order of the element
+display list.  But you can also configure the bars to be displayed in
+two other ways.  They may be displayed as a stack, where each bar
+(with the same abscissa) is stacked on the previous.  Or they can be
+drawn side-by-side as thin bars.  The width of each bar is a function
+of the number of data points with the same abscissa.
+.TP 1i
+\f(CWgrid\fR
+Extends the major and minor ticks of the X\-axis and/or Y\-axis across the 
+plotting area. 
+.TP 1i
+\f(CWlegend\fR 
+The legend displays the name and symbol of each data element. 
+The legend can be drawn in any margin or in the plotting area.
+.TP 1i
+\f(CWmarker\fR
+Markers are used annotate or highlight areas of the graph. For
+example, you could use a text marker to label a particular data
+point. Markers come in various forms: text strings, bitmaps, connected
+line segments, images, polygons, or embedded widgets.
+.TP 1i
+\f(CWpen\fR 
+Pens define attributes for elements.  Data elements use pens to
+specify how they should be drawn.  A data element may use many pens at
+once.  Here the particular pen used for a data point is determined
+from each element's weight vector (see the element's \fB\-weight\fR
+and \fB\-style\fR options).
+.TP 1i
+\f(CWpostscript\fR
+The widget can generate encapsulated PostScript output. This component
+has several options to configure how the PostScript is generated.
+.SH SYNTAX
+.DS
+\fBbarchart \fIpathName \fR?\fIoption value\fR?...
+.DE
+The \fBbarchart\fR command creates a new window \fIpathName\fR and makes
+it into a \fBbarchart\fR widget.  At the time this command is invoked, there
+must not exist a window named \fIpathName\fR, but \fIpathName\fR's
+parent must exist.  Additional options may be specified on the
+command line or in the option database to configure aspects of the
+graph such as its colors and font.  See the \fBconfigure\fR operation
+below for the exact details about what \fIoption\fR and \fIvalue\fR
+pairs are valid.
+.PP
+If successful, \fBbarchart\fR returns the path name of the widget.  It
+also creates a new Tcl command by the same name.  You can use this
+command to invoke various operations that query or modify the graph.
+The general form is:
+.DS
+\fIpathName \fIoperation\fR \fR?\fIarg\fR?...
+.DE
+Both \fIoperation\fR and its arguments determine the exact behavior of
+the command.  The operations available for the graph are described in 
+the 
+.SB "BARCHART OPERATIONS"
+section.
+.PP
+The command can also be used to access components of the graph.
+.DS
+\fIpathName component operation\fR ?\fIarg\fR?...
+.DE
+The operation, now located after the name of the component, is the
+function to be performed on that component. Each component has its own
+set of operations that manipulate that component.  They will be
+described below in their own sections.
+.SH EXAMPLE
+The \fBbarchart\fR command creates a new bar chart.  
+.CS
+# Create a new bar chart.  Plotting area is black.
+barchart .b -plotbackground black
+.CE
+A new Tcl command \f(CW.b\fR is created.  This command can be used
+to query and modify the bar chart.  For
+example, to change the title of the graph to "My Plot", you use the
+new command and the \fBconfigure\fR operation.
+.CS
+# Change the title.
+\&.b configure -title "My Plot"
+.CE
+To add data elements, you use the command and the \fBelement\fR component.
+.CS
+# Create a new element named "e1"
+\&.b element create e1 \\
+	-xdata { 1 2 3 4 5 6 7 8 9 10 } \\
+	-ydata { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 
+		155.85 166.60 175.38 }
+.CE
+The element's X-Y coordinates are specified using lists of
+numbers.  Alternately, BLT vectors could be used to hold the X-Y
+coordinates.
+.CS
+# Create two vectors and add them to the barchart.
+vector xVector yVector
+xVector set { 1 2 3 4 5 6 7 8 9 10 }
+yVector set { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 
+	166.60 175.38 }
+\&n.b element create e1 -xdata xVector -ydata yVector
+.CE
+The advantage of using vectors is that when you modify one, the graph
+is automatically redrawn to reflect the new values.
+.CS
+# Change the y coordinate of the first point.
+set yVector(0) 25.18
+.CE
+An element named \f(CWe1\fR is now created in \f(CW.b\fR.  It 
+is automatically added to the display list of elements.  You can
+use this list to control in what order elements are displayed.
+To query or reset the element display list, you use the element's 
+\fBshow\fR operation.
+.CS
+# Get the current display list 
+set elemList [.b element show]
+# Remove the first element so it won't be displayed.
+\&.b element show [lrange $elemList 0 end]
+.CE
+The element will be displayed by as many bars as there are data points
+(in this case there are ten).  The bars will be drawn centered at the
+x-coordinate of the data point.  All the bars will have the same
+attributes (colors, stipple, etc).  The width of each bar is by
+default one unit.  You can change this with using the \fB\-barwidth\fR
+option.
+.CS
+# Change the scale of the x-coordinate data 
+xVector set { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 }
+# Make sure we change the bar width too.
+\&.b configure -barwidth 0.2
+.CE
+The height of each bar is proportional to the ordinate (Y-coordinate)
+of the data point.
+.PP
+If two or more data points have the same abscissa (X-coordinate
+value), the bars representing those data points may be drawn in 
+various ways.
+The default is to overlay the bars, one on top of the other.
+The ordering is determined from the of element display list.  If
+the stacked mode is selected (using the \fB\-barmode\fR configuration
+option), the bars are stacked, each bar above the previous.
+.CS
+# Display the elements as stacked.
+\&.b configure -barmode stacked
+.CE
+If the aligned mode is selected, the bars having the same
+x-coordinates are displayed side by side.  The width of each bar is a
+fraction of its normal width, based upon the number of bars with the
+same x-coordinate.
+.CS
+# Display the elements side-by-side.
+\&.b configure -barmode aligned
+.CE
+By default, the element's label in the legend will be also
+\f(CWe1\fR.  You can change the label, or specify no legend entry,
+again using the element's \fBconfigure\fR operation.
+.CS
+# Don't display "e1" in the legend.
+\&.b element configure e1 -label ""
+.CE
+You can configure more than just the element's label.  An element has
+many attributes such as stipple, foreground and background colors,
+relief, etc.
+.CS
+\&.b element configure e1 -fg red -bg pink \\
+	-stipple gray50
+.CE
+Four coordinate axes are automatically created: \f(CWx\fR, \f(CWx2\fR,
+\f(CWy\fR, and \f(CWy2\fR.  And by default, elements are mapped onto the
+axes \f(CWx\fR and \f(CWy\fR.  This can be changed with the \fB\-mapx\fR
+and \fB\-mapy\fR options.
+.CS
+# Map "e1" on the alternate y axis "y2".
+\&.b element configure e1 -mapy y2
+.CE
+Axes can be configured in many ways too.  For example, you change the
+scale of the Y\-axis from linear to log using the \fBaxis\fR component.
+.CS
+# Y-axis is log scale.
+\&.b axis configure y -logscale yes
+.CE
+One important way axes are used is to zoom in on a particular data
+region.  Zooming is done by simply specifying new axis limits using
+the \fB\-min\fR and \fB\-max\fR configuration options.
+.CS
+\&.b axis configure x \-min 1.0 \-max 1.5
+\&.b axis configure y \-min 12.0 \-max 55.15
+.CE
+To zoom interactively, you link the\fBaxis configure\fR operations with
+some user interaction (such as pressing the mouse button), using the
+\fBbind\fR command.  To convert between screen and graph coordinates,
+use the \fBinvtransform\fR operation.
+.CS
+# Click the button to set a new minimum 
+bind .b <ButtonPress-1> { 
+    %W axis configure x \-min [%W axis invtransform x %x]
+    %W axis configure x \-min [%W axis invtransform x %y]
+}
+.CE
+By default, the limits of the axis are determined from data values.
+To reset back to the default limits, set the \fB\-min\fR and
+\fB\-max\fR options to the empty value.
+.CS
+# Reset the axes to autoscale again.
+\&.b axis configure x \-min {} \-max {}
+\&.b axis configure y \-min {} \-max {}
+.CE
+By default, the legend is drawn in the right margin.  You can
+change this or any legend configuration options using the
+\fBlegend\fR component.
+.CS
+# Configure the legend font, color, and relief
+\&.b legend configure -position left -relief raised \\
+	-font fixed -fg blue
+.CE
+To prevent the legend from being displayed, turn on the \fB\-hide\fR
+option.
+.CS
+# Don't display the legend.
+\&.b legend configure \-hide yes\fR
+.CE
+The \fBbarchart\fR has simple drawing procedures called markers.  They can be
+used to highlight or annotate data in the graph. The types of markers
+available are bitmaps, polygons, lines, or windows.  Markers can be
+used, for example, to mark or brush points.  For example there may be
+a line marker which indicates some low-water value.  Markers are created
+using the \fBmarker\fR operation.
+.CS
+# Create a line represent the low water mark at 10.0
+\&.b marker create line -name "low_water" \\
+	-coords { -Inf 10.0 Inf 10.0 } \\
+	-dashes { 2 4 2 } -fg red -bg blue 
+.CE
+This creates a line marker named \f(CWlow_water\fR.  It will display a
+horizontal line stretching across the plotting area at the
+y-coordinate 10.0.  The coordinates "-Inf" and "Inf" indicate the
+relative minimum and maximum of the axis (in this case the x-axis).  By
+default, markers are drawn last, on top of the bars.  You can change this
+with the \fB\-under\fR option.
+.CS
+# Draw the marker before elements are drawn.
+\&.b marker configure low_water -under yes
+.CE
+You can add cross hairs or grid lines using the \fBcrosshairs\fR and
+\fBgrid\fR components.
+.CS
+# Display both cross hairs and grid lines.
+\&.b crosshairs configure -hide no -color red
+\&.b grid configure -hide no -dashes { 2 2 }
+.CE
+Finally, to get hardcopy of the graph, use the \fBpostscript\fR
+component.
+.CS
+# Print the bar chart into file "file.ps"
+\&.b postscript output file.ps -maxpect yes -decorations no
+.CE
+This generates a file \f(CWfile.ps\fR containing the encapsulated
+PostScript of the graph.  The option \fB\-maxpect\fR says to scale the
+plot to the size of the page.  Turning off the \fB\-decorations\fR
+option denotes that no borders or color backgrounds should be
+drawn (i.e. the background of the margins, legend, and plotting
+area will be white).
+.SH SYNTAX
+.DS
+\fBbarchart \fIpathName \fR?\fIoption value\fR?...
+.DE
+The \fBbarchart\fR command creates a new window \fIpathName\fR and makes
+it into a barchart widget.  At the time this command is invoked, there
+must not exist a window named \fIpathName\fR, but \fIpathName\fR's
+parent must exist.  Additional options may may be specified on the
+command line or in the option database to configure aspects of the
+bar chart such as its colors and font.  See the \fBconfigure\fR operation
+below for the exact details as to what \fIoption\fR and \fIvalue\fR
+pairs are valid.
+.PP
+If successful, \fBbarchart\fR returns \fIpathName\fR. It also creates a
+new Tcl command \fIpathName\fR.  This command may be used to invoke
+various operations to query or modify the bar chart.  It has the general
+form:
+.DS
+\fIpathName \fIoperation\fR \fR?\fIarg\fR?...
+.DE
+Both \fIoperation\fR and its arguments determine the exact behavior of
+the command.  The operations available for the bar chart are described in
+the following section.
+.SH "BARCHART OPERATIONS"
+.TP
+\fIpathName \fBbar \fIelemName \fR?\fIoption value\fR?...
+Creates a new barchart element \fIelemName\fR.  It's an
+error if an element \fIelemName\fR already exists.  
+See the manual for \fBbarchart\fR for details about
+what \fIoption\fR and \fIvalue\fR pairs are valid.
+.TP
+\fIpathName \fBcget\fR \fIoption\fR
+Returns the current value of the configuration option given by
+\fIoption\fR.  \fIOption\fR may be any option described
+below for the \fBconfigure\fR operation.
+.TP
+\fIpathName \fBconfigure \fR?\fIoption value\fR?...
+Queries or modifies the configuration options of the graph.  If
+\fIoption\fR isn't specified, a list describing the current
+options for \fIpathName\fR is returned.  If \fIoption\fR is specified,
+but not \fIvalue\fR, then a list describing \fIoption\fR is returned.
+If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then
+for each pair, the option \fIoption\fR is set to \fIvalue\fR.
+The following options are valid.
+.RS
+.TP
+\fB\-background \fIcolor\fR
+Sets the background color. This includes the margins and
+legend, but not the plotting area.
+.TP
+\fB\-barmode \fImode\fR 
+Indicates how related bar elements will be drawn.  Related elements
+have data points with the same abscissas (X-coordinates). \fIMode\fR
+indicates how those segments should be drawn. \fIMode\fR can be
+\f(CWinfront\fR, \f(CWaligned\fR, \f(CWoverlap\fR, or \f(CWstacked\fR.
+The default mode is \f(CWinfront\fR.
+.RS
+.TP 1i
+\f(CWinfront\fR
+Each successive segment is drawn in front of the previous. 
+.TP 1i
+\f(CWstacked\fR
+Each successive segment is stacked vertically on top of the previous.  
+.TP 1i
+\f(CWaligned\fR
+Segments is displayed aligned from right-to-left.  
+.TP 1i
+\f(CWoverlap\fR
+Like \f(CWaligned\fR but segments slightly overlap each other.  
+.RE
+.TP
+\fB\-barwidth \fIvalue\fR 
+Specifies the width of the bars.  This value can be overrided by the
+individual elements using their \fB\-barwidth\fR configuration option.
+\fIValue\fR is the width in terms of graph-coordinates.  The
+default width is \f(CW1.0\fR.
+.TP
+\fB\-borderwidth \fIpixels\fR
+Sets the width of the 3\-D border around the outside edge of the widget.  The
+\fB\-relief\fR option determines if the border is to be drawn.  The
+default is \f(CW2\fR.
+.TP
+\fB\-bottommargin \fIpixels\fR
+Specifies the size of the margin below the X\-coordinate axis.  If
+\fIpixels\fR is \f(CW0\fR, the size of the margin is selected automatically.
+The default is \f(CW0\fR.
+.TP
+\fB\-bufferelements \fIboolean\fR
+Indicates whether an internal pixmap to buffer the display of data
+elements should be used.  If \fIboolean\fR is true, data elements are
+drawn to an internal pixmap.  This option is especially useful when
+the graph is redrawn frequently while the remains data unchanged (for
+example, moving a marker across the plot).  See the
+.SB "SPEED TIPS"
+section.
+The default is \f(CW1\fR.
+.TP
+\fB\-cursor \fIcursor\fR
+Specifies the widget's cursor.  The default cursor is \f(CWcrosshair\fR.
+.TP
+\fB\-font \fIfontName\fR 
+Specifies the font of the graph title. The default is
+\f(CW*-Helvetica-Bold-R-Normal-*-18-180-*\fR.
+.TP
+\fB\-halo \fIpixels\fR 
+Specifies a maximum distance to consider when searching for the
+closest data point (see the element's \fBclosest\fR operation below).
+Data points further than \fIpixels\fR away are ignored.  The default is
+\f(CW0.5i\fR.
+.TP
+\fB\-height \fIpixels\fR
+Specifies the requested height of widget.  The default is
+\f(CW4i\fR.
+.TP
+\fB\-invertxy \fIboolean\fR
+Indicates whether the placement X\-axis and Y\-axis should be inverted.  If
+\fIboolean\fR is true, the X and Y axes are swapped.  The default is
+\f(CW0\fR.
+.TP
+\fB\-justify \fIjustify\fR
+Specifies how the title should be justified.  This matters only when
+the title contains more than one line of text. \fIJustify\fR must be
+\f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR.  The default is
+\f(CWcenter\fR.
+.TP
+\fB\-leftmargin \fIpixels\fR
+Sets the size of the margin from the left edge of the window to 
+the Y\-coordinate axis.  If \fIpixels\fR is \f(CW0\fR, the size is
+calculated automatically.  The default is \f(CW0\fR.
+.TP
+\fB\-plotbackground \fIcolor\fR
+Specifies the background color of the plotting area.  The default is
+\f(CWwhite\fR.
+.TP
+\fB\-plotborderwidth \fIpixels\fR
+Sets the width of the 3-D border around the plotting area.  The
+\fB\-plotrelief\fR option determines if a border is drawn.  The
+default is \f(CW2\fR.
+.TP
+\fB\-plotpadx \fIpad\fR
+Sets the amount of padding to be added to the left and right sides of
+the plotting area.  \fIPad\fR can be a list of one or two screen
+distances.  If \fIpad\fR has two elements, the left side of the
+plotting area entry is padded by the first distance and the right side
+by the second.  If \fIpad\fR is just one distance, both the left and
+right sides are padded evenly.  The default is \f(CW8\fR.
+.TP
+\fB\-plotpady \fIpad\fR
+Sets the amount of padding to be added to the top and bottom of the
+plotting area.  \fIPad\fR can be a list of one or two screen
+distances.  If \fIpad\fR has two elements, the top of the plotting
+area is padded by the first distance and the bottom by the second.  If
+\fIpad\fR is just one distance, both the top and bottom are padded
+evenly.  The default is \f(CW8\fR.
+.TP
+\fB\-plotrelief \fIrelief\fR
+Specifies the 3-D effect for the plotting area.  \fIRelief\fR
+specifies how the interior of the plotting area should appear relative
+to rest of the graph; for example, \f(CWraised\fR means the plot should
+appear to protrude from the graph, relative to the surface of the
+graph.  The default is \f(CWsunken\fR.
+.TP
+\fB\-relief \fIrelief\fR
+Specifies the 3-D effect for the barchart widget.  \fIRelief\fR
+specifies how the graph should appear relative to widget it is packed
+into; for example, \f(CWraised\fR means the graph should
+appear to protrude.  The default is \f(CWflat\fR.
+.TP
+\fB\-rightmargin \fIpixels\fR
+Sets the size of margin from the plotting area to the right edge of
+the window.  By default, the legend is drawn in this margin.  If
+\fIpixels\fR is than 1, the margin size is selected automatically.
+.TP
+\fB\-takefocus\fR \fIfocus\fR 
+Provides information used when moving the focus from window to window
+via keyboard traversal (e.g., Tab and Shift-Tab).  If \fIfocus\fR is
+\f(CW0\fR, this means that this window should be skipped entirely during
+keyboard traversal.  \f(CW1\fR means that the this window should always
+receive the input focus.  An empty value means that the traversal
+scripts make the decision whether to focus on the window.
+The default is \f(CW""\fR.
+.TP
+\fB\-tile \fIimage\fR 
+Specifies a tiled background for the widget.  If \fIimage\fR isn't
+\f(CW""\fR, the background is tiled using \fIimage\fR.
+Otherwise, the normal background color is drawn (see the
+\fB\-background\fR option).  \fIImage\fR must be an image created
+using the Tk \fBimage\fR command.  The default is \f(CW""\fR.
+.TP
+\fB\-title \fItext\fR 
+Sets the title to \fItext\fR. If \fItext\fR is \f(CW""\fR,
+no title will be displayed.
+.TP
+\fB\-topmargin \fIpixels\fR
+Specifies the size of the margin above the x2 axis.  If \fIpixels\fR
+is \f(CW0\fR, the margin size is calculated automatically.
+.TP
+\fB\-width \fIpixels\fR
+Specifies the requested width of the widget.  The default is
+\f(CW5i\fR.
+.RE
+.TP
+\fIpathName \fBcrosshairs \fIoperation \fR?\fIarg\fR?
+See the 
+.SB "CROSSHAIRS COMPONENT"
+section.
+.TP
+\fIpathName \fBelement \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "ELEMENT COMPONENTS"
+section.
+.TP
+\fIpathName \fBextents \fIitem\fR 
+Returns the size of a particular item in the graph.  \fIItem\fR must
+be either \f(CWleftmargin\fR, \f(CWrightmargin\fR, \f(CWtopmargin\fR,
+\f(CWbottommargin\fR, \f(CWplotwidth\fR, or \f(CWplotheight\fR.
+.TP
+\fIpathName \fBgrid \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "GRID COMPONENT"
+section.
+.TP
+\fIpathName \fBinvtransform \fIwinX winY\fR 
+Performs an inverse coordinate transformation, mapping window
+coordinates back to graph-coordinates, using the standard X\-axis and Y\-axis.
+Returns a list of containing the X-Y graph-coordinates.
+.TP
+\fIpathName \fBinside \fIx y\fR
+Returns \f(CW1\fR is the designated screen-coordinate (\fIx\fR and \fIy\fR)
+is inside the plotting area and \f(CW0\fR otherwise.
+.TP
+\fIpathName \fBlegend \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "LEGEND COMPONENT"
+section.
+.TP
+\fIpathName \fBline\fB operation arg\fR...
+The operation is the same as \fBelement\fR.
+.TP
+\fIpathName \fBmarker \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "MARKER COMPONENTS"
+section.
+.TP
+\fIpathName\fR \fBmetafile\fR ?\fIfileName\fR?
+\fIThis operation is for Window platforms only\fR.  
+Creates a Windows enhanced metafile of the barchart.
+If present, \fIfileName\fR is the file name of the new metafile.
+Otherwise, the metafile is automatically added to the clipboard.
+.TP
+\fIpathName \fBpostscript \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "POSTSCRIPT COMPONENT"
+section.
+.TP
+\fIpathName \fBsnap \fIphotoName\fR
+Takes a snapshot of the graph and stores the contents in the photo
+image \fIphotoName\fR.  \fIPhotoName\fR is the name of a Tk photo
+image that must already exist.
+.TP
+\fIpathName \fBtransform \fIx y\fR 
+Performs a coordinate transformation, mapping graph-coordinates to
+window coordinates, using the standard X\-axis and Y\-axis.
+Returns a list containing the X\-Y screen-coordinates.
+.TP
+\fIpathName \fBxaxis \fIoperation\fR ?\fIarg\fR?...
+.TP
+\fIpathName \fBx2axis \fIoperation\fR ?\fIarg\fR?... 
+.TP
+\fIpathName \fByaxis \fIoperation\fR ?\fIarg\fR?... 
+.TP
+\fIpathName \fBy2axis \fIoperation\fR ?\fIarg\fR?... 
+See the 
+.SB "AXIS COMPONENTS"
+section.
+.SH "BARCHART COMPONENTS"
+A graph is composed of several components: coordinate axes, data
+elements, legend, grid, cross hairs, postscript, and annotation
+markers. Instead of one big set of configuration options and
+operations, the graph is partitioned, where each component has its own
+configuration options and operations that specifically control that
+aspect or part of the graph. 
+.SS "AXIS COMPONENTS"
+Four coordinate axes are automatically created: two X\-coordinate axes
+(\f(CWx\fR and \f(CWx2\fR) and two Y\-coordinate axes (\f(CWy\fR, and
+\f(CWy2\fR).  By default, the axis \f(CWx\fR is located in the bottom
+margin, \f(CWy\fR in the left margin, \f(CWx2\fR in the top margin, and
+\f(CWy2\fR in the right margin.
+.PP
+An axis consists of the axis line, title, major and minor ticks, and
+tick labels.  Major ticks are drawn at uniform intervals along the
+axis.  Each tick is labeled with its coordinate value.  Minor ticks
+are drawn at uniform intervals within major ticks.  
+.PP
+The range of the axis controls what region of data is plotted.
+Data points outside the minimum and maximum limits of the axis are
+not plotted.  By default, the minimum and maximum limits are
+determined from the data, but you can reset either limit.
+.PP
+You can create and use several axes. To create an axis, invoke
+the axis component and its create operation.
+.CS
+# Create a new axis called "temperature"
+\&.b axis create temperature
+.CE
+You map data elements to an axis using the element's \-mapy and \-mapx
+configuration options. They specify the coordinate axes an element
+is mapped onto.
+.CS
+# Now map the temperature data to this axis.
+\&.b element create "temp" \-xdata $x \-ydata $tempData \\
+    \-mapy temperature
+.CE
+While you can have many axes, only four axes can be displayed
+simultaneously.  They are drawn in each of the margins surrounding
+the plotting area.  The axes \f(CWx\fR and \f(CWy\fR are drawn in the
+bottom and left margins. The axes \f(CWx2\fR and \f(CWy2\fR are drawn in
+top and right margins.  Only \f(CWx\fR and \f(CWy\fR are shown by
+default. Note that the axes can have different scales.
+.PP
+To display a different axis, you invoke one of the following
+components: \fBxaxis\fR, \fByaxis\fR, \fBx2axis\fR, and \fBy2axis\fR.
+The \fBuse\fR operation designates the axis to be drawn in the
+corresponding margin: \fBxaxis\fR in the bottom, \fByaxis\fR in the left, 
+\fBx2axis\fR in the top, and \fBy2axis\fR in the right.
+.CS
+# Display the axis temperature in the left margin.
+\&.b yaxis use temperature
+.CE
+.PP
+You can configure axes in many ways. The axis scale can be linear or
+logarithmic.  The values along the axis can either monotonically
+increase or decrease.  If you need custom tick labels, you can specify
+a Tcl procedure to format the label any way you wish.  You can
+control how ticks are drawn, by changing the major tick interval
+or the number of minor ticks.  You can define non-uniform tick intervals,
+such as for time-series plots.
+.PP
+.TP
+\fIpathName \fBaxis \fBcget \fIaxisName \fIoption\fR
+Returns the current value of the option given by \fIoption\fR for
+\fIaxisName\fR.  \fIOption\fR may be any option described below
+for the axis \fBconfigure\fR operation.
+.TP
+\fIpathName \fBaxis \fBconfigure \fIaxisName \fR?\fIaxisName\fR?... ?\fIoption value\fR?...
+Queries or modifies the configuration options of \fIaxisName\fR.
+Several axes can be changed.  If \fIoption\fR isn't specified, a list
+describing all the current options for \fIaxisName\fR is returned.  If
+\fIoption\fR is specified, but not \fIvalue\fR, then a list describing
+\fIoption\fR is returned.  If one or more \fIoption\fR and \fIvalue\fR
+pairs are specified, then for each pair, the axis option \fIoption\fR
+is set to \fIvalue\fR.  The following options are valid for axes.
+.RS
+.TP
+\fB\-autorange \fIrange\fR 
+Sets the range of values for the axis to \fIrange\fR.  The axis limits
+are automatically reset to display the most recent data points in this range.  
+If \fIrange\fR is 0.0, the range is
+determined from the limits of the data.  If \fB\-min\fR or \fB-max\fR
+are specified, they override this option.  The default is \f(CW0.0\fR.
+.TP
+\fB\-color \fIcolor\fR
+Sets the color of the axis and tick labels.
+The default is \f(CWblack\fR.
+.TP
+\fB\-command \fIprefix\fR
+Specifies a Tcl command to be invoked when formatting the axis tick
+labels. \fIPrefix\fR is a string containing the name of a Tcl proc and
+any extra arguments for the procedure.  This command is invoked for each
+major tick on the axis.  Two additional arguments are passed to the
+procedure: the pathname of the widget and the current the numeric
+value of the tick.  The procedure returns the formatted tick label.  If
+\f(CW""\fR is returned, no label will appear next to the tick.  You can
+get the standard tick labels again by setting \fIprefix\fR to
+\f(CW""\fR.  The default is \f(CW""\fR.
+.sp 1
+Please note that this procedure is invoked while the bar chart is redrawn.
+You may query the widget's configuration options.  But do not reset
+options, because this can have unexpected results.
+.TP
+\fB\-descending \fIboolean\fR 
+Indicates whether the values along the axis are monotonically increasing or
+decreasing.  If \fIboolean\fR is true, the axis values will be
+decreasing.  The default is \f(CW0\fR.
+.TP
+\fB\-hide \fIboolean\fR
+Indicates whether the axis is displayed. 
+.TP
+\fB\-justify \fIjustify\fR
+Specifies how the axis title should be justified.  This matters only
+when the axis title contains more than one line of text. \fIJustify\fR
+must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR.  The default is
+\f(CWcenter\fR.
+.TP
+\fB\-limits \fIformatStr\fR
+Specifies a printf-like description to format the minimum and maximum
+limits of the axis.  The limits are displayed at the top/bottom or
+left/right sides of the plotting area.  \fIFormatStr\fR is a list of
+one or two format descriptions.  If one description is supplied, both
+the minimum and maximum limits are formatted in the same way.  If two,
+the first designates the format for the minimum limit, the second for
+the maximum.  If \f(CW""\fR is given as either description, then 
+the that limit will not be displayed.  The default is \f(CW""\fR.
+.TP
+\fB\-linewidth \fIpixels\fR
+Sets the width of the axis and tick lines.  The default is \f(CW1\fR
+pixel.
+.TP
+\fB\-logscale \fIboolean\fR
+Indicates whether the scale of the axis is logarithmic or linear.  If
+\fIboolean\fR is true, the axis is logarithmic.  The default scale is
+linear.
+.TP
+\fB\-loose \fIboolean\fR
+Indicates whether the limits of the axis should fit the data points tightly,
+at the outermost data points, or loosely, at the outer tick intervals.
+This is relevant only when the axis limit is automatically calculated.
+If \fIboolean\fR is true, the axis range is "loose".
+The default is \f(CW0\fR.
+.TP
+\fB\-majorticks \fImajorList\fR
+Specifies where to display major axis ticks.  You can use this option
+to display ticks at non-uniform intervals.  \fIMajorList\fR is a list
+of axis coordinates designating the location of major ticks.  No
+minor ticks are drawn.  If \fImajorList\fR is \f(CW""\fR, 
+major ticks will be automatically computed. The default is \f(CW""\fR.
+.TP
+\fB\-max \fIvalue\fR
+Sets the maximum limit of \fIaxisName\fR.  Any data point greater 
+than \fIvalue\fR is not displayed.  If \fIvalue\fR is \f(CW""\fR, 
+the maximum limit is calculated using the largest data value.
+The default is \f(CW""\fR.
+.TP
+\fB\-min \fIvalue\fR
+Sets the minimum limit of \fIaxisName\fR. Any data point less than 
+\fIvalue\fR is not displayed.  If \fIvalue\fR is \f(CW""\fR,
+the minimum limit is calculated using the smallest data value.
+The default is \f(CW""\fR.
+.TP
+\fB\-minorticks \fIminorList\fR
+Specifies where to display minor axis ticks.  You can use this option
+to display minor ticks at non-uniform intervals. \fIMinorList\fR is a
+list of real values, ranging from 0.0 to 1.0, designating the placement of
+a minor tick.  No minor ticks are drawn if the \fB\-majortick\fR
+option is also set.  If \fIminorList\fR is \f(CW""\fR, minor ticks will
+be automatically computed. The default is \f(CW""\fR.
+.TP
+\fB\-rotate \fItheta\fR
+Specifies the how many degrees to rotate the axis tick labels.
+\fITheta\fR is a real value representing the number of degrees
+to rotate the tick labels.  The default is \f(CW0.0\fR degrees.
+.TP
+\fB\-shiftby \fIvalue\fR
+Specifies how much to automatically shift the range of the axis.
+When the new data exceeds the current axis maximum, the maximum
+is increased in increments of \fIvalue\fR.  You can use this
+option to prevent the axis limits from being recomputed
+at each new time point. If \fIvalue\fR is 0.0, then no automatic
+shifting is down. The default is \f(CW0.0\fR.
+.TP
+\fB\-showticks \fIboolean\fR
+Indicates whether axis ticks should be drawn. If \fIboolean\fR is
+true, ticks are drawn.  If false, only the
+axis line is drawn. The default is \f(CW1\fR.
+.TP
+\fB\-stepsize \fIvalue\fR
+Specifies the interval between major axis ticks.  If \fIvalue\fR isn't
+a valid interval (must be less than the axis range), 
+the request is ignored and the step size is automatically calculated.
+.TP
+\fB\-subdivisions \fInumber\fR 
+Indicates how many minor axis ticks are
+to be drawn.  For example, if \fInumber\fR is two, only one minor
+tick is drawn.  If \fInumber\fR is one, no minor ticks are
+displayed.  The default is \f(CW2\fR.
+.TP
+\fB\-tickfont \fIfontName\fR 
+Specifies the font for axis tick labels. The default is
+\f(CW*-Courier-Bold-R-Normal-*-100-*\fR.
+.TP
+\fB\-ticklength \fIpixels\fR
+Sets the length of major and minor ticks (minor ticks are half the
+length of major ticks). If \fIpixels\fR is less than zero, the axis
+will be inverted with ticks drawn pointing towards the plot.  The
+default is \f(CW0.1i\fR.
+.TP
+\fB\-title \fItext\fR
+Sets the title of the axis. If \fItext\fR is 
+\f(CW""\fR, no axis title will be displayed.  
+.TP
+\fB\-titlecolor \fIcolor\fR
+Sets the color of the axis title. The default is \f(CWblack\fR.
+.TP
+\fB\-titlefont \fIfontName\fR 
+Specifies the font for axis title. The default is
+\f(CW*-Helvetica-Bold-R-Normal-*-14-140-*\fR.
+.PP
+Axis configuration options may be also be set by the \fBoption\fR
+command.  The resource class is \f(CWAxis\fR.  The resource names
+are the names of the axes (such as \f(CWx\fR or \f(CWx2\fR).
+.CS
+option add *Barchart.Axis.Color  blue
+option add *Barchart.x.LogScale  true
+option add *Barchart.x2.LogScale false
+.CE
+.RE
+.TP
+\fIpathName \fBaxis \fBcreate \fIaxisName \fR?\fIoption value\fR?...
+Creates a new axis by the name \fIaxisName\fR.  No axis by the same
+name can already exist. \fIOption\fR and \fIvalue\fR are described 
+in above in the axis \fBconfigure\fR operation.
+.TP
+\fIpathName \fBaxis \fBdelete \fR?\fIaxisName\fR?...
+Deletes the named axes. An axis is not really
+deleted until it is not longer in use, so it's safe to delete
+axes mapped to elements.
+.TP
+\fIpathName \fBaxis invtransform \fIaxisName value\fR
+Performs the inverse transformation, changing the screen-coordinate
+\fIvalue\fR to a graph-coordinate, mapping the value mapped to
+\fIaxisName\fR.  Returns the graph-coordinate.
+.TP
+\fIpathName \fBaxis limits \fIaxisName\fR
+Returns a list of the minimum and maximum limits for \fIaxisName\fR.  The order
+of the list is \f(CWmin max\fR.
+.TP
+\fIpathName \fBaxis names \fR?\fIpattern\fR?...
+Returns a list of axes matching zero or more patterns.  If no
+\fIpattern\fR argument is give, the names of all axes are returned.
+.TP
+\fIpathName \fBaxis transform \fIaxisName value\fR
+Transforms the coordinate \fIvalue\fR to a screen-coordinate by mapping
+the it to \fIaxisName\fR.  Returns the transformed screen-coordinate.
+.PP
+Only four axes can be displayed simultaneously.  By default, they are
+\f(CWx\fR, \f(CWy\fR, \f(CWx2\fR, and \f(CWy2\fR.  You can swap in a different
+axis with \fBuse\fR operation of the special axis components:
+\fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR.
+.CS
+\&.g create axis temp
+\&.g create axis time
+\&...
+\&.g xaxis use temp
+\&.g yaxis use time
+.CE
+Only the axes specified for use are displayed on the screen.
+.PP
+The \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR
+components operate on an axis location rather than a specific axis
+like the more general \fBaxis\fR component does.  The \fBxaxis\fR
+component manages the X-axis located in the bottom margin (whatever
+axis that happens to be).  Likewise, \fByaxis\fR uses the Y-axis in
+the left margin, \fBx2axis\fR the top X-axis, and \fBy2axis\fR the
+right Y-axis.
+.PP
+They implicitly control the axis that is currently using to that
+location.  By default, \fBxaxis\fR uses the \f(CWx\fR axis, \fByaxis\fR
+uses \f(CWy\fR, \fBx2axis\fR uses \f(CWx2\fR, and \fBy2axis\fR uses
+\f(CWy2\fR.  These components can be more convenient to use than always
+determining what axes are current being displayed by the graph.
+.PP
+The following operations are available for axes. They mirror exactly
+the operations of the \fBaxis\fR component.  The \fIaxis\fR argument
+must be \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, or \fBy2axis\fR.
+.TP
+\fIpathName \fIaxis \fBcget \fIoption\fR
+.TP
+\fIpathName \fIaxis \fBconfigure \fR?\fIoption value\fR?...
+.TP
+\fIpathName \fIaxis\fB invtransform \fIvalue\fR
+.TP
+\fIpathName \fIaxis \fBlimits\fR
+.TP
+\fIpathName \fIaxis\fB transform \fIvalue\fR
+.TP
+\fIpathName \fIaxis\fB use \fR?\fIaxisName\fR?  
+Designates the axis \fIaxisName\fR is to be displayed at this
+location.  \fIAxisName\fR can not be already in use at another location.  
+This command returns the name of the axis currently using this location.
+.SS "CROSSHAIRS COMPONENT"
+Cross hairs consist of two intersecting lines (one vertical and one horizontal)
+drawn completely across the plotting area.  They are used to position
+the mouse in relation to the coordinate axes.  Cross hairs differ from line
+markers in that they are implemented using XOR drawing primitives.
+This means that they can be quickly drawn and erased without redrawing
+the entire widget.
+.PP
+The following operations are available for cross hairs:
+.TP
+\fIpathName \fBcrosshairs cget \fIoption\fR
+Returns the current value of the cross hairs configuration option
+given by \fIoption\fR.  \fIOption\fR may be any option
+described below for the cross hairs \fBconfigure\fR operation.
+.TP
+\fIpathName \fBcrosshairs configure \fR?\fIoption value\fR?...  
+Queries or modifies the configuration options of the cross hairs.  If
+\fIoption\fR isn't specified, a list describing all the current
+options for the cross hairs is returned.  If \fIoption\fR is specified,
+but not \fIvalue\fR, then a list describing \fIoption\fR is returned.
+If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then
+for each pair, the cross hairs option \fIoption\fR is set to
+\fIvalue\fR.
+The following options are available for cross hairs.
+.RS
+.TP
+\fB\-color \fIcolor\fR 
+Sets the color of the cross hairs.  The default is \f(CWblack\fR.
+.TP
+\fB\-dashes \fIdashList\fR
+Sets the dash style of the cross hairs. \fIDashList\fR is a list of up
+to 11 numbers that alternately represent the lengths of the dashes
+and gaps on the cross hair lines.  Each number must be between 1 and
+255.  If \fIdashList\fR is \f(CW""\fR, the cross hairs will be solid
+lines.
+.TP
+\fB\-hide \fIboolean\fR
+Indicates whether cross hairs are drawn. If \fIboolean\fR is true,
+cross hairs are not drawn.  The default is \f(CWyes\fR.
+.TP
+\fB\-linewidth \fIpixels\fR
+Set the width of the cross hair lines.  The default is \f(CW1\fR.
+.TP
+\fB\-position \fIpos\fR 
+Specifies the screen position where the cross hairs intersect.
+\fIPos\fR must be in the form "\fI at x,y\fR", where \fIx\fR and \fIy\fR
+are the window coordinates of the intersection.
+.PP
+Cross hairs configuration options may be also be set by the
+\fBoption\fR command.  The resource name and class are
+\f(CWcrosshairs\fR and \f(CWCrosshairs\fR respectively.
+.CS
+option add *Barchart.Crosshairs.LineWidth 2
+option add *Barchart.Crosshairs.Color     red
+.CE
+.RE
+.TP
+\fIpathName \fBcrosshairs off\fR
+Turns off the cross hairs. 
+.TP
+\fIpathName \fBcrosshairs on\fR
+Turns on the display of the cross hairs.
+.TP
+\fIpathName \fBcrosshairs toggle\fR 
+Toggles the current state of the cross hairs, alternately mapping and
+unmapping the cross hairs.
+.SH "ELEMENTS"
+A data element represents a set of data.  It contains x and y vectors
+which are the coordinates of the data points.  Elements are displayed
+as bars where the length of the bar is proportional to the ordinate of
+the data point.  Elements also control the appearance of the data,
+such as the color, stipple, relief, etc.
+.PP
+When new data elements are created, they are automatically added to a
+list of displayed elements.   The display list controls what elements
+are drawn and in what order.  
+.PP
+The following operations are available for elements.
+.TP
+\fIpathName \fBelement activate \fIelemName \fR?\fIindex\fR?...
+Specifies the data points of element \fIelemName\fR to be drawn
+using active foreground and background colors.  \fIElemName\fR is the
+name of the element and \fIindex\fR is a number representing the index
+of the data point. If no indices are present then all data points
+become active.
+.TP
+\fIpathName \fBelement bind \fItagName\fR ?\fIsequence\fR?  ?\fIcommand\fR? 
+Associates \fIcommand\fR with \fItagName\fR such that whenever the
+event sequence given by \fIsequence\fR occurs for an element with this
+tag, \fIcommand\fR will be invoked.  The syntax is similar to the 
+\fBbind\fR command except that it operates on graph elements, rather 
+than widgets. See the \fBbind\fR manual entry for
+complete details on \fIsequence\fR and the substitutions performed on 
+\fIcommand\fR before invoking it.  
+.sp
+If all arguments are specified then a new binding is created, replacing 
+any existing binding for the same \fIsequence\fR and \fItagName\fR.
+If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR 
+augments an existing binding rather than replacing it. 
+If no \fIcommand\fR argument is provided then the command currently
+associated with \fItagName\fR and \fIsequence\fR (it's an error occurs 
+if there's no such binding) is returned.  If both \fIcommand\fR and 
+\fIsequence\fR are missing then a list of all the event sequences for 
+which bindings have been defined for \fItagName\fR. 
+.TP
+\fIpathName \fBelement cget \fIelemName \fIoption\fR
+Returns the current value of the element configuration option given by 
+\fIoption\fR.  \fIOption\fR may be any of the options described below
+for the element \fBconfigure\fR operation.
+.TP
+\fIpathName \fBelement closest \fIx y\fR ?\fIoption value\fR?... ?\fIelemName\fR?...
+Finds the data point representing the bar closest to the window
+coordinates \fIx\fR and \fIy\fR in the element \fIelemName\fR.
+\fIElemName\fR is the name of an element, which must be currently displayed.  
+If no elements are specified, then all displayed elements are searched.  It
+returns a key-value list containing the name of the closest element, 
+the index of its closest point, and the graph-coordinates of the
+point. If no data point within the threshold distance can be found,
+\f(CW""\fR is returned.  The following \fIoption\fR-\fIvalue\fR pairs
+are available.
+.RS
+.TP
+\fB\-halo \fIpixels\fR
+Specifies a threshold distance where selected data points are ignored.
+\fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR.
+If this option isn't specified, then it defaults to the value of the
+\fBbarchart\fR's \fB\-halo\fR option.
+.RE
+.TP
+\fIpathName \fBelement configure \fIelemName \fR?\fIelemName\fR... ?\fIoption value\fR?...
+Queries or modifies the configuration options for elements.  Several
+elements can be modified at the same time. If \fIoption\fR isn't
+specified, a list describing all the current options for
+\fIelemName\fR is returned.  If \fIoption\fR is specified, but not
+\fIvalue\fR, then a list describing the option \fIoption\fR is
+returned.  If one or more \fIoption\fR and \fIvalue\fR pairs are
+specified, then for each pair, the element option \fIoption\fR is set
+to \fIvalue\fR.  The following options are valid for elements.
+.RS
+.TP
+\fB\-activepen \fIpenName\fR
+Specifies pen to use to draw active element.  If \fIpenName\fR is
+\f(CW""\fR, no active elements will be drawn.  The default is 
+\f(CWactiveLine\fR.
+.TP
+\fB\-bindtags \fItagList\fR
+Specifies the binding tags for the element.  \fITagList\fR is a list
+of binding tag names.  The tags and their order will determine how
+events for elements.  Each tag in the list matching the current event
+sequence will have its Tcl command executed.  Implicitly the name of
+the element is always the first tag in the list.  The default value is
+\f(CWall\fR.
+.TP
+\fB\-background \fIcolor\fR
+Sets the the color of the border around each bar.  The default is
+\f(CWwhite\fR.
+.TP
+\fB\-barwidth \fIvalue\fR 
+Specifies the width the bars drawn for the element.  \fIValue\fR is
+the width in X-coordinates.  If this option isn't
+specified, the width of each bar is the value of the widget's
+\fB\-barwidth\fR option.
+.TP
+\fB\-baseline \fIvalue\fR 
+Specifies the baseline of the bar segments.  This affects how bars are 
+drawn since bars are drawn from their respective y-coordinate the 
+baseline. By default the baseline is \f(CW0.0\fR.  
+.TP
+\fB\-borderwidth \fIpixels\fR
+Sets the border width of the 3-D border drawn around the outside of
+each bar.  The \fB\-relief\fR option determines if such a border is
+drawn.  \fIPixels\fR must be a valid screen distance like \f(CW2\fR or
+\f(CW0.25i\fR. The default is \f(CW2\fR.
+.TP
+\fB\-data \fIcoordList\fR
+Specifies the X\-Y coordinates of the data.  \fICoordList\fR is a
+list of numeric expressions representing the X\-Y coordinate pairs
+of each data point.
+.TP
+\fB\-foreground \fIcolor\fR 
+Sets the color of the interior of the bars.  
+.TP
+\fB\-hide \fIboolean\fR
+Indicates whether the element is displayed.  The default is \f(CWno\fR.
+.TP
+\fB\-label \fItext\fR
+Sets the element's label in the legend.  If \fItext\fR
+is \f(CW""\fR, the element will have no entry in the legend.
+The default label is the element's name.
+.TP
+\fB\-mapx \fIxAxis\fR
+Selects the X\-axis to map the element's X\-coordinates onto.
+\fIXAxis\fR must be the name of an axis.  The default is \f(CWx\fR.
+.TP
+\fB\-mapy \fIyAxis\fR
+Selects the Y\-axis to map the element's Y\-coordinates onto.
+\fIYAxis\fR must be the name of an axis. The default is \f(CWy\fR.
+.TP
+\fB\-relief \fIstring\fR
+Specifies the 3-D effect desired for bars.  \fIRelief\fR indicates how
+the interior of the bar should appear relative to the surface of the
+chart; for example, \f(CWraised\fR means the bar should appear to
+protrude from the surface of the plotting area.  The default is
+\f(CWraised\fR.
+.TP
+\fB\-stipple \fIbitmap\fR
+Specifies a stipple pattern with which to draw the bars.  If
+\fIbitmap\fR is \f(CW""\fR, then the bar is drawn in a solid fashion.
+.TP
+\fB\-xdata \fIxVector\fR 
+Specifies the x-coordinate vector of the data.
+\fIXVector\fR is the name of a BLT vector or a
+list of numeric expressions.  
+.TP
+\fB\-ydata \fIyVector\fR 
+Specifies the y-coordinate vector of the data.
+\fIYVector\fR is the name of a BLT vector or a list of
+numeric expressions.  
+.PP
+Element configuration options may also be set by the 
+\fBoption\fR command.  The resource names  in the option database 
+are prefixed by \f(CWelem\fR.
+.CS
+option add *Barchart.Element.background blue
+.CE
+.RE
+.TP
+\fIpathName \fBelement create \fIelemName\fR ?\fIoption value\fR?...
+Creates a new element \fIelemName\fR.  Element
+names must be unique, so an element \fIelemName\fR may not already
+exist.  If additional arguments are present, they specify any of the
+element options valid for element \fBconfigure\fR operation.
+.TP
+\fIpathName \fBelement deactivate \fIpattern\fR...
+Deactivates all the elements matching \fIpattern\fR for the graph.  
+Elements whose names match any of the patterns given are redrawn 
+using their normal colors.  
+.TP
+\fIpathName \fBelement delete\fR ?\fIpattern\fR?...
+Deletes all the elements matching \fIpattern\fR for the graph.  
+Elements whose names match any of the patterns given are deleted. 
+The graph will be redrawn without the deleted elements.  
+.TP
+\fIpathName \fBelement exists \fIelemName\fR
+Returns \f(CW1\fR if an element \fIelemName\fR currently exists and
+\f(CW0\fR otherwise.
+.TP
+\fIpathName \fBelement names \fR?\fIpattern\fR?...  
+Returns the elements matching one or more pattern.  If no
+\fIpattern\fR is given, the names of all elements is returned.
+.TP
+\fIpathName \fBelement show\fR ?\fInameList\fR?  
+Queries or modifies the element display list.  The element display
+list designates the elements drawn and in what
+order. \fINameList\fR is a list of elements to be displayed in the
+order they are named.  If there is no \fInameList\fR argument,
+the current display list is returned.
+.TP
+\fIpathName \fBelement type\fR \fIelemName\fR
+Returns the type of \fIelemName\fR. 
+If the element is a bar element, the commands returns the string
+\f(CW"bar"\fR, otherwise it returns \f(CW"line"\fR.
+.CE
+.SS "GRID COMPONENT"
+Grid lines extend from the major and minor ticks of each axis
+horizontally or vertically across the plotting area.  The following
+operations are available for grid lines.
+.TP
+\fIpathName \fBgrid cget \fIoption\fR
+Returns the current value of the grid line configuration option given by 
+\fIoption\fR.  \fIOption\fR may be any option described below
+for the grid \fBconfigure\fR operation.
+.TP
+\fIpathName \fBgrid configure\fR ?\fIoption value\fR?...
+Queries or modifies the configuration options for grid lines.  If
+\fIoption\fR isn't specified, a list describing all the current
+grid options for \fIpathName\fR is returned.  If \fIoption\fR is specified,
+but not \fIvalue\fR, then a list describing \fIoption\fR is
+returned.  If one or more \fIoption\fR and \fIvalue\fR pairs are
+specified, then for each pair, the grid line option \fIoption\fR is set to
+\fIvalue\fR.  The following options are valid for grid lines.
+.RS
+.TP
+\fB\-color \fIcolor\fR 
+Sets the color of the grid lines.  The default is \f(CWblack\fR.
+.TP
+\fB\-dashes \fIdashList\fR
+Sets the dash style of the grid lines. \fIDashList\fR is a list of up
+to 11 numbers that alternately represent the lengths of the dashes
+and gaps on the grid lines.  Each number must be between 1 and 255.
+If \fIdashList\fR is \f(CW""\fR, the grid will be solid lines.
+.TP
+\fB\-hide \fIboolean\fR
+Indicates whether the grid should be drawn. If \fIboolean\fR
+is true, grid lines are not shown. The default is \f(CWyes\fR.
+.TP
+\fB\-linewidth \fIpixels\fR
+Sets the width of grid lines.  The default width is \f(CW1\fR.
+.TP
+\fB\-mapx \fIxAxis\fR
+Specifies the X\-axis to display grid lines.  \fIXAxis\fR
+must be the name of an axis or \f(CW""\fR for no grid lines.  
+The default is \f(CW""\fR.
+.TP
+\fB\-mapy \fIyAxis\fR
+Specifies the Y\-axis to display grid lines.  \fIYAxis\fR
+must be the name of an axis or \f(CW""\fR for no grid lines. 
+The default is \f(CWy\fR.
+.TP
+\fB\-minor \fIboolean\fR
+Indicates whether the grid lines should be drawn for minor ticks. 
+If \fIboolean\fR is true, the lines will appear at
+minor tick intervals.  The default is \f(CW1\fR.
+.PP
+Grid configuration options may also be set by the 
+\fBoption\fR command.  The resource name and class are \f(CWgrid\fR and 
+\f(CWGrid\fR respectively. 
+.CS
+option add *Barchart.grid.LineWidth 2
+option add *Barchart.Grid.Color     black
+.CE
+.RE
+.TP
+\fIpathName \fBgrid off\fR
+Turns off the display the grid lines.
+.TP
+\fIpathName \fBgrid on\fR
+Turns on the display the grid lines.
+.TP
+\fIpathName \fBgrid toggle\fR
+Toggles the display of the grid.  
+.SS "LEGEND COMPONENT"
+The legend displays a list of the data elements.  Each entry consists
+of the element's symbol and label.  The legend can appear in any
+margin (the default location is in the right margin).  It
+can also be positioned anywhere within the plotting area.
+.PP
+The following operations are valid for the legend.
+.TP
+\fIpathName \fBlegend activate \fIpattern\fR...
+Selects legend entries to be drawn using the active legend colors and relief.
+All entries whose element names match \fIpattern\fR  are selected.  To
+be selected, the element name must match only one \fIpattern\fR. 
+.TP
+\fIpathName \fBlegend bind \fItagName\fR ?\fIsequence\fR?  ?\fIcommand\fR? 
+Associates \fIcommand\fR with \fItagName\fR such that whenever the
+event sequence given by \fIsequence\fR occurs for a legend entry with this
+tag, \fIcommand\fR will be invoked.  Implicitly the element names
+in the entry are tags.  The syntax is similar to the 
+\fBbind\fR command except that it operates on legend entries, rather 
+than widgets. See the \fBbind\fR manual entry for
+complete details on \fIsequence\fR and the substitutions performed on 
+\fIcommand\fR before invoking it.  
+.sp
+If all arguments are specified then a new binding is created, replacing 
+any existing binding for the same \fIsequence\fR and \fItagName\fR.
+If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR 
+augments an existing binding rather than replacing it. 
+If no \fIcommand\fR argument is provided then the command currently
+associated with \fItagName\fR and \fIsequence\fR (it's an error occurs 
+if there's no such binding) is returned.  If both \fIcommand\fR and 
+\fIsequence\fR are missing then a list of all the event sequences for 
+which bindings have been defined for \fItagName\fR. 
+.TP
+\fIpathName \fBlegend cget \fIoption\fR
+Returns the current value of a legend configuration option.
+\fIOption\fR may be any option described below in the
+legend \fBconfigure\fR operation.
+.TP
+\fIpathName \fBlegend configure \fR?\fIoption value\fR?...
+Queries or modifies the configuration options for the legend.  If
+\fIoption\fR isn't specified, a list describing the current
+legend options for \fIpathName\fR is returned.  If \fIoption\fR is
+specified, but not \fIvalue\fR, then a list describing \fIoption\fR is
+returned.  If one or more \fIoption\fR and \fIvalue\fR pairs are
+specified, then for each pair, the legend option \fIoption\fR is set
+to \fIvalue\fR.  The following options are valid for the legend.
+.RS
+.TP
+\fB\-activebackground \fIcolor\fR
+Sets the background color for active legend entries.  All legend
+entries marked active (see the legend \fBactivate\fR operation) are
+drawn using this background color.
+.TP
+\fB\-activeborderwidth \fIpixels\fR
+Sets the width of the 3-D border around the outside edge of the active legend
+entries.  The default is \f(CW2\fR.
+.TP
+\fB\-activeforeground \fIcolor\fR
+Sets the foreground color for active legend entries.  All legend
+entries marked as active (see the legend \fBactivate\fR operation) are
+drawn using this foreground color.
+.TP
+\fB\-activerelief \fIrelief\fR 
+Specifies the 3-D effect desired for active legend entries.
+\fIRelief\fR denotes how the interior of the entry should appear
+relative to the legend; for example, \f(CWraised\fR means the entry
+should appear to protrude from the legend, relative to the surface of
+the legend.  The default is \f(CWflat\fR.
+.TP
+\fB\-anchor \fIanchor\fR
+Tells how to position the legend relative to the positioning point for
+the legend.  This is dependent on the value of the \fB\-position\fR
+option.  The default is \f(CWcenter\fR.
+.RS
+.TP 1.25i
+\f(CWleft\fR or \f(CWright\fR
+The anchor describes how to position the legend vertically.  
+.TP
+\f(CWtop\fR or \f(CWbottom\fR
+The anchor describes how to position the legend horizontally.  
+.TP
+\f(CW at x,y\fR
+The anchor specifies how to position the legend relative to the
+positioning point. For example, if \fIanchor\fR is \f(CWcenter\fR then
+the legend is centered on the point; if \fIanchor\fR is \f(CWn\fR then
+the legend will be drawn such that the top center point of the
+rectangular region occupied by the legend will be at the positioning
+point.
+.TP
+\f(CWplotarea\fR
+The anchor specifies how to position the legend relative to the
+plotting area. For example, if \fIanchor\fR is \f(CWcenter\fR then the
+legend is centered in the plotting area; if \fIanchor\fR is \f(CWne\fR
+then the legend will be drawn such that occupies the upper right
+corner of the plotting area.
+.RE
+.TP
+\fB\-background \fIcolor\fR
+Sets the background color of the legend. If \fIcolor\fR is \f(CW""\fR,
+the legend background with be transparent.
+.TP
+\fB\-bindtags \fItagList\fR
+Specifies the binding tags for legend entries.  \fITagList\fR is a list
+of binding tag names.  The tags and their order will determine how
+events for legend entries.  Each tag in the list matching the current 
+event sequence will have its Tcl command executed. The default value 
+is \f(CWall\fR.
+.TP
+\fB\-borderwidth \fIpixels\fR
+Sets the width of the 3-D border around the outside edge of the legend (if
+such border is being drawn; the \fBrelief\fR option determines this).
+The default is \f(CW2\fR pixels.
+.TP
+\fB\-font \fIfontName\fR 
+\fIFontName\fR specifies a font to use when drawing the labels of each
+element into the legend.  The default is
+\f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR.
+.TP
+\fB\-foreground \fIcolor\fR 
+Sets the foreground color of the text drawn for the element's label.
+The default is \f(CWblack\fR.
+.TP
+\fB\-hide \fIboolean\fR
+Indicates whether the legend should be displayed. If \fIboolean\fR is
+true, the legend will not be draw.  The default is \f(CWno\fR.
+.TP
+\fB\-ipadx \fIpad\fR 
+Sets the amount of internal padding to be added to the width of each
+legend entry.  \fIPad\fR can be a list of one or two screen distances.  If
+\fIpad\fR has two elements, the left side of the legend entry is
+padded by the first distance and the right side by the second.  If
+\fIpad\fR is just one distance, both the left and right sides are padded
+evenly.  The default is \f(CW2\fR.
+.TP
+\fB\-ipady \fIpad\fR
+Sets an amount of internal padding to be added to the height of each
+legend entry.  \fIPad\fR can be a list of one or two screen distances.  If
+\fIpad\fR has two elements, the top of the entry is padded by the
+first distance and the bottom by the second.  If \fIpad\fR is just
+one distance, both the top and bottom of the entry are padded evenly.
+The default is \f(CW2\fR.
+.TP
+\fB\-padx \fIpad\fR
+Sets the padding to the left and right exteriors of the legend.
+\fIPad\fR can be a list of one or two screen distances.  If \fIpad\fR
+has two elements, the left side of the legend is padded by the first
+distance and the right side by the second.  If \fIpad\fR has just one
+distance, both the left and right sides are padded evenly.  The
+default is \f(CW4\fR.
+.TP
+\fB\-pady \fIpad\fR
+Sets the padding above and below the legend.  \fIPad\fR can be a list
+of one or two screen distances.  If \fIpad\fR has two elements, the area above
+the legend is padded by the first distance and the area below by the
+second.  If \fIpad\fR is just one distance, both the top and
+bottom areas are padded evenly.  The default is \f(CW0\fR.
+.TP
+\fB\-position \fIpos\fR
+Specifies where the legend is drawn. The
+\fB\-anchor\fR option also affects where the legend is positioned.  If
+\fIpos\fR is \f(CWleft\fR, \f(CWleft\fR, \f(CWtop\fR, or \f(CWbottom\fR, the
+legend is drawn in the specified margin.  If \fIpos\fR is
+\f(CWplotarea\fR, then the legend is drawn inside the plotting area at a
+particular anchor.  If \fIpos\fR is in the form "\fI at x,y\fR", where
+\fIx\fR and \fIy\fR are the window coordinates, the legend is drawn in
+the plotting area at the specified coordinates.  The default is
+\f(CWright\fR.
+.TP
+\fB\-raised \fIboolean\fR
+Indicates whether the legend is above or below the data elements.  This
+matters only if the legend is in the plotting area.  If \fIboolean\fR
+is true, the legend will be drawn on top of any elements that may
+overlap it. The default is \f(CWno\fR.
+.TP
+\fB\-relief \fIrelief\fR
+Specifies the 3-D effect for the border around the legend.
+\fIRelief\fR specifies how the interior of the legend should appear
+relative to the bar chart; for example, \f(CWraised\fR means the legend
+should appear to protrude from the bar chart, relative to the surface of
+the bar chart.  The default is \f(CWsunken\fR.
+.PP
+Legend configuration options may also be set by the \fBoption\fR
+command.  The resource name and class are \f(CWlegend\fR and
+\f(CWLegend\fR respectively.
+.CS
+option add *Barchart.legend.Foreground blue
+option add *Barchart.Legend.Relief     raised
+.CE
+.RE
+.TP
+\fIpathName \fBlegend deactivate \fIpattern\fR...
+Selects legend entries to be drawn using the normal legend colors and
+relief.  All entries whose element names match \fIpattern\fR are
+selected.  To be selected, the element name must match only one
+\fIpattern\fR.
+.TP
+\fIpathName \fBlegend get \fIpos\fR
+Returns the name of the element whose entry is at the screen position
+\fIpos\fR in the legend.  \fIPos\fR must be in the form "\fI at x,y\fR",
+where \fIx\fR and \fIy\fR are window coordinates.  If the given
+coordinates do not lie over a legend entry, \f(CW""\fR is returned.
+.SS "PEN COMPONENTS"
+Pens define attributes for elements.
+Pens mirror the configuration options of data elements that pertain to
+how symbols and lines are drawn.  Data elements use pens to determine
+how they are drawn.  A data element may use several pens at once.  In
+this case, the pen used for a particular data point is determined from
+each element's weight vector (see the element's \fB\-weight\fR and
+\fB\-style\fR options).
+.PP
+One pen, called \f(CWactiveBar\fR, is automatically created.
+It's used as the default active pen for elements. So you can change
+the active attributes for all elements by simply reconfiguring this
+pen.
+.CS
+\&.g pen configure "activeBar" -fg green -bg green4
+.CE
+You can create and use several pens. To create a pen, invoke
+the pen component and its create operation.
+.CS
+\&.g pen create myPen
+.CE
+You map pens to a data element using either the element's 
+\fB\-pen\fR or \fB\-activepen\fR options.
+.CS
+\&.g element create "e1" -xdata $x -ydata $tempData \\
+    -pen myPen
+.CE
+An element can use several pens at once. This is done by specifying
+the name of the pen in the element's style list (see the
+\fB\-styles\fR option).
+.CS
+\&.g element configure "e1" -styles { myPen 2.0 3.0 }
+.CE
+This says that any data point with a weight between 2.0 and 3.0
+is to be drawn using the pen \f(CWmyPen\fR.  All other points
+are drawn with the element's default attributes.
+.PP
+The following operations are available for pen components.
+.PP
+.TP
+\fIpathName \fBpen \fBcget \fIpenName \fIoption\fR
+Returns the current value of the option given by \fIoption\fR for
+\fIpenName\fR.  \fIOption\fR may be any option described below
+for the pen \fBconfigure\fR operation.
+.TP
+\fIpathName \fBpen \fBconfigure \fIpenName \fR?\fIpenName\fR... ?\fIoption value\fR?...
+Queries or modifies the configuration options of
+\fIpenName\fR. Several pens can be modified at once.  If \fIoption\fR
+isn't specified, a list describing the current options for
+\fIpenName\fR is returned.  If \fIoption\fR is specified, but not
+\fIvalue\fR, then a list describing \fIoption\fR is returned.  If one
+or more \fIoption\fR and \fIvalue\fR pairs are specified, then for
+each pair, the pen option \fIoption\fR is set to \fIvalue\fR.  The
+following options are valid for pens.
+.RS
+.TP
+\fB\-background \fIcolor\fR
+Sets the the color of the border around each bar.  The default is
+\f(CWwhite\fR.
+.TP
+\fB\-borderwidth \fIpixels\fR
+Sets the border width of the 3-D border drawn around the outside of
+each bar.  The \fB\-relief\fR option determines if such a border is
+drawn.  \fIPixels\fR must be a valid screen distance like \f(CW2\fR or
+\f(CW0.25i\fR. The default is \f(CW2\fR.
+.TP
+\fB\-foreground \fIcolor\fR 
+Sets the color of the interior of the bars.  
+.TP
+\fB\-relief \fIstring\fR
+Specifies the 3-D effect desired for bars.  \fIRelief\fR indicates how
+the interior of the bar should appear relative to the surface of the
+chart; for example, \f(CWraised\fR means the bar should appear to
+protrude from the bar chart, relative to the surface of the plotting
+area.  The default is \f(CWraised\fR.
+.TP
+\fB\-stipple \fIbitmap\fR
+Specifies a stipple pattern with which to draw the bars.  If
+\fIbitmap\fR is \f(CW""\fR, then the bar is drawn in a solid fashion.
+.TP
+\fB\-type \fIelemType\fR 
+Specifies the type of element the pen is to be used with.
+This option should only be employed when creating the pen.  This
+is for those that wish to mix different types of elements (bars and
+lines) on the same graph.  The default type is "bar".
+.PP
+Pen configuration options may be also be set by the \fBoption\fR
+command.  The resource class is \f(CWPen\fR.  The resource names
+are the names of the pens.
+.CS
+option add *Barchart.Pen.Foreground	   blue
+option add *Barchart.activeBar.foreground  green
+.CE
+.RE
+.TP
+\fIpathName \fBpen \fBcreate \fIpenName \fR?\fIoption value\fR?...
+Creates a new pen by the name \fIpenName\fR.  No pen by the same
+name can already exist. \fIOption\fR and \fIvalue\fR are described 
+in above in the pen \fBconfigure\fR operation.
+.TP
+\fIpathName \fBpen \fBdelete \fR?\fIpenName\fR?...
+Deletes the named pens. A pen is not really
+deleted until it is not longer in use, so it's safe to delete
+pens mapped to elements.
+.TP
+\fIpathName \fBpen names \fR?\fIpattern\fR?...
+Returns a list of pens matching zero or more patterns.  If no
+\fIpattern\fR argument is give, the names of all pens are returned.
+.SS "POSTSCRIPT COMPONENT"
+The barchart can generate encapsulated PostScript output.  There
+are several configuration options you can specify to control how the
+plot will be generated.  You can change the page dimensions and
+borders.  The plot itself can be scaled, centered, or rotated to
+landscape.  The PostScript output can be written directly to a file or
+returned through the interpreter.
+.PP
+The following postscript operations are available.
+.TP
+\fIpathName \fBpostscript cget \fIoption\fR 
+Returns the current value of the postscript option given by
+\fIoption\fR.  \fIOption\fR may be any option described
+below for the postscript \fBconfigure\fR operation.
+.TP
+\fIpathName \fBpostscript configure \fR?\fIoption value\fR?...
+Queries or modifies the configuration options for PostScript
+generation.  If \fIoption\fR isn't specified, a list describing 
+the current postscript options for \fIpathName\fR is returned.  If
+\fIoption\fR is specified, but not \fIvalue\fR, then a list describing
+\fIoption\fR is returned.  If one or more \fIoption\fR and \fIvalue\fR
+pairs are specified, then for each pair, the postscript option
+\fIoption\fR is set to \fIvalue\fR.  The following postscript options
+are available.
+.RS
+.TP
+\fB\-center \fIboolean\fR
+Indicates whether the plot should be centered on the PostScript page.  If
+\fIboolean\fR is false, the plot will be placed in the upper left
+corner of the page.  The default is \f(CW1\fR.
+.TP
+\fB\-colormap \fIvarName\fR
+\fIVarName\fR must be the name of a global array variable that
+specifies a color mapping from the X color name to PostScript.  Each
+element of \fIvarName\fR must consist of PostScript code to set a
+particular color value (e.g. ``\f(CW1.0 1.0 0.0 setrgbcolor\fR'').  When
+generating color information in PostScript, the array variable \fIvarName\fR
+is checked if an element of the name as the color exists. If so, it uses 
+its value as the PostScript
+command to set the color.  If this option hasn't been specified, or if
+there isn't an entry in \fIvarName\fR for a given color, then it uses
+the red, green, and blue intensities from the X color.
+.TP
+\fB\-colormode \fImode\fR
+Specifies how to output color information.  \fIMode\fR must be either
+\f(CWcolor\fR (for full color output), \f(CWgray\fR (convert all colors to
+their gray-scale equivalents) or \f(CWmono\fR (convert foreground colors
+to black and background colors to white).  The default mode is
+\f(CWcolor\fR. 
+.TP
+\fB\-fontmap \fIvarName\fR
+\fIVarName\fR must be the name of a global array variable that
+specifies a font mapping from the X font name to PostScript.  Each
+element of \fIvarName\fR must consist of a Tcl list with one or two
+elements; the name and point size of a PostScript font.
+When outputting PostScript commands for a particular font, the array
+variable \fIvarName\fR is checked to see if an element by the 
+specified font exists.  If there is such an element, then the font
+information contained in that element is used in the PostScript
+output.  (If the point size is omitted from the list, the point size
+of the X font is used).  Otherwise the X font is examined in an
+attempt to guess what PostScript font to use.  This works only for
+fonts whose foundry property is \fIAdobe\fR (such as Times, Helvetica,
+Courier, etc.).  If all of this fails then the font defaults to
+\f(CWHelvetica-Bold\fR.
+.TP
+\fB\-decorations \fIboolean\fR
+Indicates whether PostScript commands to generate color backgrounds and 3-D
+borders will be output.  If \fIboolean\fR is false, the graph will
+background will be white and no 3-D borders will be generated. The
+default is \f(CW1\fR.
+.TP
+\fB\-height \fIpixels\fR
+Sets the height of the plot.  This lets you print the bar chart with a
+height different from the one drawn on the screen.  If
+\fIpixels\fR is 0, the height is the same as the widget's height.
+The default is \f(CW0\fR.
+.TP
+\fB\-landscape \fIboolean\fR
+If \fIboolean\fR is true, this specifies the printed area is to be
+rotated 90 degrees.  In non-rotated output the X\-axis of the printed
+area runs along the short dimension of the page (``portrait''
+orientation); in rotated output the X\-axis runs along the long
+dimension of the page (``landscape'' orientation).  Defaults to
+\f(CW0\fR.
+.TP
+\fB\-maxpect \fIboolean\fR
+Indicates to scale the plot so that it fills the PostScript page.
+The aspect ratio of the barchart is still retained.  The default is
+\f(CW0\fR.
+.TP
+\fB\-padx \fIpad\fR
+Sets the horizontal padding for the left and right page borders.  The
+borders are exterior to the plot.  \fIPad\fR can be a list of one or
+two screen distances.  If \fIpad\fR has two elements, the left border is padded
+by the first distance and the right border by the second.  If
+\fIpad\fR has just one distance, both the left and right borders are
+padded evenly.  The default is \f(CW1i\fR.
+.TP
+\fB\-pady \fIpad\fR 
+Sets the vertical padding for the top and bottom page borders. The
+borders are exterior to the plot.  \fIPad\fR can be a list of one or
+two screen distances.  If \fIpad\fR has two elements, the top border is padded
+by the first distance and the bottom border by the second.  If
+\fIpad\fR has just one distance, both the top and bottom borders are
+padded evenly.  The default is \f(CW1i\fR.
+.TP
+\fB\-paperheight \fIpixels\fR
+Sets the height of the postscript page.  This can be used to select
+between different page sizes (letter, A4, etc).  The default height is
+\f(CW11.0i\fR.
+.TP
+\fB\-paperwidth \fIpixels\fR
+Sets the width of the postscript page.  This can be used to select
+between different page sizes (letter, A4, etc).  The default width is
+\f(CW8.5i\fR.
+.TP
+\fB\-width \fIpixels\fR
+Sets the width of the plot.  This lets you generate a plot
+of a width different from that of the widget.  If \fIpixels\fR
+is 0, the width is the same as the widget's width.  The default is
+\f(CW0\fR.
+.PP
+Postscript configuration options may be also be set by the
+\fBoption\fR command.  The resource name and class are
+\f(CWpostscript\fR and \f(CWPostscript\fR respectively.
+.CS
+option add *Barchart.postscript.Decorations false
+option add *Barchart.Postscript.Landscape   true
+.CE
+.RE
+.TP
+\fIpathName \fBpostscript output \fR?\fIfileName\fR? ?\fIoption value\fR?...
+Outputs a file of encapsulated PostScript.  If a
+\fIfileName\fR argument isn't present, the command returns the
+PostScript. If any \fIoption-value\fR pairs are present, they set
+configuration options controlling how the PostScript is generated.
+\fIOption\fR and \fIvalue\fR can be anything accepted by the
+postscript \fBconfigure\fR operation above.
+.SS "MARKER COMPONENTS"
+Markers are simple drawing procedures used to annotate or highlight
+areas of the graph.  Markers have various types: text strings,
+bitmaps, images, connected lines, windows, or polygons.  They can be
+associated with a particular element, so that when the element is
+hidden or un-hidden, so is the marker.  By default, markers are the
+last items drawn, so that data elements will appear in
+behind them.  You can change this by configuring the \fB\-under\fR
+option.
+.PP
+Markers, in contrast to elements, don't affect the scaling of the
+coordinate axes.  They can also have \fIelastic\fR coordinates
+(specified by \f(CW-Inf\fR and \f(CWInf\fR respectively) that translate
+into the minimum or maximum limit of the axis.  For example, you can
+place a marker so it always remains in the lower left corner of the
+plotting area, by using the coordinates \f(CW-Inf\fR,\f(CW-Inf\fR.
+.PP
+The following operations are available for markers.
+.TP
+\fIpathName \fBmarker after \fImarkerId\fR ?\fIafterId\fR?
+Changes the order of the markers, drawing the first
+marker after the second.  If no second \fIafterId\fR argument is
+specified, the marker is placed at the end of the display list.  This
+command can be used to control how markers are displayed since markers
+are drawn in the order of this display list.
+.TP
+\fIpathName \fBmarker before \fImarkerId\fR ?\fIbeforeId\fR?
+Changes the order of the markers, drawing the first
+marker before the second.  If no second \fIbeforeId\fR argument is
+specified, the marker is placed at the beginning of the display list.
+This command can be used to control how markers are displayed since
+markers are drawn in the order of this display list.
+.TP
+\fIpathName \fBmarker bind \fItagName\fR ?\fIsequence\fR?  ?\fIcommand\fR? 
+Associates \fIcommand\fR with \fItagName\fR such that whenever the
+event sequence given by \fIsequence\fR occurs for a marker with this
+tag, \fIcommand\fR will be invoked.  The syntax is similar to the 
+\fBbind\fR command except that it operates on graph markers, rather 
+than widgets. See the \fBbind\fR manual entry for
+complete details on \fIsequence\fR and the substitutions performed on 
+\fIcommand\fR before invoking it.  
+.sp
+If all arguments are specified then a new binding is created, replacing 
+any existing binding for the same \fIsequence\fR and \fItagName\fR.
+If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR 
+augments an existing binding rather than replacing it. 
+If no \fIcommand\fR argument is provided then the command currently
+associated with \fItagName\fR and \fIsequence\fR (it's an error occurs 
+if there's no such binding) is returned.  If both \fIcommand\fR and 
+\fIsequence\fR are missing then a list of all the event sequences for 
+which bindings have been defined for \fItagName\fR. 
+.TP
+\fIpathName \fBmarker cget \fIoption\fR
+Returns the current value of the marker configuration option given by
+\fIoption\fR.  \fIOption\fR may be any option described
+below in the \fBconfigure\fR operation.
+.TP
+\fIpathName \fBmarker configure \fImarkerId\fR ?\fIoption value\fR?...
+Queries or modifies the configuration options for markers.  If
+\fIoption\fR isn't specified, a list describing the current
+options for \fImarkerId\fR is returned.  If \fIoption\fR is specified,
+but not \fIvalue\fR, then a list describing \fIoption\fR is returned.
+If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then
+for each pair, the marker option \fIoption\fR is set to \fIvalue\fR.
+.sp
+The following options are valid for all markers.
+Each type of marker also has its own type-specific options.  
+They are described in the sections below.
+.RS
+.TP
+\fB\-bindtags \fItagList\fR
+Specifies the binding tags for the marker.  \fITagList\fR is a list
+of binding tag names.  The tags and their order will determine how
+events for markers are handled.  Each tag in the list matching the 
+current event sequence will have its Tcl command executed.  Implicitly 
+the name of the marker is always the first tag in the list.
+The default value is \f(CWall\fR.
+.TP
+\fB\-coords \fIcoordList\fR
+Specifies the coordinates of the marker.  \fICoordList\fR is 
+a list of graph-coordinates.  The number of coordinates required
+is dependent on the type of marker.  Text, image, and window markers
+need only two coordinates (an X\-Y coordinate).   Bitmap markers
+can take either two or four coordinates (if four, they represent the
+corners of the bitmap). Line markers
+need at least four coordinates, polygons at least six.
+If \fIcoordList\fR is \f(CW""\fR, the marker will not be displayed.
+The default is \f(CW""\fR.
+.TP
+\fB\-element \fIelemName\fR
+Links the marker with the element \fIelemName\fR.  The marker is
+drawn only if the element is also currently displayed (see the
+element's \fBshow\fR operation).  If \fIelemName\fR is \f(CW""\fR, the
+marker is always drawn.  The default is \f(CW""\fR.
+.TP
+\fB\-hide \fIboolean\fR 
+Indicates whether the marker is drawn. If \fIboolean\fR is true,
+the marker is not drawn.  The default is \f(CWno\fR.
+.TP
+\fB\-mapx \fIxAxis\fR 
+Specifies the X\-axis to map the marker's X\-coordinates onto.
+\fIXAxis\fR must the name of an axis.  The default is \f(CWx\fR.
+.TP
+\fB\-mapy \fIyAxis\fR
+Specifies the Y\-axis to map the marker's Y\-coordinates onto.
+\fIYAxis\fR must the name of an axis.  The default is \f(CWy\fR.
+.TP
+\fB\-name \fImarkerId\fR
+Changes the identifier for the marker.  The identifier \fImarkerId\fR 
+can not already be used by another marker.  If this option
+isn't specified, the marker's name is uniquely generated.
+.TP
+\fB\-under \fIboolean\fR
+Indicates whether the marker is drawn below/above data
+elements.  If \fIboolean\fR is true, the marker is be drawn
+underneath the data elements.  Otherwise, the marker is
+drawn on top of the element.  The default is \f(CW0\fR.
+.TP
+\fB\-xoffset \fIpixels\fR
+Specifies a screen distance to offset the marker horizontally. 
+\fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR.
+The default is \f(CW0\fR.
+.TP
+\fB\-yoffset \fIpixels\fR
+Specifies a screen distance to offset the markers vertically.
+\fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR.
+The default is \f(CW0\fR.
+.PP
+Marker configuration options may also be set by the \fBoption\fR command.
+The resource class is either \f(CWBitmapMarker\fR,  \f(CWImageMarker\fR, 
+\f(CWLineMarker\fR, \f(CWPolygonMarker\fR, \f(CWTextMarker\fR, or \f(CWWindowMarker\fR,
+depending on the type of marker.  The resource name is the name of the
+marker.
+.CS
+option add *Barchart.TextMarker.Foreground white
+option add *Barchart.BitmapMarker.Foreground white
+option add *Barchart.m1.Background     blue
+.CE
+.RE
+.TP
+\fIpathName \fBmarker create \fItype\fR ?\fIoption value\fR?...
+Creates a marker of the selected type. \fIType\fR may be either
+\f(CWtext\fR, \f(CWline\fR, \f(CWbitmap\fR, \f(CWimage\fR, \f(CWpolygon\fR, or
+\f(CWwindow\fR.  This command returns the marker identifier, 
+used as the \fImarkerId\fR argument in the other marker-related
+commands.  If the \fB\-name\fR option is used, this overrides the
+normal marker identifier.  If the name provided is already used for
+another marker, the new marker will replace the old.
+.TP
+\fIpathName \fBmarker delete\fR ?\fIname\fR?...
+Removes one of more markers.  The graph will automatically be redrawn
+without the marker.\fR.  
+.TP
+\fIpathName \fBmarker exists \fImarkerId\fR 
+Returns \f(CW1\fR if the marker \fImarkerId\fR exists and \f(CW0\fR
+otherwise.
+.TP
+\fIpathName \fBmarker names\fR ?\fIpattern\fR?  
+Returns the names of all the markers that currently exist.  If
+\fIpattern\fR is supplied, only those markers whose names match it
+will be returned.
+.TP
+\fIpathName \fBmarker type \fImarkerId\fR 
+Returns the type of the marker given by \fImarkerId\fR, such as
+\f(CWline\fR or \f(CWtext\fR.  If \fImarkerId\fR is not a valid a marker
+identifier, \f(CW""\fR is returned.
+.SS "BITMAP MARKERS"
+A bitmap marker displays a bitmap.  The size of the
+bitmap is controlled by the number of coordinates specified.  If two
+coordinates, they specify the position of the top-left corner of the
+bitmap.  The bitmap retains its normal width and height.  If four
+coordinates, the first and second pairs of coordinates represent the
+corners of the bitmap.  The bitmap will be stretched or reduced as
+necessary to fit into the bounding rectangle.
+.PP
+Bitmap markers are created with the marker's \fBcreate\fR operation in
+the form:
+.DS
+\fIpathName \fBmarker create bitmap \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR pairs, each 
+sets a configuration options for the marker.  These
+same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's
+\fBconfigure\fR operation.
+.PP
+The following options are specific to bitmap markers:
+.TP
+\fB\-background \fIcolor\fR
+Same as the \fB\-fill\fR option.
+.TP
+\fB\-bitmap \fIbitmap\fR
+Specifies the bitmap to be displayed.  If \fIbitmap\fR is \f(CW""\fR,
+the marker will not be displayed.  The default is \f(CW""\fR.
+.TP
+\fB\-fill \fIcolor\fR
+Sets the background color of the bitmap.  If \fIcolor\fR is the empty
+string, no background will be transparent.  The default background color is
+\f(CW""\fR.
+.TP
+\fB\-foreground \fIcolor\fR 
+Same as the \fB\-outline\fR option.
+.TP
+\fB\-mask \fImask\fR
+Specifies a mask for the bitmap to be displayed. This mask is a bitmap
+itself, denoting the pixels that are transparent.  If \fImask\fR is
+\f(CW""\fR, all pixels of the bitmap will be drawn.  The default is
+\f(CW""\fR.
+.TP
+\fB\-outline \fIcolor\fR
+Sets the foreground color of the bitmap. The default value is \f(CWblack\fR.
+.TP
+\fB\-rotate \fItheta\fR
+Sets the rotation of the bitmap.  \fITheta\fR is a real number
+representing the angle of rotation in degrees.  The marker is first
+rotated and then placed according to its anchor position.  The default
+rotation is \f(CW0.0\fR.
+.SS "IMAGE MARKERS"
+A image marker displays an image.  Image markers are
+created with the marker's \fBcreate\fR operation in the form:
+.DS
+\fIpathName \fBmarker create image \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR
+pairs, each sets a configuration option
+for the marker.  These same \fIoption\fR\-\fIvalue\fR pairs may be
+used with the marker's \fBconfigure\fR operation.
+.PP
+The following options are specific to image markers:
+.TP
+\fB\-anchor \fIanchor\fR
+\fIAnchor\fR tells how to position the image relative to the
+positioning point for the image. For example, if \fIanchor\fR
+is \f(CWcenter\fR then the image is centered on the point;  if
+\fIanchor\fR is \f(CWn\fR then the image will be drawn such that
+the top center point of the rectangular region occupied by the
+image will be at the positioning point.
+This option defaults to \f(CWcenter\fR.
+.TP
+\fB\-image \fIimage\fR
+Specifies the image to be drawn.
+If \fIimage\fR is \f(CW""\fR, the marker will not be
+drawn.  The default is \f(CW""\fR.
+.SS "LINE MARKERS"
+A line marker displays one or more connected line segments.
+Line markers are created with marker's \fBcreate\fR operation in the form:
+.DS
+\fIpathName \fBmarker create line \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR
+pairs, each sets a configuration option
+for the marker.  These same \fIoption\fR-\fIvalue\fR pairs may be
+used with the marker's \fBconfigure\fR operation.
+.PP
+The following options are specific to line markers:
+.TP
+\fB\-dashes \fIdashList\fR
+Sets the dash style of the line. \fIDashList\fR is a list of up to 11
+numbers that alternately represent the lengths of the dashes and gaps
+on the line.  Each number must be between 1 and 255.  If
+\fIdashList\fR is \f(CW""\fR, the marker line will be solid.
+.TP
+\fB\-fill \fIcolor\fR
+Sets the background color of the line.  This color is used with
+striped lines (see the \fB\-fdashes\R option). If \fIcolor\fR is
+the empty string, no background color is drawn (the line will be
+dashed, not striped).  The default background color is \f(CW""\fR.
+.TP
+\fB\-linewidth \fIpixels\fR
+Sets the width of the lines.
+The default width is \f(CW0\fR.
+.TP
+\fB\-outline \fIcolor\fR
+Sets the foreground color of the line. The default value is \f(CWblack\fR.
+.TP
+\fB\-stipple \fIbitmap\fR
+Specifies a stipple pattern used to draw the line, rather than
+a solid line.
+\fIBitmap\fR specifies a bitmap to use as the stipple
+pattern.  If \fIbitmap\fR is \f(CW""\fR, then the
+line is drawn in a solid fashion. The default is \f(CW""\fR.
+.SS "POLYGON MARKERS"
+A polygon marker displays a closed region described as two or more
+connected line segments.  It is assumed the first and
+last points are connected.  Polygon markers are created using the
+marker \fBcreate\fR operation in the form:
+.DS
+\fIpathName \fBmarker create polygon \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR
+pairs, each sets a configuration option
+for the marker.  These same \fIoption\fR\-\fIvalue\fR pairs may be
+used with the \fBmarker configure\fR command to change the marker's
+configuration.
+The following options are supported for polygon markers:
+.TP
+\fB\-dashes \fIdashList\fR
+Sets the dash style of the outline of the polygon. \fIDashList\fR is a
+list of up to 11 numbers that alternately represent the lengths of
+the dashes and gaps on the outline.  Each number must be between 1 and
+255. If \fIdashList\fR is \f(CW""\fR, the outline will be a solid line.
+.TP
+\fB\-fill \fIcolor\fR
+Sets the fill color of the polygon.  If \fIcolor\fR is \f(CW""\fR, then
+the interior of the polygon is transparent.
+The default is \f(CWwhite\fR.
+.TP
+\fB\-linewidth \fIpixels\fR
+Sets the width of the outline of the polygon. If \fIpixels\fR is zero, 
+no outline is drawn. The default is \f(CW0\fR.
+.TP
+\fB\-outline \fIcolor\fR
+Sets the color of the outline of the polygon.  If the polygon is
+stippled (see the \fB\-stipple\fR option), then this represents the
+foreground color of the stipple.  The default is \f(CWblack\fR.
+.TP
+\fB\-stipple \fIbitmap\fR
+Specifies that the polygon should be drawn with a stippled pattern
+rather than a solid color. \fIBitmap\fR specifies a bitmap to use as
+the stipple pattern.  If \fIbitmap\fR is \f(CW""\fR, then the polygon is
+filled with a solid color (if the \fB\-fill\fR option is set).  The
+default is \f(CW""\fR.
+.SS "TEXT MARKERS"
+A text marker displays a string of characters on one or more lines of
+text.  Embedded newlines cause line breaks.  They may be used to
+annotate regions of the graph.  Text markers are created with the
+\fBcreate\fR operation in the form:
+.DS
+\fIpathName \fBmarker create text \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR pairs, 
+each sets a configuration option for the text marker.  
+These same \fIoption\fR\-\fIvalue\fR pairs may be used with the 
+marker's \fBconfigure\fR operation.  
+.PP
+The following options are specific to text markers:
+.TP
+\fB\-anchor \fIanchor\fR
+\fIAnchor\fR tells how to position the text relative to the
+positioning point for the text. For example, if \fIanchor\fR is
+\f(CWcenter\fR then the text is centered on the point; if
+\fIanchor\fR is \f(CWn\fR then the text will be drawn such that the
+top center point of the rectangular region occupied by the text will
+be at the positioning point.  This default is \f(CWcenter\fR.
+.TP
+\fB\-background \fIcolor\fR
+Same as the \fB\-fill\fR option.
+.TP
+\fB\-font \fIfontName\fR
+Specifies the font of the text.  The default is
+\f(CW*-Helvetica-Bold-R-Normal-*-120-*\fR.
+.TP
+\fB\-fill \fIcolor\fR
+Sets the background color of the text.  If \fIcolor\fR is the empty
+string, no background will be transparent.  The default background color is
+\f(CW""\fR.
+.TP
+\fB\-foreground \fIcolor\fR
+Same as the \fB\-outline\fR option.
+.TP
+\fB\-justify \fIjustify\fR
+Specifies how the text should be justified.  This matters only when
+the marker contains more than one line of text. \fIJustify\fR must be
+\f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR.  The default is
+\f(CWcenter\fR.
+.TP
+\fB\-outline \fIcolor\fR
+Sets the color of the text. The default value is \f(CWblack\fR.
+.TP
+\fB\-padx \fIpad\fR
+Sets the padding to the left and right exteriors of the text.
+\fIPad\fR can be a list of one or two screen distances.  If \fIpad\fR
+has two elements, the left side of the text is padded by the first
+distance and the right side by the second.  If \fIpad\fR has just one
+distance, both the left and right sides are padded evenly.  The
+default is \f(CW4\fR.
+.TP
+\fB\-pady \fIpad\fR
+Sets the padding above and below the text.  \fIPad\fR can be a list of
+one or two screen distances.  If \fIpad\fR has two elements, the area above the
+text is padded by the first distance and the area below by the second.
+If \fIpad\fR is just one distance, both the top and bottom areas
+are padded evenly.  The default is \f(CW4\fR.
+.TP
+\fB\-rotate \fItheta\fR
+Specifies the number of degrees to rotate the text.  \fITheta\fR is a
+real number representing the angle of rotation.  The marker is first
+rotated along its center and is then drawn according to its anchor
+position. The default is \f(CW0.0\fR.
+.TP
+\fB\-text \fItext\fR
+Specifies the text of the marker.  The exact way the text is
+displayed may be affected by other options such as \fB\-anchor\fR or
+\fB\-rotate\fR.
+.SS "WINDOW MARKERS"
+A window marker displays a widget at a given position.
+Window markers are created with the marker's \fBcreate\fR operation in
+the form:
+.DS
+\fIpathName \fBmarker create window \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR
+pairs, each sets a configuration option
+for the marker.  These same \fIoption\fR\-\fIvalue\fR pairs may be
+used with the marker's \fBconfigure\fR command.
+.PP
+The following options are specific to window markers:
+.TP
+\fB\-anchor \fIanchor\fR
+\fIAnchor\fR tells how to position the widget relative to the
+positioning point for the widget. For example, if \fIanchor\fR is
+\f(CWcenter\fR then the widget is centered on the point; if \fIanchor\fR
+is \f(CWn\fR then the widget will be displayed such that the top center
+point of the rectangular region occupied by the widget will be at the
+positioning point.  This option defaults to \f(CWcenter\fR.
+.TP
+\fB\-height \fIpixels\fR
+Specifies the height to assign to the marker's window.  If this option
+isn't specified, or if it is specified as \f(CW""\fR, then the window is
+given whatever height the widget requests internally.
+.TP
+\fB\-width \fIpixels\fR
+Specifies the width to assign to the marker's window.  If this option
+isn't specified, or if it is specified as \f(CW""\fR, then the window is
+given whatever width the widget requests internally.
+.TP
+\fB\-window \fIpathName\fR
+Specifies the widget to be managed by the barchart.  \fIPathName\fR must
+be a child of the \fBbarchart\fR widget.
+.SH "GRAPH COMPONENT BINDINGS"
+Specific barchart components, such as elements, markers and legend
+entries, can have a command trigger when event occurs in them, much
+like canvas items in Tk's canvas widget.  Not all event sequences are
+valid.  The only binding events that may be specified are those
+related to the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR,
+\fBButtonPress\fR, \fBMotion\fR, and \fBKeyPress\fR).
+.PP
+Only one element or marker can be picked during an event.  This means,
+that if the mouse is directly over both an element and a marker, only
+the uppermost component is selected.  This isn't true for legend entries.  
+Both a legend entry and an element (or marker) binding commands 
+will be invoked if both items are picked.
+.PP
+It is possible for multiple bindings to match a particular event.
+This could occur, for example, if one binding is associated with the
+element name and another is associated with one of the element's tags
+(see the \fB\-bindtags\fR option).  When this occurs, all of the 
+matching bindings are invoked.  A binding associated with the element
+name is invoked first, followed by one binding for each of the element's 
+bindtags.  If there are multiple matching bindings for a single tag, 
+then only the most specific binding is invoked.  A continue command 
+in a binding script terminates that script, and a break command 
+terminates that script and skips any remaining scripts for the event, 
+just as for the bind command.
+.PP
+The \fB\-bindtags\fR option for these components controls addition
+tag names which can be matched.  Implicitly elements and markers
+always have tags matching their names.  Setting the value of
+the \fB\-bindtags\fR option doesn't change this.
+.SH "C LANGUAGE API"
+You can manipulate data elements from the C language.  There
+may be situations where it is too expensive to translate the data
+values from ASCII strings.  Or you might want to read data in a
+special file format.
+.PP
+Data can manipulated from the C language using BLT vectors.
+You specify the X-Y data coordinates of an element as vectors and
+manipulate the vector from C.  The barchart will be redrawn automatically
+after the vectors are updated.
+.PP
+From Tcl, create the vectors and configure the element to use them.
+.CS
+vector X Y
+\&.g element configure line1 -xdata X -ydata Y
+.CE
+To set data points from C, you pass the values as arrays of doubles
+using the \fBBlt_ResetVector\fR call.  The vector is reset with the
+new data and at the next idle point (when Tk re-enters its event
+loop), the graph will be redrawn automatically.
+.CS
+#include <tcl.h>
+#include <blt.h>
+
+register int i;
+Blt_Vector *xVec, *yVec;
+double x[50], y[50];
+
+/* Get the BLT vectors "X" and "Y" (created above from Tcl) */
+if ((Blt_GetVector(interp, "X", 50, &xVec) != TCL_OK) ||
+    (Blt_GetVector(interp, "Y", 50, &yVec) != TCL_OK)) {
+    return TCL_ERROR;
+}
+
+for (i = 0; i < 50; i++) {
+    x[i] = i * 0.02;
+    y[i] = sin(x[i]);
+}	
+
+/* Put the data into BLT vectors */
+if ((Blt_ResetVector(xVec, x, 50, 50, TCL_VOLATILE) != TCL_OK) ||
+    (Blt_ResetVector(yVec, y, 50, 50, TCL_VOLATILE) != TCL_OK)) {
+   return TCL_ERROR;
+}
+.CE
+See the \fBvector\fR manual page for more details.
+.SH SPEED TIPS
+There may be cases where the bar chart needs to be drawn and updated as
+quickly as possible.  If drawing speed becomes a big
+problem, here are a few tips to speed up displays.
+.TP 2
+\(bu 
+Try to minimize the number of data points.  The more data points 
+looked at, the more work the bar chart must do.  
+.TP 2
+\(bu 
+If your data is generated as floating point values, the time required
+to convert the data values to and from ASCII strings can be
+significant, especially when there any many data points.  You can
+avoid the redundant string-to-decimal conversions using the C API to
+BLT vectors.
+.TP 2
+\(bu
+Don't stipple or dash the element.  Solid bars are much faster.
+.TP 2
+\(bu 
+If you update data elements frequently, try turning off the
+widget's \fB\-bufferelements\fR option.  When the bar chart is first
+displayed, it draws data elements into an internal pixmap.  The pixmap
+acts as a cache, so that when the bar chart needs to be redrawn again, and
+the data elements or coordinate axes haven't changed, the pixmap is
+simply copied to the screen.  This is especially useful when you are
+using markers to highlight points and regions on the bar chart.  But if
+the bar chart is updated frequently, changing either the element data or
+coordinate axes, the buffering becomes redundant.
+.SH LIMITATIONS
+Auto-scale routines do not use requested min/max limits
+as boundaries when the axis is logarithmically scaled.  
+.PP
+The PostScript output generated for polygons with more than 1500
+points may exceed the limits of some printers (See PostScript Language
+Reference Manual, page 568).  The work-around is to break the polygon
+into separate pieces.
+.SH KEYWORDS
+bar chart, widget
diff --git a/tlt3.0/doc/graph.n b/tlt3.0/doc/graph.n
new file mode 100644
index 0000000..c631975
--- /dev/null
+++ b/tlt3.0/doc/graph.n
@@ -0,0 +1,2397 @@
+'\"
+'\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies.
+'\"
+'\" Permission to use, copy, modify, and distribute this software and its
+'\" documentation for any purpose and without fee is hereby granted, provided
+'\" that the above copyright notice appear in all copies and that both that the
+'\" copyright notice and warranty disclaimer appear in supporting documentation,
+'\" and that the names of Lucent Technologies any of their entities not be used
+'\" in advertising or publicity pertaining to distribution of the software
+'\" without specific, written prior permission.
+'\"
+'\" Lucent Technologies disclaims all warranties with regard to this software,
+'\" including all implied warranties of merchantability and fitness.  In no event
+'\" shall Lucent Technologies be liable for any special, indirect or
+'\" consequential damages or any damages whatsoever resulting from loss of use,
+'\" data or profits, whether in an action of contract, negligence or other
+'\" tortuous action, arising out of or in connection with the use or performance
+'\" of this software.  
+'\"
+'\" Graph widget created by Sani Nassif and George Howlett.
+'\"
+.so man.macros
+.TH graph n BLT_VERSION BLT "BLT Built-In Commands"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+graph \-  2D graph for plotting X\-Y coordinate data.
+.SH SYNOPSIS
+\fBgraph\fI \fIpathName \fR?\fIoption value\fR?...
+.BE
+.SH DESCRIPTION
+The \fBgraph\fR command creates a graph for plotting
+two-dimensional data (X\-Y coordinates). It has many configurable
+components: coordinate axes, elements, legend, grid lines, cross
+hairs, etc.  They allow you to customize the look and feel of the
+graph.
+.SH INTRODUCTION
+The \fBgraph\fR command creates a new window for plotting
+two-dimensional data (X\-Y coordinates).  Data points are plotted in a
+rectangular area displayed in the center of the new window.  This is the
+\fIplotting area\fR.  The coordinate axes are drawn in the
+margins around the plotting area.  By default, the legend is displayed
+in the right margin.  The title is displayed in top margin.
+.PP
+The \fBgraph\fR widget is composed of several components: coordinate
+axes, data elements, legend, grid, cross hairs, pens, postscript, and
+annotation markers.
+.TP 1i
+\f(CWaxis\fR 
+The graph has four standard axes (\f(CWx\fR, \f(CWx2\fR,
+\f(CWy\fR, and \f(CWy2\fR), but you can create and display any number 
+of axes.  Axes control what region of data is
+displayed and how the data is scaled. Each axis consists of the axis
+line, title, major and minor ticks, and tick labels.  Tick labels
+display the value at each major tick.
+.TP 1i
+\f(CWcrosshairs\fR 
+Cross hairs are used to position the mouse pointer relative to the X
+and Y coordinate axes. Two perpendicular lines, intersecting at the
+current location of the mouse, extend across the plotting area to the
+coordinate axes.
+.TP 1i
+\f(CWelement\fR 
+An element represents a set of data points. Elements can be plotted 
+with a symbol at each data point and lines connecting the points. 
+The appearance of the element, such as its symbol, line width, and 
+color is configurable.
+.TP 1i
+\f(CWgrid\fR
+Extends the major and minor ticks of the X\-axis and/or Y\-axis across the 
+plotting area. 
+.TP 1i
+\f(CWlegend\fR 
+The legend displays the name and symbol of each data element. 
+The legend can be drawn in any margin or in the plotting area.
+.TP 1i
+\f(CWmarker\fR
+Markers are used annotate or highlight areas of the graph. For 
+example, you could use a polygon marker to fill an area under a 
+curve, or a text marker to label a particular data point. Markers 
+come in various forms: text strings, bitmaps, connected line 
+segments, images, polygons, or embedded widgets.
+.TP 1i
+\f(CWpen\fR 
+Pens define attributes (both symbol and line style) for elements. 
+Data elements use pens to specify how they should be drawn.  A data 
+element may use many pens at once.  Here, the particular pen 
+used for a data point is determined from each element's weight 
+vector (see the element's \fB\-weight\fR and \fB\-style\fR options).  
+.TP 1i
+\f(CWpostscript\fR
+The widget can generate encapsulated PostScript output. This component
+has several options to configure how the PostScript is generated.
+.SH SYNTAX
+.DS
+\fBgraph \fIpathName \fR?\fIoption value\fR?...
+.DE
+The \fBgraph\fR command creates a new window \fIpathName\fR and makes
+it into a \fBgraph\fR widget.  At the time this command is invoked, there
+must not exist a window named \fIpathName\fR, but \fIpathName\fR's
+parent must exist.  Additional options may be specified on the
+command line or in the option database to configure aspects of the
+graph such as its colors and font.  See the \fBconfigure\fR operation
+below for the exact details about what \fIoption\fR and \fIvalue\fR
+pairs are valid.
+.PP
+If successful, \fBgraph\fR returns the path name of the widget.  It
+also creates a new Tcl command by the same name.  You can use this
+command to invoke various operations that query or modify the graph.
+The general form is:
+.DS
+\fIpathName \fIoperation\fR \fR?\fIarg\fR?...
+.DE
+Both \fIoperation\fR and its arguments determine the exact behavior of
+the command.  The operations available for the graph are described in 
+the 
+.SB "GRAPH OPERATIONS"
+section.
+.PP
+The command can also be used to access components of the graph.
+.DS
+\fIpathName component operation\fR ?\fIarg\fR?...
+.DE
+The operation, now located after the name of the component, is the
+function to be performed on that component. Each component has its own
+set of operations that manipulate that component.  They will be
+described below in their own sections.
+.SH EXAMPLE
+The \fBgraph\fR command creates a new graph.  
+.CS
+# Create a new graph.  Plotting area is black.
+graph .g \-plotbackground black
+.CE
+A new Tcl command \f(CW.g\fR is also created.  This command can be used
+to query and modify the graph.  For example, to change the title of
+the graph to "My Plot", you use the new command and the graph's
+\fBconfigure\fR operation.
+.CS
+# Change the title.
+\&.g configure \-title "My Plot"
+.CE
+A graph has several components. To access a particular component you
+use the component's name. For example, to add data elements, you use
+the new command and the \fBelement\fR component.
+.CS
+# Create a new element named "line1"
+\&.g element create line1 \\
+	\-xdata { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 } \\
+	\-ydata { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 
+		155.85 166.60 175.38 }
+.CE
+The element's X-Y coordinates are specified using lists of
+numbers.  Alternately, BLT vectors could be used to hold the X\-Y
+coordinates.
+.CS
+# Create two vectors and add them to the graph.
+vector xVec yVec
+xVec set { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 }
+yVec set { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 
+	166.60 175.38 }
+\&.g element create line1 \-xdata xVec \-ydata yVec
+.CE
+The advantage of using vectors is that when you modify one, the graph
+is automatically redrawn to reflect the new values.
+.CS
+# Change the y coordinate of the first point.
+set yVector(0) 25.18
+.CE
+An element named \f(CWe1\fR is now created in \f(CW.b\fR.  It 
+is automatically added to the display list of elements.  You can
+use this list to control in what order elements are displayed.
+To query or reset the element display list, you use the element's 
+\fBshow\fR operation.
+.CS
+# Get the current display list 
+set elemList [.b element show]
+# Remove the first element so it won't be displayed.
+\&.b element show [lrange $elemList 0 end]
+.CE
+The element will be displayed by as many bars as there are data points
+(in this case there are ten).  The bars will be drawn centered at the
+x-coordinate of the data point.  All the bars will have the same
+attributes (colors, stipple, etc).  The width of each bar is by
+default one unit.  You can change this with using the \fB\-barwidth\fR
+option.
+.CS
+# Change the X\-Y coordinates of the first point.
+set xVec(0) 0.18
+set yVec(0) 25.18
+.CE
+An element named \f(CWline1\fR is now created in \f(CW.g\fR.  By
+default, the element's label in the legend will be also \f(CWline1\fR.
+You can change the label, or specify no legend entry, again using the
+element's \fBconfigure\fR operation.
+.CS
+# Don't display "line1" in the legend.
+\&.g element configure line1 \-label ""
+.CE
+You can configure more than just the element's label.  An element has
+many attributes such as symbol type and size, dashed or solid lines,
+colors, line width, etc.
+.CS
+\&.g element configure line1 \-symbol square \-color red \\
+	\-dashes { 2 4 2 } \-linewidth 2 \-pixels 2c
+.CE
+Four coordinate axes are automatically created: \f(CWx\fR, \f(CWx2\fR,
+\f(CWy\fR, and \f(CWy2\fR.  And by default, elements are mapped onto the
+axes \f(CWx\fR and \f(CWy\fR.  This can be changed with the \fB\-mapx\fR
+and \fB\-mapy\fR options.
+.CS
+# Map "line1" on the alternate Y\-axis "y2".
+\&.g element configure line1 \-mapy y2
+.CE
+Axes can be configured in many ways too.  For example, you change the
+scale of the Y\-axis from linear to log using the \fBaxis\fR component.
+.CS
+# Y\-axis is log scale.
+\&.g axis configure y \-logscale yes
+.CE
+One important way axes are used is to zoom in on a particular data
+region.  Zooming is done by simply specifying new axis limits using
+the \fB\-min\fR and \fB\-max\fR configuration options.
+.CS
+\&.g axis configure x \-min 1.0 \-max 1.5
+\&.g axis configure y \-min 12.0 \-max 55.15
+.CE
+To zoom interactively, you link the \fBaxis configure\fR operations with
+some user interaction (such as pressing the mouse button), using the
+\fBbind\fR command.  To convert between screen and graph coordinates,
+use the \fBinvtransform\fR operation.
+.CS
+# Click the button to set a new minimum 
+bind .g <ButtonPress-1> { 
+    %W axis configure x \-min [%W axis invtransform x %x]
+    %W axis configure x \-min [%W axis invtransform x %y]
+}
+.CE
+By default, the limits of the axis are determined from data values.
+To reset back to the default limits, set the \fB\-min\fR and
+\fB\-max\fR options to the empty value.
+.CS
+# Reset the axes to autoscale again.
+\&.g axis configure x \-min {} \-max {}
+\&.g axis configure y \-min {} \-max {}
+.CE
+By default, the legend is drawn in the right margin.  You can
+change this or any legend configuration options using the
+\fBlegend\fR component.
+.CS
+# Configure the legend font, color, and relief
+\&.g legend configure \-position left \-relief raised \\
+	\-font fixed \-fg blue
+.CE
+To prevent the legend from being displayed, turn on the \fB\-hide\fR
+option.
+.CS
+# Don't display the legend.
+\&.g legend configure \-hide yes\fR
+.CE
+The \fBgraph\fR widget has simple drawing procedures called markers.
+They can be used to highlight or annotate data in the graph. The types
+of markers available are bitmaps, images, polygons, lines, or windows.
+Markers can be used, for example, to mark or brush points.  In this
+example, is a text marker that labels the data first point.  Markers
+are created using the \fBmarker\fR component.
+.CS
+# Create a label for the first data point of "line1".
+\&.g marker create text \-name first_marker \-coords { 0.2 26.18 } \\
+	\-text "start" \-anchor se \-xoffset -10 \-yoffset -10
+.CE
+This creates a text marker named \f(CWfirst_marker\fR.  It will display
+the text "start" near the coordinates of the first data point.  The
+\fB\-anchor\fR, \fB\-xoffset\fR, and \fB\-yoffset\fR options are used
+to display the marker above and to the left of the data point, so that
+the data point isn't covered by the marker.  By default,
+markers are drawn last, on top of data.  You can change this with the
+\fB\-under\fR option.
+.CS
+# Draw the label before elements are drawn.
+\&.g marker configure first_marker \-under yes
+.CE
+You can add cross hairs or grid lines using the \fBcrosshairs\fR and
+\fBgrid\fR components.
+.CS
+# Display both cross hairs and grid lines.
+\&.g crosshairs configure \-hide no \-color red
+\&.g grid configure \-hide no \-dashes { 2 2 }
+# Set up a binding to reposition the crosshairs.
+bind .g <Motion> {
+    .g crosshairs configure -position @%x,%y
+}
+.CE
+The crosshairs are repositioned as the mouse pointer is moved
+in the graph.  The pointer X-Y coordinates define the center
+of the crosshairs.
+.PP
+Finally, to get hardcopy of the graph, use the \fBpostscript\fR
+component.
+.CS
+# Print the graph into file "file.ps"
+\&.g postscript output file.ps \-maxpect yes \-decorations no
+.CE
+This generates a file \f(CWfile.ps\fR containing the encapsulated
+PostScript of the graph.  The option \fB\-maxpect\fR says to scale the
+plot to the size of the page.  Turning off the \fB\-decorations\fR
+option denotes that no borders or color backgrounds should be
+drawn (i.e. the background of the margins, legend, and plotting
+area will be white).
+.SH "GRAPH OPERATIONS"
+.TP
+\fIpathName \fBaxis \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "AXIS COMPONENTS"
+section.
+.TP
+\fIpathName \fBbar \fIelemName \fR?\fIoption value\fR?...
+Creates a new barchart element \fIelemName\fR.  It's an
+error if an element \fIelemName\fR already exists.  
+See the manual for \fBbarchart\fR for details about
+what \fIoption\fR and \fIvalue\fR pairs are valid.
+.TP
+\fIpathName \fBcget\fR \fIoption\fR
+Returns the current value of the configuration option given by
+\fIoption\fR.  \fIOption\fR may be any option described
+below for the \fBconfigure\fR operation.
+.TP
+\fIpathName \fBconfigure \fR?\fIoption value\fR?...
+Queries or modifies the configuration options of the graph.  If
+\fIoption\fR isn't specified, a list describing the current
+options for \fIpathName\fR is returned.  If \fIoption\fR is specified,
+but not \fIvalue\fR, then a list describing \fIoption\fR is returned.
+If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then
+for each pair, the option \fIoption\fR is set to \fIvalue\fR.
+The following options are valid.
+.RS
+.TP
+\fB\-aspect \fIwidth/height\fR
+Force a fixed aspect ratio of \fIwidth/height\fR, a floating point number.
+.TP
+\fB\-background \fIcolor\fR
+Sets the background color. This includes the margins and
+legend, but not the plotting area.
+.TP
+\fB\-borderwidth \fIpixels\fR
+Sets the width of the 3\-D border around the outside edge of the widget.  The
+\fB\-relief\fR option determines if the border is to be drawn.  The
+default is \f(CW2\fR.
+.TP
+\fB\-bottommargin \fIpixels\fR
+If non-zero, overrides the computed size of the margin extending 
+below the X\-coordinate axis.
+If \fIpixels\fR is \f(CW0\fR, the automatically computed size is used.  
+The default is \f(CW0\fR.
+.TP
+\fB\-bufferelements \fIboolean\fR
+Indicates whether an internal pixmap to buffer the display of data
+elements should be used.  If \fIboolean\fR is true, data elements are
+drawn to an internal pixmap.  This option is especially useful when
+the graph is redrawn frequently while the remains data unchanged (for
+example, moving a marker across the plot).  See the
+.SB "SPEED TIPS"
+section.
+The default is \f(CW1\fR.
+.TP
+\fB\-cursor \fIcursor\fR
+Specifies the widget's cursor.  The default cursor is \f(CWcrosshair\fR.
+.TP
+\fB\-font \fIfontName\fR 
+Specifies the font of the graph title. The default is
+\f(CW*-Helvetica-Bold-R-Normal-*-18-180-*\fR.
+.TP
+\fB\-halo \fIpixels\fR 
+Specifies a maximum distance to consider when searching for the
+closest data point (see the element's \fBclosest\fR operation below).
+Data points further than \fIpixels\fR away are ignored.  The default is
+\f(CW0.5i\fR.
+.TP
+\fB\-height \fIpixels\fR
+Specifies the requested height of widget.  The default is
+\f(CW4i\fR.
+.TP
+\fB\-invertxy \fIboolean\fR
+Indicates whether the placement X\-axis and Y\-axis should be inverted.  If
+\fIboolean\fR is true, the X and Y axes are swapped.  The default is
+\f(CW0\fR.
+.TP
+\fB\-justify \fIjustify\fR
+Specifies how the title should be justified.  This matters only when
+the title contains more than one line of text. \fIJustify\fR must be
+\f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR.  The default is
+\f(CWcenter\fR.
+.TP
+\fB\-leftmargin \fIpixels\fR
+If non-zero, overrides the computed size of the margin extending 
+from the left edge of the window to the Y\-coordinate axis.  
+If \fIpixels\fR is \f(CW0\fR, the automatically computed size is used.  
+The default is \f(CW0\fR.
+.TP
+\fB\-plotbackground \fIcolor\fR
+Specifies the background color of the plotting area.  The default is
+\f(CWwhite\fR.
+.TP
+\fB\-plotborderwidth \fIpixels\fR
+Sets the width of the 3-D border around the plotting area.  The
+\fB\-plotrelief\fR option determines if a border is drawn.  The
+default is \f(CW2\fR.
+.TP
+\fB\-plotpadx \fIpad\fR
+Sets the amount of padding to be added to the left and right sides of
+the plotting area.  \fIPad\fR can be a list of one or two screen
+distances.  If \fIpad\fR has two elements, the left side of the
+plotting area entry is padded by the first distance and the right side
+by the second.  If \fIpad\fR is just one distance, both the left and
+right sides are padded evenly.  The default is \f(CW8\fR.
+.TP
+\fB\-plotpady \fIpad\fR
+Sets the amount of padding to be added to the top and bottom of the
+plotting area.  \fIPad\fR can be a list of one or two screen
+distances.  If \fIpad\fR has two elements, the top of the plotting
+area is padded by the first distance and the bottom by the second.  If
+\fIpad\fR is just one distance, both the top and bottom are padded
+evenly.  The default is \f(CW8\fR.
+.TP
+\fB\-plotrelief \fIrelief\fR
+Specifies the 3-D effect for the plotting area.  \fIRelief\fR
+specifies how the interior of the plotting area should appear relative
+to rest of the graph; for example, \f(CWraised\fR means the plot should
+appear to protrude from the graph, relative to the surface of the
+graph.  The default is \f(CWsunken\fR.
+.TP
+\fB\-relief \fIrelief\fR
+Specifies the 3-D effect for the graph widget.  \fIRelief\fR
+specifies how the graph should appear relative to widget it is packed
+into; for example, \f(CWraised\fR means the graph should
+appear to protrude.  The default is \f(CWflat\fR.
+.TP
+\fB\-rightmargin \fIpixels\fR
+If non-zero, overrides the computed size of the margin extending 
+from the plotting area to the right edge of
+the window. By default, the legend is drawn in this margin. 
+If \fIpixels\fR is \f(CW0\fR, the automatically computed size is used.  
+The default is \f(CW0\fR.
+.TP
+\fB\-takefocus\fR \fIfocus\fR 
+Provides information used when moving the focus from window to window
+via keyboard traversal (e.g., Tab and Shift-Tab).  If \fIfocus\fR is
+\f(CW0\fR, this means that this window should be skipped entirely during
+keyboard traversal.  \f(CW1\fR means that the this window should always
+receive the input focus.  An empty value means that the traversal
+scripts make the decision whether to focus on the window.
+The default is \f(CW""\fR.
+.TP
+\fB\-tile \fIimage\fR 
+Specifies a tiled background for the widget.  If \fIimage\fR isn't
+\f(CW""\fR, the background is tiled using \fIimage\fR.
+Otherwise, the normal background color is drawn (see the
+\fB\-background\fR option).  \fIImage\fR must be an image created
+using the Tk \fBimage\fR command.  The default is \f(CW""\fR.
+.TP
+\fB\-title \fItext\fR 
+Sets the title to \fItext\fR. If \fItext\fR is \f(CW""\fR,
+no title will be displayed.
+.TP
+\fB\-topmargin \fIpixels\fR 
+If non-zero, overrides the computed size of the margin above the x2
+axis.  If \fIpixels\fR is \f(CW0\fR, the automatically computed size
+is used.  The default is \f(CW0\fR.
+.TP
+\fB\-width \fIpixels\fR
+Specifies the requested width of the widget.  The default is
+\f(CW5i\fR.
+.RE
+.TP
+\fIpathName \fBcrosshairs \fIoperation \fR?\fIarg\fR?
+See the 
+.SB "CROSSHAIRS COMPONENT"
+section.
+.TP
+\fIpathName \fBelement \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "ELEMENT COMPONENTS"
+section.
+.TP
+\fIpathName \fBextents \fIitem\fR 
+Returns the size of a particular item in the graph.  \fIItem\fR must
+be either \f(CWleftmargin\fR, \f(CWrightmargin\fR, \f(CWtopmargin\fR,
+\f(CWbottommargin\fR, \f(CWplotwidth\fR, or \f(CWplotheight\fR.
+.TP
+\fIpathName \fBgrid \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "GRID COMPONENT"
+section.
+.TP
+\fIpathName \fBinvtransform \fIwinX winY\fR 
+Performs an inverse coordinate transformation, mapping window
+coordinates back to graph coordinates, using the standard X\-axis and Y\-axis.
+Returns a list of containing the X-Y graph coordinates.
+.TP
+\fIpathName \fBinside \fIx y\fR
+Returns \f(CW1\fR is the designated screen coordinate (\fIx\fR and \fIy\fR)
+is inside the plotting area and \f(CW0\fR otherwise.
+.TP
+\fIpathName \fBlegend \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "LEGEND COMPONENT"
+section.
+.TP
+\fIpathName \fBline\fB operation arg\fR...
+The operation is the same as \fBelement\fR.
+.TP
+\fIpathName \fBmarker \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "MARKER COMPONENTS"
+section.
+.TP
+\fIpathName \fBpostscript \fIoperation \fR?\fIarg\fR?...
+See the 
+.SB "POSTSCRIPT COMPONENT"
+section.
+.TP
+\fIpathName \fBsnap \fR?\fIswitches\fR? \fIoutputName\fR
+Takes a snapshot of the graph, saving the output in \fIoutputName\fR.
+The following switches are available.
+.RS
+.TP 1i
+\fB\-format\fR \fIformat\fR
+Specifies how the snapshot is output. \fIFormat\fR may be one of 
+the following listed below.  The default is \f(CWphoto\fR. 
+.RS
+.TP 
+\f(CWphoto\fR
+Saves a Tk photo image. \fIOutputName\fR represents the name of a 
+Tk photo image that must already have been created.  
+.TP 
+\f(CWwmf\fR
+Saves an Aldus Placeable Metafile.  \fIOutputName\fR represents the
+filename where the metafile is written.  If \fIoutputName\fR is
+\f(CWCLIPBOARD\fR, then output is written directly to the Windows
+clipboard.  This format is available only under Microsoft Windows.
+.TP 
+\f(CWemf\fR
+Saves an Enhanced Metafile. \fIOutputName\fR represents the filename
+where the metafile is written.  If \fIoutputName\fR is
+\f(CWCLIPBOARD\fR, then output is written directly to the Windows
+clipboard.  This format is available only under Microsoft Windows.
+.RE
+.TP 1i
+\fB\-height\fR \fIsize\fR
+Specifies the height of the graph.  \fISize\fR is a screen distance.
+The graph will be redrawn using this dimension, rather than its
+current window height.
+.TP 1i
+\fB\-width\fR \fIsize\fR
+Specifies the width of the graph.  \fISize\fR is a screen distance.
+The graph will be redrawn using this dimension, rather than its
+current window width.
+.RE
+.TP
+\fIpathName \fBtransform \fIx y\fR 
+Performs a coordinate transformation, mapping graph coordinates to
+window coordinates, using the standard X\-axis and Y\-axis.
+Returns a list containing the X\-Y screen coordinates.
+.TP
+\fIpathName \fBxaxis \fIoperation\fR ?\fIarg\fR?...
+.TP
+\fIpathName \fBx2axis \fIoperation\fR ?\fIarg\fR?... 
+.TP
+\fIpathName \fByaxis \fIoperation\fR ?\fIarg\fR?... 
+.TP
+\fIpathName \fBy2axis \fIoperation\fR ?\fIarg\fR?... 
+See the 
+.SB "AXIS COMPONENTS"
+section.
+.SH "GRAPH COMPONENTS"
+A graph is composed of several components: coordinate axes, data
+elements, legend, grid, cross hairs, postscript, and annotation
+markers. Instead of one big set of configuration options and
+operations, the graph is partitioned, where each component has its own
+configuration options and operations that specifically control that
+aspect or part of the graph. 
+.SS "AXIS COMPONENTS"
+Four coordinate axes are automatically created: two X\-coordinate axes
+(\f(CWx\fR and \f(CWx2\fR) and two Y\-coordinate axes (\f(CWy\fR, and
+\f(CWy2\fR).  By default, the axis \f(CWx\fR is located in the bottom
+margin, \f(CWy\fR in the left margin, \f(CWx2\fR in the top margin, and
+\f(CWy2\fR in the right margin.
+.PP
+An axis consists of the axis line, title, major and minor ticks, and
+tick labels.  Major ticks are drawn at uniform intervals along the
+axis.  Each tick is labeled with its coordinate value.  Minor ticks
+are drawn at uniform intervals within major ticks.  
+.PP
+The range of the axis controls what region of data is plotted.
+Data points outside the minimum and maximum limits of the axis are
+not plotted.  By default, the minimum and maximum limits are
+determined from the data, but you can reset either limit.
+.PP
+You can have several axes. To create an axis, invoke
+the axis component and its create operation.
+.CS
+# Create a new axis called "tempAxis"
+\&.g axis create tempAxis
+.CE
+You map data elements to an axis using the element's \-mapy and \-mapx
+configuration options. They specify the coordinate axes an element
+is mapped onto.
+.CS
+# Now map the tempAxis data to this axis.
+\&.g element create "e1" \-xdata $x \-ydata $y \-mapy tempAxis
+.CE
+Any number of axes can be displayed simultaneously. They are drawn in
+the margins surrounding the plotting area.  The default axes \f(CWx\fR
+and \f(CWy\fR are drawn in the bottom and left margins. The axes
+\f(CWx2\fR and \f(CWy2\fR are drawn in top and right margins.  By
+default, only \f(CWx\fR and \f(CWy\fR are shown. Note that the axes
+can have different scales.
+.PP
+To display a different axis or more than one axis, you invoke one of
+the following components: \fBxaxis\fR, \fByaxis\fR, \fBx2axis\fR, and
+\fBy2axis\fR.  Each component has a \fBuse\fR operation that
+designates the axis (or axes) to be drawn in that corresponding
+margin: \fBxaxis\fR in the bottom, \fByaxis\fR in the left,
+\fBx2axis\fR in the top, and \fBy2axis\fR in the right.
+.CS
+# Display the axis tempAxis in the left margin.
+\&.g yaxis use tempAxis
+.CE
+The \fBuse\fR operation takes a list of axis names as its last
+argument.  This is the list of axes to be drawn in this margin.
+.PP
+You can configure axes in many ways. The axis scale can be linear or
+logarithmic.  The values along the axis can either monotonically
+increase or decrease.  If you need custom tick labels, you can specify
+a Tcl procedure to format the label any way you wish.  You can control
+how ticks are drawn, by changing the major tick interval or the number
+of minor ticks.  You can define non-uniform tick intervals, such as
+for time-series plots.
+.PP
+.TP
+\fIpathName \fBaxis bind \fItagName\fR ?\fIsequence\fR?  ?\fIcommand\fR? 
+Associates \fIcommand\fR with \fItagName\fR such that whenever the
+event sequence given by \fIsequence\fR occurs for an axis with this
+tag, \fIcommand\fR will be invoked.  The syntax is similar to the 
+\fBbind\fR command except that it operates on graph axes, rather 
+than widgets. See the \fBbind\fR manual entry for
+complete details on \fIsequence\fR and the substitutions performed on 
+\fIcommand\fR before invoking it.  
+.sp
+If all arguments are specified then a new binding is created, replacing 
+any existing binding for the same \fIsequence\fR and \fItagName\fR.
+If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR 
+augments an existing binding rather than replacing it. 
+If no \fIcommand\fR argument is provided then the command currently
+associated with \fItagName\fR and \fIsequence\fR (it's an error occurs 
+if there's no such binding) is returned.  If both \fIcommand\fR and 
+\fIsequence\fR are missing then a list of all the event sequences for 
+which bindings have been defined for \fItagName\fR. 
+.TP
+\fIpathName \fBaxis \fBcget \fIaxisName \fIoption\fR
+Returns the current value of the option given by \fIoption\fR for
+\fIaxisName\fR.  \fIOption\fR may be any option described below
+for the axis \fBconfigure\fR operation.
+.TP
+\fIpathName \fBaxis \fBconfigure \fIaxisName \fR?\fIaxisName\fR?... ?\fIoption value\fR?...
+Queries or modifies the configuration options of \fIaxisName\fR.
+Several axes can be changed.  If \fIoption\fR isn't specified, a list
+describing all the current options for \fIaxisName\fR is returned.  If
+\fIoption\fR is specified, but not \fIvalue\fR, then a list describing
+\fIoption\fR is returned.  If one or more \fIoption\fR and \fIvalue\fR
+pairs are specified, then for each pair, the axis option \fIoption\fR
+is set to \fIvalue\fR.  The following options are valid for axes.
+.RS
+.TP
+\fB\-bindtags \fItagList\fR
+Specifies the binding tags for the axis.  \fITagList\fR is a list
+of binding tag names.  The tags and their order will determine how
+events for axes are handled.  Each tag in the list matching the current event
+sequence will have its Tcl command executed.  Implicitly the name of
+the element is always the first tag in the list.  The default value is
+\f(CWall\fR.
+.TP
+\fB\-color \fIcolor\fR
+Sets the color of the axis and tick labels.
+The default is \f(CWblack\fR.
+.TP
+\fB\-command \fIprefix\fR
+Specifies a Tcl command to be invoked when formatting the axis tick
+labels. \fIPrefix\fR is a string containing the name of a Tcl proc and
+any extra arguments for the procedure.  This command is invoked for each
+major tick on the axis.  Two additional arguments are passed to the
+procedure: the pathname of the widget and the current the numeric
+value of the tick.  The procedure returns the formatted tick label.  If
+\f(CW""\fR is returned, no label will appear next to the tick.  You can
+get the standard tick labels again by setting \fIprefix\fR to
+\f(CW""\fR.  The default is \f(CW""\fR.
+.sp 1
+Please note that this procedure is invoked while the graph is redrawn.
+You may query configuration options.  But do not them, because this
+can have unexpected results.
+.TP
+\fB\-descending \fIboolean\fR 
+Indicates whether the values along the axis are monotonically increasing or
+decreasing.  If \fIboolean\fR is true, the axis values will be
+decreasing.  The default is \f(CW0\fR.
+.TP
+\fB\-hide \fIboolean\fR
+Indicates if the axis is displayed. If \fIboolean\fR is false the axis 
+will be displayed. Any element mapped to the axis is displayed regardless.
+The default value is \f(CW0\fR.
+.TP
+\fB\-justify \fIjustify\fR
+Specifies how the axis title should be justified.  This matters only
+when the axis title contains more than one line of text. \fIJustify\fR
+must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR.  The default is
+\f(CWcenter\fR.
+.TP
+\fB\-limits \fIformatStr\fR
+Specifies a printf-like description to format the minimum and maximum
+limits of the axis.  The limits are displayed at the top/bottom or
+left/right sides of the plotting area.  \fIFormatStr\fR is a list of
+one or two format descriptions.  If one description is supplied, both
+the minimum and maximum limits are formatted in the same way.  If two,
+the first designates the format for the minimum limit, the second for
+the maximum.  If \f(CW""\fR is given as either description, then 
+the that limit will not be displayed.  The default is \f(CW""\fR.
+.TP
+\fB\-linewidth \fIpixels\fR
+Sets the width of the axis and tick lines.  The default is \f(CW1\fR
+pixel.
+.TP
+\fB\-logscale \fIboolean\fR
+Indicates whether the scale of the axis is logarithmic or linear.  If
+\fIboolean\fR is true, the axis is logarithmic.  The default scale is
+linear.
+.TP
+\fB\-loose \fIboolean\fR
+Indicates whether the limits of the axis should fit the data points tightly,
+at the outermost data points, or loosely, at the outer tick intervals.
+If the axis limit is set with the -min or -max option, the axes are
+displayed tightly.
+If \fIboolean\fR is true, the axis range is "loose".
+The default is \f(CW0\fR.
+.TP
+\fB\-majorticks \fImajorList\fR
+Specifies where to display major axis ticks.  You can use this option
+to display ticks at non-uniform intervals.  \fIMajorList\fR is a list
+of axis coordinates designating the location of major ticks.  No
+minor ticks are drawn.  If \fImajorList\fR is \f(CW""\fR, 
+major ticks will be automatically computed. The default is \f(CW""\fR.
+.TP
+\fB\-max \fIvalue\fR
+Sets the maximum limit of \fIaxisName\fR.  Any data point greater 
+than \fIvalue\fR is not displayed.  If \fIvalue\fR is \f(CW""\fR, 
+the maximum limit is calculated using the largest data value.
+The default is \f(CW""\fR.
+.TP
+\fB\-min \fIvalue\fR
+Sets the minimum limit of \fIaxisName\fR. Any data point less than 
+\fIvalue\fR is not displayed.  If \fIvalue\fR is \f(CW""\fR,
+the minimum limit is calculated using the smallest data value.
+The default is \f(CW""\fR.
+.TP
+\fB\-minorticks \fIminorList\fR
+Specifies where to display minor axis ticks.  You can use this option
+to display minor ticks at non-uniform intervals. \fIMinorList\fR is a
+list of real values, ranging from 0.0 to 1.0, designating the placement of
+a minor tick.  No minor ticks are drawn if the \fB\-majortick\fR
+option is also set.  If \fIminorList\fR is \f(CW""\fR, minor ticks will
+be automatically computed. The default is \f(CW""\fR.
+.TP
+\fB\-rotate \fItheta\fR
+Specifies the how many degrees to rotate the axis tick labels.
+\fITheta\fR is a real value representing the number of degrees
+to rotate the tick labels.  The default is \f(CW0.0\fR degrees.
+.TP
+\fB\-scrollcommand \fIcommand\fR
+Specify the prefix for a command used to communicate with scrollbars
+for this axis, such as \fI.sbar set\fP.
+.TP
+\fB\-scrollmax \fIvalue\fR
+Sets the maximum limit of the axis scroll region.  If \fIvalue\fR is
+\f(CW""\fR, the maximum limit is calculated using the largest data
+value.  The default is \f(CW""\fR.
+.TP
+\fB\-scrollmin \fIvalue\fR 
+Sets the minimum limit of axis scroll region.  If \fIvalue\fR is
+\f(CW""\fR, the minimum limit is calculated using the smallest data
+value.  The default is \f(CW""\fR.
+.TP
+\fB\-showticks \fIboolean\fR
+Indicates whether axis ticks should be drawn. If \fIboolean\fR is
+true, ticks are drawn.  If false, only the
+axis line is drawn. The default is \f(CW1\fR.
+.TP
+\fB\-stepsize \fIvalue\fR
+Specifies the interval between major axis ticks.  If \fIvalue\fR isn't
+a valid interval (must be less than the axis range), 
+the request is ignored and the step size is automatically calculated.
+.TP
+\fB\-subdivisions \fInumber\fR 
+Indicates how many minor axis ticks are
+to be drawn.  For example, if \fInumber\fR is two, only one minor
+tick is drawn.  If \fInumber\fR is one, no minor ticks are
+displayed.  The default is \f(CW2\fR.
+.TP
+\fB\-tickfont \fIfontName\fR 
+Specifies the font for axis tick labels. The default is
+\f(CW*-Courier-Bold-R-Normal-*-100-*\fR.
+.TP
+\fB\-ticklength \fIpixels\fR
+Sets the length of major and minor ticks (minor ticks are half the
+length of major ticks). If \fIpixels\fR is less than zero, the axis
+will be inverted with ticks drawn pointing towards the plot.  The
+default is \f(CW0.1i\fR.
+.TP
+\fB\-title \fItext\fR
+Sets the title of the axis. If \fItext\fR is 
+\f(CW""\fR, no axis title will be displayed.  
+.TP
+\fB\-titlealternate \fIboolean\fR
+Indicates to display the axis title in its alternate location. 
+Normally the axis title is centered along the axis.  This option
+places the axis either to the right (horizontal axes) or above
+(vertical axes) the axis.  The default is \f(CW0\fR.
+.TP
+\fB\-titlecolor \fIcolor\fR
+Sets the color of the axis title. The default is \f(CWblack\fR.
+.TP
+\fB\-titlefont \fIfontName\fR 
+Specifies the font for axis title. The default is
+\f(CW*-Helvetica-Bold-R-Normal-*-14-140-*\fR.
+.PP
+Axis configuration options may be also be set by the \fBoption\fR
+command.  The resource class is \f(CWAxis\fR.  The resource names
+are the names of the axes (such as \f(CWx\fR or \f(CWx2\fR).
+.CS
+option add *Graph.Axis.Color  blue
+option add *Graph.x.LogScale  true
+option add *Graph.x2.LogScale false
+.CE
+.RE
+.TP
+\fIpathName \fBaxis \fBcreate \fIaxisName \fR?\fIoption value\fR?...
+Creates a new axis by the name \fIaxisName\fR.  No axis by the same
+name can already exist. \fIOption\fR and \fIvalue\fR are described 
+in above in the axis \fBconfigure\fR operation.
+.TP
+\fIpathName \fBaxis \fBdelete \fR?\fIaxisName\fR?...
+Deletes the named axes. An axis is not really
+deleted until it is not longer in use, so it's safe to delete
+axes mapped to elements.
+.TP
+\fIpathName \fBaxis invtransform \fIaxisName value\fR
+Performs the inverse transformation, changing the screen coordinate
+\fIvalue\fR to a graph coordinate, mapping the value mapped to
+\fIaxisName\fR.  Returns the graph coordinate.
+.TP
+\fIpathName \fBaxis limits \fIaxisName\fR
+Returns a list of the minimum and maximum limits for \fIaxisName\fR.  The order
+of the list is \f(CWmin max\fR.
+.TP
+\fIpathName \fBaxis names \fR?\fIpattern\fR?...
+Returns a list of axes matching zero or more patterns.  If no
+\fIpattern\fR argument is give, the names of all axes are returned.
+.TP
+\fIpathName \fBaxis transform \fIaxisName value\fR
+Transforms the coordinate \fIvalue\fR to a screen coordinate by mapping
+the it to \fIaxisName\fR.  Returns the transformed screen coordinate.
+.TP
+\fIpathName \fBaxis view \fIaxisName\fR
+Change the viewable area of this axis. Use as an argument to a scrollbar's "\fI\-command\fR".
+.PP
+The default axes are \f(CWx\fR, \f(CWy\fR, \f(CWx2\fR, and \f(CWy2\fR.
+But you can display more than four axes simultaneously.  You can also
+swap in a different axis with \fBuse\fR operation of the special axis
+components: \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR.
+.CS
+\&.g create axis temp
+\&.g create axis time
+\&...
+\&.g xaxis use temp
+\&.g yaxis use time
+.CE
+Only the axes specified for use are displayed on the screen.
+.PP
+The \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR
+components operate on an axis location rather than a specific axis
+like the more general \fBaxis\fR component does.  They implicitly
+control the axis that is currently using to that location.  By
+default, \fBxaxis\fR uses the \f(CWx\fR axis, \fByaxis\fR uses
+\f(CWy\fR, \fBx2axis\fR uses \f(CWx2\fR, and \fBy2axis\fR uses
+\f(CWy2\fR.  When more than one axis is displayed in a margin, it
+represents the first axis displayed.
+.PP
+The following operations are available for axes. They mirror exactly
+the operations of the \fBaxis\fR component.  The \fIaxis\fR argument
+must be \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, or \fBy2axis\fR.  This
+feature is deprecated since more than one axis can now be used a
+margin.  You should only use the \fBxaxis\fR, \fBx2axis\fR,
+\fByaxis\fR, and \fBy2axis\fR components with the \fBuse\fR operation.
+For all other operations, use the general \fBaxis\fR component
+instead.
+.TP
+\fIpathName \fIaxis \fBcget \fIoption\fR
+.TP
+\fIpathName \fIaxis \fBconfigure \fR?\fIoption value\fR?...
+.TP
+\fIpathName \fIaxis\fB invtransform \fIvalue\fR
+.TP
+\fIpathName \fIaxis \fBlimits\fR
+.TP
+\fIpathName \fIaxis\fB transform \fIvalue\fR
+.TP
+\fIpathName \fIaxis\fB use \fR?\fIaxisName\fR?  
+Designates the axis \fIaxisName\fR is to be displayed at this
+location.  \fIAxisName\fR can not be already in use at another location.  
+This command returns the name of the axis currently using this location.
+.SS "CROSSHAIRS COMPONENT"
+Cross hairs consist of two intersecting lines (one vertical and one horizontal)
+drawn completely across the plotting area.  They are used to position
+the mouse in relation to the coordinate axes.  Cross hairs differ from line
+markers in that they are implemented using XOR drawing primitives.
+This means that they can be quickly drawn and erased without redrawing
+the entire graph.
+.PP
+The following operations are available for cross hairs:
+.TP
+\fIpathName \fBcrosshairs cget \fIoption\fR
+Returns the current value of the cross hairs configuration option
+given by \fIoption\fR.  \fIOption\fR may be any option
+described below for the cross hairs \fBconfigure\fR operation.
+.TP
+\fIpathName \fBcrosshairs configure \fR?\fIoption value\fR?...  
+Queries or modifies the configuration options of the cross hairs.  If
+\fIoption\fR isn't specified, a list describing all the current
+options for the cross hairs is returned.  If \fIoption\fR is specified,
+but not \fIvalue\fR, then a list describing \fIoption\fR is returned.
+If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then
+for each pair, the cross hairs option \fIoption\fR is set to
+\fIvalue\fR.
+The following options are available for cross hairs.
+.RS
+.TP
+\fB\-color \fIcolor\fR 
+Sets the color of the cross hairs.  The default is \f(CWblack\fR.
+.TP
+\fB\-dashes \fIdashList\fR
+Sets the dash style of the cross hairs. \fIDashList\fR is a list of up
+to 11 numbers that alternately represent the lengths of the dashes
+and gaps on the cross hair lines.  Each number must be between 1 and
+255.  If \fIdashList\fR is \f(CW""\fR, the cross hairs will be solid
+lines.
+.TP
+\fB\-hide \fIboolean\fR
+Indicates whether cross hairs are drawn. If \fIboolean\fR is true,
+cross hairs are not drawn.  The default is \f(CWyes\fR.
+.TP
+\fB\-linewidth \fIpixels\fR
+Set the width of the cross hair lines.  The default is \f(CW1\fR.
+.TP
+\fB\-position \fIpos\fR 
+Specifies the screen position where the cross hairs intersect.
+\fIPos\fR must be in the form "\fI at x,y\fR", where \fIx\fR and \fIy\fR
+are the window coordinates of the intersection.
+.PP
+Cross hairs configuration options may be also be set by the
+\fBoption\fR command.  The resource name and class are
+\f(CWcrosshairs\fR and \f(CWCrosshairs\fR respectively.
+.CS
+option add *Graph.Crosshairs.LineWidth 2
+option add *Graph.Crosshairs.Color     red
+.CE
+.RE
+.TP
+\fIpathName \fBcrosshairs off\fR
+Turns off the cross hairs. 
+.TP
+\fIpathName \fBcrosshairs on\fR
+Turns on the display of the cross hairs.
+.TP
+\fIpathName \fBcrosshairs toggle\fR 
+Toggles the current state of the cross hairs, alternately mapping and
+unmapping the cross hairs.
+.SS "ELEMENT COMPONENTS"
+A data element represents a set of data.  It contains x and y vectors
+containing the coordinates of the data points.  Elements can be
+displayed with a symbol at each data point and lines connecting the
+points.  Elements also control the appearance of the data, such as the
+symbol type, line width, color etc.
+.PP
+When new data elements are created, they are automatically added to a
+list of displayed elements.   The display list controls what elements
+are drawn and in what order.  
+.PP
+The following operations are available for elements.
+.TP
+\fIpathName \fBelement activate \fIelemName \fR?\fIindex\fR?...
+Specifies the data points of element \fIelemName\fR to be drawn
+using active foreground and background colors.  \fIElemName\fR is the
+name of the element and \fIindex\fR is a number representing the index
+of the data point. If no indices are present then all data points
+become active.
+.TP
+\fIpathName \fBelement bind \fItagName\fR ?\fIsequence\fR?  ?\fIcommand\fR? 
+Associates \fIcommand\fR with \fItagName\fR such that whenever the
+event sequence given by \fIsequence\fR occurs for an element with this
+tag, \fIcommand\fR will be invoked.  The syntax is similar to the 
+\fBbind\fR command except that it operates on graph elements, rather 
+than widgets. See the \fBbind\fR manual entry for
+complete details on \fIsequence\fR and the substitutions performed on 
+\fIcommand\fR before invoking it.  
+.sp
+If all arguments are specified then a new binding is created, replacing 
+any existing binding for the same \fIsequence\fR and \fItagName\fR.
+If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR 
+augments an existing binding rather than replacing it. 
+If no \fIcommand\fR argument is provided then the command currently
+associated with \fItagName\fR and \fIsequence\fR (it's an error occurs 
+if there's no such binding) is returned.  If both \fIcommand\fR and 
+\fIsequence\fR are missing then a list of all the event sequences for 
+which bindings have been defined for \fItagName\fR. 
+.TP
+\fIpathName \fBelement cget \fIelemName \fIoption\fR
+Returns the current value of the element configuration option given by 
+\fIoption\fR.  \fIOption\fR may be any of the options described below
+for the element \fBconfigure\fR operation.
+.TP
+\fIpathName \fBelement closest \fIx y\fR ?\fIoption value\fR?... ?\fIelemName\fR?...
+Searches for the data point closest to the window coordinates \fIx\fR
+and \fIy\fR.  By default, all elements are searched.  Hidden elements
+(see the \fB\-hide\fR option is false) are ignored.  You can limit the
+search by specifying only the elements you want to be considered. 
+\fIElemName\fR must be the name of an element that can not be hidden.
+It returns a key-value list containing the name of the closest element, 
+the index of the closest data point, and the graph-coordinates of the point. 
+Returns \f(CW""\fR, if no data point within the threshold distance 
+can be found. The following
+\fIoption\fR\-\fIvalue\fR pairs are available.
+.RS
+.TP
+\fB\-along \fIdirection\fR
+Search for the closest element using the following criteria:
+.RS
+.TP
+\f(CWx\fR
+Find closest element vertically from the given X-coordinate. 
+.TP
+\f(CWy\fR
+Find the closest element horizontally from the given Y-coordinate. 
+.TP
+\f(CWboth\fR
+Find the closest element for the given point (using both the X and Y
+coordinates).  
+.RE
+.TP
+\fB\-halo \fIpixels\fR
+Specifies a threshold distance where selected data points are ignored.
+\fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR.
+If this option isn't specified, then it defaults to the value of the
+graph's \fB\-halo\fR option.
+.TP
+\fB\-interpolate \fIstring\fR
+Indicates whether to consider projections that lie along the line segments 
+connecting data points when searching for the closest point.
+The default value is \f(CW0\fR. The values for \fIstring\fR are
+described below.
+.RS
+.TP 1.25i
+\f(CWno\fR 
+Search only for the closest data point.
+.TP
+\f(CWyes\fR
+Search includes projections that lie along the
+line segments connecting the data points.  
+.RE
+.RE
+.TP
+\fIpathName \fBelement configure \fIelemName \fR?\fIelemName\fR... ?\fIoption value\fR?...
+Queries or modifies the configuration options for elements.  Several
+elements can be modified at the same time. If \fIoption\fR isn't
+specified, a list describing all the current options for
+\fIelemName\fR is returned.  If \fIoption\fR is specified, but not
+\fIvalue\fR, then a list describing the option \fIoption\fR is
+returned.  If one or more \fIoption\fR and \fIvalue\fR pairs are
+specified, then for each pair, the element option \fIoption\fR is set
+to \fIvalue\fR.  The following options are valid for elements.
+.RS
+.TP
+\fB\-activepen \fIpenName\fR
+Specifies pen to use to draw active element.  If \fIpenName\fR is
+\f(CW""\fR, no active elements will be drawn.  The default is 
+\f(CWactiveLine\fR.
+.TP
+\fB\-areabackground \fIcolor\fR 
+Specifies the background color of the area under the curve. The
+background area color is drawn only for bitmaps (see the
+\fB\-areapattern\fR option).  If \fIcolor\fR is \f(CW""\fR, the
+background is transparent.  The default is \f(CWblack\fR.
+.TP
+\fB\-areaforeground \fIcolor\fR 
+Specifies the foreground color of the area under the curve. 
+The default is \f(CWblack\fR.
+.TP
+\fB\-areapattern \fIpattern\fR 
+Specifies how to fill the area under the curve.  \fIPattern\fR may be
+the name of a Tk bitmap, \f(CWsolid\fR, or \f(CW""\fR.  If "solid",
+then the area under the curve is drawn with the color designated by
+the \fB\-areaforeground\fR option.  If a bitmap, then the bitmap is
+stippled across the area.  Here the bitmap colors are controlled by the
+\fB\-areaforeground\fR and \fB\-areabackground\fR options.  If
+\fIpattern\fR is \f(CW""\fR, no filled area is drawn.  The default is
+\f(CW""\fR.
+.TP
+\fB\-areatile \fIimage\fR 
+Specifies the name of a Tk image to be used to tile the area under the
+curve.  This option supersedes the \fB\-areapattern\fR option.
+\fIImage\fR must be a photo image.  If \fIimage\fR is \f(CW""\fR, no
+tiling is performed.  The default is \f(CW""\fR.
+.TP
+\fB\-bindtags \fItagList\fR
+Specifies the binding tags for the element.  \fITagList\fR is a list
+of binding tag names.  The tags and their order will determine how
+events are handled for elements.  Each tag in the list matching the 
+current event
+sequence will have its Tcl command executed.  Implicitly the name of
+the element is always the first tag in the list.  The default value is
+\f(CWall\fR.
+.TP
+\fB\-color \fIcolor\fR 
+Sets the color of the traces connecting the data points.  
+.TP
+\fB\-dashes \fIdashList\fR
+Sets the dash style of element line. \fIDashList\fR is a list of up to
+11 numbers that alternately represent the lengths of the dashes and
+gaps on the element line.  Each number must be between 1 and 255.  If
+\fIdashList\fR is \f(CW""\fR, the lines will be solid.
+.TP
+\fB\-data \fIcoordList\fR
+Specifies the X\-Y coordinates of the data.  \fICoordList\fR is a
+list of numeric expressions representing the X\-Y coordinate pairs
+of each data point.
+.TP
+\fB\-fill \fIcolor\fR 
+Sets the interior color of symbols.  If \fIcolor\fR is \f(CW""\fR, then
+the interior of the symbol is transparent.  If \fIcolor\fR is
+\f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR
+option.  The default is \f(CWdefcolor\fR.
+.TP
+\fB\-hide \fIboolean\fR
+Indicates whether the element is displayed.  
+The default is \f(CWno\fR.
+.TP
+\fB\-label \fItext\fR
+Sets the element's label in the legend.  If \fItext\fR
+is \f(CW""\fR, the element will have no entry in the legend.
+The default label is the element's name. 
+.TP
+\fB\-linewidth \fIpixels\fR 
+Sets the width of the connecting lines between data points.  If
+\fIpixels\fR is \f(CW0\fR, no connecting lines will be drawn between
+symbols.  The default is \f(CW0\fR.
+.TP
+\fB\-mapx \fIxAxis\fR
+Selects the X\-axis to map the element's X\-coordinates onto.
+\fIXAxis\fR must be the name of an axis.  The default is \f(CWx\fR.
+.TP
+\fB\-mapy \fIyAxis\fR
+Selects the Y\-axis to map the element's Y\-coordinates onto.
+\fIYAxis\fR must be the name of an axis. The default is \f(CWy\fR.
+.TP
+\fB\-offdash \fIcolor\fR
+Sets the color of the stripes when traces are dashed (see the
+\fB\-dashes\fR option).  If \fIcolor\fR is \f(CW""\fR, then the "off"
+pixels will represent gaps instead of stripes.  If \fIcolor\fR is
+\f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR
+option.  The default is \f(CWdefcolor\fR.
+.TP
+\fB\-outline \fIcolor\fR 
+Sets the color or the outline around each symbol.  If \fIcolor\fR is
+\f(CW""\fR, then no outline is drawn. If \fIcolor\fR is \f(CWdefcolor\fR,
+then the color will be the same as the \fB\-color\fR option.  The
+default is \f(CWdefcolor\fR.
+.TP
+\fB\-pen \fIpenname\fR
+Set the pen to use for this element.
+.TP
+\fB\-outlinewidth \fIpixels\fR 
+Sets the width of the outline bordering each symbol.  If \fIpixels\fR
+is \f(CW0\fR, no outline will be drawn. The default is \f(CW1\fR.
+.TP
+\fB\-pixels \fIpixels\fR
+Sets the size of symbols.  If \fIpixels\fR is \f(CW0\fR, no symbols will
+be drawn.  The default is \f(CW0.125i\fR.
+.TP
+\fB\-scalesymbols \fIboolean\fR 
+If \fIboolean\fR is true, the size of the symbols
+drawn for \fIelemName\fR will change with scale of the X\-axis and Y\-axis.
+At the time this option is set, the current ranges of the axes are
+saved as the normalized scales (i.e scale factor is 1.0) and the
+element is drawn at its designated size (see the \fB\-pixels\fR
+option).  As the scale of the axes change, the symbol will be scaled
+according to the smaller of the X\-axis and Y\-axis scales.  If \fIboolean\fR
+is false, the element's symbols are drawn at the designated size,
+regardless of axis scales.  The default is \f(CW0\fR.
+.TP
+\fB\-smooth \fIsmooth\fR 
+Specifies how connecting line segments are drawn between data points.
+\fISmooth\fR can be either \f(CWlinear\fR, \f(CWstep\fR, \f(CWnatural\fR, or
+\f(CWquadratic\fR.  If \fIsmooth\fR is \f(CWlinear\fR, a single line
+segment is drawn, connecting both data points. When \fIsmooth\fR is
+\f(CWstep\fR, two line segments are drawn. The first is a horizontal
+line segment that steps the next X\-coordinate.  The second is a
+vertical line, moving to the next Y\-coordinate.  Both \fInatural\fR and
+\fIquadratic\fR generate multiple segments between data points.  If
+\fInatural\fR, the segments are generated using a cubic spline.  If
+\fIquadratic\fR, a quadratic spline is used.  The default is
+\fIlinear\fR.
+.TP
+\fB\-styles \fIstyleList\fR 
+Specifies what pen to use based on the range of weights given.
+\fIStyleList\fR is a list of style specifications. Each style
+specification, in turn, is a list consisting of a pen name, and
+optionally a minimum and maximum range.  Data points whose weight (see
+the \fB\-weight\fR option) falls in this range, are drawn with this
+pen.  If no range is specified it defaults to the index of the pen in
+the list.  Note that this affects only symbol attributes. Line
+attributes, such as line width, dashes, etc. are ignored.
+.TP
+\fB\-symbol \fIsymbol\fR 
+Specifies the symbol for data points.  \fISymbol\fR can be either
+\f(CWsquare\fR, \f(CWcircle\fR, \f(CWdiamond\fR, \f(CWplus\fR, \f(CWcross\fR,
+\f(CWsplus\fR, \f(CWscross\fR, \f(CWtriangle\fR, \f(CW""\fR (where no symbol
+is drawn), or a bitmap.  Bitmaps are specified as "\fIsource\fR
+?\fImask\fR?", where \fIsource\fR is the name of the bitmap, and
+\fImask\fR is the bitmap's optional mask.  The default is
+\f(CWcircle\fR.
+.TP
+\fB\-trace \fIdirection\fR 
+Indicates whether connecting lines between data points (whose
+X\-coordinate values are either increasing or decreasing) are drawn.  
+\fIDirection\fR
+must be \f(CWincreasing\fR, \f(CWdecreasing\fR, or \f(CWboth\fR.  For
+example, if \fIdirection\fR is \f(CWincreasing\fR, connecting lines will
+be drawn only between those data points where X\-coordinate values are
+monotonically increasing.  If \fIdirection\fR is \f(CWboth\fR,
+connecting lines will be draw between all data points.  The default is
+\f(CWboth\fR.
+.TP
+\fB\-weights \fIwVec\fR 
+Specifies the weights of the individual data points.  This, 
+with the list pen styles (see the \fB\-styles\fR option),
+controls how data points are drawn.  \fIWVec\fR is the name of a BLT
+vector or a list of numeric expressions representing the weights for
+each data point.
+.TP
+\fB\-xdata \fIxVec\fR 
+Specifies the X\-coordinates of the data.  \fIXVec\fR is the name of
+a BLT vector or a list of numeric expressions.
+.TP
+\fB\-ydata \fIyVec\fR 
+Specifies the Y\-coordinates of the data.  \fIYVec\fR is the name of
+a BLT vector or a list of numeric expressions.
+.PP
+Element configuration options may also be set by the \fBoption\fR
+command.  The resource class is \f(CWElement\fR. The resource name is
+the name of the element.
+.CS
+option add *Graph.Element.symbol line
+option add *Graph.e1.symbol line
+.CE
+.RE
+.TP
+\fIpathName \fBelement create \fIelemName\fR ?\fIoption value\fR?...
+Creates a new element \fIelemName\fR.  It's an error is
+an element \fIelemName\fR already exists.  If
+additional arguments are present, they specify options valid for 
+the element \fBconfigure\fR operation.
+.TP
+\fIpathName \fBelement deactivate \fIelemName\fR ?\fIelemName\fR?...
+Deactivates all the elements matching \fIpattern\fR.
+Elements whose names match any of the patterns given are redrawn using
+their normal colors.
+.TP
+\fIpathName \fBelement delete\fR ?\fIelemName\fR?...
+Deletes all the named elements.  The graph is automatically redrawn.
+.TP
+\fIpathName \fBelement exists \fIelemName\fR
+Returns \f(CW1\fR if an element \fIelemName\fR currently exists and
+\f(CW0\fR otherwise.
+.TP
+\fIpathName \fBelement names \fR?\fIpattern\fR?...  
+Returns the elements matching one or more pattern.  If no
+\fIpattern\fR is given, the names of all elements is returned.
+.TP
+\fIpathName \fBelement show\fR ?\fInameList\fR?  
+Queries or modifies the element display list.  The element display
+list designates the elements drawn and in what
+order. \fINameList\fR is a list of elements to be displayed in the
+order they are named.  If there is no \fInameList\fR argument,
+the current display list is returned.
+.TP
+\fIpathName \fBelement type\fR \fIelemName\fR
+Returns the type of \fIelemName\fR. 
+If the element is a bar element, the commands returns the string
+\f(CW"bar"\fR, otherwise it returns \f(CW"line"\fR.
+.CE
+.SS "GRID COMPONENT"
+Grid lines extend from the major and minor ticks of each axis
+horizontally or vertically across the plotting area.  The following
+operations are available for grid lines.
+.TP
+\fIpathName \fBgrid cget \fIoption\fR
+Returns the current value of the grid line configuration option given by 
+\fIoption\fR.  \fIOption\fR may be any option described below
+for the grid \fBconfigure\fR operation.
+.TP
+\fIpathName \fBgrid configure\fR ?\fIoption value\fR?...
+Queries or modifies the configuration options for grid lines.  If
+\fIoption\fR isn't specified, a list describing all the current
+grid options for \fIpathName\fR is returned.  If \fIoption\fR is specified,
+but not \fIvalue\fR, then a list describing \fIoption\fR is
+returned.  If one or more \fIoption\fR and \fIvalue\fR pairs are
+specified, then for each pair, the grid line option \fIoption\fR is set to
+\fIvalue\fR.  The following options are valid for grid lines.
+.RS
+.TP
+\fB\-color \fIcolor\fR 
+Sets the color of the grid lines.  The default is \f(CWblack\fR.
+.TP
+\fB\-dashes \fIdashList\fR
+Sets the dash style of the grid lines. \fIDashList\fR is a list of up
+to 11 numbers that alternately represent the lengths of the dashes
+and gaps on the grid lines.  Each number must be between 1 and 255.
+If \fIdashList\fR is \f(CW""\fR, the grid will be solid lines.
+.TP
+\fB\-hide \fIboolean\fR
+Indicates whether the grid should be drawn. If \fIboolean\fR
+is true, grid lines are not shown. The default is \f(CWyes\fR.
+.TP
+\fB\-linewidth \fIpixels\fR
+Sets the width of grid lines.  The default width is \f(CW1\fR.
+.TP
+\fB\-mapx \fIxAxis\fR
+Specifies the X\-axis to display grid lines.  \fIXAxis\fR
+must be the name of an axis or \f(CW""\fR for no grid lines.  
+The default is \f(CW""\fR.
+.TP
+\fB\-mapy \fIyAxis\fR
+Specifies the Y\-axis to display grid lines.  \fIYAxis\fR
+must be the name of an axis or \f(CW""\fR for no grid lines. 
+The default is \f(CWy\fR.
+.TP
+\fB\-minor \fIboolean\fR
+Indicates whether the grid lines should be drawn for minor ticks. 
+If \fIboolean\fR is true, the lines will appear at
+minor tick intervals.  The default is \f(CW1\fR.
+.PP
+Grid configuration options may also be set by the 
+\fBoption\fR command.  The resource name and class are \f(CWgrid\fR and 
+\f(CWGrid\fR respectively. 
+.CS
+option add *Graph.grid.LineWidth 2
+option add *Graph.Grid.Color     black
+.CE
+.RE
+.TP
+\fIpathName \fBgrid off\fR
+Turns off the display the grid lines.
+.TP
+\fIpathName \fBgrid on\fR
+Turns on the display the grid lines.
+.TP
+\fIpathName \fBgrid toggle\fR
+Toggles the display of the grid.  
+.SS "LEGEND COMPONENT"
+The legend displays a list of the data elements.  Each entry consists
+of the element's symbol and label.  The legend can appear in any
+margin (the default location is in the right margin).  It
+can also be positioned anywhere within the plotting area.
+.PP
+The following operations are valid for the legend.
+.TP
+\fIpathName \fBlegend activate \fIpattern\fR...
+Selects legend entries to be drawn using the active legend colors and relief.
+All entries whose element names match \fIpattern\fR  are selected.  To
+be selected, the element name must match only one \fIpattern\fR. 
+.TP
+\fIpathName \fBlegend bind \fItagName\fR ?\fIsequence\fR?  ?\fIcommand\fR? 
+Associates \fIcommand\fR with \fItagName\fR such that whenever the
+event sequence given by \fIsequence\fR occurs for a legend entry with this
+tag, \fIcommand\fR will be invoked.  Implicitly the element names
+in the entry are tags.  The syntax is similar to the 
+\fBbind\fR command except that it operates on legend entries, rather 
+than widgets. See the \fBbind\fR manual entry for
+complete details on \fIsequence\fR and the substitutions performed on 
+\fIcommand\fR before invoking it.  
+.sp
+If all arguments are specified then a new binding is created, replacing 
+any existing binding for the same \fIsequence\fR and \fItagName\fR.
+If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR 
+augments an existing binding rather than replacing it. 
+If no \fIcommand\fR argument is provided then the command currently
+associated with \fItagName\fR and \fIsequence\fR (it's an error occurs 
+if there's no such binding) is returned.  If both \fIcommand\fR and 
+\fIsequence\fR are missing then a list of all the event sequences for 
+which bindings have been defined for \fItagName\fR. 
+.TP
+\fIpathName \fBlegend cget \fIoption\fR
+Returns the current value of a legend configuration option.
+\fIOption\fR may be any option described below in the
+legend \fBconfigure\fR operation.
+.TP
+\fIpathName \fBlegend configure \fR?\fIoption value\fR?...
+Queries or modifies the configuration options for the legend.  If
+\fIoption\fR isn't specified, a list describing the current
+legend options for \fIpathName\fR is returned.  If \fIoption\fR is
+specified, but not \fIvalue\fR, then a list describing \fIoption\fR is
+returned.  If one or more \fIoption\fR and \fIvalue\fR pairs are
+specified, then for each pair, the legend option \fIoption\fR is set
+to \fIvalue\fR.  The following options are valid for the legend.
+.RS
+.TP
+\fB\-activebackground \fIcolor\fR
+Sets the background color for active legend entries.  All legend
+entries marked active (see the legend \fBactivate\fR operation) are
+drawn using this background color.
+.TP
+\fB\-activeborderwidth \fIpixels\fR
+Sets the width of the 3-D border around the outside edge of the active legend
+entries.  The default is \f(CW2\fR.
+.TP
+\fB\-activeforeground \fIcolor\fR
+Sets the foreground color for active legend entries.  All legend
+entries marked as active (see the legend \fBactivate\fR operation) are
+drawn using this foreground color.
+.TP
+\fB\-activerelief \fIrelief\fR 
+Specifies the 3-D effect desired for active legend entries.
+\fIRelief\fR denotes how the interior of the entry should appear
+relative to the legend; for example, \f(CWraised\fR means the entry
+should appear to protrude from the legend, relative to the surface of
+the legend.  The default is \f(CWflat\fR.
+.TP
+\fB\-anchor \fIanchor\fR
+Tells how to position the legend relative to the positioning point for
+the legend.  This is dependent on the value of the \fB\-position\fR
+option.  The default is \f(CWcenter\fR.
+.RS
+.TP 1.25i
+\f(CWleft\fR or \f(CWright\fR
+The anchor describes how to position the legend vertically.  
+.TP
+\f(CWtop\fR or \f(CWbottom\fR
+The anchor describes how to position the legend horizontally.  
+.TP
+\f(CW at x,y\fR
+The anchor specifies how to position the legend relative to the
+positioning point. For example, if \fIanchor\fR is \f(CWcenter\fR then
+the legend is centered on the point; if \fIanchor\fR is \f(CWn\fR then
+the legend will be drawn such that the top center point of the
+rectangular region occupied by the legend will be at the positioning
+point.
+.TP
+\f(CWplotarea\fR
+The anchor specifies how to position the legend relative to the
+plotting area. For example, if \fIanchor\fR is \f(CWcenter\fR then the
+legend is centered in the plotting area; if \fIanchor\fR is \f(CWne\fR
+then the legend will be drawn such that occupies the upper right
+corner of the plotting area.
+.RE
+.TP
+\fB\-background \fIcolor\fR
+Sets the background color of the legend. If \fIcolor\fR is \f(CW""\fR,
+the legend background with be transparent.
+.TP
+\fB\-bindtags \fItagList\fR
+Specifies the binding tags for legend entries.  \fITagList\fR is a list
+of binding tag names.  The tags and their order will determine how
+events are handled for legend entries.  Each tag in the list matching 
+the current event sequence will have its Tcl command executed. The 
+default value is \f(CWall\fR.
+.TP
+\fB\-borderwidth \fIpixels\fR
+Sets the width of the 3-D border around the outside edge of the legend (if
+such border is being drawn; the \fBrelief\fR option determines this).
+The default is \f(CW2\fR pixels.
+.TP
+\fB\-font \fIfontName\fR 
+\fIFontName\fR specifies a font to use when drawing the labels of each
+element into the legend.  The default is
+\f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR.
+.TP
+\fB\-foreground \fIcolor\fR 
+Sets the foreground color of the text drawn for the element's label.
+The default is \f(CWblack\fR.
+.TP
+\fB\-hide \fIboolean\fR
+Indicates whether the legend should be displayed. If \fIboolean\fR is
+true, the legend will not be draw.  The default is \f(CWno\fR.
+.TP
+\fB\-ipadx \fIpad\fR 
+Sets the amount of internal padding to be added to the width of each
+legend entry.  \fIPad\fR can be a list of one or two screen distances.  If
+\fIpad\fR has two elements, the left side of the legend entry is
+padded by the first distance and the right side by the second.  If
+\fIpad\fR is just one distance, both the left and right sides are padded
+evenly.  The default is \f(CW2\fR.
+.TP
+\fB\-ipady \fIpad\fR
+Sets an amount of internal padding to be added to the height of each
+legend entry.  \fIPad\fR can be a list of one or two screen distances.  If
+\fIpad\fR has two elements, the top of the entry is padded by the
+first distance and the bottom by the second.  If \fIpad\fR is just
+one distance, both the top and bottom of the entry are padded evenly.
+The default is \f(CW2\fR.
+.TP
+\fB\-padx \fIpad\fR
+Sets the padding to the left and right exteriors of the legend.
+\fIPad\fR can be a list of one or two screen distances.  If \fIpad\fR
+has two elements, the left side of the legend is padded by the first
+distance and the right side by the second.  If \fIpad\fR has just one
+distance, both the left and right sides are padded evenly.  The
+default is \f(CW4\fR.
+.TP
+\fB\-pady \fIpad\fR
+Sets the padding above and below the legend.  \fIPad\fR can be a list
+of one or two screen distances.  If \fIpad\fR has two elements, the area above
+the legend is padded by the first distance and the area below by the
+second.  If \fIpad\fR is just one distance, both the top and
+bottom areas are padded evenly.  The default is \f(CW0\fR.
+.TP
+\fB\-position \fIpos\fR
+Specifies where the legend is drawn. The
+\fB\-anchor\fR option also affects where the legend is positioned.  If
+\fIpos\fR is \f(CWleft\fR, \f(CWleft\fR, \f(CWtop\fR, or \f(CWbottom\fR, the
+legend is drawn in the specified margin.  If \fIpos\fR is
+\f(CWplotarea\fR, then the legend is drawn inside the plotting area at a
+particular anchor.  If \fIpos\fR is in the form "\fI at x,y\fR", where
+\fIx\fR and \fIy\fR are the window coordinates, the legend is drawn in
+the plotting area at the specified coordinates.  The default is
+\f(CWright\fR.
+.TP
+\fB\-raised \fIboolean\fR
+Indicates whether the legend is above or below the data elements.  This
+matters only if the legend is in the plotting area.  If \fIboolean\fR
+is true, the legend will be drawn on top of any elements that may
+overlap it. The default is \f(CWno\fR.
+.TP
+\fB\-relief \fIrelief\fR
+Specifies the 3-D effect for the border around the legend.
+\fIRelief\fR specifies how the interior of the legend should appear
+relative to the graph; for example, \f(CWraised\fR means the legend
+should appear to protrude from the graph, relative to the surface of
+the graph.  The default is \f(CWsunken\fR.
+.PP
+Legend configuration options may also be set by the \fBoption\fR
+command.  The resource name and class are \f(CWlegend\fR and
+\f(CWLegend\fR respectively.
+.CS
+option add *Graph.legend.Foreground blue
+option add *Graph.Legend.Relief     raised
+.CE
+.RE
+.TP
+\fIpathName \fBlegend deactivate \fIpattern\fR...
+Selects legend entries to be drawn using the normal legend colors and
+relief.  All entries whose element names match \fIpattern\fR are
+selected.  To be selected, the element name must match only one
+\fIpattern\fR.
+.TP
+\fIpathName \fBlegend get \fIpos\fR
+Returns the name of the element whose entry is at the screen position
+\fIpos\fR in the legend.  \fIPos\fR must be in the form "\fI at x,y\fR",
+where \fIx\fR and \fIy\fR are window coordinates.  If the given
+coordinates do not lie over a legend entry, \f(CW""\fR is returned.
+.SS "PEN COMPONENTS"
+Pens define attributes (both symbol and line style) for elements.
+Pens mirror the configuration options of data elements that pertain to
+how symbols and lines are drawn.  Data elements use pens to determine
+how they are drawn.  A data element may use several pens at once.  In
+this case, the pen used for a particular data point is determined from
+each element's weight vector (see the element's \fB\-weight\fR and
+\fB\-style\fR options).
+.PP
+One pen, called \f(CWactiveLine\fR, is automatically created.
+It's used as the default active pen for elements. So you can change
+the active attributes for all elements by simply reconfiguring this
+pen.
+.CS
+\&.g pen configure "activeLine" -color green
+.CE
+You can create and use several pens. To create a pen, invoke
+the pen component and its create operation.
+.CS
+\&.g pen create myPen
+.CE
+You map pens to a data element using either the element's 
+\fB\-pen\fR or \fB\-activepen\fR options.
+.CS
+\&.g element create "line1" -xdata $x -ydata $tempData \\
+    -pen myPen
+.CE
+An element can use several pens at once. This is done by specifying
+the name of the pen in the element's style list (see the
+\fB\-styles\fR option).
+.CS
+\&.g element configure "line1" -styles { myPen 2.0 3.0 }
+.CE
+This says that any data point with a weight between 2.0 and 3.0
+is to be drawn using the pen \f(CWmyPen\fR.  All other points
+are drawn with the element's default attributes.
+.PP
+The following operations are available for pen components.
+.PP
+.TP
+\fIpathName \fBpen \fBcget \fIpenName \fIoption\fR
+Returns the current value of the option given by \fIoption\fR for
+\fIpenName\fR.  \fIOption\fR may be any option described below
+for the pen \fBconfigure\fR operation.
+.TP
+\fIpathName \fBpen \fBconfigure \fIpenName \fR?\fIpenName\fR... ?\fIoption value\fR?...
+Queries or modifies the configuration options of
+\fIpenName\fR. Several pens can be modified at once.  If \fIoption\fR
+isn't specified, a list describing the current options for
+\fIpenName\fR is returned.  If \fIoption\fR is specified, but not
+\fIvalue\fR, then a list describing \fIoption\fR is returned.  If one
+or more \fIoption\fR and \fIvalue\fR pairs are specified, then for
+each pair, the pen option \fIoption\fR is set to \fIvalue\fR.  The
+following options are valid for pens.
+.RS
+.TP
+\fB\-color \fIcolor\fR 
+Sets the color of the traces connecting the data points.  
+.TP
+\fB\-dashes \fIdashList\fR
+Sets the dash style of element line. \fIDashList\fR is a list of up to
+11 numbers that alternately represent the lengths of the dashes and
+gaps on the element line.  Each number must be between 1 and 255.  If
+\fIdashList\fR is \f(CW""\fR, the lines will be solid.
+.TP
+\fB\-fill \fIcolor\fR 
+Sets the interior color of symbols.  If \fIcolor\fR is \f(CW""\fR, then
+the interior of the symbol is transparent.  If \fIcolor\fR is
+\f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR
+option.  The default is \f(CWdefcolor\fR.
+.TP
+\fB\-linewidth \fIpixels\fR 
+Sets the width of the connecting lines between data points.  If
+\fIpixels\fR is \f(CW0\fR, no connecting lines will be drawn between
+symbols.  The default is \f(CW0\fR.
+.TP
+\fB\-offdash \fIcolor\fR
+Sets the color of the stripes when traces are dashed (see the
+\fB\-dashes\fR option).  If \fIcolor\fR is \f(CW""\fR, then the "off"
+pixels will represent gaps instead of stripes.  If \fIcolor\fR is
+\f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR
+option.  The default is \f(CWdefcolor\fR.
+.TP
+\fB\-outline \fIcolor\fR 
+Sets the color or the outline around each symbol.  If \fIcolor\fR is
+\f(CW""\fR, then no outline is drawn. If \fIcolor\fR is \f(CWdefcolor\fR,
+then the color will be the same as the \fB\-color\fR option.  The
+default is \f(CWdefcolor\fR.
+.TP
+\fB\-outlinewidth \fIpixels\fR 
+Sets the width of the outline bordering each symbol.  If \fIpixels\fR
+is \f(CW0\fR, no outline will be drawn. The default is \f(CW1\fR.
+.TP
+\fB\-pixels \fIpixels\fR
+Sets the size of symbols.  If \fIpixels\fR is \f(CW0\fR, no symbols will
+be drawn.  The default is \f(CW0.125i\fR.
+.TP
+\fB\-symbol \fIsymbol\fR 
+Specifies the symbol for data points.  \fISymbol\fR can be either
+\f(CWsquare\fR, \f(CWcircle\fR, \f(CWdiamond\fR, \f(CWplus\fR, \f(CWcross\fR,
+\f(CWsplus\fR, \f(CWscross\fR, \f(CWtriangle\fR, \f(CW""\fR (where no symbol
+is drawn), or a bitmap.  Bitmaps are specified as "\fIsource\fR
+?\fImask\fR?", where \fIsource\fR is the name of the bitmap, and
+\fImask\fR is the bitmap's optional mask.  The default is
+\f(CWcircle\fR.
+.TP
+\fB\-type \fIelemType\fR 
+Specifies the type of element the pen is to be used with.
+This option should only be employed when creating the pen.  This
+is for those that wish to mix different types of elements (bars and
+lines) on the same graph.  The default type is "line".
+.PP
+Pen configuration options may be also be set by the \fBoption\fR
+command.  The resource class is \f(CWPen\fR.  The resource names
+are the names of the pens.
+.CS
+option add *Graph.Pen.Color  blue
+option add *Graph.activeLine.color  green
+.CE
+.RE
+.TP
+\fIpathName \fBpen \fBcreate \fIpenName \fR?\fIoption value\fR?...
+Creates a new pen by the name \fIpenName\fR.  No pen by the same
+name can already exist. \fIOption\fR and \fIvalue\fR are described 
+in above in the pen \fBconfigure\fR operation.
+.TP
+\fIpathName \fBpen \fBdelete \fR?\fIpenName\fR?...
+Deletes the named pens. A pen is not really
+deleted until it is not longer in use, so it's safe to delete
+pens mapped to elements.
+.TP
+\fIpathName \fBpen names \fR?\fIpattern\fR?...
+Returns a list of pens matching zero or more patterns.  If no
+\fIpattern\fR argument is give, the names of all pens are returned.
+.SS "POSTSCRIPT COMPONENT"
+The graph can generate encapsulated PostScript output.  There
+are several configuration options you can specify to control how the
+plot will be generated.  You can change the page dimensions and
+borders.  The plot itself can be scaled, centered, or rotated to
+landscape.  The PostScript output can be written directly to a file or
+returned through the interpreter.
+.PP
+The following postscript operations are available.
+.TP
+\fIpathName \fBpostscript cget \fIoption\fR 
+Returns the current value of the postscript option given by
+\fIoption\fR.  \fIOption\fR may be any option described
+below for the postscript \fBconfigure\fR operation.
+.TP
+\fIpathName \fBpostscript configure \fR?\fIoption value\fR?...
+Queries or modifies the configuration options for PostScript
+generation.  If \fIoption\fR isn't specified, a list describing 
+the current postscript options for \fIpathName\fR is returned.  If
+\fIoption\fR is specified, but not \fIvalue\fR, then a list describing
+\fIoption\fR is returned.  If one or more \fIoption\fR and \fIvalue\fR
+pairs are specified, then for each pair, the postscript option
+\fIoption\fR is set to \fIvalue\fR.  The following postscript options
+are available.
+.RS
+.TP
+\fB\-center \fIboolean\fR
+Indicates whether the plot should be centered on the PostScript page.  If
+\fIboolean\fR is false, the plot will be placed in the upper left
+corner of the page.  The default is \f(CW1\fR.
+.TP
+\fB\-colormap \fIvarName\fR
+\fIVarName\fR must be the name of a global array variable that
+specifies a color mapping from the X color name to PostScript.  Each
+element of \fIvarName\fR must consist of PostScript code to set a
+particular color value (e.g. ``\f(CW1.0 1.0 0.0 setrgbcolor\fR'').  When
+generating color information in PostScript, the array variable \fIvarName\fR
+is checked if an element of the name as the color exists. If so, it uses 
+its value as the PostScript
+command to set the color.  If this option hasn't been specified, or if
+there isn't an entry in \fIvarName\fR for a given color, then it uses
+the red, green, and blue intensities from the X color.
+.TP
+\fB\-colormode \fImode\fR
+Specifies how to output color information.  \fIMode\fR must be either
+\f(CWcolor\fR (for full color output), \f(CWgray\fR (convert all colors to
+their gray-scale equivalents) or \f(CWmono\fR (convert foreground colors
+to black and background colors to white).  The default mode is
+\f(CWcolor\fR. 
+.TP
+\fB\-fontmap \fIvarName\fR
+\fIVarName\fR must be the name of a global array variable that
+specifies a font mapping from the X font name to PostScript.  Each
+element of \fIvarName\fR must consist of a Tcl list with one or two
+elements; the name and point size of a PostScript font.
+When outputting PostScript commands for a particular font, the array
+variable \fIvarName\fR is checked to see if an element by the 
+specified font exists.  If there is such an element, then the font
+information contained in that element is used in the PostScript
+output.  (If the point size is omitted from the list, the point size
+of the X font is used).  Otherwise the X font is examined in an
+attempt to guess what PostScript font to use.  This works only for
+fonts whose foundry property is \fIAdobe\fR (such as Times, Helvetica,
+Courier, etc.).  If all of this fails then the font defaults to
+\f(CWHelvetica-Bold\fR.
+.TP
+\fB\-decorations \fIboolean\fR
+Indicates whether PostScript commands to generate color backgrounds and 3-D
+borders will be output.  If \fIboolean\fR is false, the background will be 
+white and no 3-D borders will be generated. The
+default is \f(CW1\fR.
+.TP
+\fB\-height \fIpixels\fR
+Sets the height of the plot.  This lets you print the graph with a
+height different from the one drawn on the screen.  If
+\fIpixels\fR is 0, the height is the same as the widget's height.
+The default is \f(CW0\fR.
+.TP
+\fB\-landscape \fIboolean\fR
+If \fIboolean\fR is true, this specifies the printed area is to be
+rotated 90 degrees.  In non-rotated output the X\-axis of the printed
+area runs along the short dimension of the page (``portrait''
+orientation); in rotated output the X\-axis runs along the long
+dimension of the page (``landscape'' orientation).  Defaults to
+\f(CW0\fR.
+.TP
+\fB\-maxpect \fIboolean\fR
+Indicates to scale the plot so that it fills the PostScript page.
+The aspect ratio of the graph is still retained.  The default is
+\f(CW0\fR.
+.TP
+\fB\-padx \fIpad\fR
+Sets the horizontal padding for the left and right page borders.  The
+borders are exterior to the plot.  \fIPad\fR can be a list of one or
+two screen distances.  If \fIpad\fR has two elements, the left border is padded
+by the first distance and the right border by the second.  If
+\fIpad\fR has just one distance, both the left and right borders are
+padded evenly.  The default is \f(CW1i\fR.
+.TP
+\fB\-pady \fIpad\fR 
+Sets the vertical padding for the top and bottom page borders. The
+borders are exterior to the plot.  \fIPad\fR can be a list of one or
+two screen distances.  If \fIpad\fR has two elements, the top border is padded
+by the first distance and the bottom border by the second.  If
+\fIpad\fR has just one distance, both the top and bottom borders are
+padded evenly.  The default is \f(CW1i\fR.
+.TP
+\fB\-paperheight \fIpixels\fR
+Sets the height of the postscript page.  This can be used to select
+between different page sizes (letter, A4, etc).  The default height is
+\f(CW11.0i\fR.
+.TP
+\fB\-paperwidth \fIpixels\fR
+Sets the width of the postscript page.  This can be used to select
+between different page sizes (letter, A4, etc).  The default width is
+\f(CW8.5i\fR.
+.TP
+\fB\-width \fIpixels\fR
+Sets the width of the plot.  This lets you generate a plot
+of a width different from that of the widget.  If \fIpixels\fR
+is 0, the width is the same as the widget's width.  The default is
+\f(CW0\fR.
+.PP
+Postscript configuration options may be also be set by the
+\fBoption\fR command.  The resource name and class are
+\f(CWpostscript\fR and \f(CWPostscript\fR respectively.
+.CS
+option add *Graph.postscript.Decorations false
+option add *Graph.Postscript.Landscape   true
+.CE
+.RE
+.TP
+\fIpathName \fBpostscript output \fR?\fIfileName\fR? ?\fIoption value\fR?...
+Outputs a file of encapsulated PostScript.  If a
+\fIfileName\fR argument isn't present, the command returns the
+PostScript. If any \fIoption-value\fR pairs are present, they set
+configuration options controlling how the PostScript is generated.
+\fIOption\fR and \fIvalue\fR can be anything accepted by the
+postscript \fBconfigure\fR operation above.
+.SS "MARKER COMPONENTS"
+Markers are simple drawing procedures used to annotate or highlight
+areas of the graph.  Markers have various types: text strings,
+bitmaps, images, connected lines, windows, or polygons.  They can be
+associated with a particular element, so that when the element is
+hidden or un-hidden, so is the marker.  By default, markers are the
+last items drawn, so that data elements will appear in
+behind them.  You can change this by configuring the \fB\-under\fR
+option.
+.PP
+Markers, in contrast to elements, don't affect the scaling of the
+coordinate axes.  They can also have \fIelastic\fR coordinates
+(specified by \f(CW-Inf\fR and \f(CWInf\fR respectively) that translate
+into the minimum or maximum limit of the axis.  For example, you can
+place a marker so it always remains in the lower left corner of the
+plotting area, by using the coordinates \f(CW-Inf\fR,\f(CW-Inf\fR.
+.PP
+The following operations are available for markers.
+.TP
+\fIpathName \fBmarker after \fImarkerId\fR ?\fIafterId\fR?
+Changes the order of the markers, drawing the first
+marker after the second.  If no second \fIafterId\fR argument is
+specified, the marker is placed at the end of the display list.  This
+command can be used to control how markers are displayed since markers
+are drawn in the order of this display list.
+.TP
+\fIpathName \fBmarker before \fImarkerId\fR ?\fIbeforeId\fR?
+Changes the order of the markers, drawing the first
+marker before the second.  If no second \fIbeforeId\fR argument is
+specified, the marker is placed at the beginning of the display list.
+This command can be used to control how markers are displayed since
+markers are drawn in the order of this display list.
+.TP
+\fIpathName \fBmarker bind \fItagName\fR ?\fIsequence\fR?  ?\fIcommand\fR? 
+Associates \fIcommand\fR with \fItagName\fR such that whenever the
+event sequence given by \fIsequence\fR occurs for a marker with this
+tag, \fIcommand\fR will be invoked.  The syntax is similar to the 
+\fBbind\fR command except that it operates on graph markers, rather 
+than widgets. See the \fBbind\fR manual entry for
+complete details on \fIsequence\fR and the substitutions performed on 
+\fIcommand\fR before invoking it.  
+.sp
+If all arguments are specified then a new binding is created, replacing 
+any existing binding for the same \fIsequence\fR and \fItagName\fR.
+If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR 
+augments an existing binding rather than replacing it. 
+If no \fIcommand\fR argument is provided then the command currently
+associated with \fItagName\fR and \fIsequence\fR (it's an error occurs 
+if there's no such binding) is returned.  If both \fIcommand\fR and 
+\fIsequence\fR are missing then a list of all the event sequences for 
+which bindings have been defined for \fItagName\fR. 
+.TP
+\fIpathName \fBmarker cget \fIoption\fR
+Returns the current value of the marker configuration option given by
+\fIoption\fR.  \fIOption\fR may be any option described
+below in the \fBconfigure\fR operation.
+.TP
+\fIpathName \fBmarker configure \fImarkerId\fR ?\fIoption value\fR?...
+Queries or modifies the configuration options for markers.  If
+\fIoption\fR isn't specified, a list describing the current
+options for \fImarkerId\fR is returned.  If \fIoption\fR is specified,
+but not \fIvalue\fR, then a list describing \fIoption\fR is returned.
+If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then
+for each pair, the marker option \fIoption\fR is set to \fIvalue\fR.
+.sp
+The following options are valid for all markers.
+Each type of marker also has its own type-specific options.  
+They are described in the sections below.
+.RS
+.TP
+\fB\-bindtags \fItagList\fR
+Specifies the binding tags for the marker.  \fITagList\fR is a list
+of binding tag names.  The tags and their order will determine how
+events for markers are handled.  Each tag in the list matching the 
+current event sequence will have its Tcl command executed.  Implicitly 
+the name of the marker is always the first tag in the list.
+The default value is \f(CWall\fR.
+.TP
+\fB\-coords \fIcoordList\fR
+Specifies the coordinates of the marker.  \fICoordList\fR is 
+a list of graph coordinates.  The number of coordinates required
+is dependent on the type of marker.  Text, image, and window markers
+need only two coordinates (an X\-Y coordinate).   Bitmap markers
+can take either two or four coordinates (if four, they represent the
+corners of the bitmap). Line markers
+need at least four coordinates, polygons at least six.
+If \fIcoordList\fR is \f(CW""\fR, the marker will not be displayed.
+The default is \f(CW""\fR.
+.TP
+\fB\-element \fIelemName\fR
+Links the marker with the element \fIelemName\fR.  The marker is
+drawn only if the element is also currently displayed (see the
+element's \fBshow\fR operation).  If \fIelemName\fR is \f(CW""\fR, the
+marker is always drawn.  The default is \f(CW""\fR.
+.TP
+\fB\-hide \fIboolean\fR 
+Indicates whether the marker is drawn. If \fIboolean\fR is true,
+the marker is not drawn.  The default is \f(CWno\fR.
+.TP
+\fB\-mapx \fIxAxis\fR 
+Specifies the X\-axis to map the marker's X\-coordinates onto.
+\fIXAxis\fR must the name of an axis.  The default is \f(CWx\fR.
+.TP
+\fB\-mapy \fIyAxis\fR
+Specifies the Y\-axis to map the marker's Y\-coordinates onto.
+\fIYAxis\fR must the name of an axis.  The default is \f(CWy\fR.
+.TP
+\fB\-name \fImarkerId\fR
+Changes the identifier for the marker.  The identifier \fImarkerId\fR 
+can not already be used by another marker.  If this option
+isn't specified, the marker's name is uniquely generated.
+.TP
+\fB\-under \fIboolean\fR
+Indicates whether the marker is drawn below/above data
+elements.  If \fIboolean\fR is true, the marker is be drawn
+underneath the data element symbols and lines.  Otherwise, the marker is
+drawn on top of the element.  The default is \f(CW0\fR.
+.TP
+\fB\-xoffset \fIpixels\fR
+Specifies a screen distance to offset the marker horizontally. 
+\fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR.
+The default is \f(CW0\fR.
+.TP
+\fB\-yoffset \fIpixels\fR
+Specifies a screen distance to offset the markers vertically.
+\fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR.
+The default is \f(CW0\fR.
+.PP
+Marker configuration options may also be set by the \fBoption\fR command.
+The resource class is either \f(CWBitmapMarker\fR,  \f(CWImageMarker\fR, 
+\f(CWLineMarker\fR, \f(CWPolygonMarker\fR, \f(CWTextMarker\fR, or \f(CWWindowMarker\fR,
+depending on the type of marker.  The resource name is the name of the
+marker.
+.CS
+option add *Graph.TextMarker.Foreground white
+option add *Graph.BitmapMarker.Foreground white
+option add *Graph.m1.Background     blue
+.CE
+.RE
+.TP
+\fIpathName \fBmarker create \fItype\fR ?\fIoption value\fR?...
+Creates a marker of the selected type. \fIType\fR may be either
+\f(CWtext\fR, \f(CWline\fR, \f(CWbitmap\fR, \f(CWimage\fR, \f(CWpolygon\fR, or
+\f(CWwindow\fR.  This command returns the marker identifier, 
+used as the \fImarkerId\fR argument in the other marker-related
+commands.  If the \fB\-name\fR option is used, this overrides the
+normal marker identifier.  If the name provided is already used for
+another marker, the new marker will replace the old.
+.TP
+\fIpathName \fBmarker delete\fR ?\fIname\fR?...
+Removes one of more markers.  The graph will automatically be redrawn
+without the marker.\fR.  
+.TP
+\fIpathName \fBmarker exists \fImarkerId\fR 
+Returns \f(CW1\fR if the marker \fImarkerId\fR exists and \f(CW0\fR
+otherwise.
+.TP
+\fIpathName \fBmarker names\fR ?\fIpattern\fR?  
+Returns the names of all the markers that currently exist.  If
+\fIpattern\fR is supplied, only those markers whose names match it
+will be returned.
+.TP
+\fIpathName \fBmarker type \fImarkerId\fR 
+Returns the type of the marker given by \fImarkerId\fR, such as
+\f(CWline\fR or \f(CWtext\fR.  If \fImarkerId\fR is not a valid a marker
+identifier, \f(CW""\fR is returned.
+.SS "BITMAP MARKERS"
+A bitmap marker displays a bitmap.  The size of the
+bitmap is controlled by the number of coordinates specified.  If two
+coordinates, they specify the position of the top-left corner of the
+bitmap.  The bitmap retains its normal width and height.  If four
+coordinates, the first and second pairs of coordinates represent the
+corners of the bitmap.  The bitmap will be stretched or reduced as
+necessary to fit into the bounding rectangle.
+.PP
+Bitmap markers are created with the marker's \fBcreate\fR operation in
+the form:
+.DS
+\fIpathName \fBmarker create bitmap \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR pairs, each 
+sets a configuration options for the marker.  These
+same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's
+\fBconfigure\fR operation.
+.PP
+The following options are specific to bitmap markers:
+.TP
+\fB\-background \fIcolor\fR
+Same as the \fB\-fill\fR option.
+.TP
+\fB\-bitmap \fIbitmap\fR
+Specifies the bitmap to be displayed.  If \fIbitmap\fR is \f(CW""\fR,
+the marker will not be displayed.  The default is \f(CW""\fR.
+.TP
+\fB\-fill \fIcolor\fR
+Sets the background color of the bitmap.  If \fIcolor\fR is the empty
+string, no background will be transparent.  The default background color is
+\f(CW""\fR.
+.TP
+\fB\-foreground \fIcolor\fR 
+Same as the \fB\-outline\fR option.
+.TP
+\fB\-mask \fImask\fR
+Specifies a mask for the bitmap to be displayed. This mask is a bitmap
+itself, denoting the pixels that are transparent.  If \fImask\fR is
+\f(CW""\fR, all pixels of the bitmap will be drawn.  The default is
+\f(CW""\fR.
+.TP
+\fB\-outline \fIcolor\fR
+Sets the foreground color of the bitmap. The default value is \f(CWblack\fR.
+.TP
+\fB\-rotate \fItheta\fR
+Sets the rotation of the bitmap.  \fITheta\fR is a real number
+representing the angle of rotation in degrees.  The marker is first
+rotated and then placed according to its anchor position.  The default
+rotation is \f(CW0.0\fR.
+.SS "IMAGE MARKERS"
+A image marker displays an image.  Image markers are
+created with the marker's \fBcreate\fR operation in the form:
+.DS
+\fIpathName \fBmarker create image \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR
+pairs, each sets a configuration option
+for the marker.  These same \fIoption\fR\-\fIvalue\fR pairs may be
+used with the marker's \fBconfigure\fR operation.
+.PP
+The following options are specific to image markers:
+.TP
+\fB\-anchor \fIanchor\fR
+\fIAnchor\fR tells how to position the image relative to the
+positioning point for the image. For example, if \fIanchor\fR
+is \f(CWcenter\fR then the image is centered on the point;  if
+\fIanchor\fR is \f(CWn\fR then the image will be drawn such that
+the top center point of the rectangular region occupied by the
+image will be at the positioning point.
+This option defaults to \f(CWcenter\fR.
+.TP
+\fB\-image \fIimage\fR
+Specifies the image to be drawn.
+If \fIimage\fR is \f(CW""\fR, the marker will not be
+drawn.  The default is \f(CW""\fR.
+.SS "LINE MARKERS"
+A line marker displays one or more connected line segments.
+Line markers are created with marker's \fBcreate\fR operation in the form:
+.DS
+\fIpathName \fBmarker create line \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR
+pairs, each sets a configuration option
+for the marker.  These same \fIoption\fR-\fIvalue\fR pairs may be
+used with the marker's \fBconfigure\fR operation.
+.PP
+The following options are specific to line markers:
+.TP
+\fB\-dashes \fIdashList\fR
+Sets the dash style of the line. \fIDashList\fR is a list of up to 11
+numbers that alternately represent the lengths of the dashes and gaps
+on the line.  Each number must be between 1 and 255.  If
+\fIdashList\fR is \f(CW""\fR, the marker line will be solid.
+.TP
+\fB\-fill \fIcolor\fR
+Sets the background color of the line.  This color is used with
+striped lines (see the \fB\-fdashes\fR option). If \fIcolor\fR is
+the empty string, no background color is drawn (the line will be
+dashed, not striped).  The default background color is \f(CW""\fR.
+.TP
+\fB\-linewidth \fIpixels\fR
+Sets the width of the lines.
+The default width is \f(CW0\fR.
+.TP
+\fB\-outline \fIcolor\fR
+Sets the foreground color of the line. The default value is \f(CWblack\fR.
+.TP
+\fB\-stipple \fIbitmap\fR
+Specifies a stipple pattern used to draw the line, rather than
+a solid line.
+\fIBitmap\fR specifies a bitmap to use as the stipple
+pattern.  If \fIbitmap\fR is \f(CW""\fR, then the
+line is drawn in a solid fashion. The default is \f(CW""\fR.
+.SS "POLYGON MARKERS"
+A polygon marker displays a closed region described as two or more
+connected line segments.  It is assumed the first and
+last points are connected.  Polygon markers are created using the
+marker \fBcreate\fR operation in the form:
+.DS
+\fIpathName \fBmarker create polygon \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR
+pairs, each sets a configuration option
+for the marker.  These same \fIoption\fR\-\fIvalue\fR pairs may be
+used with the \fBmarker configure\fR command to change the marker's
+configuration.
+The following options are supported for polygon markers:
+.TP
+\fB\-dashes \fIdashList\fR
+Sets the dash style of the outline of the polygon. \fIDashList\fR is a
+list of up to 11 numbers that alternately represent the lengths of
+the dashes and gaps on the outline.  Each number must be between 1 and
+255. If \fIdashList\fR is \f(CW""\fR, the outline will be a solid line.
+.TP
+\fB\-fill \fIcolor\fR
+Sets the fill color of the polygon.  If \fIcolor\fR is \f(CW""\fR, then
+the interior of the polygon is transparent.
+The default is \f(CWwhite\fR.
+.TP
+\fB\-linewidth \fIpixels\fR
+Sets the width of the outline of the polygon. If \fIpixels\fR is zero, 
+no outline is drawn. The default is \f(CW0\fR.
+.TP
+\fB\-outline \fIcolor\fR
+Sets the color of the outline of the polygon.  If the polygon is
+stippled (see the \fB\-stipple\fR option), then this represents the
+foreground color of the stipple.  The default is \f(CWblack\fR.
+.TP
+\fB\-stipple \fIbitmap\fR
+Specifies that the polygon should be drawn with a stippled pattern
+rather than a solid color. \fIBitmap\fR specifies a bitmap to use as
+the stipple pattern.  If \fIbitmap\fR is \f(CW""\fR, then the polygon is
+filled with a solid color (if the \fB\-fill\fR option is set).  The
+default is \f(CW""\fR.
+.SS "TEXT MARKERS"
+A text marker displays a string of characters on one or more lines of
+text.  Embedded newlines cause line breaks.  They may be used to
+annotate regions of the graph.  Text markers are created with the
+\fBcreate\fR operation in the form:
+.DS
+\fIpathName \fBmarker create text \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR pairs, 
+each sets a configuration option for the text marker.  
+These same \fIoption\fR\-\fIvalue\fR pairs may be used with the 
+marker's \fBconfigure\fR operation.  
+.PP
+The following options are specific to text markers:
+.TP
+\fB\-anchor \fIanchor\fR
+\fIAnchor\fR tells how to position the text relative to the
+positioning point for the text. For example, if \fIanchor\fR is
+\f(CWcenter\fR then the text is centered on the point; if
+\fIanchor\fR is \f(CWn\fR then the text will be drawn such that the
+top center point of the rectangular region occupied by the text will
+be at the positioning point.  This default is \f(CWcenter\fR.
+.TP
+\fB\-background \fIcolor\fR
+Same as the \fB\-fill\fR option.
+.TP
+\fB\-font \fIfontName\fR
+Specifies the font of the text.  The default is
+\f(CW*-Helvetica-Bold-R-Normal-*-120-*\fR.
+.TP
+\fB\-fill \fIcolor\fR
+Sets the background color of the text.  If \fIcolor\fR is the empty
+string, no background will be transparent.  The default background color is
+\f(CW""\fR.
+.TP
+\fB\-foreground \fIcolor\fR
+Same as the \fB\-outline\fR option.
+.TP
+\fB\-justify \fIjustify\fR
+Specifies how the text should be justified.  This matters only when
+the marker contains more than one line of text. \fIJustify\fR must be
+\f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR.  The default is
+\f(CWcenter\fR.
+.TP
+\fB\-outline \fIcolor\fR
+Sets the color of the text. The default value is \f(CWblack\fR.
+.TP
+\fB\-padx \fIpad\fR
+Sets the padding to the left and right exteriors of the text.
+\fIPad\fR can be a list of one or two screen distances.  If \fIpad\fR
+has two elements, the left side of the text is padded by the first
+distance and the right side by the second.  If \fIpad\fR has just one
+distance, both the left and right sides are padded evenly.  The
+default is \f(CW4\fR.
+.TP
+\fB\-pady \fIpad\fR
+Sets the padding above and below the text.  \fIPad\fR can be a list of
+one or two screen distances.  If \fIpad\fR has two elements, the area above the
+text is padded by the first distance and the area below by the second.
+If \fIpad\fR is just one distance, both the top and bottom areas
+are padded evenly.  The default is \f(CW4\fR.
+.TP
+\fB\-rotate \fItheta\fR
+Specifies the number of degrees to rotate the text.  \fITheta\fR is a
+real number representing the angle of rotation.  The marker is first
+rotated along its center and is then drawn according to its anchor
+position. The default is \f(CW0.0\fR.
+.TP
+\fB\-text \fItext\fR
+Specifies the text of the marker.  The exact way the text is
+displayed may be affected by other options such as \fB\-anchor\fR or
+\fB\-rotate\fR.
+.SS "WINDOW MARKERS"
+A window marker displays a widget at a given position.
+Window markers are created with the marker's \fBcreate\fR operation in
+the form:
+.DS
+\fIpathName \fBmarker create window \fR?\fIoption value\fR?...
+.DE
+There may be many \fIoption\fR-\fIvalue\fR
+pairs, each sets a configuration option
+for the marker.  These same \fIoption\fR\-\fIvalue\fR pairs may be
+used with the marker's \fBconfigure\fR command.
+.PP
+The following options are specific to window markers:
+.TP
+\fB\-anchor \fIanchor\fR
+\fIAnchor\fR tells how to position the widget relative to the
+positioning point for the widget. For example, if \fIanchor\fR is
+\f(CWcenter\fR then the widget is centered on the point; if \fIanchor\fR
+is \f(CWn\fR then the widget will be displayed such that the top center
+point of the rectangular region occupied by the widget will be at the
+positioning point.  This option defaults to \f(CWcenter\fR.
+.TP
+\fB\-height \fIpixels\fR
+Specifies the height to assign to the marker's window.  If this option
+isn't specified, or if it is specified as \f(CW""\fR, then the window is
+given whatever height the widget requests internally.
+.TP
+\fB\-width \fIpixels\fR
+Specifies the width to assign to the marker's window.  If this option
+isn't specified, or if it is specified as \f(CW""\fR, then the window is
+given whatever width the widget requests internally.
+.TP
+\fB\-window \fIpathName\fR
+Specifies the widget to be managed by the graph.  \fIPathName\fR must
+be a child of the \fBgraph\fR widget.
+.SH "GRAPH COMPONENT BINDINGS"
+Specific graph components, such as elements, markers and legend
+entries, can have a command trigger when event occurs in them, much
+like canvas items in Tk's canvas widget.  Not all event sequences are
+valid.  The only binding events that may be specified are those
+related to the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR,
+\fBButtonPress\fR, \fBMotion\fR, and \fBKeyPress\fR).
+.PP
+Only one element or marker can be picked during an event.  This means,
+that if the mouse is directly over both an element and a marker, only
+the uppermost component is selected.  This isn't true for legend entries.  
+Both a legend entry and an element (or marker) binding commands 
+will be invoked if both items are picked.
+.PP
+It is possible for multiple bindings to match a particular event.
+This could occur, for example, if one binding is associated with the
+element name and another is associated with one of the element's tags
+(see the \fB\-bindtags\fR option).  When this occurs, all of the 
+matching bindings are invoked.  A binding associated with the element
+name is invoked first, followed by one binding for each of the element's 
+bindtags.  If there are multiple matching bindings for a single tag, 
+then only the most specific binding is invoked.  A continue command 
+in a binding script terminates that script, and a break command 
+terminates that script and skips any remaining scripts for the event, 
+just as for the bind command.
+.PP
+The \fB\-bindtags\fR option for these components controls addition
+tag names which can be matched.  Implicitly elements and markers
+always have tags matching their names.  Setting the value of
+the \fB\-bindtags\fR option doesn't change this.
+.SH "C LANGUAGE API"
+You can manipulate data elements from the C language.  There
+may be situations where it is too expensive to translate the data
+values from ASCII strings.  Or you might want to read data in a
+special file format.
+.PP
+Data can manipulated from the C language using BLT vectors.
+You specify the X-Y data coordinates of an element as vectors and
+manipulate the vector from C.  The graph will be redrawn automatically
+after the vectors are updated.
+.PP
+From Tcl, create the vectors and configure the element to use them.
+.CS
+vector X Y
+\&.g element configure line1 -xdata X -ydata Y
+.CE
+To set data points from C, you pass the values as arrays of doubles
+using the \fBBlt_ResetVector\fR call.  The vector is reset with the
+new data and at the next idle point (when Tk re-enters its event
+loop), the graph will be redrawn automatically.
+.CS
+#include <tcl.h>
+#include <blt.h>
+
+register int i;
+Blt_Vector *xVec, *yVec;
+double x[50], y[50];
+
+/* Get the BLT vectors "X" and "Y" (created above from Tcl) */
+if ((Blt_GetVector(interp, "X", &xVec) != TCL_OK) ||
+    (Blt_GetVector(interp, "Y", &yVec) != TCL_OK)) {
+    return TCL_ERROR;
+}
+
+for (i = 0; i < 50; i++) {
+    x[i] = i * 0.02;
+    y[i] = sin(x[i]);
+}	
+
+/* Put the data into BLT vectors */
+if ((Blt_ResetVector(xVec, x, 50, 50, TCL_VOLATILE) != TCL_OK) ||
+    (Blt_ResetVector(yVec, y, 50, 50, TCL_VOLATILE) != TCL_OK)) {
+   return TCL_ERROR;
+}
+.CE
+See the \fBvector\fR manual page for more details.
+.SH SPEED TIPS
+There may be cases where the graph needs to be drawn and updated as
+quickly as possible.  If drawing speed becomes a big
+problem, here are a few tips to speed up displays.
+.TP 2
+\(bu 
+Try to minimize the number of data points.  The more data points
+the looked at, the more work the graph must do.
+.TP 2
+\(bu 
+If your data is generated as floating point values, the time required
+to convert the data values to and from ASCII strings can be
+significant, especially when there any many data points.  You can
+avoid the redundant string-to-decimal conversions using the C API to
+BLT vectors.
+.TP 2
+\(bu
+Data elements without symbols are drawn faster than with symbols.
+Set the data element's \fB\-symbol\fR option to \f(CWnone\fR.  If you need to
+draw symbols, try using the simple symbols such as \f(CWsplus\fR and
+\f(CWscross\fR.
+.TP 2
+\(bu
+Don't stipple or dash the element.  Solid lines are much faster.
+.TP 2
+\(bu 
+If you update data elements frequently, try turning off the
+widget's \fB\-bufferelements\fR option.  When the graph is first
+displayed, it draws data elements into an internal pixmap.  The pixmap
+acts as a cache, so that when the graph needs to be redrawn again, and
+the data elements or coordinate axes haven't changed, the pixmap is
+simply copied to the screen.  This is especially useful when you are
+using markers to highlight points and regions on the graph.  But if
+the graph is updated frequently, changing either the element data or
+coordinate axes, the buffering becomes redundant.
+.SH LIMITATIONS
+Auto-scale routines do not use requested min/max limits as boundaries
+when the axis is logarithmically scaled.
+.PP
+The PostScript output generated for polygons with more than 1500
+points may exceed the limits of some printers (See PostScript Language
+Reference Manual, page 568).  The work-around is to break the polygon
+into separate pieces.
+.SH KEYWORDS
+graph, widget
diff --git a/tlt3.0/doc/vector.n b/tlt3.0/doc/vector.n
new file mode 100644
index 0000000..da7abf2
--- /dev/null
+++ b/tlt3.0/doc/vector.n
@@ -0,0 +1,1130 @@
+'\"
+'\" Copyright 1991-1997 by Lucent Technologies, Inc.
+'\"
+'\" Permission to use, copy, modify, and distribute this software and its
+'\" documentation for any purpose and without fee is hereby granted, provided
+'\" that the above copyright notice appear in all copies and that both that the
+'\" copyright notice and warranty disclaimer appear in supporting documentation,
+'\" and that the names of Lucent Technologies any of their entities not be used
+'\" in advertising or publicity pertaining to distribution of the software
+'\" without specific, written prior permission.
+'\"
+'\" Lucent Technologies disclaims all warranties with regard to this software,
+'\" including all implied warranties of merchantability and fitness.  In no event
+'\" shall Lucent Technologies be liable for any special, indirect or
+'\" consequential damages or any damages whatsoever resulting from loss of use,
+'\" data or profits, whether in an action of contract, negligence or other
+'\" tortuous action, arising out of or in connection with the use or performance
+'\" of this software.  
+'\"
+'\" Vector command created by George Howlett.
+'\"
+.so man.macros
+.TH blt::vector n BLT_VERSION BLT "BLT Built-In Commands"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+\fBvector\fR \-  Vector data type for Tcl
+.SH SYNOPSIS
+\fBblt::vector create \fIvecName \fR?\fIvecName\fR...? ?\fIswitches\fR? 
+.sp
+\fBblt::vector destroy \fIvecName \fR?\fIvecName\fR...?
+.sp
+\fBblt::vector expr \fIexpression\fR
+.sp
+\fBblt::vector names \fR?\fIpattern\fR...?
+.BE
+.SH DESCRIPTION
+The \fBvector\fR command creates an array of floating point
+values.  The vector's components can be manipulated in three ways:
+through a Tcl array variable, a Tcl command, or the C API.
+.SH INTRODUCTION
+A vector is an ordered set of real numbers.  The components of a
+vector are indexed by integers.
+.PP
+Vectors are common data structures for many applications.  For
+example, a graph may use two vectors to represent the X-Y
+coordinates of the data plotted.  The graph will automatically
+be redrawn when the vectors are updated or changed. By using vectors, 
+you can separate
+data analysis from the graph widget.  This makes it easier, for
+example, to add data transformations, such as splines.  It's possible
+to plot the same data to in multiple graphs, where each graph presents
+a different view or scale of the data.
+.PP
+You could try to use Tcl's associative arrays as vectors.  Tcl arrays
+are easy to use.  You can access individual elements randomly by
+specifying the index, or the set the entire array by providing a list
+of index and value pairs for each element.  The disadvantages of 
+associative arrays as vectors lie in the fact they are implemented as
+hash tables.
+.TP 2
+\(bu 
+There's no implied ordering to the associative arrays.  If you used
+vectors for plotting, you would want to insure the second component
+comes after the first, an so on.  This isn't possible since arrays
+are actually hash tables.  For example, you can't get a range of
+values between two indices.  Nor can you sort an array.
+.TP 2
+\(bu
+Arrays consume lots of memory when the number of elements becomes
+large (tens of thousands).  This is because each element's index and
+value are stored as strings in the hash table.
+.TP 2
+\(bu 
+The C programming interface is unwieldy.  Normally with vectors, you
+would like to view the Tcl array as you do a C array, as an array of
+floats or doubles.  But with hash tables, you must convert both the
+index and value to and from decimal strings, just to access
+an element in the array.  This makes it cumbersome to perform operations on
+the array as a whole.
+.PP
+The \fBvector\fR command tries to overcome these disadvantages while
+still retaining the ease of use of Tcl arrays.  The \fBvector\fR
+command creates both a new Tcl command and associate array which are
+linked to the vector components.  You can randomly access vector
+components though the elements of array.  Not have all indices are
+generated for the array, so printing the array (using the \fBparray\fR
+procedure) does not print out all the component values.  You can use
+the Tcl command to access the array as a whole.  You can copy, append,
+or sort vector using its command.  If you need greater performance, or
+customized behavior, you can write your own C code to manage vectors.
+.SH EXAMPLE
+You create vectors using the \fBvector\fR command and its \fBcreate\fR
+operation.
+.CS
+# Create a new vector. 
+blt::vector create y(50)
+.CE
+This creates a new vector named \f(CWy\fR.  It has fifty components, by
+default, initialized to \f(CW0.0\fR.  In addition, both a Tcl command
+and array variable, both named \f(CWy\fR, are created.  You can use
+either the command or variable to query or modify components of the
+vector.
+.CS
+# Set the first value. 
+set y(0) 9.25
+puts "y has [y length] components"
+.CE
+The array \f(CWy\fR can be used to read or set individual components of
+the vector.  Vector components are indexed from zero.  The array index
+must be a number less than the number of components.  For example,
+it's an error if you try to set the 51st element of \f(CWy\fR.
+.CS
+# This is an error. The vector only has 50 components.
+set y(50) 0.02
+.CE
+You can also specify a range of indices using a colon (:) to separate
+the first and last indices of the range.
+.CS
+# Set the first six components of y 
+set y(0:5) 25.2
+.CE
+If you don't include an index, then it will default to the first
+and/or last component of the vector.
+.CS
+# Print out all the components of y 
+puts "y = $y(:)"
+.CE
+There are special non-numeric indices.  The index \f(CWend\fR, specifies
+the last component of the vector.  It's an error to use this index if
+the vector is empty (length is zero).  The index \f(CW++end\fR can be
+used to extend the vector by one component and initialize it to a specific 
+value.  You can't read from the array using this index, though.
+.CS
+# Extend the vector by one component.
+set y(++end) 0.02
+.CE
+The other special indices are \f(CWmin\fR and \f(CWmax\fR.  They return the
+current smallest and largest components of the vector.  
+.CS
+# Print the bounds of the vector
+puts "min=$y(min) max=$y(max)"
+.CE
+To delete components from a vector, simply unset the corresponding
+array element. In the following example, the first component of
+\f(CWy\fR is deleted.  All the remaining components of \f(CWy\fR will be
+moved down by one index as the length of the vector is reduced by
+one.
+.CS
+# Delete the first component
+unset y(0)
+puts "new first element is $y(0)"
+.CE
+The vector's Tcl command can also be used to query or set the vector.
+.CS
+# Create and set the components of a new vector
+blt::vector create x
+x set { 0.02 0.04 0.06 0.08 0.10 0.12 0.14 0.16 0.18 0.20 }
+.CE
+Here we've created a vector \f(CWx\fR without a initial length specification.
+In this case, the length is zero.  The \fBset\fR operation resets the vector,
+extending it and setting values for each new component.  
+.PP
+There are several operations for vectors.  The \fBrange\fR operation
+lists the components of a vector between two indices.
+.CS
+# List the components 
+puts "x = [x range 0 end]"
+.CE
+You can search for a particular value using the \fBsearch\fR
+operation.  It returns a list of indices of the components with the
+same value.  If no component has the same value, it returns \f(CW""\fR.
+.CS
+# Find the index of the biggest component
+set indices [x search $x(max)]
+.CE
+Other operations copy, append, or sort vectors.  You can append
+vectors or new values onto an existing vector with the \fBappend\fR
+operation.
+.CS
+# Append assorted vectors and values to x
+x append x2 x3 { 2.3 4.5 } x4
+.CE
+The \fBsort\fR operation sorts the vector.  If any additional vectors
+are specified, they are rearranged in the same order as the vector.
+For example, you could use it to sort data points represented by x and
+y vectors.
+.CS
+# Sort the data points
+x sort y
+.CE
+The vector \f(CWx\fR is sorted while the components of \f(CWy\fR are 
+rearranged so that the original x,y coordinate pairs are retained.
+.PP
+The \fBexpr\fR operation lets you perform arithmetic on vectors.  
+The result is stored in the vector.
+.CS
+# Add the two vectors and a scalar
+x expr { x + y }
+x expr { x * 2 }
+.CE
+When a vector is modified, resized, or deleted, it may trigger
+call-backs to notify the clients of the vector.  For example, when a
+vector used in the \fBgraph\fR widget is updated, the vector
+automatically notifies the widget that it has changed.  The graph can
+then redrawn itself at the next idle point.  By default, the
+notification occurs when Tk is next idle.  This way you can modify the
+vector many times without incurring the penalty of the graph redrawing
+itself for each change.  You can change this behavior using the
+\fBnotify\fR operation.
+.CS
+# Make vector x notify after every change
+x notify always
+	...
+# Never notify
+x notify never
+	...
+# Force notification now
+x notify now
+.CE
+To delete a vector, use the \fBvector delete\fR command.  
+Both the vector and its corresponding Tcl command are destroyed.
+.CS
+# Remove vector x
+blt::vector destroy x
+.CE
+.SH SYNTAX
+Vectors are created using the \fBvector create\fR operation.  
+Th \fBcreate\fR operation can be invoked in one of three forms:
+.TP
+\fBblt::vector create \fIvecName\fR
+This creates a new vector \fIvecName\fR which initially has no components.
+.TP
+\fBblt::vector create \fIvecName\fR(\fIsize\fR)
+This second form creates a new vector which will contain \fIsize\fR
+number of components.  The components will be indexed starting from
+zero (0). The default value for the components is \f(CW0.0\fR.
+.TP
+\fBblt::vector create \fIvecName\fR(\fIfirst\fR:\fIlast\fR)
+The last form creates a new vector of indexed \fIfirst\fR through
+\fIlast\fR.  \fIFirst\fR and \fIlast\fR can be any integer value
+so long as \fIfirst\fR is less than \fIlast\fR.
+.PP
+Vector names must start with a letter and consist of letters, digits,
+or underscores.  
+.CS
+# Error: must start with letter
+blt::vector create 1abc
+.CE
+You can automatically generate vector names using the
+"\f(CW#auto\fR" vector name.  The \fBcreate\fR operation will generate a 
+unique vector name.
+.CS
+set vec [blt::vector create #auto]
+puts "$vec has [$vec length] components"
+.CE
+.SS VECTOR INDICES
+Vectors are indexed by integers.  You can access the individual vector
+components via its array variable or Tcl command.  The string
+representing the index can be an integer, a numeric expression, a
+range, or a special keyword.
+.PP
+The index must lie within the current range of the vector, otherwise
+an an error message is returned.  Normally the indices of a vector
+are start from 0.  But you can use the \fBoffset\fR operation to
+change a vector's indices on-the-fly.
+.CS
+puts $vecName(0)
+vecName offset -5
+puts $vecName(-5)
+.CE
+You can also use numeric expressions as indices.  The result
+of the expression must be an integer value.  
+.CS
+set n 21
+set vecName($n+3) 50.2
+.CE
+The following special non-numeric indices are available: \f(CWmin\fR, \f(CWmax\fR, \f(CWend\fR, and
+\f(CW++end\fR.  
+.CS
+puts "min = $vecName($min)"
+set vecName(end) -1.2
+.CE
+The indices \f(CWmin\fR and \f(CWmax\fR will return the minimum and maximum
+values of the vector.  The index \f(CWend\fR returns the value of the 
+last component in the vector.  The index \f(CW++end\fR is used to append
+new value onto the vector.  It automatically extends the vector by
+one component and sets its value.
+.CS
+# Append an new component to the end
+set vecName(++end) 3.2
+.CE
+A range of indices can be indicated by a colon (:).  
+.CS
+# Set the first six components to 1.0
+set vecName(0:5) 1.0
+.CE
+If no index is supplied the first or last component is assumed.
+.CS
+# Print the values of all the components
+puts $vecName(:)
+.CE
+.SH VECTOR OPERATIONS
+.TP
+\fBblt::vector create \fIvecName\fR?(\fIsize\fR)?... \fR?\fIswitches\fR? 
+The \fBcreate\fR operation creates a new vector \fIvecName\fR.  Both a
+Tcl command and array variable \fIvecName\fR are also created.  The
+name \fIvecName\fR must be unique, so another Tcl command or array
+variable can not already exist in that scope.  You can access the
+components of the vector using its variable.  If you change a value in
+the array, or unset an array element, the vector is updated to reflect
+the changes.  When the variable \fIvecName\fR is unset, the vector and
+its Tcl command are also destroyed.
+.sp
+The vector has optional switches that affect how the vector is created. They
+are as follows:
+.RS
+.TP
+\fB\-variable \fIvarName\fR
+Specifies the name of a Tcl variable to be mapped to the vector. If
+the variable already exists, it is first deleted, then recreated. 
+If \fIvarName\fR is the empty string, then no variable will be mapped.
+You can always map a variable back to the vector using the vector's 
+\fBvariable\fR operation.
+.TP
+\fB\-command \fIcmdName\fR
+Maps a Tcl command to the vector. The vector can be accessed using 
+\fIcmdName\fR and one of the vector instance operations.  
+A Tcl command by that name cannot already exist.
+If \fIcmdName\fR is the empty string, no command mapping
+will be made.
+.TP
+\fB\-watchunset \fIboolean\fR
+Indicates that the vector should automatically delete itself if
+the variable associated with the vector is unset.  By default,
+the vector will not be deleted.  This is different from previous
+releases.  Set \fIboolean\fR to "true" to get the old behavior.
+.RE
+.TP
+\fBblt::vector destroy \fIvecName\fR \fR?\fIvecName...\fR?
+Deletes one or more vectors.  Both the Tcl command and array variable
+are removed also.
+.TP
+\fBblt::vector expr \fIexpression\fR
+.RS
+All binary operators take vectors as operands (remember that numbers
+are treated as one-component vectors).  The exact action of binary
+operators depends upon the length of the second operand.  If the
+second operand has only one component, then each element of the first
+vector operand is computed by that value.  For example, the expression
+"x * 2" multiples all elements of the vector x by 2.  If the second
+operand has more than one component, both operands must be the same
+length.  Each pair of corresponding elements are computed.  So "x + y"
+adds the the first components of x and y together, the second, and so on.
+.sp
+The valid operators are listed below, grouped in decreasing order
+of precedence:
+.TP 20
+\fB\-\0\0!\fR
+Unary minus and logical NOT.  The unary minus flips the sign of each
+component in the vector.  The logical not operator returns a vector of
+whose values are 0.0 or 1.0.  For each non-zero component 1.0 is returned,
+0.0 otherwise.
+.TP 20
+\fB^\fR
+Exponentiation.  
+.TP 20
+\fB*\0\0/\0\0%\fR
+Multiply, divide, remainder.  
+.TP 20
+\fB+\0\0\-\fR
+Add and subtract.  
+.TP 20
+\fB<<\0\0>>\fR
+Left and right shift.  Circularly shifts the values of the vector 
+(not implemented yet).
+.TP 20
+\fB<\0\0>\0\0<=\0\0>=\fR
+Boolean less, greater, less than or equal, and greater than or equal.
+Each operator returns a vector of ones and zeros.  If the condition is true, 
+1.0 is the component value, 0.0 otherwise.
+.TP 20
+\fB==\0\0!=\fR
+Boolean equal and not equal.
+Each operator returns a vector of ones and zeros.  If the condition is true, 
+1.0 is the component value, 0.0 otherwise.
+.TP 20
+\fB|\fR
+Bit-wise OR.  (Not implemented).
+.TP 20
+\fB&&\fR
+Logical AND.  Produces a 1 result if both operands are non-zero, 0 otherwise.
+.TP 20
+\fB||\fR
+Logical OR.  Produces a 0 result if both operands are zero, 1 otherwise.
+.TP 20
+\fIx\fB?\fIy\fB:\fIz\fR
+If-then-else, as in C.  (Not implemented yet).
+.LP
+See the C manual for more details on the results produced by each
+operator.  All of the binary operators group left-to-right within the
+same precedence level.  
+.sp
+Several mathematical functions are supported for vectors.  Each of
+the following functions invokes the math library function of the same name;
+see the manual entries for the library functions for details on what
+they do.  The operation is applied to all elements of the vector
+returning the results. 
+.CS
+.ta 3c 6c 9c
+\fBacos\fR	\fBcos\fR	\fBhypot\fR	\fBsinh\fR 
+\fBasin\fR	\fBcosh\fR	\fBlog\fR	\fBsqrt\fR 
+\fBatan\fR	\fBexp\fR	\fBlog10\fR	\fBtan\fR  
+\fBceil\fR	\fBfloor\fR	\fBsin\fR	\fBtanh\fR 
+.CE
+Additional functions are:
+.TP 1i
+\fBabs\fR
+Returns the absolute value of each component.
+.TP 1i
+\fBrandom\fR
+Returns a vector of non-negative values uniformly distributed 
+between [0.0, 1.0) using \fIdrand48\fR.
+The seed comes from the internal clock of the machine or may be 
+set manual with the srandom function.
+.TP 1i
+\fBround\fR
+Rounds each component of the vector.
+.TP 1i
+\fBsrandom\fR
+Initializes the random number generator using \fIsrand48\fR.
+The high order 32-bits are set using the integral portion of the first 
+vector component. All other components are ignored.  The low order 16-bits 
+are set to an arbitrary value.
+.PP
+The following functions return a single value.
+.TP 1i
+\fBadev\fR 
+Returns the average deviation (defined as the sum of the absolute values 
+of the differences between component and the mean, divided by the length
+of the vector).
+.TP 1i
+\fBkurtosis\fR
+Returns the degree of peakedness (fourth moment) of the vector.
+.TP 1i
+\fBlength\fR
+Returns the number of components in the vector.
+.TP 1i
+\fBmax\fR
+Returns the vector's maximum value.
+.TP 1i
+\fBmean\fR
+Returns the mean value of the vector.
+.TP 1i
+\fBmedian\fR
+Returns the median of the vector.
+.TP 1i
+\fBmin\fR
+Returns the vector's minimum value.
+.TP 1i
+\fBq1\fR
+Returns the first quartile of the vector.
+.TP 1i
+\fBq3\fR
+Returns the third quartile of the vector.
+.TP 1i
+\fBprod\fR 
+Returns the product of the components.
+.TP 1i
+\fBsdev\fR 
+Returns the standard deviation (defined as the square root of the variance)
+of the vector.
+.TP 1i
+\fBskew\fR 
+Returns the skewness (or third moment) of the vector.  This characterizes
+the degree of asymmetry of the vector about the mean.
+.TP 1i
+\fBsum\fR 
+Returns the sum of the components.
+.TP 1i
+\fBvar\fR
+Returns the variance of the vector. The sum of the squared differences 
+between each component and the mean is computed.  The variance is 
+the sum divided by the length of the vector minus 1.
+.PP
+The last set returns a vector of the same length as the argument.
+.TP 1i
+\fBnorm\fR 
+Scales the values of the vector to lie in the range [0.0..1.0].
+.TP 1i
+\fBsort\fR
+Returns the vector components sorted in ascending order.
+.RE
+.TP
+\fBvector names \fR?\fIpattern\fR?
+.SH INSTANCE OPERATIONS
+You can also use the vector's Tcl command to query or modify it.  The
+general form is
+.DS
+\fIvecName \fIoperation\fR \fR?\fIarg\fR?...
+.DE
+Both \fIoperation\fR and its arguments determine the exact behavior of
+the command.  The operations available for vectors are listed below.
+.TP
+\fIvecName \fBappend\fR \fIitem\fR ?\fIitem\fR?...
+Appends the component values from \fIitem\fR to \fIvecName\fR.
+\fIItem\fR can be either the name of a vector or a list of numeric
+values.
+.TP
+\fIvecName \fBbinread\fR \fIchannel\fR ?\fIlength\fR? ?\fIswitches\fR? 
+Reads binary values from a Tcl channel. Values are either appended
+to the end of the vector or placed at a given index (using the
+\fB\-at\fR option), overwriting existing values.  Data is read until EOF
+is found on the channel or a specified number of values \fIlength\fR 
+are read (note that this is not necessarily the same as the number of 
+bytes). The following switches are supported:
+.RS
+.TP
+\fB\-swap\fR
+Swap bytes and words.  The default endian is the host machine.
+.TP
+\fB\-at \fIindex\fR
+New values will start at vector index \fIindex\fR.  This will
+overwrite any current values.
+.TP
+\fB\-format\fR \fIformat\fR
+Specifies the format of the data.  \fIFormat\fR can be one of the
+following: "i1", "i2", "i4", "i8", "u1, "u2", "u4", "u8", "r4",
+"r8", or "r16".  The number indicates the number of bytes
+required for each value.  The letter indicates the type: "i" for signed,
+"u" for unsigned, "r" or real.  The default format is "r16".
+.RE
+.TP
+\fIvecName \fBclear\fR 
+Clears the element indices from the array variable associated with
+\fIvecName\fR.  This doesn't affect the components of the vector.  By
+default, the number of entries in the Tcl array doesn't match the
+number of components in the vector.  This is because its too expensive
+to maintain decimal strings for both the index and value for each
+component.  Instead, the index and value are saved only when you read
+or write an element with a new index.  This command removes the index
+and value strings from the array.  This is useful when the vector is
+large.
+.TP
+\fIvecName \fBdelete\fR \fIindex\fR ?\fIindex\fR?...
+Deletes the \fIindex\fRth component from the vector \fIvecName\fR.
+\fIIndex\fR is the index of the element to be deleted.  This is the
+same as unsetting the array variable element \fIindex\fR.  The vector
+is compacted after all the indices have been deleted.
+.TP
+\fIvecName \fBdup\fR \fIdestName\fR 
+Copies \fIvecName\fR to \fIdestName\fR. \fIDestName\fR is the name of a
+destination vector.  If a vector \fIdestName\fR already exists, it is
+overwritten with the components of \fIvecName\fR.  Otherwise a 
+new vector is created.
+.TP
+\fIvecName \fBexpr\fR \fIexpression\fR
+Computes the expression and resets the values of the vector accordingly.
+Both scalar and vector math operations are allowed.  All values in
+expressions are either real numbers or names of vectors.  All numbers
+are treated as one component vectors.
+.TP
+\fIvecName \fBlength\fR ?\fInewSize\fR?
+Queries or resets the number of components in \fIvecName\fR.
+\fINewSize\fR is a number specifying the new size of the vector.  If
+\fInewSize\fR is smaller than the current size of \fIvecName\fR,
+\fIvecName\fR is truncated.  If \fInewSize\fR is greater, the vector
+is extended and the new components are initialized to \f(CW0.0\fR.  If
+no \fInewSize\fR argument is present, the current length of the vector
+is returned.
+.TP
+\fIvecName \fBmerge\fR \fIsrcName\fR ?\fIsrcName\fR?...
+Merges the named vectors into a single vector.  The resulting 
+vector is formed by merging the components of each source vector 
+one index at a time.
+.TP
+\fIvecName \fBnotify\fR \fIkeyword\fR
+Controls how vector clients are notified of changes to the vector.  
+The exact behavior is determined by \fIkeyword\fR.
+.RS
+.TP 0.75i
+\f(CWalways\fR 
+Indicates that clients are to be notified immediately whenever the
+vector is updated.
+.TP
+\f(CWnever\fR
+Indicates that no clients are to be notified.
+.TP
+\f(CWwhenidle\fR
+Indicates that clients are to be notified at the next idle point
+whenever the vector is updated.
+.TP
+\f(CWnow\fR
+If any client notifications is currently pending, they are notified
+immediately.
+.TP
+\f(CWcancel\fR
+Cancels pending notifications of clients using the vector.
+.TP
+\f(CWpending\fR
+Returns \f(CW1\fR if a client notification is pending, and \f(CW0\fR otherwise.
+.RE
+.TP
+\fIvecName \fBoffset\fR ?\fIvalue\fR?
+Shifts the indices of the vector by the amount specified by \fIvalue\fR.
+\fIValue\fR is an integer number.  If no \fIvalue\fR argument is 
+given, the current offset is returned.
+.TP
+\fIvecName \fBpopulate\fR \fIdestName\fR ?\fIdensity\fR?
+Creates a vector \fIdestName\fR which is a superset of \fIvecName\fR.
+\fIDestName\fR will include all the components of \fIvecName\fR, in
+addition the interval between each of the original components will
+contain a \fIdensity\fR number of new components, whose values are
+evenly distributed between the original components values.  This is
+useful for generating abscissas to be interpolated along a spline.
+.TP
+\fIvecName \fBrange\fR \fIfirstIndex\fR ?\fIlastIndex\fR?...
+Returns a list of numeric values representing the vector components
+between two indices. Both \fIfirstIndex\fR and \fIlastIndex\fR are 
+indices representing the range of components to be returned. If 
+\fIlastIndex\fR is less than \fIfirstIndex\fR, the components are
+listed in reverse order.
+.TP
+\fIvecName \fBsearch\fR \fIvalue\fR ?\fIvalue\fR?  
+Searches for a value or range of values among the components of
+\fIvecName\fR.  If one \fIvalue\fR argument is given, a list of
+indices of the components which equal \fIvalue\fR is returned.  If a
+second \fIvalue\fR is also provided, then the indices of all
+components which lie within the range of the two values are returned.
+If no components are found, then \f(CW""\fR is returned.
+.TP
+\fIvecName \fBset\fR \fIitem\fR
+Resets the components of the vector to \fIitem\fR. \fIItem\fR can
+be either a list of numeric expressions or another vector.
+.TP
+\fIvecName \fBseq\fR \fIstart\fR ?\fIfinish\fR? ?\fIstep\fR?
+Generates a sequence of values starting with the value \fIstart\fR.
+\fIFinish\fR indicates the terminating value of the sequence.  
+The vector is automatically resized to contain just the sequence.
+If three arguments are present, \fIstep\fR designates the interval.  
+.sp
+With only two arguments (no \fIfinish\fR argument), the sequence will
+continue until the vector is filled.  With one argument, the interval 
+defaults to 1.0.
+.TP
+\fIvecName \fBsort\fR ?\fB-reverse\fR? ?\fIargName\fR?...  
+Sorts the vector \fIvecName\fR in increasing order.  If the
+\fB-reverse\fR flag is present, the vector is sorted in decreasing
+order.  If other arguments \fIargName\fR are present, they are the
+names of vectors which will be rearranged in the same manner as
+\fIvecName\fR.  Each vector must be the same length as \fIvecName\fR.
+You could use this to sort the x vector of a graph, while still
+retaining the same x,y coordinate pairs in a y vector.
+.TP
+\fIvecName \fBvariable\fR \fIvarName\fR
+Maps a Tcl variable to the vector, creating another means for 
+accessing the vector.  The variable \fIvarName\fR can't already 
+exist. This overrides any current variable mapping the vector
+may have.
+.RE
+.SH C LANGUAGE API
+You can create, modify, and destroy vectors from C code, using 
+library routines.  
+You need to include the header file \f(CWblt.h\fR. It contains the
+definition of the structure \fBBlt_Vector\fR, which represents the
+vector.  It appears below.
+.CS
+\fRtypedef struct {
+    double *\fIvalueArr\fR; 
+    int \fInumValues\fR;    
+    int \fIarraySize\fR;    
+    double \fImin\fR, \fImax\fR;  
+} \fBBlt_Vector\fR;
+.CE
+The field \fIvalueArr\fR points to memory holding the vector
+components.  The components are stored in a double precision array,
+whose size size is represented by \fIarraySize\fR.  \fINumValues\fR is
+the length of vector.  The size of the array is always equal to or
+larger than the length of the vector.  \fIMin\fR and \fImax\fR are
+minimum and maximum component values.
+.SH LIBRARY ROUTINES
+The following routines are available from C to manage vectors.
+Vectors are identified by the vector name.
+.PP
+\fBBlt_CreateVector\fR 
+.RS .25i
+.TP 1i
+Synopsis:
+.CS 
+int \fBBlt_CreateVector\fR (\fIinterp\fR, \fIvecName\fR, \fIlength\fR, \fIvecPtrPtr\fR)
+.RS 1.25i
+Tcl_Interp *\fIinterp\fR;
+char *\fIvecName\fR;
+int \fIlength\fR;
+Blt_Vector **\fIvecPtrPtr\fR;
+.RE
+.CE
+.TP
+Description:
+Creates a new vector \fIvecName\fR\fR with a length of \fIlength\fR.
+\fBBlt_CreateVector\fR creates both a new Tcl command and array 
+variable \fIvecName\fR.  Neither a command nor variable named 
+\fIvecName\fR can already exist.  A pointer to the vector is 
+placed into \fIvecPtrPtr\fR.
+.TP
+Results:
+Returns \f(CWTCL_OK\fR if the vector is successfully created.  If
+\fIlength\fR is negative, a Tcl variable or command \fIvecName\fR
+already exists, or memory cannot be allocated for the vector, then
+\f(CWTCL_ERROR\fR is returned and \fIinterp->result\fR will contain an
+error message.
+.RE
+.sp
+.PP
+\fBBlt_DeleteVectorByName\fR 
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+int \fBBlt_DeleteVectorByName\fR (\fIinterp\fR, \fIvecName\fR)
+.RS 1.25i
+Tcl_Interp *\fIinterp\fR;
+char *\fIvecName\fR;
+.RE
+.CE
+.TP 1i
+Description:
+Removes the vector \fIvecName\fR.  \fIVecName\fR is the name of a vector
+which must already exist.  Both the Tcl command and array variable
+\fIvecName\fR are destroyed.  All clients of the vector will be notified
+immediately that the vector has been destroyed.
+.TP
+Results:
+Returns \f(CWTCL_OK\fR if the vector is successfully deleted.  If
+\fIvecName\fR is not the name a vector, then \f(CWTCL_ERROR\fR is returned
+and \fIinterp->result\fR will contain an error message.
+.RE
+.sp
+.PP
+\fBBlt_DeleteVector\fR 
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+int \fBBlt_DeleteVector\fR (\fIvecPtr\fR)
+.RS 1.25i
+Blt_Vector *\fIvecPtr\fR;
+.RE
+.CE
+.TP 1i
+Description:
+Removes the vector pointed to by \fIvecPtr\fR.  \fIVecPtr\fR is a
+pointer to a vector, typically set by \fBBlt_GetVector\fR or
+\fBBlt_CreateVector\fR.  Both the Tcl command and array variable of
+the vector are destroyed.  All clients of the vector will be notified
+immediately that the vector has been destroyed.
+.TP
+Results:
+Returns \f(CWTCL_OK\fR if the vector is successfully deleted.  If
+\fIvecName\fR is not the name a vector, then \f(CWTCL_ERROR\fR is returned
+and \fIinterp->result\fR will contain an error message.
+.RE
+.sp
+.PP
+\fBBlt_GetVector\fR 
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+int \fBBlt_GetVector\fR (\fIinterp\fR, \fIvecName\fR, \fIvecPtrPtr\fR)
+.RS 1.25i
+Tcl_Interp *\fIinterp\fR;
+char *\fIvecName\fR;
+Blt_Vector **\fIvecPtrPtr\fR;
+.RE
+.CE
+.TP 1i
+Description:
+Retrieves the vector \fIvecName\fR.  \fIVecName\fR is the name of a
+vector which must already exist.  \fIVecPtrPtr\fR will point be set to
+the address of the vector.
+.TP
+Results:
+Returns \f(CWTCL_OK\fR if the vector is successfully retrieved.  If
+\fIvecName\fR is not the name of a vector, then \f(CWTCL_ERROR\fR is
+returned and \fIinterp->result\fR will contain an error message.
+.RE
+.sp
+.PP
+\fBBlt_ResetVector\fR 
+.PP
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+int \fBBlt_ResetVector\fR (\fIvecPtr\fR, \fIdataArr\fR, 
+	\fInumValues\fR, \fIarraySize\fR, \fIfreeProc\fR)
+.RS 1.25i
+Blt_Vector *\fIvecPtr\fR;
+double *\fIdataArr\fR;
+int *\fInumValues\fR;
+int *\fIarraySize\fR;
+Tcl_FreeProc *\fIfreeProc\fR;
+.RE
+.CE
+.TP
+Description: 
+Resets the components of the vector pointed to by \fIvecPtr\fR.
+Calling \fBBlt_ResetVector\fR will trigger the vector to dispatch
+notifications to its clients. \fIDataArr\fR is the array of doubles
+which represents the vector data. \fINumValues\fR is the number of
+elements in the array. \fIArraySize\fR is the actual size of the array
+(the array may be bigger than the number of values stored in
+it). \fIFreeProc\fP indicates how the storage for the vector component
+array (\fIdataArr\fR) was allocated.  It is used to determine how to
+reallocate memory when the vector is resized or destroyed.  It must be
+\f(CWTCL_DYNAMIC\fR, \f(CWTCL_STATIC\fR, \f(CWTCL_VOLATILE\fR, or a pointer
+to a function to free the memory allocated for the vector array. If
+\fIfreeProc\fR is \f(CWTCL_VOLATILE\fR, it indicates that \fIdataArr\fR
+must be copied and saved.  If \fIfreeProc\fR is \f(CWTCL_DYNAMIC\fR, it
+indicates that \fIdataArr\fR was dynamically allocated and that Tcl
+should free \fIdataArr\fR if necessary.  \f(CWStatic\fR indicates that
+nothing should be done to release storage for \fIdataArr\fR.
+.TP
+Results:
+Returns \f(CWTCL_OK\fR if the vector is successfully resized.  If
+\fInewSize\fR is negative, a vector \fIvecName\fR does not exist, or
+memory cannot be allocated for the vector, then \f(CWTCL_ERROR\fR is
+returned and \fIinterp->result\fR will contain an error message.
+.RE
+.sp
+.PP
+\fBBlt_ResizeVector\fR 
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+int \fBBlt_ResizeVector\fR (\fIvecPtr\fR, \fInewSize\fR)
+.RS 1.25i
+Blt_Vector *\fIvecPtr\fR;
+int \fInewSize\fR;
+.RE
+.CE
+.TP
+Description:
+Resets the length of the vector pointed to by \fIvecPtr\fR to
+\fInewSize\fR.  If \fInewSize\fR is smaller than the current size of
+the vector, it is truncated.  If \fInewSize\fR is greater, the vector
+is extended and the new components are initialized to \f(CW0.0\fR.
+Calling \fBBlt_ResetVector\fR will trigger the vector to dispatch
+notifications.
+.TP
+Results:
+Returns \f(CWTCL_OK\fR if the vector is successfully resized.  If
+\fInewSize\fR is negative or memory can not be allocated for the vector, 
+then \f(CWTCL_ERROR\fR is returned and \fIinterp->result\fR will contain 
+an error message.
+.sp
+.PP
+\fBBlt_VectorExists\fR 
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+int \fBBlt_VectorExists\fR (\fIinterp\fR, \fIvecName\fR)
+.RS 1.25i
+Tcl_Interp *\fIinterp\fR;
+char *\fIvecName\fR;
+.RE
+.CE
+.TP
+Description:
+Indicates if a vector named \fIvecName\fR exists in \fIinterp\fR.
+.TP
+Results:
+Returns \f(CW1\fR if a vector \fIvecName\fR exists and \f(CW0\fR otherwise.
+.RE
+.sp
+.PP
+If your application needs to be notified when a vector changes, it can
+allocate a unique \fIclient identifier\fR for itself.  Using this
+identifier, you can then register a call-back to be made whenever the
+vector is updated or destroyed.  By default, the call-backs are made at
+the next idle point.  This can be changed to occur at the time the
+vector is modified.  An application can allocate more than one
+identifier for any vector.  When the client application is done with
+the vector, it should free the identifier.
+.PP
+The call-back routine must of the following type.
+.CS
+.RS
+.sp
+typedef void (\fBBlt_VectorChangedProc\fR) (Tcl_Interp *\fIinterp\fR, 
+.RS .25i
+ClientData \fIclientData\fR, Blt_VectorNotify \fInotify\fR);
+.RE
+.sp
+.RE
+.CE
+.fi
+\fIClientData\fR is passed to this routine whenever it is called.  You
+can use this to pass information to the call-back.  The \fInotify\fR 
+argument indicates whether the vector has been updated of destroyed. It
+is an enumerated type.
+.CS
+.RS
+.sp
+typedef enum {
+    \f(CWBLT_VECTOR_NOTIFY_UPDATE\fR=1,
+    \f(CWBLT_VECTOR_NOTIFY_DESTROY\fR=2
+} \fBBlt_VectorNotify\fR;
+.sp
+.RE
+.CE
+.PP
+\fBBlt_AllocVectorId\fR
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+Blt_VectorId \fBBlt_AllocVectorId\fR (\fIinterp\fR, \fIvecName\fR)
+.RS 1.25i
+Tcl_Interp *\fIinterp\fR;
+char *\fIvecName\fR;
+.RE
+.CE
+.TP
+Description:
+Allocates an client identifier for with the vector \fIvecName\fR.
+This identifier can be used to specify a call-back which is triggered
+when the vector is updated or destroyed.
+.TP
+Results:
+Returns a client identifier if successful.  If \fIvecName\fR is not
+the name of a vector, then \f(CWNULL\fR is returned and
+\fIinterp->result\fR will contain an error message.
+.RE
+.sp
+.PP
+\fBBlt_GetVectorById\fR 
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+int \fBBlt_GetVector\fR (\fIinterp\fR, \fIclientId\fR, \fIvecPtrPtr\fR)
+.RS 1.25i
+Tcl_Interp *\fIinterp\fR;
+Blt_VectorId \fIclientId\fR;
+Blt_Vector **\fIvecPtrPtr\fR;
+.RE
+.CE
+.TP 1i
+Description:
+Retrieves the vector used by \fIclientId\fR.  \fIClientId\fR is a valid
+vector client identifier allocated by \fBBlt_AllocVectorId\fR.
+\fIVecPtrPtr\fR will point be set to the address of the vector.
+.TP
+Results:
+Returns \f(CWTCL_OK\fR if the vector is successfully retrieved.  
+.RE
+.sp
+.PP
+\fBBlt_SetVectorChangedProc\fR
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+void \fBBlt_SetVectorChangedProc\fR (\fIclientId\fR, \fIproc\fR, \fIclientData\fR);
+.RS 1.25i
+Blt_VectorId \fIclientId\fR;
+Blt_VectorChangedProc *\fIproc\fR;
+ClientData *\fIclientData\fR;
+.RE
+.CE
+.TP
+Description: 
+Specifies a call-back routine to be called whenever the vector
+associated with \fIclientId\fR is updated or deleted.  \fIProc\fR is a
+pointer to call-back routine and must be of the type
+\fBBlt_VectorChangedProc\fR.  \fIClientData\fR is a one-word value to
+be passed to the routine when it is invoked. If \fIproc\fR is
+\f(CWNULL\fR, then the client is not notified.
+.TP
+Results:
+The designated call-back procedure will be invoked when the vector is 
+updated or destroyed.
+.RE
+.sp
+.PP
+\fBBlt_FreeVectorId\fR
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+void \fBBlt_FreeVectorId\fR (\fIclientId\fR);
+.RS 1.25i
+Blt_VectorId \fIclientId\fR;
+.RE
+.CE
+.TP
+Description: 
+Frees the client identifier.  Memory allocated for the identifier 
+is released.  The client will no longer be notified when the
+vector is modified.
+.TP
+Results:
+The designated call-back procedure will be no longer be invoked when
+the vector is updated or destroyed.
+.RE
+.sp
+.PP
+\fBBlt_NameOfVectorId\fR
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+char *\fBBlt_NameOfVectorId\fR (\fIclientId\fR);
+.RS 1.25i
+Blt_VectorId \fIclientId\fR;
+.RE
+.CE
+.TP
+Description: 
+Retrieves the name of the vector associated with the client identifier
+\fIclientId\fR.  
+.TP
+Results:
+Returns the name of the vector associated with \fIclientId\fR.  If
+\fIclientId\fR is not an identifier or the vector has been destroyed, 
+\f(CWNULL\fR is returned.
+.RE
+.sp
+.PP
+\fBBlt_InstallIndexProc\fR
+.RS .25i
+.TP 1i
+Synopsis:
+.CS
+void \fBBlt_InstallIndexProc\fR (\fIindexName\fR, \fIprocPtr\fR)
+.RS 1.25i
+char *\fIindexName\fR;
+Blt_VectorIndexProc *\fIprocPtr\fR;
+.RE
+.CE
+.TP
+Description: 
+Registers a function to be called to retrieved the index \fIindexName\fR
+from the vector's array variable.  
+.sp
+typedef double Blt_VectorIndexProc(Vector *vecPtr);
+.sp
+The function will be passed a pointer to the vector.  The function must
+return a double representing the value at the index.
+.TP
+Results:
+The new index is installed into the vector.
+.RE
+.RE
+.SH C API EXAMPLE
+The following example opens a file of binary data and stores it in an
+array of doubles. The array size is computed from the size of the
+file. If the vector "data" exists, calling \fBBlt_VectorExists\fR,
+\fBBlt_GetVector\fR is called to get the pointer to the vector.
+Otherwise the routine \fBBlt_CreateVector\fR is called to create a new
+vector and returns a pointer to it. Just like the Tcl interface, both
+a new Tcl command and array variable are created when a new vector is
+created. It doesn't make any difference what the initial size of the
+vector is since it will be reset shortly. The vector is updated when
+\fBlt_ResetVector\fR is called.  Blt_ResetVector makes the changes
+visible to the Tcl interface and other vector clients (such as a graph
+widget).
+.sp
+.CS
+#include <tcl.h>
+#include <blt.h>				
+...
+Blt_Vector *vecPtr;
+double *newArr;
+FILE *f;
+struct stat statBuf;
+int numBytes, numValues;
+
+f = fopen("binary.dat", "r");
+fstat(fileno(f), &statBuf);
+numBytes = (int)statBuf.st_size;
+
+/* Allocate an array big enough to hold all the data */
+newArr = (double *)malloc(numBytes);
+numValues = numBytes / sizeof(double);
+fread((void *)newArr, numValues, sizeof(double), f);
+fclose(f);
+
+if (Blt_VectorExists(interp, "data"))  {
+    if (Blt_GetVector(interp, "data", &vecPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+} else {
+   if (Blt_CreateVector(interp, "data", 0, &vecPtr) != TCL_OK) {
+	return TCL_ERROR;
+   }
+}
+/* 
+ * Reset the vector. Clients will be notified when Tk is idle. 
+ * TCL_DYNAMIC tells the vector to free the memory allocated 
+ * if it needs to reallocate or destroy the vector.
+ */
+if (Blt_ResetVector(vecPtr, newArr, numValues, numValues, 
+	TCL_DYNAMIC) != TCL_OK) {
+    return TCL_ERROR;
+}
+.CE
+.SH "INCOMPATIBILITIES"
+In previous versions, if the array variable isn't global 
+(i.e. local to a Tcl procedure), the vector is automatically 
+destroyed when the procedure returns.
+.CS
+proc doit {} {
+    # Temporary vector x
+    vector x(10)
+    set x(9) 2.0
+      ...
+}
+.CE
+.PP
+This has changed.  Variables are not automatically destroyed when
+their variable is unset.  You can restore the old behavior by
+setting the "-watchunset" switch.
+.CE
+.SH KEYWORDS
+vector, graph, widget
diff --git a/tlt3.0/library/afm/AvantGarde-Book.afm b/tlt3.0/library/afm/AvantGarde-Book.afm
new file mode 100644
index 0000000..1e60fee
--- /dev/null
+++ b/tlt3.0/library/afm/AvantGarde-Book.afm
@@ -0,0 +1,574 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Mon Mar  4 13:37:31 1991
+Comment UniqueID 34364
+Comment VMusage 24225 31117
+FontName AvantGarde-Book
+FullName ITC Avant Garde Gothic Book
+FamilyName ITC Avant Garde Gothic
+Weight Book
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -113 -222 1148 955
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.006
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated.  All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation.
+EncodingScheme AdobeStandardEncoding
+CapHeight 740
+XHeight 547
+Ascender 740
+Descender -192
+StartCharMetrics 228
+C 32 ; WX 277 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 295 ; N exclam ; B 111 0 185 740 ;
+C 34 ; WX 309 ; N quotedbl ; B 36 444 273 740 ;
+C 35 ; WX 554 ; N numbersign ; B 33 0 521 740 ;
+C 36 ; WX 554 ; N dollar ; B 70 -70 485 811 ;
+C 37 ; WX 775 ; N percent ; B 21 -13 753 751 ;
+C 38 ; WX 757 ; N ampersand ; B 56 -12 736 753 ;
+C 39 ; WX 351 ; N quoteright ; B 94 546 256 740 ;
+C 40 ; WX 369 ; N parenleft ; B 47 -205 355 757 ;
+C 41 ; WX 369 ; N parenright ; B 14 -205 322 757 ;
+C 42 ; WX 425 ; N asterisk ; B 58 446 367 740 ;
+C 43 ; WX 606 ; N plus ; B 51 0 555 506 ;
+C 44 ; WX 277 ; N comma ; B 14 -67 176 126 ;
+C 45 ; WX 332 ; N hyphen ; B 30 248 302 315 ;
+C 46 ; WX 277 ; N period ; B 102 0 176 126 ;
+C 47 ; WX 437 ; N slash ; B 44 -100 403 740 ;
+C 48 ; WX 554 ; N zero ; B 29 -13 525 753 ;
+C 49 ; WX 554 ; N one ; B 135 0 336 740 ;
+C 50 ; WX 554 ; N two ; B 40 0 514 753 ;
+C 51 ; WX 554 ; N three ; B 34 -13 506 753 ;
+C 52 ; WX 554 ; N four ; B 14 0 528 740 ;
+C 53 ; WX 554 ; N five ; B 26 -13 530 740 ;
+C 54 ; WX 554 ; N six ; B 24 -13 530 739 ;
+C 55 ; WX 554 ; N seven ; B 63 0 491 740 ;
+C 56 ; WX 554 ; N eight ; B 41 -13 513 753 ;
+C 57 ; WX 554 ; N nine ; B 24 0 530 752 ;
+C 58 ; WX 277 ; N colon ; B 102 0 176 548 ;
+C 59 ; WX 277 ; N semicolon ; B 14 -67 176 548 ;
+C 60 ; WX 606 ; N less ; B 46 -8 554 514 ;
+C 61 ; WX 606 ; N equal ; B 51 118 555 388 ;
+C 62 ; WX 606 ; N greater ; B 52 -8 560 514 ;
+C 63 ; WX 591 ; N question ; B 64 0 526 752 ;
+C 64 ; WX 867 ; N at ; B 65 -13 803 753 ;
+C 65 ; WX 740 ; N A ; B 12 0 729 740 ;
+C 66 ; WX 574 ; N B ; B 74 0 544 740 ;
+C 67 ; WX 813 ; N C ; B 43 -13 771 752 ;
+C 68 ; WX 744 ; N D ; B 74 0 699 740 ;
+C 69 ; WX 536 ; N E ; B 70 0 475 740 ;
+C 70 ; WX 485 ; N F ; B 70 0 444 740 ;
+C 71 ; WX 872 ; N G ; B 40 -13 828 753 ;
+C 72 ; WX 683 ; N H ; B 76 0 607 740 ;
+C 73 ; WX 226 ; N I ; B 76 0 150 740 ;
+C 74 ; WX 482 ; N J ; B 6 -13 402 740 ;
+C 75 ; WX 591 ; N K ; B 81 0 591 740 ;
+C 76 ; WX 462 ; N L ; B 82 0 462 740 ;
+C 77 ; WX 919 ; N M ; B 76 0 843 740 ;
+C 78 ; WX 740 ; N N ; B 75 0 664 740 ;
+C 79 ; WX 869 ; N O ; B 43 -13 826 753 ;
+C 80 ; WX 592 ; N P ; B 75 0 564 740 ;
+C 81 ; WX 871 ; N Q ; B 40 -13 837 753 ;
+C 82 ; WX 607 ; N R ; B 70 0 572 740 ;
+C 83 ; WX 498 ; N S ; B 22 -13 473 753 ;
+C 84 ; WX 426 ; N T ; B 6 0 419 740 ;
+C 85 ; WX 655 ; N U ; B 75 -13 579 740 ;
+C 86 ; WX 702 ; N V ; B 8 0 693 740 ;
+C 87 ; WX 960 ; N W ; B 11 0 950 740 ;
+C 88 ; WX 609 ; N X ; B 8 0 602 740 ;
+C 89 ; WX 592 ; N Y ; B 1 0 592 740 ;
+C 90 ; WX 480 ; N Z ; B 12 0 470 740 ;
+C 91 ; WX 351 ; N bracketleft ; B 133 -179 337 753 ;
+C 92 ; WX 605 ; N backslash ; B 118 -100 477 740 ;
+C 93 ; WX 351 ; N bracketright ; B 14 -179 218 753 ;
+C 94 ; WX 606 ; N asciicircum ; B 53 307 553 740 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 351 ; N quoteleft ; B 95 546 257 740 ;
+C 97 ; WX 683 ; N a ; B 42 -13 621 561 ;
+C 98 ; WX 682 ; N b ; B 68 -13 647 740 ;
+C 99 ; WX 647 ; N c ; B 41 -13 607 561 ;
+C 100 ; WX 685 ; N d ; B 39 -13 618 740 ;
+C 101 ; WX 650 ; N e ; B 38 -13 608 561 ;
+C 102 ; WX 314 ; N f ; B 19 0 314 753 ; L i fi ; L l fl ;
+C 103 ; WX 673 ; N g ; B 37 -215 606 561 ;
+C 104 ; WX 610 ; N h ; B 62 0 543 740 ;
+C 105 ; WX 200 ; N i ; B 65 0 135 740 ;
+C 106 ; WX 203 ; N j ; B -44 -192 137 740 ;
+C 107 ; WX 502 ; N k ; B 70 0 498 740 ;
+C 108 ; WX 200 ; N l ; B 65 0 135 740 ;
+C 109 ; WX 938 ; N m ; B 66 0 872 561 ;
+C 110 ; WX 610 ; N n ; B 65 0 546 561 ;
+C 111 ; WX 655 ; N o ; B 42 -13 614 561 ;
+C 112 ; WX 682 ; N p ; B 64 -192 643 561 ;
+C 113 ; WX 682 ; N q ; B 37 -192 616 561 ;
+C 114 ; WX 301 ; N r ; B 65 0 291 561 ;
+C 115 ; WX 388 ; N s ; B 24 -13 364 561 ;
+C 116 ; WX 339 ; N t ; B 14 0 330 740 ;
+C 117 ; WX 608 ; N u ; B 62 -13 541 547 ;
+C 118 ; WX 554 ; N v ; B 7 0 546 547 ;
+C 119 ; WX 831 ; N w ; B 13 0 820 547 ;
+C 120 ; WX 480 ; N x ; B 12 0 468 547 ;
+C 121 ; WX 536 ; N y ; B 15 -192 523 547 ;
+C 122 ; WX 425 ; N z ; B 10 0 415 547 ;
+C 123 ; WX 351 ; N braceleft ; B 70 -189 331 740 ;
+C 124 ; WX 672 ; N bar ; B 299 -100 373 740 ;
+C 125 ; WX 351 ; N braceright ; B 20 -189 281 740 ;
+C 126 ; WX 606 ; N asciitilde ; B 72 179 534 319 ;
+C 161 ; WX 295 ; N exclamdown ; B 110 -192 184 548 ;
+C 162 ; WX 554 ; N cent ; B 48 62 510 707 ;
+C 163 ; WX 554 ; N sterling ; B 4 0 552 753 ;
+C 164 ; WX 166 ; N fraction ; B -113 0 280 740 ;
+C 165 ; WX 554 ; N yen ; B 4 0 550 740 ;
+C 166 ; WX 554 ; N florin ; B -12 -153 518 818 ;
+C 167 ; WX 615 ; N section ; B 85 -141 529 753 ;
+C 168 ; WX 554 ; N currency ; B 8 42 546 580 ;
+C 169 ; WX 198 ; N quotesingle ; B 59 444 140 740 ;
+C 170 ; WX 502 ; N quotedblleft ; B 97 546 406 740 ;
+C 171 ; WX 425 ; N guillemotleft ; B 40 81 386 481 ;
+C 172 ; WX 251 ; N guilsinglleft ; B 40 81 212 481 ;
+C 173 ; WX 251 ; N guilsinglright ; B 39 81 211 481 ;
+C 174 ; WX 487 ; N fi ; B 19 0 422 753 ;
+C 175 ; WX 485 ; N fl ; B 19 0 420 753 ;
+C 177 ; WX 500 ; N endash ; B 35 248 465 315 ;
+C 178 ; WX 553 ; N dagger ; B 59 -133 493 740 ;
+C 179 ; WX 553 ; N daggerdbl ; B 59 -133 493 740 ;
+C 180 ; WX 277 ; N periodcentered ; B 102 190 176 316 ;
+C 182 ; WX 564 ; N paragraph ; B 22 -110 551 740 ;
+C 183 ; WX 606 ; N bullet ; B 150 222 455 532 ;
+C 184 ; WX 354 ; N quotesinglbase ; B 89 -68 251 126 ;
+C 185 ; WX 502 ; N quotedblbase ; B 89 -68 399 126 ;
+C 186 ; WX 484 ; N quotedblright ; B 96 546 405 740 ;
+C 187 ; WX 425 ; N guillemotright ; B 39 81 385 481 ;
+C 188 ; WX 1000 ; N ellipsis ; B 130 0 870 126 ;
+C 189 ; WX 1174 ; N perthousand ; B 25 -13 1148 751 ;
+C 191 ; WX 591 ; N questiondown ; B 65 -205 527 548 ;
+C 193 ; WX 378 ; N grave ; B 69 619 300 786 ;
+C 194 ; WX 375 ; N acute ; B 78 619 309 786 ;
+C 195 ; WX 502 ; N circumflex ; B 74 639 428 764 ;
+C 196 ; WX 439 ; N tilde ; B 47 651 392 754 ;
+C 197 ; WX 485 ; N macron ; B 73 669 411 736 ;
+C 198 ; WX 453 ; N breve ; B 52 651 401 754 ;
+C 199 ; WX 222 ; N dotaccent ; B 74 639 148 765 ;
+C 200 ; WX 369 ; N dieresis ; B 73 639 295 765 ;
+C 202 ; WX 332 ; N ring ; B 62 600 269 807 ;
+C 203 ; WX 324 ; N cedilla ; B 80 -222 254 0 ;
+C 205 ; WX 552 ; N hungarumlaut ; B 119 605 453 800 ;
+C 206 ; WX 302 ; N ogonek ; B 73 -191 228 0 ;
+C 207 ; WX 502 ; N caron ; B 68 639 423 764 ;
+C 208 ; WX 1000 ; N emdash ; B 35 248 965 315 ;
+C 225 ; WX 992 ; N AE ; B -20 0 907 740 ;
+C 227 ; WX 369 ; N ordfeminine ; B -3 407 356 753 ;
+C 232 ; WX 517 ; N Lslash ; B 59 0 517 740 ;
+C 233 ; WX 868 ; N Oslash ; B 43 -83 826 819 ;
+C 234 ; WX 1194 ; N OE ; B 45 -13 1142 753 ;
+C 235 ; WX 369 ; N ordmasculine ; B 12 407 356 753 ;
+C 241 ; WX 1157 ; N ae ; B 34 -13 1113 561 ;
+C 245 ; WX 200 ; N dotlessi ; B 65 0 135 547 ;
+C 248 ; WX 300 ; N lslash ; B 43 0 259 740 ;
+C 249 ; WX 653 ; N oslash ; B 41 -64 613 614 ;
+C 250 ; WX 1137 ; N oe ; B 34 -13 1104 561 ;
+C 251 ; WX 554 ; N germandbls ; B 61 -13 525 753 ;
+C -1 ; WX 650 ; N ecircumflex ; B 38 -13 608 764 ;
+C -1 ; WX 650 ; N edieresis ; B 38 -13 608 765 ;
+C -1 ; WX 683 ; N aacute ; B 42 -13 621 786 ;
+C -1 ; WX 747 ; N registered ; B -9 -12 755 752 ;
+C -1 ; WX 200 ; N icircumflex ; B -77 0 277 764 ;
+C -1 ; WX 608 ; N udieresis ; B 62 -13 541 765 ;
+C -1 ; WX 655 ; N ograve ; B 42 -13 614 786 ;
+C -1 ; WX 608 ; N uacute ; B 62 -13 541 786 ;
+C -1 ; WX 608 ; N ucircumflex ; B 62 -13 541 764 ;
+C -1 ; WX 740 ; N Aacute ; B 12 0 729 949 ;
+C -1 ; WX 200 ; N igrave ; B -60 0 171 786 ;
+C -1 ; WX 226 ; N Icircumflex ; B -64 0 290 927 ;
+C -1 ; WX 647 ; N ccedilla ; B 41 -222 607 561 ;
+C -1 ; WX 683 ; N adieresis ; B 42 -13 621 765 ;
+C -1 ; WX 536 ; N Ecircumflex ; B 70 0 475 927 ;
+C -1 ; WX 388 ; N scaron ; B 11 -13 366 764 ;
+C -1 ; WX 682 ; N thorn ; B 64 -192 643 740 ;
+C -1 ; WX 1000 ; N trademark ; B 9 296 816 740 ;
+C -1 ; WX 650 ; N egrave ; B 38 -13 608 786 ;
+C -1 ; WX 332 ; N threesuperior ; B 18 289 318 747 ;
+C -1 ; WX 425 ; N zcaron ; B 10 0 415 764 ;
+C -1 ; WX 683 ; N atilde ; B 42 -13 621 754 ;
+C -1 ; WX 683 ; N aring ; B 42 -13 621 807 ;
+C -1 ; WX 655 ; N ocircumflex ; B 42 -13 614 764 ;
+C -1 ; WX 536 ; N Edieresis ; B 70 0 475 928 ;
+C -1 ; WX 831 ; N threequarters ; B 46 0 784 747 ;
+C -1 ; WX 536 ; N ydieresis ; B 15 -192 523 765 ;
+C -1 ; WX 536 ; N yacute ; B 15 -192 523 786 ;
+C -1 ; WX 200 ; N iacute ; B 31 0 262 786 ;
+C -1 ; WX 740 ; N Acircumflex ; B 12 0 729 927 ;
+C -1 ; WX 655 ; N Uacute ; B 75 -13 579 949 ;
+C -1 ; WX 650 ; N eacute ; B 38 -13 608 786 ;
+C -1 ; WX 869 ; N Ograve ; B 43 -13 826 949 ;
+C -1 ; WX 683 ; N agrave ; B 42 -13 621 786 ;
+C -1 ; WX 655 ; N Udieresis ; B 75 -13 579 928 ;
+C -1 ; WX 683 ; N acircumflex ; B 42 -13 621 764 ;
+C -1 ; WX 226 ; N Igrave ; B -47 0 184 949 ;
+C -1 ; WX 332 ; N twosuperior ; B 19 296 318 747 ;
+C -1 ; WX 655 ; N Ugrave ; B 75 -13 579 949 ;
+C -1 ; WX 831 ; N onequarter ; B 100 0 729 740 ;
+C -1 ; WX 655 ; N Ucircumflex ; B 75 -13 579 927 ;
+C -1 ; WX 498 ; N Scaron ; B 22 -13 473 927 ;
+C -1 ; WX 226 ; N Idieresis ; B 2 0 224 928 ;
+C -1 ; WX 200 ; N idieresis ; B -11 0 211 765 ;
+C -1 ; WX 536 ; N Egrave ; B 70 0 475 949 ;
+C -1 ; WX 869 ; N Oacute ; B 43 -13 826 949 ;
+C -1 ; WX 606 ; N divide ; B 51 -13 555 519 ;
+C -1 ; WX 740 ; N Atilde ; B 12 0 729 917 ;
+C -1 ; WX 740 ; N Aring ; B 12 0 729 955 ;
+C -1 ; WX 869 ; N Odieresis ; B 43 -13 826 928 ;
+C -1 ; WX 740 ; N Adieresis ; B 12 0 729 928 ;
+C -1 ; WX 740 ; N Ntilde ; B 75 0 664 917 ;
+C -1 ; WX 480 ; N Zcaron ; B 12 0 470 927 ;
+C -1 ; WX 592 ; N Thorn ; B 60 0 549 740 ;
+C -1 ; WX 226 ; N Iacute ; B 44 0 275 949 ;
+C -1 ; WX 606 ; N plusminus ; B 51 -24 555 518 ;
+C -1 ; WX 606 ; N multiply ; B 74 24 533 482 ;
+C -1 ; WX 536 ; N Eacute ; B 70 0 475 949 ;
+C -1 ; WX 592 ; N Ydieresis ; B 1 0 592 928 ;
+C -1 ; WX 332 ; N onesuperior ; B 63 296 198 740 ;
+C -1 ; WX 608 ; N ugrave ; B 62 -13 541 786 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 109 555 388 ;
+C -1 ; WX 610 ; N ntilde ; B 65 0 546 754 ;
+C -1 ; WX 869 ; N Otilde ; B 43 -13 826 917 ;
+C -1 ; WX 655 ; N otilde ; B 42 -13 614 754 ;
+C -1 ; WX 813 ; N Ccedilla ; B 43 -222 771 752 ;
+C -1 ; WX 740 ; N Agrave ; B 12 0 729 949 ;
+C -1 ; WX 831 ; N onehalf ; B 81 0 750 740 ;
+C -1 ; WX 790 ; N Eth ; B 40 0 739 740 ;
+C -1 ; WX 400 ; N degree ; B 56 421 344 709 ;
+C -1 ; WX 592 ; N Yacute ; B 1 0 592 949 ;
+C -1 ; WX 869 ; N Ocircumflex ; B 43 -13 826 927 ;
+C -1 ; WX 655 ; N oacute ; B 42 -13 614 786 ;
+C -1 ; WX 608 ; N mu ; B 80 -184 527 547 ;
+C -1 ; WX 606 ; N minus ; B 51 219 555 287 ;
+C -1 ; WX 655 ; N eth ; B 42 -12 614 753 ;
+C -1 ; WX 655 ; N odieresis ; B 42 -13 614 765 ;
+C -1 ; WX 747 ; N copyright ; B -9 -12 755 752 ;
+C -1 ; WX 672 ; N brokenbar ; B 299 -100 373 740 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 216
+
+KPX A y -62
+KPX A w -65
+KPX A v -70
+KPX A u -20
+KPX A quoteright -100
+KPX A quotedblright -100
+KPX A Y -92
+KPX A W -60
+KPX A V -102
+KPX A U -40
+KPX A T -45
+KPX A Q -40
+KPX A O -50
+KPX A G -40
+KPX A C -40
+
+KPX B A -10
+
+KPX C A -40
+
+KPX D period -20
+KPX D comma -20
+KPX D Y -30
+KPX D W -10
+KPX D V -50
+KPX D A -50
+
+KPX F period -160
+KPX F e -20
+KPX F comma -180
+KPX F a -20
+KPX F A -75
+
+KPX G period -20
+KPX G comma -20
+KPX G Y -20
+
+KPX J period -15
+KPX J a -20
+KPX J A -30
+
+KPX K o -15
+KPX K e -20
+KPX K O -20
+
+KPX L y -23
+KPX L quoteright -130
+KPX L quotedblright -130
+KPX L Y -91
+KPX L W -67
+KPX L V -113
+KPX L T -46
+
+KPX O period -30
+KPX O comma -30
+KPX O Y -30
+KPX O X -30
+KPX O W -20
+KPX O V -60
+KPX O T -30
+KPX O A -60
+
+KPX P period -300
+KPX P o -60
+KPX P e -20
+KPX P comma -280
+KPX P a -20
+KPX P A -114
+
+KPX Q comma 20
+
+KPX R Y -10
+KPX R W 10
+KPX R V -10
+KPX R T 6
+
+KPX S comma 20
+
+KPX T y -50
+KPX T w -55
+KPX T u -46
+KPX T semicolon -29
+KPX T r -30
+KPX T period -91
+KPX T o -70
+KPX T i 10
+KPX T hyphen -75
+KPX T e -49
+KPX T comma -82
+KPX T colon -15
+KPX T a -90
+KPX T O -30
+KPX T A -45
+
+KPX U period -20
+KPX U comma -20
+KPX U A -40
+
+KPX V u -40
+KPX V semicolon -33
+KPX V period -165
+KPX V o -101
+KPX V i -5
+KPX V hyphen -75
+KPX V e -101
+KPX V comma -145
+KPX V colon -18
+KPX V a -104
+KPX V O -60
+KPX V G -20
+KPX V A -102
+
+KPX W y -2
+KPX W u -30
+KPX W semicolon -33
+KPX W period -106
+KPX W o -46
+KPX W i 6
+KPX W hyphen -35
+KPX W e -47
+KPX W comma -106
+KPX W colon -15
+KPX W a -50
+KPX W O -20
+KPX W A -58
+
+KPX Y u -52
+KPX Y semicolon -23
+KPX Y period -175
+KPX Y o -89
+KPX Y hyphen -85
+KPX Y e -89
+KPX Y comma -145
+KPX Y colon -10
+KPX Y a -93
+KPX Y O -30
+KPX Y A -92
+
+KPX a p 20
+KPX a b 20
+
+KPX b y -20
+KPX b v -20
+
+KPX c y -20
+KPX c k -15
+
+KPX comma space -110
+KPX comma quoteright -120
+KPX comma quotedblright -120
+
+KPX e y -20
+KPX e w -20
+KPX e v -20
+
+KPX f period -50
+KPX f o -40
+KPX f l -30
+KPX f i -34
+KPX f f -60
+KPX f e -20
+KPX f dotlessi -34
+KPX f comma -50
+KPX f a -40
+
+KPX g a -15
+
+KPX h y -30
+
+KPX k y -5
+KPX k e -15
+
+KPX m y -20
+KPX m u -20
+KPX m a -20
+
+KPX n y -15
+KPX n v -20
+
+KPX o y -20
+KPX o x -15
+KPX o w -20
+KPX o v -30
+
+KPX p y -20
+
+KPX period space -110
+KPX period quoteright -120
+KPX period quotedblright -120
+
+KPX quotedblleft quoteleft -35
+KPX quotedblleft A -100
+
+KPX quotedblright space -110
+
+KPX quoteleft quoteleft -203
+KPX quoteleft A -100
+
+KPX quoteright v -30
+KPX quoteright t 10
+KPX quoteright space -110
+KPX quoteright s -15
+KPX quoteright r -20
+KPX quoteright quoteright -203
+KPX quoteright quotedblright -35
+KPX quoteright d -110
+
+KPX r y 40
+KPX r v 40
+KPX r u 20
+KPX r t 20
+KPX r s 20
+KPX r q -8
+KPX r period -73
+KPX r p 20
+KPX r o -20
+KPX r n 21
+KPX r m 28
+KPX r l 20
+KPX r k 20
+KPX r i 20
+KPX r hyphen -60
+KPX r g -15
+KPX r e -4
+KPX r d -6
+KPX r comma -75
+KPX r c -20
+KPX r a -20
+
+KPX s period 20
+KPX s comma 20
+
+KPX space quoteleft -110
+KPX space quotedblleft -110
+KPX space Y -60
+KPX space W -25
+KPX space V -50
+KPX space T -25
+KPX space A -20
+
+KPX v period -130
+KPX v o -30
+KPX v e -20
+KPX v comma -100
+KPX v a -30
+
+KPX w period -100
+KPX w o -30
+KPX w h 15
+KPX w e -20
+KPX w comma -90
+KPX w a -30
+
+KPX y period -125
+KPX y o -30
+KPX y e -20
+KPX y comma -110
+KPX y a -30
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 183 163 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 119 163 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 186 163 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 181 163 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 204 148 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 151 163 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 81 163 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 17 163 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 84 163 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 79 163 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -34 163 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -138 163 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -71 163 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -116 163 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 151 163 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 247 163 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 184 163 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 163 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 246 163 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 163 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron -2 163 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 163 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 77 163 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 143 163 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 119 163 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 129 163 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 112 163 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron -11 163 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 154 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 91 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 157 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 153 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 176 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 122 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 138 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 74 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 141 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 136 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -151 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -84 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -129 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 86 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 140 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 77 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 143 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 108 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron -57 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 137 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 53 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 120 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 95 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 101 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron -38 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/AvantGarde-BookOblique.afm b/tlt3.0/library/afm/AvantGarde-BookOblique.afm
new file mode 100644
index 0000000..ca315b5
--- /dev/null
+++ b/tlt3.0/library/afm/AvantGarde-BookOblique.afm
@@ -0,0 +1,574 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Mon Mar  4 13:41:11 1991
+Comment UniqueID 34367
+Comment VMusage 6555 39267
+FontName AvantGarde-BookOblique
+FullName ITC Avant Garde Gothic Book Oblique
+FamilyName ITC Avant Garde Gothic
+Weight Book
+ItalicAngle -10.5
+IsFixedPitch false
+FontBBox -113 -222 1279 955
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.006
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated.  All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation.
+EncodingScheme AdobeStandardEncoding
+CapHeight 740
+XHeight 547
+Ascender 740
+Descender -192
+StartCharMetrics 228
+C 32 ; WX 277 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 295 ; N exclam ; B 111 0 322 740 ;
+C 34 ; WX 309 ; N quotedbl ; B 130 444 410 740 ;
+C 35 ; WX 554 ; N numbersign ; B 71 0 620 740 ;
+C 36 ; WX 554 ; N dollar ; B 107 -70 581 811 ;
+C 37 ; WX 775 ; N percent ; B 124 -13 787 751 ;
+C 38 ; WX 757 ; N ampersand ; B 92 -12 775 753 ;
+C 39 ; WX 351 ; N quoteright ; B 195 546 393 740 ;
+C 40 ; WX 369 ; N parenleft ; B 89 -205 495 757 ;
+C 41 ; WX 369 ; N parenright ; B -24 -205 382 757 ;
+C 42 ; WX 425 ; N asterisk ; B 170 446 479 740 ;
+C 43 ; WX 606 ; N plus ; B 92 0 608 506 ;
+C 44 ; WX 277 ; N comma ; B 2 -67 199 126 ;
+C 45 ; WX 332 ; N hyphen ; B 76 248 360 315 ;
+C 46 ; WX 277 ; N period ; B 102 0 199 126 ;
+C 47 ; WX 437 ; N slash ; B 25 -100 540 740 ;
+C 48 ; WX 554 ; N zero ; B 71 -13 622 753 ;
+C 49 ; WX 554 ; N one ; B 260 0 473 740 ;
+C 50 ; WX 554 ; N two ; B 40 0 615 753 ;
+C 51 ; WX 554 ; N three ; B 73 -13 565 753 ;
+C 52 ; WX 554 ; N four ; B 39 0 598 740 ;
+C 53 ; WX 554 ; N five ; B 69 -13 605 740 ;
+C 54 ; WX 554 ; N six ; B 65 -13 580 739 ;
+C 55 ; WX 554 ; N seven ; B 110 0 628 740 ;
+C 56 ; WX 554 ; N eight ; B 77 -13 580 753 ;
+C 57 ; WX 554 ; N nine ; B 111 0 626 752 ;
+C 58 ; WX 277 ; N colon ; B 102 0 278 548 ;
+C 59 ; WX 277 ; N semicolon ; B 2 -67 278 548 ;
+C 60 ; WX 606 ; N less ; B 87 -8 649 514 ;
+C 61 ; WX 606 ; N equal ; B 73 118 627 388 ;
+C 62 ; WX 606 ; N greater ; B 51 -8 613 514 ;
+C 63 ; WX 591 ; N question ; B 158 0 628 752 ;
+C 64 ; WX 867 ; N at ; B 126 -13 888 753 ;
+C 65 ; WX 740 ; N A ; B 12 0 729 740 ;
+C 66 ; WX 574 ; N B ; B 74 0 606 740 ;
+C 67 ; WX 813 ; N C ; B 105 -13 870 752 ;
+C 68 ; WX 744 ; N D ; B 74 0 773 740 ;
+C 69 ; WX 536 ; N E ; B 70 0 612 740 ;
+C 70 ; WX 485 ; N F ; B 70 0 581 740 ;
+C 71 ; WX 872 ; N G ; B 103 -13 891 753 ;
+C 72 ; WX 683 ; N H ; B 76 0 744 740 ;
+C 73 ; WX 226 ; N I ; B 76 0 287 740 ;
+C 74 ; WX 482 ; N J ; B 37 -13 539 740 ;
+C 75 ; WX 591 ; N K ; B 81 0 728 740 ;
+C 76 ; WX 462 ; N L ; B 82 0 474 740 ;
+C 77 ; WX 919 ; N M ; B 76 0 980 740 ;
+C 78 ; WX 740 ; N N ; B 75 0 801 740 ;
+C 79 ; WX 869 ; N O ; B 105 -13 901 753 ;
+C 80 ; WX 592 ; N P ; B 75 0 664 740 ;
+C 81 ; WX 871 ; N Q ; B 102 -13 912 753 ;
+C 82 ; WX 607 ; N R ; B 70 0 669 740 ;
+C 83 ; WX 498 ; N S ; B 57 -13 561 753 ;
+C 84 ; WX 426 ; N T ; B 131 0 556 740 ;
+C 85 ; WX 655 ; N U ; B 118 -13 716 740 ;
+C 86 ; WX 702 ; N V ; B 145 0 830 740 ;
+C 87 ; WX 960 ; N W ; B 148 0 1087 740 ;
+C 88 ; WX 609 ; N X ; B 8 0 724 740 ;
+C 89 ; WX 592 ; N Y ; B 138 0 729 740 ;
+C 90 ; WX 480 ; N Z ; B 12 0 596 740 ;
+C 91 ; WX 351 ; N bracketleft ; B 145 -179 477 753 ;
+C 92 ; WX 605 ; N backslash ; B 255 -100 458 740 ;
+C 93 ; WX 351 ; N bracketright ; B -19 -179 312 753 ;
+C 94 ; WX 606 ; N asciicircum ; B 110 307 610 740 ;
+C 95 ; WX 500 ; N underscore ; B -23 -125 486 -75 ;
+C 96 ; WX 351 ; N quoteleft ; B 232 546 358 740 ;
+C 97 ; WX 683 ; N a ; B 88 -13 722 561 ;
+C 98 ; WX 682 ; N b ; B 68 -13 703 740 ;
+C 99 ; WX 647 ; N c ; B 87 -13 678 561 ;
+C 100 ; WX 685 ; N d ; B 85 -13 755 740 ;
+C 101 ; WX 650 ; N e ; B 84 -13 664 561 ;
+C 102 ; WX 314 ; N f ; B 104 0 454 753 ; L i fi ; L l fl ;
+C 103 ; WX 673 ; N g ; B 56 -215 707 561 ;
+C 104 ; WX 610 ; N h ; B 62 0 606 740 ;
+C 105 ; WX 200 ; N i ; B 65 0 272 740 ;
+C 106 ; WX 203 ; N j ; B -80 -192 274 740 ;
+C 107 ; WX 502 ; N k ; B 70 0 588 740 ;
+C 108 ; WX 200 ; N l ; B 65 0 272 740 ;
+C 109 ; WX 938 ; N m ; B 66 0 938 561 ;
+C 110 ; WX 610 ; N n ; B 65 0 609 561 ;
+C 111 ; WX 655 ; N o ; B 88 -13 669 561 ;
+C 112 ; WX 682 ; N p ; B 28 -192 699 561 ;
+C 113 ; WX 682 ; N q ; B 83 -192 717 561 ;
+C 114 ; WX 301 ; N r ; B 65 0 395 561 ;
+C 115 ; WX 388 ; N s ; B 49 -13 424 561 ;
+C 116 ; WX 339 ; N t ; B 104 0 431 740 ;
+C 117 ; WX 608 ; N u ; B 100 -13 642 547 ;
+C 118 ; WX 554 ; N v ; B 108 0 647 547 ;
+C 119 ; WX 831 ; N w ; B 114 0 921 547 ;
+C 120 ; WX 480 ; N x ; B 12 0 569 547 ;
+C 121 ; WX 536 ; N y ; B 97 -192 624 547 ;
+C 122 ; WX 425 ; N z ; B 10 0 498 547 ;
+C 123 ; WX 351 ; N braceleft ; B 115 -189 468 740 ;
+C 124 ; WX 672 ; N bar ; B 280 -100 510 740 ;
+C 125 ; WX 351 ; N braceright ; B -15 -189 338 740 ;
+C 126 ; WX 606 ; N asciitilde ; B 114 179 584 319 ;
+C 161 ; WX 295 ; N exclamdown ; B 74 -192 286 548 ;
+C 162 ; WX 554 ; N cent ; B 115 62 596 707 ;
+C 163 ; WX 554 ; N sterling ; B 29 0 614 753 ;
+C 164 ; WX 166 ; N fraction ; B -113 0 417 740 ;
+C 165 ; WX 554 ; N yen ; B 75 0 687 740 ;
+C 166 ; WX 554 ; N florin ; B -39 -153 669 818 ;
+C 167 ; WX 615 ; N section ; B 118 -141 597 753 ;
+C 168 ; WX 554 ; N currency ; B 24 42 645 580 ;
+C 169 ; WX 198 ; N quotesingle ; B 153 444 277 740 ;
+C 170 ; WX 502 ; N quotedblleft ; B 234 546 507 740 ;
+C 171 ; WX 425 ; N guillemotleft ; B 92 81 469 481 ;
+C 172 ; WX 251 ; N guilsinglleft ; B 92 81 295 481 ;
+C 173 ; WX 251 ; N guilsinglright ; B 60 81 263 481 ;
+C 174 ; WX 487 ; N fi ; B 104 0 559 753 ;
+C 175 ; WX 485 ; N fl ; B 104 0 557 753 ;
+C 177 ; WX 500 ; N endash ; B 81 248 523 315 ;
+C 178 ; WX 553 ; N dagger ; B 146 -133 593 740 ;
+C 179 ; WX 553 ; N daggerdbl ; B 72 -133 593 740 ;
+C 180 ; WX 277 ; N periodcentered ; B 137 190 235 316 ;
+C 182 ; WX 564 ; N paragraph ; B 119 -110 688 740 ;
+C 183 ; WX 606 ; N bullet ; B 217 222 528 532 ;
+C 184 ; WX 354 ; N quotesinglbase ; B 76 -68 274 126 ;
+C 185 ; WX 502 ; N quotedblbase ; B 76 -68 422 126 ;
+C 186 ; WX 484 ; N quotedblright ; B 197 546 542 740 ;
+C 187 ; WX 425 ; N guillemotright ; B 60 81 437 481 ;
+C 188 ; WX 1000 ; N ellipsis ; B 130 0 893 126 ;
+C 189 ; WX 1174 ; N perthousand ; B 128 -13 1182 751 ;
+C 191 ; WX 591 ; N questiondown ; B 64 -205 534 548 ;
+C 193 ; WX 378 ; N grave ; B 204 619 425 786 ;
+C 194 ; WX 375 ; N acute ; B 203 619 444 786 ;
+C 195 ; WX 502 ; N circumflex ; B 192 639 546 764 ;
+C 196 ; WX 439 ; N tilde ; B 179 651 520 754 ;
+C 197 ; WX 485 ; N macron ; B 197 669 547 736 ;
+C 198 ; WX 453 ; N breve ; B 192 651 541 754 ;
+C 199 ; WX 222 ; N dotaccent ; B 192 639 290 765 ;
+C 200 ; WX 369 ; N dieresis ; B 191 639 437 765 ;
+C 202 ; WX 332 ; N ring ; B 191 600 401 807 ;
+C 203 ; WX 324 ; N cedilla ; B 52 -222 231 0 ;
+C 205 ; WX 552 ; N hungarumlaut ; B 239 605 594 800 ;
+C 206 ; WX 302 ; N ogonek ; B 53 -191 202 0 ;
+C 207 ; WX 502 ; N caron ; B 210 639 565 764 ;
+C 208 ; WX 1000 ; N emdash ; B 81 248 1023 315 ;
+C 225 ; WX 992 ; N AE ; B -20 0 1044 740 ;
+C 227 ; WX 369 ; N ordfeminine ; B 102 407 494 753 ;
+C 232 ; WX 517 ; N Lslash ; B 107 0 529 740 ;
+C 233 ; WX 868 ; N Oslash ; B 76 -83 929 819 ;
+C 234 ; WX 1194 ; N OE ; B 107 -13 1279 753 ;
+C 235 ; WX 369 ; N ordmasculine ; B 116 407 466 753 ;
+C 241 ; WX 1157 ; N ae ; B 80 -13 1169 561 ;
+C 245 ; WX 200 ; N dotlessi ; B 65 0 236 547 ;
+C 248 ; WX 300 ; N lslash ; B 95 0 354 740 ;
+C 249 ; WX 653 ; N oslash ; B 51 -64 703 614 ;
+C 250 ; WX 1137 ; N oe ; B 80 -13 1160 561 ;
+C 251 ; WX 554 ; N germandbls ; B 61 -13 578 753 ;
+C -1 ; WX 650 ; N ecircumflex ; B 84 -13 664 764 ;
+C -1 ; WX 650 ; N edieresis ; B 84 -13 664 765 ;
+C -1 ; WX 683 ; N aacute ; B 88 -13 722 786 ;
+C -1 ; WX 747 ; N registered ; B 53 -12 830 752 ;
+C -1 ; WX 200 ; N icircumflex ; B 41 0 395 764 ;
+C -1 ; WX 608 ; N udieresis ; B 100 -13 642 765 ;
+C -1 ; WX 655 ; N ograve ; B 88 -13 669 786 ;
+C -1 ; WX 608 ; N uacute ; B 100 -13 642 786 ;
+C -1 ; WX 608 ; N ucircumflex ; B 100 -13 642 764 ;
+C -1 ; WX 740 ; N Aacute ; B 12 0 729 949 ;
+C -1 ; WX 200 ; N igrave ; B 65 0 296 786 ;
+C -1 ; WX 226 ; N Icircumflex ; B 76 0 439 927 ;
+C -1 ; WX 647 ; N ccedilla ; B 87 -222 678 561 ;
+C -1 ; WX 683 ; N adieresis ; B 88 -13 722 765 ;
+C -1 ; WX 536 ; N Ecircumflex ; B 70 0 612 927 ;
+C -1 ; WX 388 ; N scaron ; B 49 -13 508 764 ;
+C -1 ; WX 682 ; N thorn ; B 28 -192 699 740 ;
+C -1 ; WX 1000 ; N trademark ; B 137 296 953 740 ;
+C -1 ; WX 650 ; N egrave ; B 84 -13 664 786 ;
+C -1 ; WX 332 ; N threesuperior ; B 98 289 408 747 ;
+C -1 ; WX 425 ; N zcaron ; B 10 0 527 764 ;
+C -1 ; WX 683 ; N atilde ; B 88 -13 722 754 ;
+C -1 ; WX 683 ; N aring ; B 88 -13 722 807 ;
+C -1 ; WX 655 ; N ocircumflex ; B 88 -13 669 764 ;
+C -1 ; WX 536 ; N Edieresis ; B 70 0 612 928 ;
+C -1 ; WX 831 ; N threequarters ; B 126 0 825 747 ;
+C -1 ; WX 536 ; N ydieresis ; B 97 -192 624 765 ;
+C -1 ; WX 536 ; N yacute ; B 97 -192 624 786 ;
+C -1 ; WX 200 ; N iacute ; B 65 0 397 786 ;
+C -1 ; WX 740 ; N Acircumflex ; B 12 0 729 927 ;
+C -1 ; WX 655 ; N Uacute ; B 118 -13 716 949 ;
+C -1 ; WX 650 ; N eacute ; B 84 -13 664 786 ;
+C -1 ; WX 869 ; N Ograve ; B 105 -13 901 949 ;
+C -1 ; WX 683 ; N agrave ; B 88 -13 722 786 ;
+C -1 ; WX 655 ; N Udieresis ; B 118 -13 716 928 ;
+C -1 ; WX 683 ; N acircumflex ; B 88 -13 722 764 ;
+C -1 ; WX 226 ; N Igrave ; B 76 0 340 949 ;
+C -1 ; WX 332 ; N twosuperior ; B 74 296 433 747 ;
+C -1 ; WX 655 ; N Ugrave ; B 118 -13 716 949 ;
+C -1 ; WX 831 ; N onequarter ; B 183 0 770 740 ;
+C -1 ; WX 655 ; N Ucircumflex ; B 118 -13 716 927 ;
+C -1 ; WX 498 ; N Scaron ; B 57 -13 593 927 ;
+C -1 ; WX 226 ; N Idieresis ; B 76 0 396 928 ;
+C -1 ; WX 200 ; N idieresis ; B 65 0 353 765 ;
+C -1 ; WX 536 ; N Egrave ; B 70 0 612 949 ;
+C -1 ; WX 869 ; N Oacute ; B 105 -13 901 949 ;
+C -1 ; WX 606 ; N divide ; B 92 -13 608 519 ;
+C -1 ; WX 740 ; N Atilde ; B 12 0 729 917 ;
+C -1 ; WX 740 ; N Aring ; B 12 0 729 955 ;
+C -1 ; WX 869 ; N Odieresis ; B 105 -13 901 928 ;
+C -1 ; WX 740 ; N Adieresis ; B 12 0 729 928 ;
+C -1 ; WX 740 ; N Ntilde ; B 75 0 801 917 ;
+C -1 ; WX 480 ; N Zcaron ; B 12 0 596 927 ;
+C -1 ; WX 592 ; N Thorn ; B 60 0 621 740 ;
+C -1 ; WX 226 ; N Iacute ; B 76 0 440 949 ;
+C -1 ; WX 606 ; N plusminus ; B 47 -24 618 518 ;
+C -1 ; WX 606 ; N multiply ; B 87 24 612 482 ;
+C -1 ; WX 536 ; N Eacute ; B 70 0 612 949 ;
+C -1 ; WX 592 ; N Ydieresis ; B 138 0 729 928 ;
+C -1 ; WX 332 ; N onesuperior ; B 190 296 335 740 ;
+C -1 ; WX 608 ; N ugrave ; B 100 -13 642 786 ;
+C -1 ; WX 606 ; N logicalnot ; B 110 109 627 388 ;
+C -1 ; WX 610 ; N ntilde ; B 65 0 609 754 ;
+C -1 ; WX 869 ; N Otilde ; B 105 -13 901 917 ;
+C -1 ; WX 655 ; N otilde ; B 88 -13 669 754 ;
+C -1 ; WX 813 ; N Ccedilla ; B 105 -222 870 752 ;
+C -1 ; WX 740 ; N Agrave ; B 12 0 729 949 ;
+C -1 ; WX 831 ; N onehalf ; B 164 0 810 740 ;
+C -1 ; WX 790 ; N Eth ; B 104 0 813 740 ;
+C -1 ; WX 400 ; N degree ; B 158 421 451 709 ;
+C -1 ; WX 592 ; N Yacute ; B 138 0 729 949 ;
+C -1 ; WX 869 ; N Ocircumflex ; B 105 -13 901 927 ;
+C -1 ; WX 655 ; N oacute ; B 88 -13 669 786 ;
+C -1 ; WX 608 ; N mu ; B 46 -184 628 547 ;
+C -1 ; WX 606 ; N minus ; B 92 219 608 287 ;
+C -1 ; WX 655 ; N eth ; B 88 -12 675 753 ;
+C -1 ; WX 655 ; N odieresis ; B 88 -13 669 765 ;
+C -1 ; WX 747 ; N copyright ; B 53 -12 830 752 ;
+C -1 ; WX 672 ; N brokenbar ; B 280 -100 510 740 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 216
+
+KPX A y -62
+KPX A w -65
+KPX A v -70
+KPX A u -20
+KPX A quoteright -100
+KPX A quotedblright -100
+KPX A Y -92
+KPX A W -60
+KPX A V -102
+KPX A U -40
+KPX A T -45
+KPX A Q -40
+KPX A O -50
+KPX A G -40
+KPX A C -40
+
+KPX B A -10
+
+KPX C A -40
+
+KPX D period -20
+KPX D comma -20
+KPX D Y -30
+KPX D W -10
+KPX D V -50
+KPX D A -50
+
+KPX F period -160
+KPX F e -20
+KPX F comma -180
+KPX F a -20
+KPX F A -75
+
+KPX G period -20
+KPX G comma -20
+KPX G Y -20
+
+KPX J period -15
+KPX J a -20
+KPX J A -30
+
+KPX K o -15
+KPX K e -20
+KPX K O -20
+
+KPX L y -23
+KPX L quoteright -130
+KPX L quotedblright -130
+KPX L Y -91
+KPX L W -67
+KPX L V -113
+KPX L T -46
+
+KPX O period -30
+KPX O comma -30
+KPX O Y -30
+KPX O X -30
+KPX O W -20
+KPX O V -60
+KPX O T -30
+KPX O A -60
+
+KPX P period -300
+KPX P o -60
+KPX P e -20
+KPX P comma -280
+KPX P a -20
+KPX P A -114
+
+KPX Q comma 20
+
+KPX R Y -10
+KPX R W 10
+KPX R V -10
+KPX R T 6
+
+KPX S comma 20
+
+KPX T y -50
+KPX T w -55
+KPX T u -46
+KPX T semicolon -29
+KPX T r -30
+KPX T period -91
+KPX T o -70
+KPX T i 10
+KPX T hyphen -75
+KPX T e -49
+KPX T comma -82
+KPX T colon -15
+KPX T a -90
+KPX T O -30
+KPX T A -45
+
+KPX U period -20
+KPX U comma -20
+KPX U A -40
+
+KPX V u -40
+KPX V semicolon -33
+KPX V period -165
+KPX V o -101
+KPX V i -5
+KPX V hyphen -75
+KPX V e -101
+KPX V comma -145
+KPX V colon -18
+KPX V a -104
+KPX V O -60
+KPX V G -20
+KPX V A -102
+
+KPX W y -2
+KPX W u -30
+KPX W semicolon -33
+KPX W period -106
+KPX W o -46
+KPX W i 6
+KPX W hyphen -35
+KPX W e -47
+KPX W comma -106
+KPX W colon -15
+KPX W a -50
+KPX W O -20
+KPX W A -58
+
+KPX Y u -52
+KPX Y semicolon -23
+KPX Y period -175
+KPX Y o -89
+KPX Y hyphen -85
+KPX Y e -89
+KPX Y comma -145
+KPX Y colon -10
+KPX Y a -93
+KPX Y O -30
+KPX Y A -92
+
+KPX a p 20
+KPX a b 20
+
+KPX b y -20
+KPX b v -20
+
+KPX c y -20
+KPX c k -15
+
+KPX comma space -110
+KPX comma quoteright -120
+KPX comma quotedblright -120
+
+KPX e y -20
+KPX e w -20
+KPX e v -20
+
+KPX f period -50
+KPX f o -40
+KPX f l -30
+KPX f i -34
+KPX f f -60
+KPX f e -20
+KPX f dotlessi -34
+KPX f comma -50
+KPX f a -40
+
+KPX g a -15
+
+KPX h y -30
+
+KPX k y -5
+KPX k e -15
+
+KPX m y -20
+KPX m u -20
+KPX m a -20
+
+KPX n y -15
+KPX n v -20
+
+KPX o y -20
+KPX o x -15
+KPX o w -20
+KPX o v -30
+
+KPX p y -20
+
+KPX period space -110
+KPX period quoteright -120
+KPX period quotedblright -120
+
+KPX quotedblleft quoteleft -35
+KPX quotedblleft A -100
+
+KPX quotedblright space -110
+
+KPX quoteleft quoteleft -203
+KPX quoteleft A -100
+
+KPX quoteright v -30
+KPX quoteright t 10
+KPX quoteright space -110
+KPX quoteright s -15
+KPX quoteright r -20
+KPX quoteright quoteright -203
+KPX quoteright quotedblright -35
+KPX quoteright d -110
+
+KPX r y 40
+KPX r v 40
+KPX r u 20
+KPX r t 20
+KPX r s 20
+KPX r q -8
+KPX r period -73
+KPX r p 20
+KPX r o -20
+KPX r n 21
+KPX r m 28
+KPX r l 20
+KPX r k 20
+KPX r i 20
+KPX r hyphen -60
+KPX r g -15
+KPX r e -4
+KPX r d -6
+KPX r comma -75
+KPX r c -20
+KPX r a -20
+
+KPX s period 20
+KPX s comma 20
+
+KPX space quoteleft -110
+KPX space quotedblleft -110
+KPX space Y -60
+KPX space W -25
+KPX space V -50
+KPX space T -25
+KPX space A -20
+
+KPX v period -130
+KPX v o -30
+KPX v e -20
+KPX v comma -100
+KPX v a -30
+
+KPX w period -100
+KPX w o -30
+KPX w h 15
+KPX w e -20
+KPX w comma -90
+KPX w a -30
+
+KPX y period -125
+KPX y o -30
+KPX y e -20
+KPX y comma -110
+KPX y a -30
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 213 163 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 149 163 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 216 163 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 211 163 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 231 148 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 181 163 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 111 163 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 47 163 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 114 163 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 109 163 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -4 163 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -108 163 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -41 163 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -86 163 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 181 163 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 277 163 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 214 163 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 280 163 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 276 163 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 245 163 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 28 163 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 190 163 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 107 163 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 173 163 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 149 163 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 159 163 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 142 163 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 19 163 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 154 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 91 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 157 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 153 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 176 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 122 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 138 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 74 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 141 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 136 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -151 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -84 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -129 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 86 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 140 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 77 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 143 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 108 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron -57 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 137 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 53 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 120 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 95 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 101 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron -38 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/AvantGarde-Demi.afm b/tlt3.0/library/afm/AvantGarde-Demi.afm
new file mode 100644
index 0000000..6f96912
--- /dev/null
+++ b/tlt3.0/library/afm/AvantGarde-Demi.afm
@@ -0,0 +1,577 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Mon Mar  4 13:46:34 1991
+Comment UniqueID 34370
+Comment VMusage 24954 31846
+FontName AvantGarde-Demi
+FullName ITC Avant Garde Gothic Demi
+FamilyName ITC Avant Garde Gothic
+Weight Demi
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -123 -251 1222 1021
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated.  All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation.
+EncodingScheme AdobeStandardEncoding
+CapHeight 740
+XHeight 555
+Ascender 740
+Descender -185
+StartCharMetrics 228
+C 32 ; WX 280 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 280 ; N exclam ; B 73 0 206 740 ;
+C 34 ; WX 360 ; N quotedbl ; B 19 444 341 740 ;
+C 35 ; WX 560 ; N numbersign ; B 29 0 525 700 ;
+C 36 ; WX 560 ; N dollar ; B 58 -86 501 857 ;
+C 37 ; WX 860 ; N percent ; B 36 -15 822 755 ;
+C 38 ; WX 680 ; N ampersand ; B 34 -15 665 755 ;
+C 39 ; WX 280 ; N quoteright ; B 72 466 205 740 ;
+C 40 ; WX 380 ; N parenleft ; B 74 -157 350 754 ;
+C 41 ; WX 380 ; N parenright ; B 37 -157 313 754 ;
+C 42 ; WX 440 ; N asterisk ; B 67 457 374 755 ;
+C 43 ; WX 600 ; N plus ; B 48 0 552 506 ;
+C 44 ; WX 280 ; N comma ; B 73 -141 206 133 ;
+C 45 ; WX 420 ; N hyphen ; B 71 230 349 348 ;
+C 46 ; WX 280 ; N period ; B 73 0 206 133 ;
+C 47 ; WX 460 ; N slash ; B 6 -100 454 740 ;
+C 48 ; WX 560 ; N zero ; B 32 -15 529 755 ;
+C 49 ; WX 560 ; N one ; B 137 0 363 740 ;
+C 50 ; WX 560 ; N two ; B 36 0 523 755 ;
+C 51 ; WX 560 ; N three ; B 28 -15 532 755 ;
+C 52 ; WX 560 ; N four ; B 15 0 545 740 ;
+C 53 ; WX 560 ; N five ; B 25 -15 535 740 ;
+C 54 ; WX 560 ; N six ; B 23 -15 536 739 ;
+C 55 ; WX 560 ; N seven ; B 62 0 498 740 ;
+C 56 ; WX 560 ; N eight ; B 33 -15 527 755 ;
+C 57 ; WX 560 ; N nine ; B 24 0 537 754 ;
+C 58 ; WX 280 ; N colon ; B 73 0 206 555 ;
+C 59 ; WX 280 ; N semicolon ; B 73 -141 206 555 ;
+C 60 ; WX 600 ; N less ; B 46 -8 554 514 ;
+C 61 ; WX 600 ; N equal ; B 48 81 552 425 ;
+C 62 ; WX 600 ; N greater ; B 46 -8 554 514 ;
+C 63 ; WX 560 ; N question ; B 38 0 491 755 ;
+C 64 ; WX 740 ; N at ; B 50 -12 750 712 ;
+C 65 ; WX 740 ; N A ; B 7 0 732 740 ;
+C 66 ; WX 580 ; N B ; B 70 0 551 740 ;
+C 67 ; WX 780 ; N C ; B 34 -15 766 755 ;
+C 68 ; WX 700 ; N D ; B 63 0 657 740 ;
+C 69 ; WX 520 ; N E ; B 61 0 459 740 ;
+C 70 ; WX 480 ; N F ; B 61 0 438 740 ;
+C 71 ; WX 840 ; N G ; B 27 -15 817 755 ;
+C 72 ; WX 680 ; N H ; B 71 0 610 740 ;
+C 73 ; WX 280 ; N I ; B 72 0 209 740 ;
+C 74 ; WX 480 ; N J ; B 2 -15 409 740 ;
+C 75 ; WX 620 ; N K ; B 89 0 620 740 ;
+C 76 ; WX 440 ; N L ; B 72 0 435 740 ;
+C 77 ; WX 900 ; N M ; B 63 0 837 740 ;
+C 78 ; WX 740 ; N N ; B 70 0 671 740 ;
+C 79 ; WX 840 ; N O ; B 33 -15 807 755 ;
+C 80 ; WX 560 ; N P ; B 72 0 545 740 ;
+C 81 ; WX 840 ; N Q ; B 32 -15 824 755 ;
+C 82 ; WX 580 ; N R ; B 64 0 565 740 ;
+C 83 ; WX 520 ; N S ; B 12 -15 493 755 ;
+C 84 ; WX 420 ; N T ; B 6 0 418 740 ;
+C 85 ; WX 640 ; N U ; B 55 -15 585 740 ;
+C 86 ; WX 700 ; N V ; B 8 0 695 740 ;
+C 87 ; WX 900 ; N W ; B 7 0 899 740 ;
+C 88 ; WX 680 ; N X ; B 4 0 676 740 ;
+C 89 ; WX 620 ; N Y ; B -2 0 622 740 ;
+C 90 ; WX 500 ; N Z ; B 19 0 481 740 ;
+C 91 ; WX 320 ; N bracketleft ; B 66 -157 284 754 ;
+C 92 ; WX 640 ; N backslash ; B 96 -100 544 740 ;
+C 93 ; WX 320 ; N bracketright ; B 36 -157 254 754 ;
+C 94 ; WX 600 ; N asciicircum ; B 73 375 527 740 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 280 ; N quoteleft ; B 72 466 205 740 ;
+C 97 ; WX 660 ; N a ; B 27 -18 613 574 ;
+C 98 ; WX 660 ; N b ; B 47 -18 632 740 ;
+C 99 ; WX 640 ; N c ; B 37 -18 610 574 ;
+C 100 ; WX 660 ; N d ; B 34 -18 618 740 ;
+C 101 ; WX 640 ; N e ; B 31 -18 610 577 ;
+C 102 ; WX 280 ; N f ; B 15 0 280 755 ; L i fi ; L l fl ;
+C 103 ; WX 660 ; N g ; B 32 -226 623 574 ;
+C 104 ; WX 600 ; N h ; B 54 0 546 740 ;
+C 105 ; WX 240 ; N i ; B 53 0 186 740 ;
+C 106 ; WX 260 ; N j ; B 16 -185 205 740 ;
+C 107 ; WX 580 ; N k ; B 80 0 571 740 ;
+C 108 ; WX 240 ; N l ; B 54 0 187 740 ;
+C 109 ; WX 940 ; N m ; B 54 0 887 574 ;
+C 110 ; WX 600 ; N n ; B 54 0 547 574 ;
+C 111 ; WX 640 ; N o ; B 25 -18 615 574 ;
+C 112 ; WX 660 ; N p ; B 47 -185 629 574 ;
+C 113 ; WX 660 ; N q ; B 31 -185 613 574 ;
+C 114 ; WX 320 ; N r ; B 63 0 317 574 ;
+C 115 ; WX 440 ; N s ; B 19 -18 421 574 ;
+C 116 ; WX 300 ; N t ; B 21 0 299 740 ;
+C 117 ; WX 600 ; N u ; B 50 -18 544 555 ;
+C 118 ; WX 560 ; N v ; B 3 0 556 555 ;
+C 119 ; WX 800 ; N w ; B 11 0 789 555 ;
+C 120 ; WX 560 ; N x ; B 3 0 556 555 ;
+C 121 ; WX 580 ; N y ; B 8 -185 571 555 ;
+C 122 ; WX 460 ; N z ; B 20 0 442 555 ;
+C 123 ; WX 340 ; N braceleft ; B -3 -191 317 747 ;
+C 124 ; WX 600 ; N bar ; B 233 -100 366 740 ;
+C 125 ; WX 340 ; N braceright ; B 23 -191 343 747 ;
+C 126 ; WX 600 ; N asciitilde ; B 67 160 533 347 ;
+C 161 ; WX 280 ; N exclamdown ; B 74 -185 207 555 ;
+C 162 ; WX 560 ; N cent ; B 43 39 517 715 ;
+C 163 ; WX 560 ; N sterling ; B -2 0 562 755 ;
+C 164 ; WX 160 ; N fraction ; B -123 0 282 740 ;
+C 165 ; WX 560 ; N yen ; B -10 0 570 740 ;
+C 166 ; WX 560 ; N florin ; B 0 -151 512 824 ;
+C 167 ; WX 560 ; N section ; B 28 -158 530 755 ;
+C 168 ; WX 560 ; N currency ; B 27 69 534 577 ;
+C 169 ; WX 220 ; N quotesingle ; B 44 444 177 740 ;
+C 170 ; WX 480 ; N quotedblleft ; B 70 466 410 740 ;
+C 171 ; WX 460 ; N guillemotleft ; B 61 108 400 469 ;
+C 172 ; WX 240 ; N guilsinglleft ; B 50 108 190 469 ;
+C 173 ; WX 240 ; N guilsinglright ; B 50 108 190 469 ;
+C 174 ; WX 520 ; N fi ; B 25 0 461 755 ;
+C 175 ; WX 520 ; N fl ; B 25 0 461 755 ;
+C 177 ; WX 500 ; N endash ; B 35 230 465 348 ;
+C 178 ; WX 560 ; N dagger ; B 51 -142 509 740 ;
+C 179 ; WX 560 ; N daggerdbl ; B 51 -142 509 740 ;
+C 180 ; WX 280 ; N periodcentered ; B 73 187 206 320 ;
+C 182 ; WX 600 ; N paragraph ; B -7 -103 607 740 ;
+C 183 ; WX 600 ; N bullet ; B 148 222 453 532 ;
+C 184 ; WX 280 ; N quotesinglbase ; B 72 -141 205 133 ;
+C 185 ; WX 480 ; N quotedblbase ; B 70 -141 410 133 ;
+C 186 ; WX 480 ; N quotedblright ; B 70 466 410 740 ;
+C 187 ; WX 460 ; N guillemotright ; B 61 108 400 469 ;
+C 188 ; WX 1000 ; N ellipsis ; B 100 0 899 133 ;
+C 189 ; WX 1280 ; N perthousand ; B 36 -15 1222 755 ;
+C 191 ; WX 560 ; N questiondown ; B 68 -200 521 555 ;
+C 193 ; WX 420 ; N grave ; B 50 624 329 851 ;
+C 194 ; WX 420 ; N acute ; B 91 624 370 849 ;
+C 195 ; WX 540 ; N circumflex ; B 71 636 470 774 ;
+C 196 ; WX 480 ; N tilde ; B 44 636 437 767 ;
+C 197 ; WX 420 ; N macron ; B 72 648 349 759 ;
+C 198 ; WX 480 ; N breve ; B 42 633 439 770 ;
+C 199 ; WX 280 ; N dotaccent ; B 74 636 207 769 ;
+C 200 ; WX 500 ; N dieresis ; B 78 636 422 769 ;
+C 202 ; WX 360 ; N ring ; B 73 619 288 834 ;
+C 203 ; WX 340 ; N cedilla ; B 98 -251 298 6 ;
+C 205 ; WX 700 ; N hungarumlaut ; B 132 610 609 862 ;
+C 206 ; WX 340 ; N ogonek ; B 79 -195 262 9 ;
+C 207 ; WX 540 ; N caron ; B 71 636 470 774 ;
+C 208 ; WX 1000 ; N emdash ; B 35 230 965 348 ;
+C 225 ; WX 900 ; N AE ; B -5 0 824 740 ;
+C 227 ; WX 360 ; N ordfeminine ; B 19 438 334 755 ;
+C 232 ; WX 480 ; N Lslash ; B 26 0 460 740 ;
+C 233 ; WX 840 ; N Oslash ; B 33 -71 807 814 ;
+C 234 ; WX 1060 ; N OE ; B 37 -15 1007 755 ;
+C 235 ; WX 360 ; N ordmasculine ; B 23 438 338 755 ;
+C 241 ; WX 1080 ; N ae ; B 29 -18 1048 574 ;
+C 245 ; WX 240 ; N dotlessi ; B 53 0 186 555 ;
+C 248 ; WX 320 ; N lslash ; B 34 0 305 740 ;
+C 249 ; WX 660 ; N oslash ; B 35 -50 625 608 ;
+C 250 ; WX 1080 ; N oe ; B 30 -18 1050 574 ;
+C 251 ; WX 600 ; N germandbls ; B 51 -18 585 755 ;
+C -1 ; WX 640 ; N ecircumflex ; B 31 -18 610 774 ;
+C -1 ; WX 640 ; N edieresis ; B 31 -18 610 769 ;
+C -1 ; WX 660 ; N aacute ; B 27 -18 613 849 ;
+C -1 ; WX 740 ; N registered ; B -12 -12 752 752 ;
+C -1 ; WX 240 ; N icircumflex ; B -79 0 320 774 ;
+C -1 ; WX 600 ; N udieresis ; B 50 -18 544 769 ;
+C -1 ; WX 640 ; N ograve ; B 25 -18 615 851 ;
+C -1 ; WX 600 ; N uacute ; B 50 -18 544 849 ;
+C -1 ; WX 600 ; N ucircumflex ; B 50 -18 544 774 ;
+C -1 ; WX 740 ; N Aacute ; B 7 0 732 1019 ;
+C -1 ; WX 240 ; N igrave ; B -65 0 214 851 ;
+C -1 ; WX 280 ; N Icircumflex ; B -59 0 340 944 ;
+C -1 ; WX 640 ; N ccedilla ; B 37 -251 610 574 ;
+C -1 ; WX 660 ; N adieresis ; B 27 -18 613 769 ;
+C -1 ; WX 520 ; N Ecircumflex ; B 61 0 460 944 ;
+C -1 ; WX 440 ; N scaron ; B 19 -18 421 774 ;
+C -1 ; WX 660 ; N thorn ; B 47 -185 629 740 ;
+C -1 ; WX 1000 ; N trademark ; B 9 296 821 740 ;
+C -1 ; WX 640 ; N egrave ; B 31 -18 610 851 ;
+C -1 ; WX 336 ; N threesuperior ; B 8 287 328 749 ;
+C -1 ; WX 460 ; N zcaron ; B 20 0 455 774 ;
+C -1 ; WX 660 ; N atilde ; B 27 -18 613 767 ;
+C -1 ; WX 660 ; N aring ; B 27 -18 613 834 ;
+C -1 ; WX 640 ; N ocircumflex ; B 25 -18 615 774 ;
+C -1 ; WX 520 ; N Edieresis ; B 61 0 459 939 ;
+C -1 ; WX 840 ; N threequarters ; B 18 0 803 749 ;
+C -1 ; WX 580 ; N ydieresis ; B 8 -185 571 769 ;
+C -1 ; WX 580 ; N yacute ; B 8 -185 571 849 ;
+C -1 ; WX 240 ; N iacute ; B 26 0 305 849 ;
+C -1 ; WX 740 ; N Acircumflex ; B 7 0 732 944 ;
+C -1 ; WX 640 ; N Uacute ; B 55 -15 585 1019 ;
+C -1 ; WX 640 ; N eacute ; B 31 -18 610 849 ;
+C -1 ; WX 840 ; N Ograve ; B 33 -15 807 1021 ;
+C -1 ; WX 660 ; N agrave ; B 27 -18 613 851 ;
+C -1 ; WX 640 ; N Udieresis ; B 55 -15 585 939 ;
+C -1 ; WX 660 ; N acircumflex ; B 27 -18 613 774 ;
+C -1 ; WX 280 ; N Igrave ; B -45 0 234 1021 ;
+C -1 ; WX 336 ; N twosuperior ; B 13 296 322 749 ;
+C -1 ; WX 640 ; N Ugrave ; B 55 -15 585 1021 ;
+C -1 ; WX 840 ; N onequarter ; B 92 0 746 740 ;
+C -1 ; WX 640 ; N Ucircumflex ; B 55 -15 585 944 ;
+C -1 ; WX 520 ; N Scaron ; B 12 -15 493 944 ;
+C -1 ; WX 280 ; N Idieresis ; B -32 0 312 939 ;
+C -1 ; WX 240 ; N idieresis ; B -52 0 292 769 ;
+C -1 ; WX 520 ; N Egrave ; B 61 0 459 1021 ;
+C -1 ; WX 840 ; N Oacute ; B 33 -15 807 1019 ;
+C -1 ; WX 600 ; N divide ; B 48 -20 552 526 ;
+C -1 ; WX 740 ; N Atilde ; B 7 0 732 937 ;
+C -1 ; WX 740 ; N Aring ; B 7 0 732 969 ;
+C -1 ; WX 840 ; N Odieresis ; B 33 -15 807 939 ;
+C -1 ; WX 740 ; N Adieresis ; B 7 0 732 939 ;
+C -1 ; WX 740 ; N Ntilde ; B 70 0 671 937 ;
+C -1 ; WX 500 ; N Zcaron ; B 19 0 481 944 ;
+C -1 ; WX 560 ; N Thorn ; B 72 0 545 740 ;
+C -1 ; WX 280 ; N Iacute ; B 46 0 325 1019 ;
+C -1 ; WX 600 ; N plusminus ; B 48 -62 552 556 ;
+C -1 ; WX 600 ; N multiply ; B 59 12 541 494 ;
+C -1 ; WX 520 ; N Eacute ; B 61 0 459 1019 ;
+C -1 ; WX 620 ; N Ydieresis ; B -2 0 622 939 ;
+C -1 ; WX 336 ; N onesuperior ; B 72 296 223 740 ;
+C -1 ; WX 600 ; N ugrave ; B 50 -18 544 851 ;
+C -1 ; WX 600 ; N logicalnot ; B 48 108 552 425 ;
+C -1 ; WX 600 ; N ntilde ; B 54 0 547 767 ;
+C -1 ; WX 840 ; N Otilde ; B 33 -15 807 937 ;
+C -1 ; WX 640 ; N otilde ; B 25 -18 615 767 ;
+C -1 ; WX 780 ; N Ccedilla ; B 34 -251 766 755 ;
+C -1 ; WX 740 ; N Agrave ; B 7 0 732 1021 ;
+C -1 ; WX 840 ; N onehalf ; B 62 0 771 740 ;
+C -1 ; WX 742 ; N Eth ; B 25 0 691 740 ;
+C -1 ; WX 400 ; N degree ; B 57 426 343 712 ;
+C -1 ; WX 620 ; N Yacute ; B -2 0 622 1019 ;
+C -1 ; WX 840 ; N Ocircumflex ; B 33 -15 807 944 ;
+C -1 ; WX 640 ; N oacute ; B 25 -18 615 849 ;
+C -1 ; WX 576 ; N mu ; B 38 -187 539 555 ;
+C -1 ; WX 600 ; N minus ; B 48 193 552 313 ;
+C -1 ; WX 640 ; N eth ; B 27 -18 616 754 ;
+C -1 ; WX 640 ; N odieresis ; B 25 -18 615 769 ;
+C -1 ; WX 740 ; N copyright ; B -12 -12 752 752 ;
+C -1 ; WX 600 ; N brokenbar ; B 233 -100 366 740 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 218
+
+KPX A y -50
+KPX A w -65
+KPX A v -70
+KPX A u -20
+KPX A quoteright -90
+KPX A Y -80
+KPX A W -60
+KPX A V -102
+KPX A U -40
+KPX A T -25
+KPX A Q -50
+KPX A O -50
+KPX A G -40
+KPX A C -40
+
+KPX B A -10
+
+KPX C A -40
+
+KPX D period -20
+KPX D comma -20
+KPX D Y -45
+KPX D W -25
+KPX D V -50
+KPX D A -50
+
+KPX F period -129
+KPX F e -20
+KPX F comma -162
+KPX F a -20
+KPX F A -75
+
+KPX G period -20
+KPX G comma -20
+KPX G Y -15
+
+KPX J period -15
+KPX J a -20
+KPX J A -30
+
+KPX K y -20
+KPX K u -15
+KPX K o -45
+KPX K e -40
+KPX K O -30
+
+KPX L y -23
+KPX L quoteright -30
+KPX L quotedblright -30
+KPX L Y -80
+KPX L W -55
+KPX L V -85
+KPX L T -46
+
+KPX O period -30
+KPX O comma -30
+KPX O Y -30
+KPX O X -30
+KPX O W -20
+KPX O V -45
+KPX O T -15
+KPX O A -60
+
+KPX P period -200
+KPX P o -20
+KPX P e -20
+KPX P comma -220
+KPX P a -20
+KPX P A -100
+
+KPX Q comma 20
+
+KPX R W 25
+KPX R V -10
+KPX R U 25
+KPX R T 40
+KPX R O 25
+
+KPX S comma 20
+
+KPX T y -10
+KPX T w -55
+KPX T u -46
+KPX T semicolon -29
+KPX T r -30
+KPX T period -91
+KPX T o -49
+KPX T hyphen -75
+KPX T e -49
+KPX T comma -82
+KPX T colon -15
+KPX T a -70
+KPX T O -15
+KPX T A -25
+
+KPX U period -20
+KPX U comma -20
+KPX U A -40
+
+KPX V u -55
+KPX V semicolon -33
+KPX V period -145
+KPX V o -101
+KPX V i -15
+KPX V hyphen -75
+KPX V e -101
+KPX V comma -145
+KPX V colon -18
+KPX V a -95
+KPX V O -45
+KPX V G -20
+KPX V A -102
+
+KPX W y -15
+KPX W u -30
+KPX W semicolon -33
+KPX W period -106
+KPX W o -46
+KPX W i -10
+KPX W hyphen -35
+KPX W e -47
+KPX W comma -106
+KPX W colon -15
+KPX W a -50
+KPX W O -20
+KPX W A -58
+
+KPX Y u -52
+KPX Y semicolon -23
+KPX Y period -145
+KPX Y o -89
+KPX Y hyphen -100
+KPX Y e -89
+KPX Y comma -145
+KPX Y colon -10
+KPX Y a -93
+KPX Y O -30
+KPX Y A -80
+
+KPX a t 5
+KPX a p 20
+KPX a b 5
+
+KPX b y -20
+KPX b v -20
+
+KPX c y -20
+KPX c l -15
+KPX c k -15
+
+KPX comma space -50
+KPX comma quoteright -70
+KPX comma quotedblright -70
+
+KPX e y -20
+KPX e x -20
+KPX e w -20
+KPX e v -20
+
+KPX f period -40
+KPX f o -20
+KPX f l -15
+KPX f i -15
+KPX f f -20
+KPX f dotlessi -15
+KPX f comma -40
+KPX f a -15
+
+KPX g i 25
+KPX g a 15
+
+KPX h y -30
+
+KPX k y -5
+KPX k o -30
+KPX k e -40
+
+KPX m y -20
+KPX m u -20
+
+KPX n y -15
+KPX n v -30
+
+KPX o y -20
+KPX o x -30
+KPX o w -20
+KPX o v -30
+
+KPX p y -20
+
+KPX period space -50
+KPX period quoteright -70
+KPX period quotedblright -70
+
+KPX quotedblleft A -50
+
+KPX quotedblright space -50
+
+KPX quoteleft quoteleft -80
+KPX quoteleft A -50
+
+KPX quoteright v -10
+KPX quoteright t 10
+KPX quoteright space -50
+KPX quoteright s -15
+KPX quoteright r -20
+KPX quoteright quoteright -80
+KPX quoteright d -50
+
+KPX r y 40
+KPX r v 40
+KPX r u 20
+KPX r t 20
+KPX r s 20
+KPX r q -8
+KPX r period -73
+KPX r p 20
+KPX r o -15
+KPX r n 21
+KPX r m 15
+KPX r l 20
+KPX r k 5
+KPX r i 20
+KPX r hyphen -60
+KPX r g 1
+KPX r e -4
+KPX r d -6
+KPX r comma -75
+KPX r c -7
+
+KPX s period 20
+KPX s comma 20
+
+KPX space quoteleft -50
+KPX space quotedblleft -50
+KPX space Y -60
+KPX space W -25
+KPX space V -80
+KPX space T -25
+KPX space A -20
+
+KPX v period -90
+KPX v o -20
+KPX v e -20
+KPX v comma -90
+KPX v a -30
+
+KPX w period -90
+KPX w o -30
+KPX w e -20
+KPX w comma -90
+KPX w a -30
+
+KPX x e -20
+
+KPX y period -100
+KPX y o -30
+KPX y e -20
+KPX y comma -100
+KPX y c -35
+KPX y a -30
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 170 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 100 170 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 120 170 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 170 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 190 135 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 130 170 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 50 170 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex -10 170 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 10 170 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 50 170 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -45 170 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -130 170 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -110 170 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -95 170 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 170 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 210 170 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 150 170 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 170 170 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 210 170 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 180 170 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron -10 170 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 145 170 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 50 170 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 70 170 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 75 170 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 135 170 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 60 170 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 5 170 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 60 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 150 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 90 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 70 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 110 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -65 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -150 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -130 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -115 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 50 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 80 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron -50 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 125 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 50 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 55 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 115 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron -15 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/AvantGarde-DemiOblique.afm b/tlt3.0/library/afm/AvantGarde-DemiOblique.afm
new file mode 100644
index 0000000..ea40ef1
--- /dev/null
+++ b/tlt3.0/library/afm/AvantGarde-DemiOblique.afm
@@ -0,0 +1,577 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Mon Mar  4 13:49:44 1991
+Comment UniqueID 34373
+Comment VMusage 6550 39938
+FontName AvantGarde-DemiOblique
+FullName ITC Avant Garde Gothic Demi Oblique
+FamilyName ITC Avant Garde Gothic
+Weight Demi
+ItalicAngle -10.5
+IsFixedPitch false
+FontBBox -123 -251 1256 1021
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated.  All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation.
+EncodingScheme AdobeStandardEncoding
+CapHeight 740
+XHeight 555
+Ascender 740
+Descender -185
+StartCharMetrics 228
+C 32 ; WX 280 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 280 ; N exclam ; B 73 0 343 740 ;
+C 34 ; WX 360 ; N quotedbl ; B 127 444 478 740 ;
+C 35 ; WX 560 ; N numbersign ; B 66 0 618 700 ;
+C 36 ; WX 560 ; N dollar ; B 99 -86 582 857 ;
+C 37 ; WX 860 ; N percent ; B 139 -15 856 755 ;
+C 38 ; WX 680 ; N ampersand ; B 71 -15 742 755 ;
+C 39 ; WX 280 ; N quoteright ; B 159 466 342 740 ;
+C 40 ; WX 380 ; N parenleft ; B 120 -157 490 754 ;
+C 41 ; WX 380 ; N parenright ; B 8 -157 378 754 ;
+C 42 ; WX 440 ; N asterisk ; B 174 457 492 755 ;
+C 43 ; WX 600 ; N plus ; B 84 0 610 506 ;
+C 44 ; WX 280 ; N comma ; B 48 -141 231 133 ;
+C 45 ; WX 420 ; N hyphen ; B 114 230 413 348 ;
+C 46 ; WX 280 ; N period ; B 73 0 231 133 ;
+C 47 ; WX 460 ; N slash ; B -13 -100 591 740 ;
+C 48 ; WX 560 ; N zero ; B 70 -15 628 755 ;
+C 49 ; WX 560 ; N one ; B 230 0 500 740 ;
+C 50 ; WX 560 ; N two ; B 44 0 622 755 ;
+C 51 ; WX 560 ; N three ; B 67 -15 585 755 ;
+C 52 ; WX 560 ; N four ; B 36 0 604 740 ;
+C 53 ; WX 560 ; N five ; B 64 -15 600 740 ;
+C 54 ; WX 560 ; N six ; B 64 -15 587 739 ;
+C 55 ; WX 560 ; N seven ; B 83 0 635 740 ;
+C 56 ; WX 560 ; N eight ; B 71 -15 590 755 ;
+C 57 ; WX 560 ; N nine ; B 110 0 633 754 ;
+C 58 ; WX 280 ; N colon ; B 73 0 309 555 ;
+C 59 ; WX 280 ; N semicolon ; B 48 -141 309 555 ;
+C 60 ; WX 600 ; N less ; B 84 -8 649 514 ;
+C 61 ; WX 600 ; N equal ; B 63 81 631 425 ;
+C 62 ; WX 600 ; N greater ; B 45 -8 610 514 ;
+C 63 ; WX 560 ; N question ; B 135 0 593 755 ;
+C 64 ; WX 740 ; N at ; B 109 -12 832 712 ;
+C 65 ; WX 740 ; N A ; B 7 0 732 740 ;
+C 66 ; WX 580 ; N B ; B 70 0 610 740 ;
+C 67 ; WX 780 ; N C ; B 97 -15 864 755 ;
+C 68 ; WX 700 ; N D ; B 63 0 732 740 ;
+C 69 ; WX 520 ; N E ; B 61 0 596 740 ;
+C 70 ; WX 480 ; N F ; B 61 0 575 740 ;
+C 71 ; WX 840 ; N G ; B 89 -15 887 755 ;
+C 72 ; WX 680 ; N H ; B 71 0 747 740 ;
+C 73 ; WX 280 ; N I ; B 72 0 346 740 ;
+C 74 ; WX 480 ; N J ; B 34 -15 546 740 ;
+C 75 ; WX 620 ; N K ; B 89 0 757 740 ;
+C 76 ; WX 440 ; N L ; B 72 0 459 740 ;
+C 77 ; WX 900 ; N M ; B 63 0 974 740 ;
+C 78 ; WX 740 ; N N ; B 70 0 808 740 ;
+C 79 ; WX 840 ; N O ; B 95 -15 882 755 ;
+C 80 ; WX 560 ; N P ; B 72 0 645 740 ;
+C 81 ; WX 840 ; N Q ; B 94 -15 882 755 ;
+C 82 ; WX 580 ; N R ; B 64 0 656 740 ;
+C 83 ; WX 520 ; N S ; B 49 -15 578 755 ;
+C 84 ; WX 420 ; N T ; B 119 0 555 740 ;
+C 85 ; WX 640 ; N U ; B 97 -15 722 740 ;
+C 86 ; WX 700 ; N V ; B 145 0 832 740 ;
+C 87 ; WX 900 ; N W ; B 144 0 1036 740 ;
+C 88 ; WX 680 ; N X ; B 4 0 813 740 ;
+C 89 ; WX 620 ; N Y ; B 135 0 759 740 ;
+C 90 ; WX 500 ; N Z ; B 19 0 599 740 ;
+C 91 ; WX 320 ; N bracketleft ; B 89 -157 424 754 ;
+C 92 ; WX 640 ; N backslash ; B 233 -100 525 740 ;
+C 93 ; WX 320 ; N bracketright ; B 7 -157 342 754 ;
+C 94 ; WX 600 ; N asciicircum ; B 142 375 596 740 ;
+C 95 ; WX 500 ; N underscore ; B -23 -125 486 -75 ;
+C 96 ; WX 280 ; N quoteleft ; B 158 466 341 740 ;
+C 97 ; WX 660 ; N a ; B 73 -18 716 574 ;
+C 98 ; WX 660 ; N b ; B 47 -18 689 740 ;
+C 99 ; WX 640 ; N c ; B 84 -18 679 574 ;
+C 100 ; WX 660 ; N d ; B 80 -18 755 740 ;
+C 101 ; WX 640 ; N e ; B 77 -18 667 577 ;
+C 102 ; WX 280 ; N f ; B 62 0 420 755 ; L i fi ; L l fl ;
+C 103 ; WX 660 ; N g ; B 33 -226 726 574 ;
+C 104 ; WX 600 ; N h ; B 54 0 614 740 ;
+C 105 ; WX 240 ; N i ; B 53 0 323 740 ;
+C 106 ; WX 260 ; N j ; B -18 -185 342 740 ;
+C 107 ; WX 580 ; N k ; B 80 0 648 740 ;
+C 108 ; WX 240 ; N l ; B 54 0 324 740 ;
+C 109 ; WX 940 ; N m ; B 54 0 954 574 ;
+C 110 ; WX 600 ; N n ; B 54 0 613 574 ;
+C 111 ; WX 640 ; N o ; B 71 -18 672 574 ;
+C 112 ; WX 660 ; N p ; B 13 -185 686 574 ;
+C 113 ; WX 660 ; N q ; B 78 -185 716 574 ;
+C 114 ; WX 320 ; N r ; B 63 0 423 574 ;
+C 115 ; WX 440 ; N s ; B 49 -18 483 574 ;
+C 116 ; WX 300 ; N t ; B 86 0 402 740 ;
+C 117 ; WX 600 ; N u ; B 87 -18 647 555 ;
+C 118 ; WX 560 ; N v ; B 106 0 659 555 ;
+C 119 ; WX 800 ; N w ; B 114 0 892 555 ;
+C 120 ; WX 560 ; N x ; B 3 0 632 555 ;
+C 121 ; WX 580 ; N y ; B 75 -185 674 555 ;
+C 122 ; WX 460 ; N z ; B 20 0 528 555 ;
+C 123 ; WX 340 ; N braceleft ; B 40 -191 455 747 ;
+C 124 ; WX 600 ; N bar ; B 214 -100 503 740 ;
+C 125 ; WX 340 ; N braceright ; B -12 -191 405 747 ;
+C 126 ; WX 600 ; N asciitilde ; B 114 160 579 347 ;
+C 161 ; WX 280 ; N exclamdown ; B 40 -185 310 555 ;
+C 162 ; WX 560 ; N cent ; B 110 39 599 715 ;
+C 163 ; WX 560 ; N sterling ; B 38 0 615 755 ;
+C 164 ; WX 160 ; N fraction ; B -123 0 419 740 ;
+C 165 ; WX 560 ; N yen ; B 83 0 707 740 ;
+C 166 ; WX 560 ; N florin ; B -27 -151 664 824 ;
+C 167 ; WX 560 ; N section ; B 65 -158 602 755 ;
+C 168 ; WX 560 ; N currency ; B 53 69 628 577 ;
+C 169 ; WX 220 ; N quotesingle ; B 152 444 314 740 ;
+C 170 ; WX 480 ; N quotedblleft ; B 156 466 546 740 ;
+C 171 ; WX 460 ; N guillemotleft ; B 105 108 487 469 ;
+C 172 ; WX 240 ; N guilsinglleft ; B 94 108 277 469 ;
+C 173 ; WX 240 ; N guilsinglright ; B 70 108 253 469 ;
+C 174 ; WX 520 ; N fi ; B 72 0 598 755 ;
+C 175 ; WX 520 ; N fl ; B 72 0 598 755 ;
+C 177 ; WX 500 ; N endash ; B 78 230 529 348 ;
+C 178 ; WX 560 ; N dagger ; B 133 -142 612 740 ;
+C 179 ; WX 560 ; N daggerdbl ; B 63 -142 618 740 ;
+C 180 ; WX 280 ; N periodcentered ; B 108 187 265 320 ;
+C 182 ; WX 600 ; N paragraph ; B 90 -103 744 740 ;
+C 183 ; WX 600 ; N bullet ; B 215 222 526 532 ;
+C 184 ; WX 280 ; N quotesinglbase ; B 47 -141 230 133 ;
+C 185 ; WX 480 ; N quotedblbase ; B 45 -141 435 133 ;
+C 186 ; WX 480 ; N quotedblright ; B 157 466 547 740 ;
+C 187 ; WX 460 ; N guillemotright ; B 81 108 463 469 ;
+C 188 ; WX 1000 ; N ellipsis ; B 100 0 924 133 ;
+C 189 ; WX 1280 ; N perthousand ; B 139 -15 1256 755 ;
+C 191 ; WX 560 ; N questiondown ; B 69 -200 527 555 ;
+C 193 ; WX 420 ; N grave ; B 189 624 462 851 ;
+C 194 ; WX 420 ; N acute ; B 224 624 508 849 ;
+C 195 ; WX 540 ; N circumflex ; B 189 636 588 774 ;
+C 196 ; WX 480 ; N tilde ; B 178 636 564 767 ;
+C 197 ; WX 420 ; N macron ; B 192 648 490 759 ;
+C 198 ; WX 480 ; N breve ; B 185 633 582 770 ;
+C 199 ; WX 280 ; N dotaccent ; B 192 636 350 769 ;
+C 200 ; WX 500 ; N dieresis ; B 196 636 565 769 ;
+C 202 ; WX 360 ; N ring ; B 206 619 424 834 ;
+C 203 ; WX 340 ; N cedilla ; B 67 -251 272 6 ;
+C 205 ; WX 700 ; N hungarumlaut ; B 258 610 754 862 ;
+C 206 ; WX 340 ; N ogonek ; B 59 -195 243 9 ;
+C 207 ; WX 540 ; N caron ; B 214 636 613 774 ;
+C 208 ; WX 1000 ; N emdash ; B 78 230 1029 348 ;
+C 225 ; WX 900 ; N AE ; B -5 0 961 740 ;
+C 227 ; WX 360 ; N ordfeminine ; B 127 438 472 755 ;
+C 232 ; WX 480 ; N Lslash ; B 68 0 484 740 ;
+C 233 ; WX 840 ; N Oslash ; B 94 -71 891 814 ;
+C 234 ; WX 1060 ; N OE ; B 98 -15 1144 755 ;
+C 235 ; WX 360 ; N ordmasculine ; B 131 438 451 755 ;
+C 241 ; WX 1080 ; N ae ; B 75 -18 1105 574 ;
+C 245 ; WX 240 ; N dotlessi ; B 53 0 289 555 ;
+C 248 ; WX 320 ; N lslash ; B 74 0 404 740 ;
+C 249 ; WX 660 ; N oslash ; B 81 -50 685 608 ;
+C 250 ; WX 1080 ; N oe ; B 76 -18 1108 574 ;
+C 251 ; WX 600 ; N germandbls ; B 51 -18 629 755 ;
+C -1 ; WX 640 ; N ecircumflex ; B 77 -18 667 774 ;
+C -1 ; WX 640 ; N edieresis ; B 77 -18 667 769 ;
+C -1 ; WX 660 ; N aacute ; B 73 -18 716 849 ;
+C -1 ; WX 740 ; N registered ; B 50 -12 827 752 ;
+C -1 ; WX 240 ; N icircumflex ; B 39 0 438 774 ;
+C -1 ; WX 600 ; N udieresis ; B 87 -18 647 769 ;
+C -1 ; WX 640 ; N ograve ; B 71 -18 672 851 ;
+C -1 ; WX 600 ; N uacute ; B 87 -18 647 849 ;
+C -1 ; WX 600 ; N ucircumflex ; B 87 -18 647 774 ;
+C -1 ; WX 740 ; N Aacute ; B 7 0 732 1019 ;
+C -1 ; WX 240 ; N igrave ; B 53 0 347 851 ;
+C -1 ; WX 280 ; N Icircumflex ; B 72 0 489 944 ;
+C -1 ; WX 640 ; N ccedilla ; B 83 -251 679 574 ;
+C -1 ; WX 660 ; N adieresis ; B 73 -18 716 769 ;
+C -1 ; WX 520 ; N Ecircumflex ; B 61 0 609 944 ;
+C -1 ; WX 440 ; N scaron ; B 49 -18 563 774 ;
+C -1 ; WX 660 ; N thorn ; B 13 -185 686 740 ;
+C -1 ; WX 1000 ; N trademark ; B 131 296 958 740 ;
+C -1 ; WX 640 ; N egrave ; B 77 -18 667 851 ;
+C -1 ; WX 336 ; N threesuperior ; B 87 287 413 749 ;
+C -1 ; WX 460 ; N zcaron ; B 20 0 598 774 ;
+C -1 ; WX 660 ; N atilde ; B 73 -18 716 767 ;
+C -1 ; WX 660 ; N aring ; B 73 -18 716 834 ;
+C -1 ; WX 640 ; N ocircumflex ; B 71 -18 672 774 ;
+C -1 ; WX 520 ; N Edieresis ; B 61 0 606 939 ;
+C -1 ; WX 840 ; N threequarters ; B 97 0 836 749 ;
+C -1 ; WX 580 ; N ydieresis ; B 75 -185 674 769 ;
+C -1 ; WX 580 ; N yacute ; B 75 -185 674 849 ;
+C -1 ; WX 240 ; N iacute ; B 53 0 443 849 ;
+C -1 ; WX 740 ; N Acircumflex ; B 7 0 732 944 ;
+C -1 ; WX 640 ; N Uacute ; B 97 -15 722 1019 ;
+C -1 ; WX 640 ; N eacute ; B 77 -18 667 849 ;
+C -1 ; WX 840 ; N Ograve ; B 95 -15 882 1021 ;
+C -1 ; WX 660 ; N agrave ; B 73 -18 716 851 ;
+C -1 ; WX 640 ; N Udieresis ; B 97 -15 722 939 ;
+C -1 ; WX 660 ; N acircumflex ; B 73 -18 716 774 ;
+C -1 ; WX 280 ; N Igrave ; B 72 0 398 1021 ;
+C -1 ; WX 336 ; N twosuperior ; B 73 296 436 749 ;
+C -1 ; WX 640 ; N Ugrave ; B 97 -15 722 1021 ;
+C -1 ; WX 840 ; N onequarter ; B 187 0 779 740 ;
+C -1 ; WX 640 ; N Ucircumflex ; B 97 -15 722 944 ;
+C -1 ; WX 520 ; N Scaron ; B 49 -15 635 944 ;
+C -1 ; WX 280 ; N Idieresis ; B 72 0 486 939 ;
+C -1 ; WX 240 ; N idieresis ; B 53 0 435 769 ;
+C -1 ; WX 520 ; N Egrave ; B 61 0 596 1021 ;
+C -1 ; WX 840 ; N Oacute ; B 95 -15 882 1019 ;
+C -1 ; WX 600 ; N divide ; B 84 -20 610 526 ;
+C -1 ; WX 740 ; N Atilde ; B 7 0 732 937 ;
+C -1 ; WX 740 ; N Aring ; B 7 0 732 969 ;
+C -1 ; WX 840 ; N Odieresis ; B 95 -15 882 939 ;
+C -1 ; WX 740 ; N Adieresis ; B 7 0 732 939 ;
+C -1 ; WX 740 ; N Ntilde ; B 70 0 808 937 ;
+C -1 ; WX 500 ; N Zcaron ; B 19 0 650 944 ;
+C -1 ; WX 560 ; N Thorn ; B 72 0 619 740 ;
+C -1 ; WX 280 ; N Iacute ; B 72 0 494 1019 ;
+C -1 ; WX 600 ; N plusminus ; B 37 -62 626 556 ;
+C -1 ; WX 600 ; N multiply ; B 76 12 617 494 ;
+C -1 ; WX 520 ; N Eacute ; B 61 0 596 1019 ;
+C -1 ; WX 620 ; N Ydieresis ; B 135 0 759 939 ;
+C -1 ; WX 336 ; N onesuperior ; B 182 296 360 740 ;
+C -1 ; WX 600 ; N ugrave ; B 87 -18 647 851 ;
+C -1 ; WX 600 ; N logicalnot ; B 105 108 631 425 ;
+C -1 ; WX 600 ; N ntilde ; B 54 0 624 767 ;
+C -1 ; WX 840 ; N Otilde ; B 95 -15 882 937 ;
+C -1 ; WX 640 ; N otilde ; B 71 -18 672 767 ;
+C -1 ; WX 780 ; N Ccedilla ; B 97 -251 864 755 ;
+C -1 ; WX 740 ; N Agrave ; B 7 0 732 1021 ;
+C -1 ; WX 840 ; N onehalf ; B 157 0 830 740 ;
+C -1 ; WX 742 ; N Eth ; B 83 0 766 740 ;
+C -1 ; WX 400 ; N degree ; B 160 426 451 712 ;
+C -1 ; WX 620 ; N Yacute ; B 135 0 759 1019 ;
+C -1 ; WX 840 ; N Ocircumflex ; B 95 -15 882 944 ;
+C -1 ; WX 640 ; N oacute ; B 71 -18 672 849 ;
+C -1 ; WX 576 ; N mu ; B 3 -187 642 555 ;
+C -1 ; WX 600 ; N minus ; B 84 193 610 313 ;
+C -1 ; WX 640 ; N eth ; B 73 -18 699 754 ;
+C -1 ; WX 640 ; N odieresis ; B 71 -18 672 769 ;
+C -1 ; WX 740 ; N copyright ; B 50 -12 827 752 ;
+C -1 ; WX 600 ; N brokenbar ; B 214 -100 503 740 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 218
+
+KPX A y -50
+KPX A w -65
+KPX A v -70
+KPX A u -20
+KPX A quoteright -90
+KPX A Y -80
+KPX A W -60
+KPX A V -102
+KPX A U -40
+KPX A T -25
+KPX A Q -50
+KPX A O -50
+KPX A G -40
+KPX A C -40
+
+KPX B A -10
+
+KPX C A -40
+
+KPX D period -20
+KPX D comma -20
+KPX D Y -45
+KPX D W -25
+KPX D V -50
+KPX D A -50
+
+KPX F period -129
+KPX F e -20
+KPX F comma -162
+KPX F a -20
+KPX F A -75
+
+KPX G period -20
+KPX G comma -20
+KPX G Y -15
+
+KPX J period -15
+KPX J a -20
+KPX J A -30
+
+KPX K y -20
+KPX K u -15
+KPX K o -45
+KPX K e -40
+KPX K O -30
+
+KPX L y -23
+KPX L quoteright -30
+KPX L quotedblright -30
+KPX L Y -80
+KPX L W -55
+KPX L V -85
+KPX L T -46
+
+KPX O period -30
+KPX O comma -30
+KPX O Y -30
+KPX O X -30
+KPX O W -20
+KPX O V -45
+KPX O T -15
+KPX O A -60
+
+KPX P period -200
+KPX P o -20
+KPX P e -20
+KPX P comma -220
+KPX P a -20
+KPX P A -100
+
+KPX Q comma 20
+
+KPX R W 25
+KPX R V -10
+KPX R U 25
+KPX R T 40
+KPX R O 25
+
+KPX S comma 20
+
+KPX T y -10
+KPX T w -55
+KPX T u -46
+KPX T semicolon -29
+KPX T r -30
+KPX T period -91
+KPX T o -49
+KPX T hyphen -75
+KPX T e -49
+KPX T comma -82
+KPX T colon -15
+KPX T a -70
+KPX T O -15
+KPX T A -25
+
+KPX U period -20
+KPX U comma -20
+KPX U A -40
+
+KPX V u -55
+KPX V semicolon -33
+KPX V period -145
+KPX V o -101
+KPX V i -15
+KPX V hyphen -75
+KPX V e -101
+KPX V comma -145
+KPX V colon -18
+KPX V a -95
+KPX V O -45
+KPX V G -20
+KPX V A -102
+
+KPX W y -15
+KPX W u -30
+KPX W semicolon -33
+KPX W period -106
+KPX W o -46
+KPX W i -10
+KPX W hyphen -35
+KPX W e -47
+KPX W comma -106
+KPX W colon -15
+KPX W a -50
+KPX W O -20
+KPX W A -58
+
+KPX Y u -52
+KPX Y semicolon -23
+KPX Y period -145
+KPX Y o -89
+KPX Y hyphen -100
+KPX Y e -89
+KPX Y comma -145
+KPX Y colon -10
+KPX Y a -93
+KPX Y O -30
+KPX Y A -80
+
+KPX a t 5
+KPX a p 20
+KPX a b 5
+
+KPX b y -20
+KPX b v -20
+
+KPX c y -20
+KPX c l -15
+KPX c k -15
+
+KPX comma space -50
+KPX comma quoteright -70
+KPX comma quotedblright -70
+
+KPX e y -20
+KPX e x -20
+KPX e w -20
+KPX e v -20
+
+KPX f period -40
+KPX f o -20
+KPX f l -15
+KPX f i -15
+KPX f f -20
+KPX f dotlessi -15
+KPX f comma -40
+KPX f a -15
+
+KPX g i 25
+KPX g a 15
+
+KPX h y -30
+
+KPX k y -5
+KPX k o -30
+KPX k e -40
+
+KPX m y -20
+KPX m u -20
+
+KPX n y -15
+KPX n v -30
+
+KPX o y -20
+KPX o x -30
+KPX o w -20
+KPX o v -30
+
+KPX p y -20
+
+KPX period space -50
+KPX period quoteright -70
+KPX period quotedblright -70
+
+KPX quotedblleft A -50
+
+KPX quotedblright space -50
+
+KPX quoteleft quoteleft -80
+KPX quoteleft A -50
+
+KPX quoteright v -10
+KPX quoteright t 10
+KPX quoteright space -50
+KPX quoteright s -15
+KPX quoteright r -20
+KPX quoteright quoteright -80
+KPX quoteright d -50
+
+KPX r y 40
+KPX r v 40
+KPX r u 20
+KPX r t 20
+KPX r s 20
+KPX r q -8
+KPX r period -73
+KPX r p 20
+KPX r o -15
+KPX r n 21
+KPX r m 15
+KPX r l 20
+KPX r k 5
+KPX r i 20
+KPX r hyphen -60
+KPX r g 1
+KPX r e -4
+KPX r d -6
+KPX r comma -75
+KPX r c -7
+
+KPX s period 20
+KPX s comma 20
+
+KPX space quoteleft -50
+KPX space quotedblleft -50
+KPX space Y -60
+KPX space W -25
+KPX space V -80
+KPX space T -25
+KPX space A -20
+
+KPX v period -90
+KPX v o -20
+KPX v e -20
+KPX v comma -90
+KPX v a -30
+
+KPX w period -90
+KPX w o -30
+KPX w e -20
+KPX w comma -90
+KPX w a -30
+
+KPX x e -20
+
+KPX y period -100
+KPX y o -30
+KPX y e -20
+KPX y comma -100
+KPX y c -35
+KPX y a -30
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 192 170 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 132 170 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 152 170 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 192 170 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 215 135 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 162 170 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 82 170 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 22 170 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 42 170 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 82 170 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -13 170 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -98 170 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -78 170 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -63 170 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 162 170 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 242 170 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 182 170 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 202 170 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 242 170 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 212 170 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 22 170 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 177 170 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 82 170 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 102 170 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 107 170 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 170 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 92 170 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 37 170 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 60 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 150 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 90 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 70 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 110 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -65 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -150 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -130 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -115 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 50 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 80 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron -50 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 125 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 50 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 55 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 115 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron -15 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Bookman-Demi.afm b/tlt3.0/library/afm/Bookman-Demi.afm
new file mode 100644
index 0000000..51cb737
--- /dev/null
+++ b/tlt3.0/library/afm/Bookman-Demi.afm
@@ -0,0 +1,416 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Jan 21 16:13:29 1992
+Comment UniqueID 37831
+Comment VMusage 31983 38875
+FontName Bookman-Demi
+FullName ITC Bookman Demi
+FamilyName ITC Bookman
+Weight Demi
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -194 -250 1346 934 
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.004
+Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated.  All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation.
+EncodingScheme AdobeStandardEncoding
+CapHeight 681
+XHeight 502
+Ascender 725
+Descender -212
+StartCharMetrics 228
+C 32 ; WX 340 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 360 ; N exclam ; B 82 -8 282 698 ;
+C 34 ; WX 420 ; N quotedbl ; B 11 379 369 698 ;
+C 35 ; WX 660 ; N numbersign ; B 84 0 576 681 ;
+C 36 ; WX 660 ; N dollar ; B 48 -119 620 805 ;
+C 37 ; WX 940 ; N percent ; B 12 -8 924 698 ;
+C 38 ; WX 800 ; N ampersand ; B 21 -17 772 698 ;
+C 39 ; WX 320 ; N quoteright ; B 82 440 242 698 ;
+C 40 ; WX 320 ; N parenleft ; B 48 -150 289 749 ;
+C 41 ; WX 320 ; N parenright ; B 20 -150 262 749 ;
+C 42 ; WX 460 ; N asterisk ; B 62 317 405 697 ;
+C 43 ; WX 600 ; N plus ; B 51 9 555 514 ;
+C 44 ; WX 340 ; N comma ; B 78 -124 257 162 ;
+C 45 ; WX 360 ; N hyphen ; B 20 210 340 318 ;
+C 46 ; WX 340 ; N period ; B 76 -8 258 172 ;
+C 47 ; WX 600 ; N slash ; B 50 -149 555 725 ;
+C 48 ; WX 660 ; N zero ; B 30 -17 639 698 ;
+C 49 ; WX 660 ; N one ; B 137 0 568 681 ;
+C 50 ; WX 660 ; N two ; B 41 0 628 698 ;
+C 51 ; WX 660 ; N three ; B 37 -17 631 698 ;
+C 52 ; WX 660 ; N four ; B 19 0 649 681 ;
+C 53 ; WX 660 ; N five ; B 44 -17 623 723 ;
+C 54 ; WX 660 ; N six ; B 34 -17 634 698 ;
+C 55 ; WX 660 ; N seven ; B 36 0 632 681 ;
+C 56 ; WX 660 ; N eight ; B 36 -17 633 698 ;
+C 57 ; WX 660 ; N nine ; B 33 -17 636 698 ;
+C 58 ; WX 340 ; N colon ; B 76 -8 258 515 ;
+C 59 ; WX 340 ; N semicolon ; B 75 -124 259 515 ;
+C 60 ; WX 600 ; N less ; B 49 -9 558 542 ;
+C 61 ; WX 600 ; N equal ; B 51 109 555 421 ;
+C 62 ; WX 600 ; N greater ; B 48 -9 557 542 ;
+C 63 ; WX 660 ; N question ; B 61 -8 608 698 ;
+C 64 ; WX 820 ; N at ; B 60 -17 758 698 ;
+C 65 ; WX 720 ; N A ; B -34 0 763 681 ;
+C 66 ; WX 720 ; N B ; B 20 0 693 681 ;
+C 67 ; WX 740 ; N C ; B 35 -17 724 698 ;
+C 68 ; WX 780 ; N D ; B 20 0 748 681 ;
+C 69 ; WX 720 ; N E ; B 20 0 724 681 ;
+C 70 ; WX 680 ; N F ; B 20 0 686 681 ;
+C 71 ; WX 780 ; N G ; B 35 -17 773 698 ;
+C 72 ; WX 820 ; N H ; B 20 0 800 681 ;
+C 73 ; WX 400 ; N I ; B 20 0 379 681 ;
+C 74 ; WX 640 ; N J ; B -12 -17 622 681 ;
+C 75 ; WX 800 ; N K ; B 20 0 796 681 ;
+C 76 ; WX 640 ; N L ; B 20 0 668 681 ;
+C 77 ; WX 940 ; N M ; B 20 0 924 681 ;
+C 78 ; WX 740 ; N N ; B 20 0 724 681 ;
+C 79 ; WX 800 ; N O ; B 35 -17 769 698 ;
+C 80 ; WX 660 ; N P ; B 20 0 658 681 ;
+C 81 ; WX 800 ; N Q ; B 35 -226 775 698 ;
+C 82 ; WX 780 ; N R ; B 20 0 783 681 ;
+C 83 ; WX 660 ; N S ; B 21 -17 639 698 ;
+C 84 ; WX 700 ; N T ; B -4 0 703 681 ;
+C 85 ; WX 740 ; N U ; B 15 -17 724 681 ;
+C 86 ; WX 720 ; N V ; B -20 0 730 681 ;
+C 87 ; WX 940 ; N W ; B -20 0 963 681 ;
+C 88 ; WX 780 ; N X ; B 1 0 770 681 ;
+C 89 ; WX 700 ; N Y ; B -20 0 718 681 ;
+C 90 ; WX 640 ; N Z ; B 6 0 635 681 ;
+C 91 ; WX 300 ; N bracketleft ; B 75 -138 285 725 ;
+C 92 ; WX 600 ; N backslash ; B 50 0 555 725 ;
+C 93 ; WX 300 ; N bracketright ; B 21 -138 231 725 ;
+C 94 ; WX 600 ; N asciicircum ; B 52 281 554 681 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 320 ; N quoteleft ; B 82 440 242 698 ;
+C 97 ; WX 580 ; N a ; B 28 -8 588 515 ;
+C 98 ; WX 600 ; N b ; B -20 -8 568 725 ;
+C 99 ; WX 580 ; N c ; B 31 -8 550 515 ;
+C 100 ; WX 640 ; N d ; B 31 -8 622 725 ;
+C 101 ; WX 580 ; N e ; B 31 -8 548 515 ;
+C 102 ; WX 380 ; N f ; B 22 0 461 741 ; L i fi ; L l fl ;
+C 103 ; WX 580 ; N g ; B 9 -243 583 595 ;
+C 104 ; WX 680 ; N h ; B 22 0 654 725 ;
+C 105 ; WX 360 ; N i ; B 22 0 335 729 ;
+C 106 ; WX 340 ; N j ; B -94 -221 278 729 ;
+C 107 ; WX 660 ; N k ; B 22 0 643 725 ;
+C 108 ; WX 340 ; N l ; B 9 0 322 725 ;
+C 109 ; WX 1000 ; N m ; B 22 0 980 515 ;
+C 110 ; WX 680 ; N n ; B 22 0 652 515 ;
+C 111 ; WX 620 ; N o ; B 31 -8 585 515 ;
+C 112 ; WX 640 ; N p ; B 22 -212 611 515 ;
+C 113 ; WX 620 ; N q ; B 31 -212 633 515 ;
+C 114 ; WX 460 ; N r ; B 22 0 462 502 ;
+C 115 ; WX 520 ; N s ; B 22 -8 492 515 ;
+C 116 ; WX 460 ; N t ; B 22 -8 445 660 ;
+C 117 ; WX 660 ; N u ; B 22 -8 653 502 ;
+C 118 ; WX 600 ; N v ; B -6 0 593 502 ;
+C 119 ; WX 800 ; N w ; B -6 0 810 502 ;
+C 120 ; WX 600 ; N x ; B 8 0 591 502 ;
+C 121 ; WX 620 ; N y ; B 6 -221 613 502 ;
+C 122 ; WX 560 ; N z ; B 22 0 547 502 ;
+C 123 ; WX 320 ; N braceleft ; B 14 -139 301 726 ;
+C 124 ; WX 600 ; N bar ; B 243 -250 362 750 ;
+C 125 ; WX 320 ; N braceright ; B 15 -140 302 725 ;
+C 126 ; WX 600 ; N asciitilde ; B 51 162 555 368 ;
+C 161 ; WX 360 ; N exclamdown ; B 84 -191 284 515 ;
+C 162 ; WX 660 ; N cent ; B 133 17 535 674 ;
+C 163 ; WX 660 ; N sterling ; B 10 -17 659 698 ;
+C 164 ; WX 120 ; N fraction ; B -194 0 312 681 ;
+C 165 ; WX 660 ; N yen ; B -28 0 696 681 ;
+C 166 ; WX 660 ; N florin ; B -46 -209 674 749 ;
+C 167 ; WX 600 ; N section ; B 36 -153 560 698 ;
+C 168 ; WX 660 ; N currency ; B 77 88 584 593 ;
+C 169 ; WX 240 ; N quotesingle ; B 42 379 178 698 ;
+C 170 ; WX 540 ; N quotedblleft ; B 82 439 449 698 ;
+C 171 ; WX 400 ; N guillemotleft ; B 34 101 360 457 ;
+C 172 ; WX 220 ; N guilsinglleft ; B 34 101 188 457 ;
+C 173 ; WX 220 ; N guilsinglright ; B 34 101 188 457 ;
+C 174 ; WX 740 ; N fi ; B 22 0 710 741 ;
+C 175 ; WX 740 ; N fl ; B 22 0 710 741 ;
+C 177 ; WX 500 ; N endash ; B -25 212 525 318 ;
+C 178 ; WX 440 ; N dagger ; B 33 -156 398 698 ;
+C 179 ; WX 380 ; N daggerdbl ; B 8 -156 380 698 ;
+C 180 ; WX 340 ; N periodcentered ; B 76 175 258 355 ;
+C 182 ; WX 800 ; N paragraph ; B 51 0 698 681 ;
+C 183 ; WX 460 ; N bullet ; B 60 170 404 511 ;
+C 184 ; WX 320 ; N quotesinglbase ; B 82 -114 242 144 ;
+C 185 ; WX 540 ; N quotedblbase ; B 82 -114 450 144 ;
+C 186 ; WX 540 ; N quotedblright ; B 82 440 449 698 ;
+C 187 ; WX 400 ; N guillemotright ; B 34 101 360 457 ;
+C 188 ; WX 1000 ; N ellipsis ; B 76 -8 924 172 ;
+C 189 ; WX 1360 ; N perthousand ; B 12 -8 1346 698 ;
+C 191 ; WX 660 ; N questiondown ; B 62 -191 609 515 ;
+C 193 ; WX 400 ; N grave ; B 68 547 327 730 ;
+C 194 ; WX 400 ; N acute ; B 68 547 327 731 ;
+C 195 ; WX 500 ; N circumflex ; B 68 555 430 731 ;
+C 196 ; WX 480 ; N tilde ; B 69 556 421 691 ;
+C 197 ; WX 460 ; N macron ; B 68 577 383 663 ;
+C 198 ; WX 500 ; N breve ; B 68 553 429 722 ;
+C 199 ; WX 320 ; N dotaccent ; B 68 536 259 730 ;
+C 200 ; WX 500 ; N dieresis ; B 68 560 441 698 ;
+C 202 ; WX 340 ; N ring ; B 68 552 275 755 ;
+C 203 ; WX 360 ; N cedilla ; B 68 -213 284 0 ;
+C 205 ; WX 440 ; N hungarumlaut ; B 68 554 365 741 ;
+C 206 ; WX 320 ; N ogonek ; B 68 -163 246 0 ;
+C 207 ; WX 500 ; N caron ; B 68 541 430 717 ;
+C 208 ; WX 1000 ; N emdash ; B -25 212 1025 318 ;
+C 225 ; WX 1140 ; N AE ; B -34 0 1149 681 ;
+C 227 ; WX 400 ; N ordfeminine ; B 27 383 396 698 ;
+C 232 ; WX 640 ; N Lslash ; B 20 0 668 681 ;
+C 233 ; WX 800 ; N Oslash ; B 35 -110 771 781 ;
+C 234 ; WX 1220 ; N OE ; B 35 -17 1219 698 ;
+C 235 ; WX 400 ; N ordmasculine ; B 17 383 383 698 ;
+C 241 ; WX 880 ; N ae ; B 28 -8 852 515 ;
+C 245 ; WX 360 ; N dotlessi ; B 22 0 335 502 ;
+C 248 ; WX 340 ; N lslash ; B 9 0 322 725 ;
+C 249 ; WX 620 ; N oslash ; B 31 -40 586 551 ;
+C 250 ; WX 940 ; N oe ; B 31 -8 908 515 ;
+C 251 ; WX 660 ; N germandbls ; B -61 -91 644 699 ;
+C -1 ; WX 580 ; N ecircumflex ; B 31 -8 548 731 ;
+C -1 ; WX 580 ; N edieresis ; B 31 -8 548 698 ;
+C -1 ; WX 580 ; N aacute ; B 28 -8 588 731 ;
+C -1 ; WX 740 ; N registered ; B 23 -17 723 698 ;
+C -1 ; WX 360 ; N icircumflex ; B -2 0 360 731 ;
+C -1 ; WX 660 ; N udieresis ; B 22 -8 653 698 ;
+C -1 ; WX 620 ; N ograve ; B 31 -8 585 730 ;
+C -1 ; WX 660 ; N uacute ; B 22 -8 653 731 ;
+C -1 ; WX 660 ; N ucircumflex ; B 22 -8 653 731 ;
+C -1 ; WX 720 ; N Aacute ; B -34 0 763 910 ;
+C -1 ; WX 360 ; N igrave ; B 22 0 335 730 ;
+C -1 ; WX 400 ; N Icircumflex ; B 18 0 380 910 ;
+C -1 ; WX 580 ; N ccedilla ; B 31 -213 550 515 ;
+C -1 ; WX 580 ; N adieresis ; B 28 -8 588 698 ;
+C -1 ; WX 720 ; N Ecircumflex ; B 20 0 724 910 ;
+C -1 ; WX 520 ; N scaron ; B 22 -8 492 717 ;
+C -1 ; WX 640 ; N thorn ; B 22 -212 611 725 ;
+C -1 ; WX 980 ; N trademark ; B 42 277 982 681 ;
+C -1 ; WX 580 ; N egrave ; B 31 -8 548 730 ;
+C -1 ; WX 396 ; N threesuperior ; B 5 269 391 698 ;
+C -1 ; WX 560 ; N zcaron ; B 22 0 547 717 ;
+C -1 ; WX 580 ; N atilde ; B 28 -8 588 691 ;
+C -1 ; WX 580 ; N aring ; B 28 -8 588 755 ;
+C -1 ; WX 620 ; N ocircumflex ; B 31 -8 585 731 ;
+C -1 ; WX 720 ; N Edieresis ; B 20 0 724 877 ;
+C -1 ; WX 990 ; N threequarters ; B 15 0 967 692 ;
+C -1 ; WX 620 ; N ydieresis ; B 6 -221 613 698 ;
+C -1 ; WX 620 ; N yacute ; B 6 -221 613 731 ;
+C -1 ; WX 360 ; N iacute ; B 22 0 335 731 ;
+C -1 ; WX 720 ; N Acircumflex ; B -34 0 763 910 ;
+C -1 ; WX 740 ; N Uacute ; B 15 -17 724 910 ;
+C -1 ; WX 580 ; N eacute ; B 31 -8 548 731 ;
+C -1 ; WX 800 ; N Ograve ; B 35 -17 769 909 ;
+C -1 ; WX 580 ; N agrave ; B 28 -8 588 730 ;
+C -1 ; WX 740 ; N Udieresis ; B 15 -17 724 877 ;
+C -1 ; WX 580 ; N acircumflex ; B 28 -8 588 731 ;
+C -1 ; WX 400 ; N Igrave ; B 20 0 379 909 ;
+C -1 ; WX 396 ; N twosuperior ; B 14 279 396 698 ;
+C -1 ; WX 740 ; N Ugrave ; B 15 -17 724 909 ;
+C -1 ; WX 990 ; N onequarter ; B 65 0 967 681 ;
+C -1 ; WX 740 ; N Ucircumflex ; B 15 -17 724 910 ;
+C -1 ; WX 660 ; N Scaron ; B 21 -17 639 896 ;
+C -1 ; WX 400 ; N Idieresis ; B 18 0 391 877 ;
+C -1 ; WX 360 ; N idieresis ; B -2 0 371 698 ;
+C -1 ; WX 720 ; N Egrave ; B 20 0 724 909 ;
+C -1 ; WX 800 ; N Oacute ; B 35 -17 769 910 ;
+C -1 ; WX 600 ; N divide ; B 51 9 555 521 ;
+C -1 ; WX 720 ; N Atilde ; B -34 0 763 870 ;
+C -1 ; WX 720 ; N Aring ; B -34 0 763 934 ;
+C -1 ; WX 800 ; N Odieresis ; B 35 -17 769 877 ;
+C -1 ; WX 720 ; N Adieresis ; B -34 0 763 877 ;
+C -1 ; WX 740 ; N Ntilde ; B 20 0 724 870 ;
+C -1 ; WX 640 ; N Zcaron ; B 6 0 635 896 ;
+C -1 ; WX 660 ; N Thorn ; B 20 0 658 681 ;
+C -1 ; WX 400 ; N Iacute ; B 20 0 379 910 ;
+C -1 ; WX 600 ; N plusminus ; B 51 0 555 514 ;
+C -1 ; WX 600 ; N multiply ; B 48 10 552 514 ;
+C -1 ; WX 720 ; N Eacute ; B 20 0 724 910 ;
+C -1 ; WX 700 ; N Ydieresis ; B -20 0 718 877 ;
+C -1 ; WX 396 ; N onesuperior ; B 65 279 345 687 ;
+C -1 ; WX 660 ; N ugrave ; B 22 -8 653 730 ;
+C -1 ; WX 600 ; N logicalnot ; B 51 129 555 421 ;
+C -1 ; WX 680 ; N ntilde ; B 22 0 652 691 ;
+C -1 ; WX 800 ; N Otilde ; B 35 -17 769 870 ;
+C -1 ; WX 620 ; N otilde ; B 31 -8 585 691 ;
+C -1 ; WX 740 ; N Ccedilla ; B 35 -213 724 698 ;
+C -1 ; WX 720 ; N Agrave ; B -34 0 763 909 ;
+C -1 ; WX 990 ; N onehalf ; B 65 0 980 681 ;
+C -1 ; WX 780 ; N Eth ; B 20 0 748 681 ;
+C -1 ; WX 400 ; N degree ; B 50 398 350 698 ;
+C -1 ; WX 700 ; N Yacute ; B -20 0 718 910 ;
+C -1 ; WX 800 ; N Ocircumflex ; B 35 -17 769 910 ;
+C -1 ; WX 620 ; N oacute ; B 31 -8 585 731 ;
+C -1 ; WX 660 ; N mu ; B 22 -221 653 502 ;
+C -1 ; WX 600 ; N minus ; B 51 207 555 323 ;
+C -1 ; WX 620 ; N eth ; B 31 -8 585 741 ;
+C -1 ; WX 620 ; N odieresis ; B 31 -8 585 698 ;
+C -1 ; WX 740 ; N copyright ; B 23 -17 723 698 ;
+C -1 ; WX 600 ; N brokenbar ; B 243 -175 362 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 90
+
+KPX A y -1
+KPX A w -9
+KPX A v -8
+KPX A Y -52
+KPX A W -20
+KPX A V -68
+KPX A T -40
+
+KPX F period -132
+KPX F comma -130
+KPX F A -59
+
+KPX L y 19
+KPX L Y -35
+KPX L W -41
+KPX L V -50
+KPX L T -4
+
+KPX P period -128
+KPX P comma -129
+KPX P A -46
+
+KPX R y -8
+KPX R Y -20
+KPX R W -24
+KPX R V -29
+KPX R T -4
+
+KPX T semicolon 5
+KPX T s -10
+KPX T r 27
+KPX T period -122
+KPX T o -28
+KPX T i 27
+KPX T hyphen -10
+KPX T e -29
+KPX T comma -122
+KPX T colon 7
+KPX T c -29
+KPX T a -24
+KPX T A -42
+
+KPX V y 12
+KPX V u -11
+KPX V semicolon -38
+KPX V r -15
+KPX V period -105
+KPX V o -79
+KPX V i 15
+KPX V hyphen -10
+KPX V e -80
+KPX V comma -103
+KPX V colon -37
+KPX V a -74
+KPX V A -88
+
+KPX W y 12
+KPX W u -11
+KPX W semicolon -38
+KPX W r -15
+KPX W period -105
+KPX W o -78
+KPX W i 15
+KPX W hyphen -10
+KPX W e -79
+KPX W comma -103
+KPX W colon -37
+KPX W a -73
+KPX W A -60
+
+KPX Y v 24
+KPX Y u -13
+KPX Y semicolon -34
+KPX Y q -66
+KPX Y period -105
+KPX Y p -23
+KPX Y o -66
+KPX Y i 2
+KPX Y hyphen -10
+KPX Y e -67
+KPX Y comma -103
+KPX Y colon -32
+KPX Y a -60
+KPX Y A -56
+
+KPX f f 21
+
+KPX r q -9
+KPX r period -102
+KPX r o -9
+KPX r n 20
+KPX r m 20
+KPX r hyphen -10
+KPX r h -23
+KPX r g -9
+KPX r f 20
+KPX r e -10
+KPX r d -10
+KPX r comma -101
+KPX r c -9
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 179 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 110 179 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 110 179 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 179 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 190 179 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 179 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 160 179 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 110 179 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 110 179 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 160 179 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 179 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -50 179 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -50 179 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 179 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 179 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 200 179 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 150 179 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 150 179 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 179 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 160 179 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 80 179 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 170 179 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 120 179 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 120 179 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 170 179 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 150 179 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 100 179 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 70 179 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 90 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 40 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 40 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 90 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 100 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 30 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 40 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 40 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -20 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -70 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -70 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -20 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 80 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 60 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 60 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 50 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 10 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 130 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 80 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 80 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 130 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 110 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 60 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 30 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Bookman-DemiItalic.afm b/tlt3.0/library/afm/Bookman-DemiItalic.afm
new file mode 100644
index 0000000..4b05c18
--- /dev/null
+++ b/tlt3.0/library/afm/Bookman-DemiItalic.afm
@@ -0,0 +1,418 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Jan 21 16:12:43 1992
+Comment UniqueID 37832
+Comment VMusage 32139 39031
+FontName Bookman-DemiItalic
+FullName ITC Bookman Demi Italic
+FamilyName ITC Bookman
+Weight Demi
+ItalicAngle -10
+IsFixedPitch false
+FontBBox -231 -250 1333 941 
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.004
+Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated.  All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation.
+EncodingScheme AdobeStandardEncoding
+CapHeight 681
+XHeight 515
+Ascender 732
+Descender -213
+StartCharMetrics 228
+C 32 ; WX 340 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 320 ; N exclam ; B 86 -8 366 698 ;
+C 34 ; WX 380 ; N quotedbl ; B 140 371 507 697 ;
+C 35 ; WX 680 ; N numbersign ; B 157 0 649 681 ;
+C 36 ; WX 680 ; N dollar ; B 45 -164 697 790 ;
+C 37 ; WX 880 ; N percent ; B 106 -17 899 698 ;
+C 38 ; WX 980 ; N ampersand ; B 48 -17 1016 698 ;
+C 39 ; WX 320 ; N quoteright ; B 171 420 349 698 ;
+C 40 ; WX 260 ; N parenleft ; B 31 -134 388 741 ;
+C 41 ; WX 260 ; N parenright ; B -35 -134 322 741 ;
+C 42 ; WX 460 ; N asterisk ; B 126 346 508 698 ;
+C 43 ; WX 600 ; N plus ; B 91 9 595 514 ;
+C 44 ; WX 340 ; N comma ; B 100 -124 298 185 ;
+C 45 ; WX 280 ; N hyphen ; B 59 218 319 313 ;
+C 46 ; WX 340 ; N period ; B 106 -8 296 177 ;
+C 47 ; WX 360 ; N slash ; B 9 -106 502 742 ;
+C 48 ; WX 680 ; N zero ; B 87 -17 703 698 ;
+C 49 ; WX 680 ; N one ; B 123 0 565 681 ;
+C 50 ; WX 680 ; N two ; B 67 0 674 698 ;
+C 51 ; WX 680 ; N three ; B 72 -17 683 698 ;
+C 52 ; WX 680 ; N four ; B 63 0 708 681 ;
+C 53 ; WX 680 ; N five ; B 78 -17 669 681 ;
+C 54 ; WX 680 ; N six ; B 88 -17 704 698 ;
+C 55 ; WX 680 ; N seven ; B 123 0 739 681 ;
+C 56 ; WX 680 ; N eight ; B 68 -17 686 698 ;
+C 57 ; WX 680 ; N nine ; B 71 -17 712 698 ;
+C 58 ; WX 340 ; N colon ; B 106 -8 356 515 ;
+C 59 ; WX 340 ; N semicolon ; B 100 -124 352 515 ;
+C 60 ; WX 620 ; N less ; B 79 -9 588 540 ;
+C 61 ; WX 600 ; N equal ; B 91 109 595 421 ;
+C 62 ; WX 620 ; N greater ; B 89 -9 598 540 ;
+C 63 ; WX 620 ; N question ; B 145 -8 668 698 ;
+C 64 ; WX 780 ; N at ; B 80 -17 790 698 ;
+C 65 ; WX 720 ; N A ; B -27 0 769 681 ;
+C 66 ; WX 720 ; N B ; B 14 0 762 681 ;
+C 67 ; WX 700 ; N C ; B 78 -17 754 698 ;
+C 68 ; WX 760 ; N D ; B 14 0 805 681 ;
+C 69 ; WX 720 ; N E ; B 14 0 777 681 ;
+C 70 ; WX 660 ; N F ; B 14 0 763 681 ;
+C 71 ; WX 760 ; N G ; B 77 -17 828 698 ;
+C 72 ; WX 800 ; N H ; B 14 0 910 681 ;
+C 73 ; WX 380 ; N I ; B 14 0 485 681 ;
+C 74 ; WX 620 ; N J ; B 8 -17 721 681 ;
+C 75 ; WX 780 ; N K ; B 14 0 879 681 ;
+C 76 ; WX 640 ; N L ; B 14 0 725 681 ;
+C 77 ; WX 860 ; N M ; B 14 0 970 681 ;
+C 78 ; WX 740 ; N N ; B 14 0 845 681 ;
+C 79 ; WX 760 ; N O ; B 78 -17 806 698 ;
+C 80 ; WX 640 ; N P ; B -6 0 724 681 ;
+C 81 ; WX 760 ; N Q ; B 37 -213 805 698 ;
+C 82 ; WX 740 ; N R ; B 14 0 765 681 ;
+C 83 ; WX 700 ; N S ; B 59 -17 731 698 ;
+C 84 ; WX 700 ; N T ; B 70 0 802 681 ;
+C 85 ; WX 740 ; N U ; B 112 -17 855 681 ;
+C 86 ; WX 660 ; N V ; B 72 0 819 681 ;
+C 87 ; WX 1000 ; N W ; B 72 0 1090 681 ;
+C 88 ; WX 740 ; N X ; B -7 0 835 681 ;
+C 89 ; WX 660 ; N Y ; B 72 0 817 681 ;
+C 90 ; WX 680 ; N Z ; B 23 0 740 681 ;
+C 91 ; WX 260 ; N bracketleft ; B 9 -118 374 741 ;
+C 92 ; WX 580 ; N backslash ; B 73 0 575 741 ;
+C 93 ; WX 260 ; N bracketright ; B -18 -118 347 741 ;
+C 94 ; WX 620 ; N asciicircum ; B 92 281 594 681 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 320 ; N quoteleft ; B 155 420 333 698 ;
+C 97 ; WX 680 ; N a ; B 84 -8 735 515 ;
+C 98 ; WX 600 ; N b ; B 57 -8 633 732 ;
+C 99 ; WX 560 ; N c ; B 58 -8 597 515 ;
+C 100 ; WX 680 ; N d ; B 60 -8 714 732 ;
+C 101 ; WX 560 ; N e ; B 59 -8 596 515 ;
+C 102 ; WX 420 ; N f ; B -192 -213 641 741 ; L i fi ; L l fl ;
+C 103 ; WX 620 ; N g ; B 21 -213 669 515 ;
+C 104 ; WX 700 ; N h ; B 93 -8 736 732 ;
+C 105 ; WX 380 ; N i ; B 83 -8 420 755 ;
+C 106 ; WX 320 ; N j ; B -160 -213 392 755 ;
+C 107 ; WX 700 ; N k ; B 97 -8 732 732 ;
+C 108 ; WX 380 ; N l ; B 109 -8 410 732 ;
+C 109 ; WX 960 ; N m ; B 83 -8 996 515 ;
+C 110 ; WX 680 ; N n ; B 83 -8 715 515 ;
+C 111 ; WX 600 ; N o ; B 59 -8 627 515 ;
+C 112 ; WX 660 ; N p ; B -24 -213 682 515 ;
+C 113 ; WX 620 ; N q ; B 60 -213 640 515 ;
+C 114 ; WX 500 ; N r ; B 84 0 582 515 ;
+C 115 ; WX 540 ; N s ; B 32 -8 573 515 ;
+C 116 ; WX 440 ; N t ; B 106 -8 488 658 ;
+C 117 ; WX 680 ; N u ; B 83 -8 720 507 ;
+C 118 ; WX 540 ; N v ; B 56 -8 572 515 ;
+C 119 ; WX 860 ; N w ; B 56 -8 891 515 ;
+C 120 ; WX 620 ; N x ; B 10 -8 654 515 ;
+C 121 ; WX 600 ; N y ; B 25 -213 642 507 ;
+C 122 ; WX 560 ; N z ; B 36 -8 586 515 ;
+C 123 ; WX 300 ; N braceleft ; B 49 -123 413 742 ;
+C 124 ; WX 620 ; N bar ; B 303 -250 422 750 ;
+C 125 ; WX 300 ; N braceright ; B -8 -114 356 751 ;
+C 126 ; WX 620 ; N asciitilde ; B 101 162 605 368 ;
+C 161 ; WX 320 ; N exclamdown ; B 64 -191 344 515 ;
+C 162 ; WX 680 ; N cent ; B 161 25 616 718 ;
+C 163 ; WX 680 ; N sterling ; B 0 -17 787 698 ;
+C 164 ; WX 120 ; N fraction ; B -144 0 382 681 ;
+C 165 ; WX 680 ; N yen ; B 92 0 782 681 ;
+C 166 ; WX 680 ; N florin ; B -28 -199 743 741 ;
+C 167 ; WX 620 ; N section ; B 46 -137 638 698 ;
+C 168 ; WX 680 ; N currency ; B 148 85 637 571 ;
+C 169 ; WX 180 ; N quotesingle ; B 126 370 295 696 ;
+C 170 ; WX 520 ; N quotedblleft ; B 156 420 545 698 ;
+C 171 ; WX 380 ; N guillemotleft ; B 62 84 406 503 ;
+C 172 ; WX 220 ; N guilsinglleft ; B 62 84 249 503 ;
+C 173 ; WX 220 ; N guilsinglright ; B 62 84 249 503 ;
+C 174 ; WX 820 ; N fi ; B -191 -213 850 741 ;
+C 175 ; WX 820 ; N fl ; B -191 -213 850 741 ;
+C 177 ; WX 500 ; N endash ; B 40 219 573 311 ;
+C 178 ; WX 420 ; N dagger ; B 89 -137 466 698 ;
+C 179 ; WX 420 ; N daggerdbl ; B 79 -137 486 698 ;
+C 180 ; WX 340 ; N periodcentered ; B 126 173 316 358 ;
+C 182 ; WX 680 ; N paragraph ; B 137 0 715 681 ;
+C 183 ; WX 360 ; N bullet ; B 60 170 404 511 ;
+C 184 ; WX 300 ; N quotesinglbase ; B 106 -112 284 166 ;
+C 185 ; WX 520 ; N quotedblbase ; B 106 -112 495 166 ;
+C 186 ; WX 520 ; N quotedblright ; B 171 420 560 698 ;
+C 187 ; WX 380 ; N guillemotright ; B 62 84 406 503 ;
+C 188 ; WX 1000 ; N ellipsis ; B 86 -8 942 177 ;
+C 189 ; WX 1360 ; N perthousand ; B 106 -17 1333 698 ;
+C 191 ; WX 620 ; N questiondown ; B 83 -189 606 515 ;
+C 193 ; WX 380 ; N grave ; B 193 566 424 771 ;
+C 194 ; WX 340 ; N acute ; B 176 566 407 771 ;
+C 195 ; WX 480 ; N circumflex ; B 183 582 523 749 ;
+C 196 ; WX 480 ; N tilde ; B 178 587 533 709 ;
+C 197 ; WX 480 ; N macron ; B 177 603 531 691 ;
+C 198 ; WX 460 ; N breve ; B 177 577 516 707 ;
+C 199 ; WX 380 ; N dotaccent ; B 180 570 345 734 ;
+C 200 ; WX 520 ; N dieresis ; B 180 570 569 734 ;
+C 202 ; WX 360 ; N ring ; B 185 558 406 775 ;
+C 203 ; WX 360 ; N cedilla ; B 68 -220 289 -8 ;
+C 205 ; WX 560 ; N hungarumlaut ; B 181 560 616 775 ;
+C 206 ; WX 320 ; N ogonek ; B 68 -182 253 0 ;
+C 207 ; WX 480 ; N caron ; B 183 582 523 749 ;
+C 208 ; WX 1000 ; N emdash ; B 40 219 1073 311 ;
+C 225 ; WX 1140 ; N AE ; B -27 0 1207 681 ;
+C 227 ; WX 440 ; N ordfeminine ; B 118 400 495 685 ;
+C 232 ; WX 640 ; N Lslash ; B 14 0 724 681 ;
+C 233 ; WX 760 ; N Oslash ; B 21 -29 847 725 ;
+C 234 ; WX 1180 ; N OE ; B 94 -17 1245 698 ;
+C 235 ; WX 440 ; N ordmasculine ; B 127 400 455 685 ;
+C 241 ; WX 880 ; N ae ; B 39 -8 913 515 ;
+C 245 ; WX 380 ; N dotlessi ; B 83 -8 420 507 ;
+C 248 ; WX 380 ; N lslash ; B 63 -8 412 732 ;
+C 249 ; WX 600 ; N oslash ; B 17 -54 661 571 ;
+C 250 ; WX 920 ; N oe ; B 48 -8 961 515 ;
+C 251 ; WX 660 ; N germandbls ; B -231 -213 702 741 ;
+C -1 ; WX 560 ; N ecircumflex ; B 59 -8 596 749 ;
+C -1 ; WX 560 ; N edieresis ; B 59 -8 596 734 ;
+C -1 ; WX 680 ; N aacute ; B 84 -8 735 771 ;
+C -1 ; WX 780 ; N registered ; B 83 -17 783 698 ;
+C -1 ; WX 380 ; N icircumflex ; B 83 -8 433 749 ;
+C -1 ; WX 680 ; N udieresis ; B 83 -8 720 734 ;
+C -1 ; WX 600 ; N ograve ; B 59 -8 627 771 ;
+C -1 ; WX 680 ; N uacute ; B 83 -8 720 771 ;
+C -1 ; WX 680 ; N ucircumflex ; B 83 -8 720 749 ;
+C -1 ; WX 720 ; N Aacute ; B -27 0 769 937 ;
+C -1 ; WX 380 ; N igrave ; B 83 -8 424 771 ;
+C -1 ; WX 380 ; N Icircumflex ; B 14 0 493 915 ;
+C -1 ; WX 560 ; N ccedilla ; B 58 -220 597 515 ;
+C -1 ; WX 680 ; N adieresis ; B 84 -8 735 734 ;
+C -1 ; WX 720 ; N Ecircumflex ; B 14 0 777 915 ;
+C -1 ; WX 540 ; N scaron ; B 32 -8 573 749 ;
+C -1 ; WX 660 ; N thorn ; B -24 -213 682 732 ;
+C -1 ; WX 940 ; N trademark ; B 42 277 982 681 ;
+C -1 ; WX 560 ; N egrave ; B 59 -8 596 771 ;
+C -1 ; WX 408 ; N threesuperior ; B 86 269 483 698 ;
+C -1 ; WX 560 ; N zcaron ; B 36 -8 586 749 ;
+C -1 ; WX 680 ; N atilde ; B 84 -8 735 709 ;
+C -1 ; WX 680 ; N aring ; B 84 -8 735 775 ;
+C -1 ; WX 600 ; N ocircumflex ; B 59 -8 627 749 ;
+C -1 ; WX 720 ; N Edieresis ; B 14 0 777 900 ;
+C -1 ; WX 1020 ; N threequarters ; B 86 0 1054 691 ;
+C -1 ; WX 600 ; N ydieresis ; B 25 -213 642 734 ;
+C -1 ; WX 600 ; N yacute ; B 25 -213 642 771 ;
+C -1 ; WX 380 ; N iacute ; B 83 -8 420 771 ;
+C -1 ; WX 720 ; N Acircumflex ; B -27 0 769 915 ;
+C -1 ; WX 740 ; N Uacute ; B 112 -17 855 937 ;
+C -1 ; WX 560 ; N eacute ; B 59 -8 596 771 ;
+C -1 ; WX 760 ; N Ograve ; B 78 -17 806 937 ;
+C -1 ; WX 680 ; N agrave ; B 84 -8 735 771 ;
+C -1 ; WX 740 ; N Udieresis ; B 112 -17 855 900 ;
+C -1 ; WX 680 ; N acircumflex ; B 84 -8 735 749 ;
+C -1 ; WX 380 ; N Igrave ; B 14 0 485 937 ;
+C -1 ; WX 408 ; N twosuperior ; B 91 279 485 698 ;
+C -1 ; WX 740 ; N Ugrave ; B 112 -17 855 937 ;
+C -1 ; WX 1020 ; N onequarter ; B 118 0 1054 681 ;
+C -1 ; WX 740 ; N Ucircumflex ; B 112 -17 855 915 ;
+C -1 ; WX 700 ; N Scaron ; B 59 -17 731 915 ;
+C -1 ; WX 380 ; N Idieresis ; B 14 0 499 900 ;
+C -1 ; WX 380 ; N idieresis ; B 83 -8 479 734 ;
+C -1 ; WX 720 ; N Egrave ; B 14 0 777 937 ;
+C -1 ; WX 760 ; N Oacute ; B 78 -17 806 937 ;
+C -1 ; WX 600 ; N divide ; B 91 9 595 521 ;
+C -1 ; WX 720 ; N Atilde ; B -27 0 769 875 ;
+C -1 ; WX 720 ; N Aring ; B -27 0 769 941 ;
+C -1 ; WX 760 ; N Odieresis ; B 78 -17 806 900 ;
+C -1 ; WX 720 ; N Adieresis ; B -27 0 769 900 ;
+C -1 ; WX 740 ; N Ntilde ; B 14 0 845 875 ;
+C -1 ; WX 680 ; N Zcaron ; B 23 0 740 915 ;
+C -1 ; WX 640 ; N Thorn ; B -6 0 701 681 ;
+C -1 ; WX 380 ; N Iacute ; B 14 0 485 937 ;
+C -1 ; WX 600 ; N plusminus ; B 91 0 595 514 ;
+C -1 ; WX 600 ; N multiply ; B 91 10 595 514 ;
+C -1 ; WX 720 ; N Eacute ; B 14 0 777 937 ;
+C -1 ; WX 660 ; N Ydieresis ; B 72 0 817 900 ;
+C -1 ; WX 408 ; N onesuperior ; B 118 279 406 688 ;
+C -1 ; WX 680 ; N ugrave ; B 83 -8 720 771 ;
+C -1 ; WX 620 ; N logicalnot ; B 81 129 585 421 ;
+C -1 ; WX 680 ; N ntilde ; B 83 -8 715 709 ;
+C -1 ; WX 760 ; N Otilde ; B 78 -17 806 875 ;
+C -1 ; WX 600 ; N otilde ; B 59 -8 627 709 ;
+C -1 ; WX 700 ; N Ccedilla ; B 78 -220 754 698 ;
+C -1 ; WX 720 ; N Agrave ; B -27 0 769 937 ;
+C -1 ; WX 1020 ; N onehalf ; B 118 0 1036 681 ;
+C -1 ; WX 760 ; N Eth ; B 14 0 805 681 ;
+C -1 ; WX 400 ; N degree ; B 130 398 430 698 ;
+C -1 ; WX 660 ; N Yacute ; B 72 0 817 937 ;
+C -1 ; WX 760 ; N Ocircumflex ; B 78 -17 806 915 ;
+C -1 ; WX 600 ; N oacute ; B 59 -8 627 771 ;
+C -1 ; WX 680 ; N mu ; B 54 -213 720 507 ;
+C -1 ; WX 600 ; N minus ; B 91 207 595 323 ;
+C -1 ; WX 600 ; N eth ; B 59 -8 662 741 ;
+C -1 ; WX 600 ; N odieresis ; B 59 -8 627 734 ;
+C -1 ; WX 780 ; N copyright ; B 83 -17 783 698 ;
+C -1 ; WX 620 ; N brokenbar ; B 303 -175 422 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 92
+
+KPX A y 20
+KPX A w 20
+KPX A v 20
+KPX A Y -25
+KPX A W -35
+KPX A V -40
+KPX A T -17
+
+KPX F period -105
+KPX F comma -98
+KPX F A -35
+
+KPX L y 62
+KPX L Y -5
+KPX L W -15
+KPX L V -19
+KPX L T -26
+
+KPX P period -105
+KPX P comma -98
+KPX P A -31
+
+KPX R y 27
+KPX R Y 4
+KPX R W -4
+KPX R V -8
+KPX R T -3
+
+KPX T y 56
+KPX T w 69
+KPX T u 42
+KPX T semicolon 31
+KPX T s -1
+KPX T r 41
+KPX T period -107
+KPX T o -5
+KPX T i 42
+KPX T hyphen -20
+KPX T e -10
+KPX T comma -100
+KPX T colon 26
+KPX T c -8
+KPX T a -8
+KPX T A -42
+
+KPX V y 17
+KPX V u -1
+KPX V semicolon -22
+KPX V r 2
+KPX V period -115
+KPX V o -50
+KPX V i 32
+KPX V hyphen -20
+KPX V e -50
+KPX V comma -137
+KPX V colon -28
+KPX V a -50
+KPX V A -50
+
+KPX W y -51
+KPX W u -69
+KPX W semicolon -81
+KPX W r -66
+KPX W period -183
+KPX W o -100
+KPX W i -36
+KPX W hyphen -22
+KPX W e -100
+KPX W comma -201
+KPX W colon -86
+KPX W a -100
+KPX W A -77
+
+KPX Y v 26
+KPX Y u -1
+KPX Y semicolon -4
+KPX Y q -43
+KPX Y period -113
+KPX Y o -41
+KPX Y i 20
+KPX Y hyphen -20
+KPX Y e -46
+KPX Y comma -106
+KPX Y colon -9
+KPX Y a -45
+KPX Y A -30
+
+KPX f f 10
+
+KPX r q -3
+KPX r period -120
+KPX r o -1
+KPX r n 39
+KPX r m 39
+KPX r hyphen -20
+KPX r h -35
+KPX r g -23
+KPX r f 42
+KPX r e -6
+KPX r d -3
+KPX r comma -113
+KPX r c -5
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 190 166 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 120 166 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 100 166 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 170 166 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 200 166 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 166 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 190 166 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 120 166 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 100 166 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 170 166 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 20 166 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -30 166 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -70 166 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 166 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 166 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 210 166 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 140 166 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 140 166 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 190 166 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 140 166 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 110 166 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 200 166 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 130 166 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 130 166 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 180 166 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 160 166 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 70 166 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 100 166 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 170 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 100 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 150 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 160 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 100 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 60 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 20 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -90 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -90 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 130 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 60 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 40 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 60 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 30 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 170 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 100 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 80 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 150 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 130 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 40 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Bookman-Light.afm b/tlt3.0/library/afm/Bookman-Light.afm
new file mode 100644
index 0000000..75e019b
--- /dev/null
+++ b/tlt3.0/library/afm/Bookman-Light.afm
@@ -0,0 +1,408 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Jan 21 16:15:53 1992
+Comment UniqueID 37833
+Comment VMusage 32321 39213
+FontName Bookman-Light
+FullName ITC Bookman Light
+FamilyName ITC Bookman
+Weight Light
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -188 -251 1266 908 
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.004
+Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated.  All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation.
+EncodingScheme AdobeStandardEncoding
+CapHeight 681
+XHeight 484
+Ascender 717
+Descender -228
+StartCharMetrics 228
+C 32 ; WX 320 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 300 ; N exclam ; B 75 -8 219 698 ;
+C 34 ; WX 380 ; N quotedbl ; B 56 458 323 698 ;
+C 35 ; WX 620 ; N numbersign ; B 65 0 556 681 ;
+C 36 ; WX 620 ; N dollar ; B 34 -109 593 791 ;
+C 37 ; WX 900 ; N percent ; B 22 -8 873 698 ;
+C 38 ; WX 800 ; N ampersand ; B 45 -17 787 698 ;
+C 39 ; WX 220 ; N quoteright ; B 46 480 178 698 ;
+C 40 ; WX 300 ; N parenleft ; B 76 -145 278 727 ;
+C 41 ; WX 300 ; N parenright ; B 17 -146 219 727 ;
+C 42 ; WX 440 ; N asterisk ; B 54 325 391 698 ;
+C 43 ; WX 600 ; N plus ; B 51 8 555 513 ;
+C 44 ; WX 320 ; N comma ; B 90 -114 223 114 ;
+C 45 ; WX 400 ; N hyphen ; B 50 232 350 292 ;
+C 46 ; WX 320 ; N period ; B 92 -8 220 123 ;
+C 47 ; WX 600 ; N slash ; B 74 -149 532 717 ;
+C 48 ; WX 620 ; N zero ; B 40 -17 586 698 ;
+C 49 ; WX 620 ; N one ; B 160 0 501 681 ;
+C 50 ; WX 620 ; N two ; B 42 0 576 698 ;
+C 51 ; WX 620 ; N three ; B 40 -17 576 698 ;
+C 52 ; WX 620 ; N four ; B 25 0 600 681 ;
+C 53 ; WX 620 ; N five ; B 60 -17 584 717 ;
+C 54 ; WX 620 ; N six ; B 45 -17 590 698 ;
+C 55 ; WX 620 ; N seven ; B 60 0 586 681 ;
+C 56 ; WX 620 ; N eight ; B 44 -17 583 698 ;
+C 57 ; WX 620 ; N nine ; B 37 -17 576 698 ;
+C 58 ; WX 320 ; N colon ; B 92 -8 220 494 ;
+C 59 ; WX 320 ; N semicolon ; B 90 -114 223 494 ;
+C 60 ; WX 600 ; N less ; B 49 -2 558 526 ;
+C 61 ; WX 600 ; N equal ; B 51 126 555 398 ;
+C 62 ; WX 600 ; N greater ; B 48 -2 557 526 ;
+C 63 ; WX 540 ; N question ; B 27 -8 514 698 ;
+C 64 ; WX 820 ; N at ; B 55 -17 755 698 ;
+C 65 ; WX 680 ; N A ; B -37 0 714 681 ;
+C 66 ; WX 740 ; N B ; B 31 0 702 681 ;
+C 67 ; WX 740 ; N C ; B 44 -17 702 698 ;
+C 68 ; WX 800 ; N D ; B 31 0 752 681 ;
+C 69 ; WX 720 ; N E ; B 31 0 705 681 ;
+C 70 ; WX 640 ; N F ; B 31 0 654 681 ;
+C 71 ; WX 800 ; N G ; B 44 -17 778 698 ;
+C 72 ; WX 800 ; N H ; B 31 0 769 681 ;
+C 73 ; WX 340 ; N I ; B 31 0 301 681 ;
+C 74 ; WX 600 ; N J ; B -23 -17 567 681 ;
+C 75 ; WX 720 ; N K ; B 31 0 750 681 ;
+C 76 ; WX 600 ; N L ; B 31 0 629 681 ;
+C 77 ; WX 920 ; N M ; B 26 0 894 681 ;
+C 78 ; WX 740 ; N N ; B 26 0 722 681 ;
+C 79 ; WX 800 ; N O ; B 44 -17 758 698 ;
+C 80 ; WX 620 ; N P ; B 31 0 613 681 ;
+C 81 ; WX 820 ; N Q ; B 44 -189 769 698 ;
+C 82 ; WX 720 ; N R ; B 31 0 757 681 ;
+C 83 ; WX 660 ; N S ; B 28 -17 634 698 ;
+C 84 ; WX 620 ; N T ; B -37 0 656 681 ;
+C 85 ; WX 780 ; N U ; B 25 -17 754 681 ;
+C 86 ; WX 700 ; N V ; B -30 0 725 681 ;
+C 87 ; WX 960 ; N W ; B -30 0 984 681 ;
+C 88 ; WX 720 ; N X ; B -30 0 755 681 ;
+C 89 ; WX 640 ; N Y ; B -30 0 666 681 ;
+C 90 ; WX 640 ; N Z ; B 10 0 656 681 ;
+C 91 ; WX 300 ; N bracketleft ; B 92 -136 258 717 ;
+C 92 ; WX 600 ; N backslash ; B 74 0 532 717 ;
+C 93 ; WX 300 ; N bracketright ; B 41 -136 207 717 ;
+C 94 ; WX 600 ; N asciicircum ; B 52 276 554 681 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 220 ; N quoteleft ; B 46 479 178 698 ;
+C 97 ; WX 580 ; N a ; B 35 -8 587 494 ;
+C 98 ; WX 620 ; N b ; B -2 -8 582 717 ;
+C 99 ; WX 520 ; N c ; B 37 -8 498 494 ;
+C 100 ; WX 620 ; N d ; B 37 -8 591 717 ;
+C 101 ; WX 520 ; N e ; B 37 -8 491 494 ;
+C 102 ; WX 320 ; N f ; B 20 0 414 734 ; L i fi ; L l fl ;
+C 103 ; WX 540 ; N g ; B 17 -243 542 567 ;
+C 104 ; WX 660 ; N h ; B 20 0 643 717 ;
+C 105 ; WX 300 ; N i ; B 20 0 288 654 ;
+C 106 ; WX 300 ; N j ; B -109 -251 214 654 ;
+C 107 ; WX 620 ; N k ; B 20 0 628 717 ;
+C 108 ; WX 300 ; N l ; B 20 0 286 717 ;
+C 109 ; WX 940 ; N m ; B 17 0 928 494 ;
+C 110 ; WX 660 ; N n ; B 20 0 649 494 ;
+C 111 ; WX 560 ; N o ; B 37 -8 526 494 ;
+C 112 ; WX 620 ; N p ; B 20 -228 583 494 ;
+C 113 ; WX 580 ; N q ; B 37 -228 589 494 ;
+C 114 ; WX 440 ; N r ; B 20 0 447 494 ;
+C 115 ; WX 520 ; N s ; B 40 -8 487 494 ;
+C 116 ; WX 380 ; N t ; B 20 -8 388 667 ;
+C 117 ; WX 680 ; N u ; B 20 -8 653 484 ;
+C 118 ; WX 520 ; N v ; B -23 0 534 484 ;
+C 119 ; WX 780 ; N w ; B -19 0 804 484 ;
+C 120 ; WX 560 ; N x ; B -16 0 576 484 ;
+C 121 ; WX 540 ; N y ; B -23 -236 549 484 ;
+C 122 ; WX 480 ; N z ; B 7 0 476 484 ;
+C 123 ; WX 280 ; N braceleft ; B 21 -136 260 717 ;
+C 124 ; WX 600 ; N bar ; B 264 -250 342 750 ;
+C 125 ; WX 280 ; N braceright ; B 21 -136 260 717 ;
+C 126 ; WX 600 ; N asciitilde ; B 52 173 556 352 ;
+C 161 ; WX 300 ; N exclamdown ; B 75 -214 219 494 ;
+C 162 ; WX 620 ; N cent ; B 116 20 511 651 ;
+C 163 ; WX 620 ; N sterling ; B 8 -17 631 698 ;
+C 164 ; WX 140 ; N fraction ; B -188 0 335 681 ;
+C 165 ; WX 620 ; N yen ; B -22 0 647 681 ;
+C 166 ; WX 620 ; N florin ; B -29 -155 633 749 ;
+C 167 ; WX 520 ; N section ; B 33 -178 486 698 ;
+C 168 ; WX 620 ; N currency ; B 58 89 563 591 ;
+C 169 ; WX 220 ; N quotesingle ; B 67 458 153 698 ;
+C 170 ; WX 400 ; N quotedblleft ; B 46 479 348 698 ;
+C 171 ; WX 360 ; N guillemotleft ; B 51 89 312 437 ;
+C 172 ; WX 240 ; N guilsinglleft ; B 51 89 189 437 ;
+C 173 ; WX 240 ; N guilsinglright ; B 51 89 189 437 ;
+C 174 ; WX 620 ; N fi ; B 20 0 608 734 ;
+C 175 ; WX 620 ; N fl ; B 20 0 606 734 ;
+C 177 ; WX 500 ; N endash ; B -15 232 515 292 ;
+C 178 ; WX 540 ; N dagger ; B 79 -156 455 698 ;
+C 179 ; WX 540 ; N daggerdbl ; B 79 -156 455 698 ;
+C 180 ; WX 320 ; N periodcentered ; B 92 196 220 327 ;
+C 182 ; WX 600 ; N paragraph ; B 14 0 577 681 ;
+C 183 ; WX 460 ; N bullet ; B 60 170 404 511 ;
+C 184 ; WX 220 ; N quotesinglbase ; B 46 -108 178 110 ;
+C 185 ; WX 400 ; N quotedblbase ; B 46 -108 348 110 ;
+C 186 ; WX 400 ; N quotedblright ; B 46 480 348 698 ;
+C 187 ; WX 360 ; N guillemotright ; B 51 89 312 437 ;
+C 188 ; WX 1000 ; N ellipsis ; B 101 -8 898 123 ;
+C 189 ; WX 1280 ; N perthousand ; B 22 -8 1266 698 ;
+C 191 ; WX 540 ; N questiondown ; B 23 -217 510 494 ;
+C 193 ; WX 340 ; N grave ; B 68 571 274 689 ;
+C 194 ; WX 340 ; N acute ; B 68 571 274 689 ;
+C 195 ; WX 420 ; N circumflex ; B 68 567 352 685 ;
+C 196 ; WX 440 ; N tilde ; B 68 572 375 661 ;
+C 197 ; WX 440 ; N macron ; B 68 587 364 635 ;
+C 198 ; WX 460 ; N breve ; B 68 568 396 687 ;
+C 199 ; WX 260 ; N dotaccent ; B 68 552 186 672 ;
+C 200 ; WX 420 ; N dieresis ; B 68 552 349 674 ;
+C 202 ; WX 320 ; N ring ; B 68 546 252 731 ;
+C 203 ; WX 320 ; N cedilla ; B 68 -200 257 0 ;
+C 205 ; WX 380 ; N hungarumlaut ; B 68 538 311 698 ;
+C 206 ; WX 320 ; N ogonek ; B 68 -145 245 0 ;
+C 207 ; WX 420 ; N caron ; B 68 554 352 672 ;
+C 208 ; WX 1000 ; N emdash ; B -15 232 1015 292 ;
+C 225 ; WX 1260 ; N AE ; B -36 0 1250 681 ;
+C 227 ; WX 420 ; N ordfeminine ; B 49 395 393 698 ;
+C 232 ; WX 600 ; N Lslash ; B 31 0 629 681 ;
+C 233 ; WX 800 ; N Oslash ; B 44 -53 758 733 ;
+C 234 ; WX 1240 ; N OE ; B 44 -17 1214 698 ;
+C 235 ; WX 420 ; N ordmasculine ; B 56 394 361 698 ;
+C 241 ; WX 860 ; N ae ; B 35 -8 832 494 ;
+C 245 ; WX 300 ; N dotlessi ; B 20 0 288 484 ;
+C 248 ; WX 320 ; N lslash ; B 20 0 291 717 ;
+C 249 ; WX 560 ; N oslash ; B 37 -40 526 534 ;
+C 250 ; WX 900 ; N oe ; B 37 -8 876 494 ;
+C 251 ; WX 660 ; N germandbls ; B -109 -110 614 698 ;
+C -1 ; WX 520 ; N ecircumflex ; B 37 -8 491 685 ;
+C -1 ; WX 520 ; N edieresis ; B 37 -8 491 674 ;
+C -1 ; WX 580 ; N aacute ; B 35 -8 587 689 ;
+C -1 ; WX 740 ; N registered ; B 23 -17 723 698 ;
+C -1 ; WX 300 ; N icircumflex ; B 8 0 292 685 ;
+C -1 ; WX 680 ; N udieresis ; B 20 -8 653 674 ;
+C -1 ; WX 560 ; N ograve ; B 37 -8 526 689 ;
+C -1 ; WX 680 ; N uacute ; B 20 -8 653 689 ;
+C -1 ; WX 680 ; N ucircumflex ; B 20 -8 653 685 ;
+C -1 ; WX 680 ; N Aacute ; B -37 0 714 866 ;
+C -1 ; WX 300 ; N igrave ; B 20 0 288 689 ;
+C -1 ; WX 340 ; N Icircumflex ; B 28 0 312 862 ;
+C -1 ; WX 520 ; N ccedilla ; B 37 -200 498 494 ;
+C -1 ; WX 580 ; N adieresis ; B 35 -8 587 674 ;
+C -1 ; WX 720 ; N Ecircumflex ; B 31 0 705 862 ;
+C -1 ; WX 520 ; N scaron ; B 40 -8 487 672 ;
+C -1 ; WX 620 ; N thorn ; B 20 -228 583 717 ;
+C -1 ; WX 980 ; N trademark ; B 34 277 930 681 ;
+C -1 ; WX 520 ; N egrave ; B 37 -8 491 689 ;
+C -1 ; WX 372 ; N threesuperior ; B 12 269 360 698 ;
+C -1 ; WX 480 ; N zcaron ; B 7 0 476 672 ;
+C -1 ; WX 580 ; N atilde ; B 35 -8 587 661 ;
+C -1 ; WX 580 ; N aring ; B 35 -8 587 731 ;
+C -1 ; WX 560 ; N ocircumflex ; B 37 -8 526 685 ;
+C -1 ; WX 720 ; N Edieresis ; B 31 0 705 851 ;
+C -1 ; WX 930 ; N threequarters ; B 52 0 889 691 ;
+C -1 ; WX 540 ; N ydieresis ; B -23 -236 549 674 ;
+C -1 ; WX 540 ; N yacute ; B -23 -236 549 689 ;
+C -1 ; WX 300 ; N iacute ; B 20 0 288 689 ;
+C -1 ; WX 680 ; N Acircumflex ; B -37 0 714 862 ;
+C -1 ; WX 780 ; N Uacute ; B 25 -17 754 866 ;
+C -1 ; WX 520 ; N eacute ; B 37 -8 491 689 ;
+C -1 ; WX 800 ; N Ograve ; B 44 -17 758 866 ;
+C -1 ; WX 580 ; N agrave ; B 35 -8 587 689 ;
+C -1 ; WX 780 ; N Udieresis ; B 25 -17 754 851 ;
+C -1 ; WX 580 ; N acircumflex ; B 35 -8 587 685 ;
+C -1 ; WX 340 ; N Igrave ; B 31 0 301 866 ;
+C -1 ; WX 372 ; N twosuperior ; B 20 279 367 698 ;
+C -1 ; WX 780 ; N Ugrave ; B 25 -17 754 866 ;
+C -1 ; WX 930 ; N onequarter ; B 80 0 869 681 ;
+C -1 ; WX 780 ; N Ucircumflex ; B 25 -17 754 862 ;
+C -1 ; WX 660 ; N Scaron ; B 28 -17 634 849 ;
+C -1 ; WX 340 ; N Idieresis ; B 28 0 309 851 ;
+C -1 ; WX 300 ; N idieresis ; B 8 0 289 674 ;
+C -1 ; WX 720 ; N Egrave ; B 31 0 705 866 ;
+C -1 ; WX 800 ; N Oacute ; B 44 -17 758 866 ;
+C -1 ; WX 600 ; N divide ; B 51 10 555 514 ;
+C -1 ; WX 680 ; N Atilde ; B -37 0 714 838 ;
+C -1 ; WX 680 ; N Aring ; B -37 0 714 908 ;
+C -1 ; WX 800 ; N Odieresis ; B 44 -17 758 851 ;
+C -1 ; WX 680 ; N Adieresis ; B -37 0 714 851 ;
+C -1 ; WX 740 ; N Ntilde ; B 26 0 722 838 ;
+C -1 ; WX 640 ; N Zcaron ; B 10 0 656 849 ;
+C -1 ; WX 620 ; N Thorn ; B 31 0 613 681 ;
+C -1 ; WX 340 ; N Iacute ; B 31 0 301 866 ;
+C -1 ; WX 600 ; N plusminus ; B 51 0 555 513 ;
+C -1 ; WX 600 ; N multiply ; B 51 9 555 513 ;
+C -1 ; WX 720 ; N Eacute ; B 31 0 705 866 ;
+C -1 ; WX 640 ; N Ydieresis ; B -30 0 666 851 ;
+C -1 ; WX 372 ; N onesuperior ; B 80 279 302 688 ;
+C -1 ; WX 680 ; N ugrave ; B 20 -8 653 689 ;
+C -1 ; WX 600 ; N logicalnot ; B 51 128 555 398 ;
+C -1 ; WX 660 ; N ntilde ; B 20 0 649 661 ;
+C -1 ; WX 800 ; N Otilde ; B 44 -17 758 838 ;
+C -1 ; WX 560 ; N otilde ; B 37 -8 526 661 ;
+C -1 ; WX 740 ; N Ccedilla ; B 44 -200 702 698 ;
+C -1 ; WX 680 ; N Agrave ; B -37 0 714 866 ;
+C -1 ; WX 930 ; N onehalf ; B 80 0 885 681 ;
+C -1 ; WX 800 ; N Eth ; B 31 0 752 681 ;
+C -1 ; WX 400 ; N degree ; B 50 398 350 698 ;
+C -1 ; WX 640 ; N Yacute ; B -30 0 666 866 ;
+C -1 ; WX 800 ; N Ocircumflex ; B 44 -17 758 862 ;
+C -1 ; WX 560 ; N oacute ; B 37 -8 526 689 ;
+C -1 ; WX 680 ; N mu ; B 20 -251 653 484 ;
+C -1 ; WX 600 ; N minus ; B 51 224 555 300 ;
+C -1 ; WX 560 ; N eth ; B 37 -8 526 734 ;
+C -1 ; WX 560 ; N odieresis ; B 37 -8 526 674 ;
+C -1 ; WX 740 ; N copyright ; B 24 -17 724 698 ;
+C -1 ; WX 600 ; N brokenbar ; B 264 -175 342 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 82
+
+KPX A y 32
+KPX A w 4
+KPX A v 7
+KPX A Y -35
+KPX A W -40
+KPX A V -56
+KPX A T 1
+
+KPX F period -46
+KPX F comma -41
+KPX F A -21
+
+KPX L y 79
+KPX L Y 13
+KPX L W 1
+KPX L V -4
+KPX L T 28
+
+KPX P period -60
+KPX P comma -55
+KPX P A -8
+
+KPX R y 59
+KPX R Y 26
+KPX R W 13
+KPX R V 8
+KPX R T 71
+
+KPX T s 16
+KPX T r 38
+KPX T period -33
+KPX T o 15
+KPX T i 42
+KPX T hyphen 90
+KPX T e 13
+KPX T comma -28
+KPX T c 14
+KPX T a 17
+KPX T A 1
+
+KPX V y 15
+KPX V u -38
+KPX V r -41
+KPX V period -40
+KPX V o -71
+KPX V i -20
+KPX V hyphen 11
+KPX V e -72
+KPX V comma -34
+KPX V a -69
+KPX V A -66
+
+KPX W y 15
+KPX W u -38
+KPX W r -41
+KPX W period -40
+KPX W o -68
+KPX W i -20
+KPX W hyphen 11
+KPX W e -69
+KPX W comma -34
+KPX W a -66
+KPX W A -64
+
+KPX Y v 15
+KPX Y u -38
+KPX Y q -55
+KPX Y period -40
+KPX Y p -31
+KPX Y o -57
+KPX Y i -37
+KPX Y hyphen 11
+KPX Y e -58
+KPX Y comma -34
+KPX Y a -54
+KPX Y A -53
+
+KPX f f 29
+
+KPX r q 9
+KPX r period -64
+KPX r o 8
+KPX r n 31
+KPX r m 31
+KPX r hyphen 70
+KPX r h -21
+KPX r g -4
+KPX r f 33
+KPX r e 7
+KPX r d 7
+KPX r comma -58
+KPX r c 7
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 200 177 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 130 177 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 130 177 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 140 177 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 180 177 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 177 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 220 177 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 150 177 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 150 177 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 160 177 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 20 177 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -40 177 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -40 177 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -20 177 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 150 177 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 260 177 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 190 177 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 190 177 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 177 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 180 177 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 120 177 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 250 177 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 180 177 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 180 177 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 190 177 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 150 177 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 110 177 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 110 177 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 80 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 130 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 70 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 50 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -20 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -60 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -60 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -20 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 110 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 70 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 60 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 50 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 170 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 130 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 130 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 170 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 100 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 60 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 30 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Bookman-LightItalic.afm b/tlt3.0/library/afm/Bookman-LightItalic.afm
new file mode 100644
index 0000000..3e6ef4c
--- /dev/null
+++ b/tlt3.0/library/afm/Bookman-LightItalic.afm
@@ -0,0 +1,411 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Jan 21 16:12:06 1992
+Comment UniqueID 37830
+Comment VMusage 33139 40031
+FontName Bookman-LightItalic
+FullName ITC Bookman Light Italic
+FamilyName ITC Bookman
+Weight Light
+ItalicAngle -10
+IsFixedPitch false
+FontBBox -228 -250 1269 883 
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.004
+Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated.  All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation.
+EncodingScheme AdobeStandardEncoding
+CapHeight 681
+XHeight 494
+Ascender 717
+Descender -212
+StartCharMetrics 228
+C 32 ; WX 300 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 320 ; N exclam ; B 103 -8 342 698 ;
+C 34 ; WX 360 ; N quotedbl ; B 107 468 402 698 ;
+C 35 ; WX 620 ; N numbersign ; B 107 0 598 681 ;
+C 36 ; WX 620 ; N dollar ; B 78 -85 619 762 ;
+C 37 ; WX 800 ; N percent ; B 56 -8 811 691 ;
+C 38 ; WX 820 ; N ampersand ; B 65 -18 848 698 ;
+C 39 ; WX 280 ; N quoteright ; B 148 470 288 698 ;
+C 40 ; WX 280 ; N parenleft ; B 96 -146 383 727 ;
+C 41 ; WX 280 ; N parenright ; B -8 -146 279 727 ;
+C 42 ; WX 440 ; N asterisk ; B 139 324 505 698 ;
+C 43 ; WX 600 ; N plus ; B 91 43 595 548 ;
+C 44 ; WX 300 ; N comma ; B 88 -115 227 112 ;
+C 45 ; WX 320 ; N hyphen ; B 78 269 336 325 ;
+C 46 ; WX 300 ; N period ; B 96 -8 231 127 ;
+C 47 ; WX 600 ; N slash ; B 104 -149 562 717 ;
+C 48 ; WX 620 ; N zero ; B 86 -17 646 698 ;
+C 49 ; WX 620 ; N one ; B 154 0 500 681 ;
+C 50 ; WX 620 ; N two ; B 66 0 636 698 ;
+C 51 ; WX 620 ; N three ; B 55 -17 622 698 ;
+C 52 ; WX 620 ; N four ; B 69 0 634 681 ;
+C 53 ; WX 620 ; N five ; B 70 -17 614 681 ;
+C 54 ; WX 620 ; N six ; B 89 -17 657 698 ;
+C 55 ; WX 620 ; N seven ; B 143 0 672 681 ;
+C 56 ; WX 620 ; N eight ; B 61 -17 655 698 ;
+C 57 ; WX 620 ; N nine ; B 77 -17 649 698 ;
+C 58 ; WX 300 ; N colon ; B 96 -8 292 494 ;
+C 59 ; WX 300 ; N semicolon ; B 88 -114 292 494 ;
+C 60 ; WX 600 ; N less ; B 79 33 588 561 ;
+C 61 ; WX 600 ; N equal ; B 91 161 595 433 ;
+C 62 ; WX 600 ; N greater ; B 93 33 602 561 ;
+C 63 ; WX 540 ; N question ; B 114 -8 604 698 ;
+C 64 ; WX 780 ; N at ; B 102 -17 802 698 ;
+C 65 ; WX 700 ; N A ; B -25 0 720 681 ;
+C 66 ; WX 720 ; N B ; B 21 0 746 681 ;
+C 67 ; WX 720 ; N C ; B 88 -17 746 698 ;
+C 68 ; WX 740 ; N D ; B 21 0 782 681 ;
+C 69 ; WX 680 ; N E ; B 21 0 736 681 ;
+C 70 ; WX 620 ; N F ; B 21 0 743 681 ;
+C 71 ; WX 760 ; N G ; B 88 -17 813 698 ;
+C 72 ; WX 800 ; N H ; B 21 0 888 681 ;
+C 73 ; WX 320 ; N I ; B 21 0 412 681 ;
+C 74 ; WX 560 ; N J ; B -2 -17 666 681 ;
+C 75 ; WX 720 ; N K ; B 21 0 804 681 ;
+C 76 ; WX 580 ; N L ; B 21 0 656 681 ;
+C 77 ; WX 860 ; N M ; B 18 0 956 681 ;
+C 78 ; WX 720 ; N N ; B 18 0 823 681 ;
+C 79 ; WX 760 ; N O ; B 88 -17 799 698 ;
+C 80 ; WX 600 ; N P ; B 21 0 681 681 ;
+C 81 ; WX 780 ; N Q ; B 61 -191 812 698 ;
+C 82 ; WX 700 ; N R ; B 21 0 736 681 ;
+C 83 ; WX 640 ; N S ; B 61 -17 668 698 ;
+C 84 ; WX 600 ; N T ; B 50 0 725 681 ;
+C 85 ; WX 720 ; N U ; B 118 -17 842 681 ;
+C 86 ; WX 680 ; N V ; B 87 0 815 681 ;
+C 87 ; WX 960 ; N W ; B 87 0 1095 681 ;
+C 88 ; WX 700 ; N X ; B -25 0 815 681 ;
+C 89 ; WX 660 ; N Y ; B 87 0 809 681 ;
+C 90 ; WX 580 ; N Z ; B 8 0 695 681 ;
+C 91 ; WX 260 ; N bracketleft ; B 56 -136 351 717 ;
+C 92 ; WX 600 ; N backslash ; B 84 0 542 717 ;
+C 93 ; WX 260 ; N bracketright ; B 15 -136 309 717 ;
+C 94 ; WX 600 ; N asciicircum ; B 97 276 599 681 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 280 ; N quoteleft ; B 191 470 330 698 ;
+C 97 ; WX 620 ; N a ; B 71 -8 686 494 ;
+C 98 ; WX 600 ; N b ; B 88 -8 621 717 ;
+C 99 ; WX 480 ; N c ; B 65 -8 522 494 ;
+C 100 ; WX 640 ; N d ; B 65 -8 695 717 ;
+C 101 ; WX 540 ; N e ; B 65 -8 575 494 ;
+C 102 ; WX 340 ; N f ; B -160 -218 557 725 ; L i fi ; L l fl ;
+C 103 ; WX 560 ; N g ; B 4 -221 581 494 ;
+C 104 ; WX 620 ; N h ; B 88 -8 689 717 ;
+C 105 ; WX 280 ; N i ; B 88 -8 351 663 ;
+C 106 ; WX 280 ; N j ; B -200 -221 308 663 ;
+C 107 ; WX 600 ; N k ; B 88 -8 657 717 ;
+C 108 ; WX 280 ; N l ; B 100 -8 342 717 ;
+C 109 ; WX 880 ; N m ; B 88 -8 952 494 ;
+C 110 ; WX 620 ; N n ; B 88 -8 673 494 ;
+C 111 ; WX 540 ; N o ; B 65 -8 572 494 ;
+C 112 ; WX 600 ; N p ; B -24 -212 620 494 ;
+C 113 ; WX 560 ; N q ; B 65 -212 584 494 ;
+C 114 ; WX 400 ; N r ; B 88 0 481 494 ;
+C 115 ; WX 540 ; N s ; B 65 -8 547 494 ;
+C 116 ; WX 340 ; N t ; B 88 -8 411 664 ;
+C 117 ; WX 620 ; N u ; B 88 -8 686 484 ;
+C 118 ; WX 540 ; N v ; B 88 -8 562 494 ;
+C 119 ; WX 880 ; N w ; B 88 -8 893 494 ;
+C 120 ; WX 540 ; N x ; B 9 -8 626 494 ;
+C 121 ; WX 600 ; N y ; B 60 -221 609 484 ;
+C 122 ; WX 520 ; N z ; B 38 -8 561 494 ;
+C 123 ; WX 360 ; N braceleft ; B 122 -191 442 717 ;
+C 124 ; WX 600 ; N bar ; B 294 -250 372 750 ;
+C 125 ; WX 380 ; N braceright ; B 13 -191 333 717 ;
+C 126 ; WX 600 ; N asciitilde ; B 91 207 595 386 ;
+C 161 ; WX 320 ; N exclamdown ; B 73 -213 301 494 ;
+C 162 ; WX 620 ; N cent ; B 148 -29 596 715 ;
+C 163 ; WX 620 ; N sterling ; B 4 -17 702 698 ;
+C 164 ; WX 20 ; N fraction ; B -228 0 323 681 ;
+C 165 ; WX 620 ; N yen ; B 71 0 735 681 ;
+C 166 ; WX 620 ; N florin ; B -26 -218 692 725 ;
+C 167 ; WX 620 ; N section ; B 38 -178 638 698 ;
+C 168 ; WX 620 ; N currency ; B 100 89 605 591 ;
+C 169 ; WX 200 ; N quotesingle ; B 99 473 247 698 ;
+C 170 ; WX 440 ; N quotedblleft ; B 191 470 493 698 ;
+C 171 ; WX 300 ; N guillemotleft ; B 70 129 313 434 ;
+C 172 ; WX 180 ; N guilsinglleft ; B 75 129 208 434 ;
+C 173 ; WX 180 ; N guilsinglright ; B 70 129 203 434 ;
+C 174 ; WX 640 ; N fi ; B -159 -222 709 725 ;
+C 175 ; WX 660 ; N fl ; B -159 -218 713 725 ;
+C 177 ; WX 500 ; N endash ; B 33 269 561 325 ;
+C 178 ; WX 620 ; N dagger ; B 192 -130 570 698 ;
+C 179 ; WX 620 ; N daggerdbl ; B 144 -122 566 698 ;
+C 180 ; WX 300 ; N periodcentered ; B 137 229 272 364 ;
+C 182 ; WX 620 ; N paragraph ; B 112 0 718 681 ;
+C 183 ; WX 460 ; N bullet ; B 100 170 444 511 ;
+C 184 ; WX 320 ; N quotesinglbase ; B 87 -114 226 113 ;
+C 185 ; WX 480 ; N quotedblbase ; B 87 -114 390 113 ;
+C 186 ; WX 440 ; N quotedblright ; B 148 470 451 698 ;
+C 187 ; WX 300 ; N guillemotright ; B 60 129 303 434 ;
+C 188 ; WX 1000 ; N ellipsis ; B 99 -8 900 127 ;
+C 189 ; WX 1180 ; N perthousand ; B 56 -8 1199 691 ;
+C 191 ; WX 540 ; N questiondown ; B 18 -212 508 494 ;
+C 193 ; WX 340 ; N grave ; B 182 551 377 706 ;
+C 194 ; WX 320 ; N acute ; B 178 551 373 706 ;
+C 195 ; WX 440 ; N circumflex ; B 176 571 479 685 ;
+C 196 ; WX 440 ; N tilde ; B 180 586 488 671 ;
+C 197 ; WX 440 ; N macron ; B 178 599 484 658 ;
+C 198 ; WX 440 ; N breve ; B 191 577 500 680 ;
+C 199 ; WX 260 ; N dotaccent ; B 169 543 290 664 ;
+C 200 ; WX 420 ; N dieresis ; B 185 569 467 688 ;
+C 202 ; WX 300 ; N ring ; B 178 551 334 706 ;
+C 203 ; WX 320 ; N cedilla ; B 45 -178 240 0 ;
+C 205 ; WX 340 ; N hungarumlaut ; B 167 547 402 738 ;
+C 206 ; WX 260 ; N ogonek ; B 51 -173 184 0 ;
+C 207 ; WX 440 ; N caron ; B 178 571 481 684 ;
+C 208 ; WX 1000 ; N emdash ; B 33 269 1061 325 ;
+C 225 ; WX 1220 ; N AE ; B -45 0 1269 681 ;
+C 227 ; WX 440 ; N ordfeminine ; B 130 396 513 698 ;
+C 232 ; WX 580 ; N Lslash ; B 21 0 656 681 ;
+C 233 ; WX 760 ; N Oslash ; B 88 -95 799 777 ;
+C 234 ; WX 1180 ; N OE ; B 88 -17 1237 698 ;
+C 235 ; WX 400 ; N ordmasculine ; B 139 396 455 698 ;
+C 241 ; WX 880 ; N ae ; B 71 -8 918 494 ;
+C 245 ; WX 280 ; N dotlessi ; B 88 -8 351 484 ;
+C 248 ; WX 340 ; N lslash ; B 50 -8 398 717 ;
+C 249 ; WX 540 ; N oslash ; B 65 -49 571 532 ;
+C 250 ; WX 900 ; N oe ; B 65 -8 948 494 ;
+C 251 ; WX 620 ; N germandbls ; B -121 -111 653 698 ;
+C -1 ; WX 540 ; N ecircumflex ; B 65 -8 575 685 ;
+C -1 ; WX 540 ; N edieresis ; B 65 -8 575 688 ;
+C -1 ; WX 620 ; N aacute ; B 71 -8 686 706 ;
+C -1 ; WX 740 ; N registered ; B 84 -17 784 698 ;
+C -1 ; WX 280 ; N icircumflex ; B 76 -8 379 685 ;
+C -1 ; WX 620 ; N udieresis ; B 88 -8 686 688 ;
+C -1 ; WX 540 ; N ograve ; B 65 -8 572 706 ;
+C -1 ; WX 620 ; N uacute ; B 88 -8 686 706 ;
+C -1 ; WX 620 ; N ucircumflex ; B 88 -8 686 685 ;
+C -1 ; WX 700 ; N Aacute ; B -25 0 720 883 ;
+C -1 ; WX 280 ; N igrave ; B 88 -8 351 706 ;
+C -1 ; WX 320 ; N Icircumflex ; B 21 0 449 862 ;
+C -1 ; WX 480 ; N ccedilla ; B 65 -178 522 494 ;
+C -1 ; WX 620 ; N adieresis ; B 71 -8 686 688 ;
+C -1 ; WX 680 ; N Ecircumflex ; B 21 0 736 862 ;
+C -1 ; WX 540 ; N scaron ; B 65 -8 547 684 ;
+C -1 ; WX 600 ; N thorn ; B -24 -212 620 717 ;
+C -1 ; WX 980 ; N trademark ; B 69 277 965 681 ;
+C -1 ; WX 540 ; N egrave ; B 65 -8 575 706 ;
+C -1 ; WX 372 ; N threesuperior ; B 70 269 439 698 ;
+C -1 ; WX 520 ; N zcaron ; B 38 -8 561 684 ;
+C -1 ; WX 620 ; N atilde ; B 71 -8 686 671 ;
+C -1 ; WX 620 ; N aring ; B 71 -8 686 706 ;
+C -1 ; WX 540 ; N ocircumflex ; B 65 -8 572 685 ;
+C -1 ; WX 680 ; N Edieresis ; B 21 0 736 865 ;
+C -1 ; WX 930 ; N threequarters ; B 99 0 913 691 ;
+C -1 ; WX 600 ; N ydieresis ; B 60 -221 609 688 ;
+C -1 ; WX 600 ; N yacute ; B 60 -221 609 706 ;
+C -1 ; WX 280 ; N iacute ; B 88 -8 351 706 ;
+C -1 ; WX 700 ; N Acircumflex ; B -25 0 720 862 ;
+C -1 ; WX 720 ; N Uacute ; B 118 -17 842 883 ;
+C -1 ; WX 540 ; N eacute ; B 65 -8 575 706 ;
+C -1 ; WX 760 ; N Ograve ; B 88 -17 799 883 ;
+C -1 ; WX 620 ; N agrave ; B 71 -8 686 706 ;
+C -1 ; WX 720 ; N Udieresis ; B 118 -17 842 865 ;
+C -1 ; WX 620 ; N acircumflex ; B 71 -8 686 685 ;
+C -1 ; WX 320 ; N Igrave ; B 21 0 412 883 ;
+C -1 ; WX 372 ; N twosuperior ; B 68 279 439 698 ;
+C -1 ; WX 720 ; N Ugrave ; B 118 -17 842 883 ;
+C -1 ; WX 930 ; N onequarter ; B 91 0 913 681 ;
+C -1 ; WX 720 ; N Ucircumflex ; B 118 -17 842 862 ;
+C -1 ; WX 640 ; N Scaron ; B 61 -17 668 861 ;
+C -1 ; WX 320 ; N Idieresis ; B 21 0 447 865 ;
+C -1 ; WX 280 ; N idieresis ; B 88 -8 377 688 ;
+C -1 ; WX 680 ; N Egrave ; B 21 0 736 883 ;
+C -1 ; WX 760 ; N Oacute ; B 88 -17 799 883 ;
+C -1 ; WX 600 ; N divide ; B 91 46 595 548 ;
+C -1 ; WX 700 ; N Atilde ; B -25 0 720 848 ;
+C -1 ; WX 700 ; N Aring ; B -25 0 720 883 ;
+C -1 ; WX 760 ; N Odieresis ; B 88 -17 799 865 ;
+C -1 ; WX 700 ; N Adieresis ; B -25 0 720 865 ;
+C -1 ; WX 720 ; N Ntilde ; B 18 0 823 848 ;
+C -1 ; WX 580 ; N Zcaron ; B 8 0 695 861 ;
+C -1 ; WX 600 ; N Thorn ; B 21 0 656 681 ;
+C -1 ; WX 320 ; N Iacute ; B 21 0 412 883 ;
+C -1 ; WX 600 ; N plusminus ; B 91 0 595 548 ;
+C -1 ; WX 600 ; N multiply ; B 91 44 595 548 ;
+C -1 ; WX 680 ; N Eacute ; B 21 0 736 883 ;
+C -1 ; WX 660 ; N Ydieresis ; B 87 0 809 865 ;
+C -1 ; WX 372 ; N onesuperior ; B 114 279 339 688 ;
+C -1 ; WX 620 ; N ugrave ; B 88 -8 686 706 ;
+C -1 ; WX 600 ; N logicalnot ; B 91 163 595 433 ;
+C -1 ; WX 620 ; N ntilde ; B 88 -8 673 671 ;
+C -1 ; WX 760 ; N Otilde ; B 88 -17 799 848 ;
+C -1 ; WX 540 ; N otilde ; B 65 -8 572 671 ;
+C -1 ; WX 720 ; N Ccedilla ; B 88 -178 746 698 ;
+C -1 ; WX 700 ; N Agrave ; B -25 0 720 883 ;
+C -1 ; WX 930 ; N onehalf ; B 91 0 925 681 ;
+C -1 ; WX 740 ; N Eth ; B 21 0 782 681 ;
+C -1 ; WX 400 ; N degree ; B 120 398 420 698 ;
+C -1 ; WX 660 ; N Yacute ; B 87 0 809 883 ;
+C -1 ; WX 760 ; N Ocircumflex ; B 88 -17 799 862 ;
+C -1 ; WX 540 ; N oacute ; B 65 -8 572 706 ;
+C -1 ; WX 620 ; N mu ; B 53 -221 686 484 ;
+C -1 ; WX 600 ; N minus ; B 91 259 595 335 ;
+C -1 ; WX 540 ; N eth ; B 65 -8 642 725 ;
+C -1 ; WX 540 ; N odieresis ; B 65 -8 572 688 ;
+C -1 ; WX 740 ; N copyright ; B 84 -17 784 698 ;
+C -1 ; WX 600 ; N brokenbar ; B 294 -175 372 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 85
+
+KPX A Y -62
+KPX A W -73
+KPX A V -78
+KPX A T -5
+
+KPX F period -97
+KPX F comma -98
+KPX F A -16
+
+KPX L y 20
+KPX L Y 7
+KPX L W 9
+KPX L V 4
+
+KPX P period -105
+KPX P comma -106
+KPX P A -30
+
+KPX R Y 11
+KPX R W 2
+KPX R V 2
+KPX R T 65
+
+KPX T semicolon 48
+KPX T s -7
+KPX T r 67
+KPX T period -78
+KPX T o 14
+KPX T i 71
+KPX T hyphen 20
+KPX T e 10
+KPX T comma -79
+KPX T colon 48
+KPX T c 16
+KPX T a 9
+KPX T A -14
+
+KPX V y -14
+KPX V u -10
+KPX V semicolon -44
+KPX V r -20
+KPX V period -100
+KPX V o -70
+KPX V i 3
+KPX V hyphen 20
+KPX V e -70
+KPX V comma -109
+KPX V colon -35
+KPX V a -70
+KPX V A -70
+
+KPX W y -14
+KPX W u -20
+KPX W semicolon -42
+KPX W r -30
+KPX W period -100
+KPX W o -60
+KPX W i 3
+KPX W hyphen 20
+KPX W e -60
+KPX W comma -109
+KPX W colon -35
+KPX W a -60
+KPX W A -60
+
+KPX Y v -19
+KPX Y u -31
+KPX Y semicolon -40
+KPX Y q -72
+KPX Y period -100
+KPX Y p -37
+KPX Y o -75
+KPX Y i -11
+KPX Y hyphen 20
+KPX Y e -78
+KPX Y comma -109
+KPX Y colon -35
+KPX Y a -79
+KPX Y A -82
+
+KPX f f -19
+
+KPX r q -14
+KPX r period -134
+KPX r o -10
+KPX r n 38
+KPX r m 37
+KPX r hyphen 20
+KPX r h -20
+KPX r g -3
+KPX r f -9
+KPX r e -15
+KPX r d -9
+KPX r comma -143
+KPX r c -8
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 200 177 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 130 177 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 140 177 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 177 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 220 177 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 130 177 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 210 177 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 140 177 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 150 177 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 150 177 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 30 177 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -30 177 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -20 177 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -30 177 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 177 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 177 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 190 177 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 200 177 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 210 177 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 190 177 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 100 177 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 230 177 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 170 177 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 180 177 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 170 177 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 200 177 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 140 177 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 70 177 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 70 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 110 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 140 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 60 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 30 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 40 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 80 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -40 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -100 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -90 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -60 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 80 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 20 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 40 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 80 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 30 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 30 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 120 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 60 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 70 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 110 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 140 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 70 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 20 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Courier-Bold.afm b/tlt3.0/library/afm/Courier-Bold.afm
new file mode 100644
index 0000000..4ade4fa
--- /dev/null
+++ b/tlt3.0/library/afm/Courier-Bold.afm
@@ -0,0 +1,345 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved.
+Comment Creation Date: Tue Sep 17 14:02:41 1991
+Comment UniqueID 36384
+Comment VMusage 31992 40360
+FontName Courier-Bold
+FullName Courier Bold
+FamilyName Courier
+Weight Bold
+ItalicAngle 0
+IsFixedPitch true
+FontBBox -113 -250 749 801
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.004
+Notice Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 439
+Ascender 626
+Descender -142
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ;
+C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ;
+C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ;
+C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ;
+C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ;
+C 39 ; WX 600 ; N quoteright ; B 171 277 423 562 ;
+C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ;
+C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ;
+C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ;
+C 43 ; WX 600 ; N plus ; B 71 39 529 478 ;
+C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ;
+C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ;
+C 46 ; WX 600 ; N period ; B 192 -15 408 171 ;
+C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ;
+C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ;
+C 49 ; WX 600 ; N one ; B 81 0 539 616 ;
+C 50 ; WX 600 ; N two ; B 61 0 499 616 ;
+C 51 ; WX 600 ; N three ; B 63 -15 501 616 ;
+C 52 ; WX 600 ; N four ; B 53 0 507 616 ;
+C 53 ; WX 600 ; N five ; B 70 -15 521 601 ;
+C 54 ; WX 600 ; N six ; B 90 -15 521 616 ;
+C 55 ; WX 600 ; N seven ; B 55 0 494 601 ;
+C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ;
+C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ;
+C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ;
+C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ;
+C 60 ; WX 600 ; N less ; B 66 15 523 501 ;
+C 61 ; WX 600 ; N equal ; B 71 118 529 398 ;
+C 62 ; WX 600 ; N greater ; B 77 15 534 501 ;
+C 63 ; WX 600 ; N question ; B 98 -14 501 580 ;
+C 64 ; WX 600 ; N at ; B 16 -15 584 616 ;
+C 65 ; WX 600 ; N A ; B -9 0 609 562 ;
+C 66 ; WX 600 ; N B ; B 30 0 573 562 ;
+C 67 ; WX 600 ; N C ; B 22 -18 560 580 ;
+C 68 ; WX 600 ; N D ; B 30 0 594 562 ;
+C 69 ; WX 600 ; N E ; B 25 0 560 562 ;
+C 70 ; WX 600 ; N F ; B 39 0 570 562 ;
+C 71 ; WX 600 ; N G ; B 22 -18 594 580 ;
+C 72 ; WX 600 ; N H ; B 20 0 580 562 ;
+C 73 ; WX 600 ; N I ; B 77 0 523 562 ;
+C 74 ; WX 600 ; N J ; B 37 -18 601 562 ;
+C 75 ; WX 600 ; N K ; B 21 0 599 562 ;
+C 76 ; WX 600 ; N L ; B 39 0 578 562 ;
+C 77 ; WX 600 ; N M ; B -2 0 602 562 ;
+C 78 ; WX 600 ; N N ; B 8 -12 610 562 ;
+C 79 ; WX 600 ; N O ; B 22 -18 578 580 ;
+C 80 ; WX 600 ; N P ; B 48 0 559 562 ;
+C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ;
+C 82 ; WX 600 ; N R ; B 24 0 599 562 ;
+C 83 ; WX 600 ; N S ; B 47 -22 553 582 ;
+C 84 ; WX 600 ; N T ; B 21 0 579 562 ;
+C 85 ; WX 600 ; N U ; B 4 -18 596 562 ;
+C 86 ; WX 600 ; N V ; B -13 0 613 562 ;
+C 87 ; WX 600 ; N W ; B -18 0 618 562 ;
+C 88 ; WX 600 ; N X ; B 12 0 588 562 ;
+C 89 ; WX 600 ; N Y ; B 12 0 589 562 ;
+C 90 ; WX 600 ; N Z ; B 62 0 539 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ;
+C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ;
+C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ;
+C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ;
+C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 178 277 428 562 ;
+C 97 ; WX 600 ; N a ; B 35 -15 570 454 ;
+C 98 ; WX 600 ; N b ; B 0 -15 584 626 ;
+C 99 ; WX 600 ; N c ; B 40 -15 545 459 ;
+C 100 ; WX 600 ; N d ; B 20 -15 591 626 ;
+C 101 ; WX 600 ; N e ; B 40 -15 563 454 ;
+C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 30 -146 580 454 ;
+C 104 ; WX 600 ; N h ; B 5 0 592 626 ;
+C 105 ; WX 600 ; N i ; B 77 0 523 658 ;
+C 106 ; WX 600 ; N j ; B 63 -146 440 658 ;
+C 107 ; WX 600 ; N k ; B 20 0 585 626 ;
+C 108 ; WX 600 ; N l ; B 77 0 523 626 ;
+C 109 ; WX 600 ; N m ; B -22 0 626 454 ;
+C 110 ; WX 600 ; N n ; B 18 0 592 454 ;
+C 111 ; WX 600 ; N o ; B 30 -15 570 454 ;
+C 112 ; WX 600 ; N p ; B -1 -142 570 454 ;
+C 113 ; WX 600 ; N q ; B 20 -142 591 454 ;
+C 114 ; WX 600 ; N r ; B 47 0 580 454 ;
+C 115 ; WX 600 ; N s ; B 68 -17 535 459 ;
+C 116 ; WX 600 ; N t ; B 47 -15 532 562 ;
+C 117 ; WX 600 ; N u ; B -1 -15 569 439 ;
+C 118 ; WX 600 ; N v ; B -1 0 601 439 ;
+C 119 ; WX 600 ; N w ; B -18 0 618 439 ;
+C 120 ; WX 600 ; N x ; B 6 0 594 439 ;
+C 121 ; WX 600 ; N y ; B -4 -142 601 439 ;
+C 122 ; WX 600 ; N z ; B 81 0 520 439 ;
+C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ;
+C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ;
+C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ;
+C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ;
+C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ;
+C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ;
+C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ;
+C 164 ; WX 600 ; N fraction ; B 25 -60 576 661 ;
+C 165 ; WX 600 ; N yen ; B 10 0 590 562 ;
+C 166 ; WX 600 ; N florin ; B -30 -131 572 616 ;
+C 167 ; WX 600 ; N section ; B 83 -70 517 580 ;
+C 168 ; WX 600 ; N currency ; B 54 49 546 517 ;
+C 169 ; WX 600 ; N quotesingle ; B 227 277 373 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ;
+C 174 ; WX 600 ; N fi ; B 12 0 593 626 ;
+C 175 ; WX 600 ; N fl ; B 12 0 593 626 ;
+C 177 ; WX 600 ; N endash ; B 65 203 535 313 ;
+C 178 ; WX 600 ; N dagger ; B 106 -70 494 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 196 165 404 351 ;
+C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ;
+C 183 ; WX 600 ; N bullet ; B 140 132 460 430 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ;
+C 185 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ;
+C 186 ; WX 600 ; N quotedblright ; B 61 277 525 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ;
+C 189 ; WX 600 ; N perthousand ; B -113 -15 713 616 ;
+C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ;
+C 193 ; WX 600 ; N grave ; B 132 508 395 661 ;
+C 194 ; WX 600 ; N acute ; B 205 508 468 661 ;
+C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ;
+C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ;
+C 197 ; WX 600 ; N macron ; B 88 505 512 585 ;
+C 198 ; WX 600 ; N breve ; B 83 468 517 631 ;
+C 199 ; WX 600 ; N dotaccent ; B 230 485 370 625 ;
+C 200 ; WX 600 ; N dieresis ; B 128 485 472 625 ;
+C 202 ; WX 600 ; N ring ; B 198 481 402 678 ;
+C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ;
+C 206 ; WX 600 ; N ogonek ; B 169 -199 367 0 ;
+C 207 ; WX 600 ; N caron ; B 103 493 497 667 ;
+C 208 ; WX 600 ; N emdash ; B -10 203 610 313 ;
+C 225 ; WX 600 ; N AE ; B -29 0 602 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ;
+C 232 ; WX 600 ; N Lslash ; B 39 0 578 562 ;
+C 233 ; WX 600 ; N Oslash ; B 22 -22 578 584 ;
+C 234 ; WX 600 ; N OE ; B -25 0 595 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ;
+C 241 ; WX 600 ; N ae ; B -4 -15 601 454 ;
+C 245 ; WX 600 ; N dotlessi ; B 77 0 523 439 ;
+C 248 ; WX 600 ; N lslash ; B 77 0 523 626 ;
+C 249 ; WX 600 ; N oslash ; B 30 -24 570 463 ;
+C 250 ; WX 600 ; N oe ; B -18 -15 611 454 ;
+C 251 ; WX 600 ; N germandbls ; B 22 -15 596 626 ;
+C -1 ; WX 600 ; N Odieresis ; B 22 -18 578 748 ;
+C -1 ; WX 600 ; N logicalnot ; B 71 103 529 413 ;
+C -1 ; WX 600 ; N minus ; B 71 203 529 313 ;
+C -1 ; WX 600 ; N merge ; B 137 -15 464 487 ;
+C -1 ; WX 600 ; N degree ; B 86 243 474 616 ;
+C -1 ; WX 600 ; N dectab ; B 8 0 592 320 ;
+C -1 ; WX 600 ; N ll ; B -12 0 600 626 ;
+C -1 ; WX 600 ; N IJ ; B -8 -18 622 562 ;
+C -1 ; WX 600 ; N Eacute ; B 25 0 560 784 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ;
+C -1 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ;
+C -1 ; WX 600 ; N left ; B 65 44 535 371 ;
+C -1 ; WX 600 ; N threesuperior ; B 138 222 433 616 ;
+C -1 ; WX 600 ; N up ; B 136 0 463 447 ;
+C -1 ; WX 600 ; N multiply ; B 81 39 520 478 ;
+C -1 ; WX 600 ; N Scaron ; B 47 -22 553 790 ;
+C -1 ; WX 600 ; N tab ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ;
+C -1 ; WX 600 ; N divide ; B 71 16 529 500 ;
+C -1 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ;
+C -1 ; WX 600 ; N eacute ; B 40 -15 563 661 ;
+C -1 ; WX 600 ; N uacute ; B -1 -15 569 661 ;
+C -1 ; WX 600 ; N Aacute ; B -9 0 609 784 ;
+C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N twosuperior ; B 143 230 436 616 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ;
+C -1 ; WX 600 ; N ntilde ; B 18 0 592 636 ;
+C -1 ; WX 600 ; N down ; B 137 -15 464 439 ;
+C -1 ; WX 600 ; N center ; B 40 14 560 580 ;
+C -1 ; WX 600 ; N onesuperior ; B 153 230 447 616 ;
+C -1 ; WX 600 ; N ij ; B 6 -146 574 658 ;
+C -1 ; WX 600 ; N edieresis ; B 40 -15 563 625 ;
+C -1 ; WX 600 ; N graybox ; B 76 0 525 599 ;
+C -1 ; WX 600 ; N odieresis ; B 30 -15 570 625 ;
+C -1 ; WX 600 ; N Ograve ; B 22 -18 578 784 ;
+C -1 ; WX 600 ; N threequarters ; B -47 -60 648 661 ;
+C -1 ; WX 600 ; N plusminus ; B 71 24 529 515 ;
+C -1 ; WX 600 ; N prescription ; B 24 -15 599 562 ;
+C -1 ; WX 600 ; N eth ; B 58 -27 543 626 ;
+C -1 ; WX 600 ; N largebullet ; B 248 229 352 333 ;
+C -1 ; WX 600 ; N egrave ; B 40 -15 563 661 ;
+C -1 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ;
+C -1 ; WX 600 ; N notegraphic ; B 77 -15 523 572 ;
+C -1 ; WX 600 ; N Udieresis ; B 4 -18 596 748 ;
+C -1 ; WX 600 ; N Gcaron ; B 22 -18 594 790 ;
+C -1 ; WX 600 ; N arrowdown ; B 144 -15 456 608 ;
+C -1 ; WX 600 ; N format ; B 5 -146 115 601 ;
+C -1 ; WX 600 ; N Otilde ; B 22 -18 578 759 ;
+C -1 ; WX 600 ; N Idieresis ; B 77 0 523 748 ;
+C -1 ; WX 600 ; N adieresis ; B 35 -15 570 625 ;
+C -1 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ;
+C -1 ; WX 600 ; N Eth ; B 30 0 594 562 ;
+C -1 ; WX 600 ; N onequarter ; B -56 -60 656 661 ;
+C -1 ; WX 600 ; N LL ; B -45 0 645 562 ;
+C -1 ; WX 600 ; N agrave ; B 35 -15 570 661 ;
+C -1 ; WX 600 ; N Zcaron ; B 62 0 539 790 ;
+C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ;
+C -1 ; WX 600 ; N Idot ; B 77 0 523 748 ;
+C -1 ; WX 600 ; N Iacute ; B 77 0 523 784 ;
+C -1 ; WX 600 ; N indent ; B 65 45 535 372 ;
+C -1 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ;
+C -1 ; WX 600 ; N scaron ; B 68 -17 535 667 ;
+C -1 ; WX 600 ; N overscore ; B 0 579 600 629 ;
+C -1 ; WX 600 ; N Aring ; B -9 0 609 801 ;
+C -1 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ;
+C -1 ; WX 600 ; N Igrave ; B 77 0 523 784 ;
+C -1 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ;
+C -1 ; WX 600 ; N Oacute ; B 22 -18 578 784 ;
+C -1 ; WX 600 ; N otilde ; B 30 -15 570 636 ;
+C -1 ; WX 600 ; N Yacute ; B 12 0 589 784 ;
+C -1 ; WX 600 ; N lira ; B 72 -28 558 611 ;
+C -1 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ;
+C -1 ; WX 600 ; N Atilde ; B -9 0 609 759 ;
+C -1 ; WX 600 ; N Uacute ; B 4 -18 596 784 ;
+C -1 ; WX 600 ; N Ydieresis ; B 12 0 589 748 ;
+C -1 ; WX 600 ; N ydieresis ; B -4 -142 601 625 ;
+C -1 ; WX 600 ; N idieresis ; B 77 0 523 625 ;
+C -1 ; WX 600 ; N Adieresis ; B -9 0 609 748 ;
+C -1 ; WX 600 ; N mu ; B -1 -142 569 439 ;
+C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ;
+C -1 ; WX 600 ; N oacute ; B 30 -15 570 661 ;
+C -1 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ;
+C -1 ; WX 600 ; N Agrave ; B -9 0 609 784 ;
+C -1 ; WX 600 ; N return ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N atilde ; B 35 -15 570 636 ;
+C -1 ; WX 600 ; N square ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N stop ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N udieresis ; B -1 -15 569 625 ;
+C -1 ; WX 600 ; N arrowup ; B 144 3 456 626 ;
+C -1 ; WX 600 ; N igrave ; B 77 0 523 661 ;
+C -1 ; WX 600 ; N Edieresis ; B 25 0 560 748 ;
+C -1 ; WX 600 ; N zcaron ; B 81 0 520 667 ;
+C -1 ; WX 600 ; N arrowboth ; B -24 143 624 455 ;
+C -1 ; WX 600 ; N gcaron ; B 30 -146 580 667 ;
+C -1 ; WX 600 ; N arrowleft ; B -24 143 634 455 ;
+C -1 ; WX 600 ; N aacute ; B 35 -15 570 661 ;
+C -1 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ;
+C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ;
+C -1 ; WX 600 ; N ograve ; B 30 -15 570 661 ;
+C -1 ; WX 600 ; N onehalf ; B -47 -60 648 661 ;
+C -1 ; WX 600 ; N ugrave ; B -1 -15 569 661 ;
+C -1 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ;
+C -1 ; WX 600 ; N iacute ; B 77 0 523 661 ;
+C -1 ; WX 600 ; N arrowright ; B -34 143 624 455 ;
+C -1 ; WX 600 ; N Thorn ; B 48 0 557 562 ;
+C -1 ; WX 600 ; N Egrave ; B 25 0 560 784 ;
+C -1 ; WX 600 ; N thorn ; B -14 -142 570 626 ;
+C -1 ; WX 600 ; N aring ; B 35 -15 570 678 ;
+C -1 ; WX 600 ; N yacute ; B -4 -142 601 661 ;
+C -1 ; WX 600 ; N icircumflex ; B 63 0 523 657 ;
+EndCharMetrics
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 30 123 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -30 123 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -20 123 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave -50 123 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring -10 123 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde -30 123 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 30 123 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 123 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 123 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 123 ;
+CC Gcaron 2 ; PCC G 0 0 ; PCC caron 10 123 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 123 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 123 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 123 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 123 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 123 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 123 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 123 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 123 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 123 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 123 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 123 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 30 123 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 123 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 123 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave -30 123 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 30 123 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 123 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 123 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex -20 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis -10 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave -30 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC gcaron 2 ; PCC g 0 0 ; PCC caron -40 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -40 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -40 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -20 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis -20 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 30 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 10 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Courier-BoldOblique.afm b/tlt3.0/library/afm/Courier-BoldOblique.afm
new file mode 100644
index 0000000..e0b3940
--- /dev/null
+++ b/tlt3.0/library/afm/Courier-BoldOblique.afm
@@ -0,0 +1,345 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved.
+Comment Creation Date: Tue Sep 17 14:13:24 1991
+Comment UniqueID 36389
+Comment VMusage 10055 54684
+FontName Courier-BoldOblique
+FullName Courier Bold Oblique
+FamilyName Courier
+Weight Bold
+ItalicAngle -12
+IsFixedPitch true
+FontBBox -56 -250 868 801
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.004
+Notice Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 439
+Ascender 626
+Descender -142
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 216 -15 495 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 212 277 584 562 ;
+C 35 ; WX 600 ; N numbersign ; B 88 -45 640 651 ;
+C 36 ; WX 600 ; N dollar ; B 87 -126 629 666 ;
+C 37 ; WX 600 ; N percent ; B 102 -15 624 616 ;
+C 38 ; WX 600 ; N ampersand ; B 62 -15 594 543 ;
+C 39 ; WX 600 ; N quoteright ; B 230 277 542 562 ;
+C 40 ; WX 600 ; N parenleft ; B 266 -102 592 616 ;
+C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ;
+C 42 ; WX 600 ; N asterisk ; B 179 219 597 601 ;
+C 43 ; WX 600 ; N plus ; B 114 39 596 478 ;
+C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ;
+C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ;
+C 46 ; WX 600 ; N period ; B 207 -15 426 171 ;
+C 47 ; WX 600 ; N slash ; B 91 -77 626 626 ;
+C 48 ; WX 600 ; N zero ; B 136 -15 592 616 ;
+C 49 ; WX 600 ; N one ; B 93 0 561 616 ;
+C 50 ; WX 600 ; N two ; B 61 0 593 616 ;
+C 51 ; WX 600 ; N three ; B 72 -15 571 616 ;
+C 52 ; WX 600 ; N four ; B 82 0 558 616 ;
+C 53 ; WX 600 ; N five ; B 77 -15 621 601 ;
+C 54 ; WX 600 ; N six ; B 136 -15 652 616 ;
+C 55 ; WX 600 ; N seven ; B 147 0 622 601 ;
+C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ;
+C 57 ; WX 600 ; N nine ; B 76 -15 592 616 ;
+C 58 ; WX 600 ; N colon ; B 206 -15 479 425 ;
+C 59 ; WX 600 ; N semicolon ; B 99 -111 480 425 ;
+C 60 ; WX 600 ; N less ; B 121 15 612 501 ;
+C 61 ; WX 600 ; N equal ; B 96 118 614 398 ;
+C 62 ; WX 600 ; N greater ; B 97 15 589 501 ;
+C 63 ; WX 600 ; N question ; B 183 -14 591 580 ;
+C 64 ; WX 600 ; N at ; B 66 -15 641 616 ;
+C 65 ; WX 600 ; N A ; B -9 0 631 562 ;
+C 66 ; WX 600 ; N B ; B 30 0 629 562 ;
+C 67 ; WX 600 ; N C ; B 75 -18 674 580 ;
+C 68 ; WX 600 ; N D ; B 30 0 664 562 ;
+C 69 ; WX 600 ; N E ; B 25 0 669 562 ;
+C 70 ; WX 600 ; N F ; B 39 0 683 562 ;
+C 71 ; WX 600 ; N G ; B 75 -18 674 580 ;
+C 72 ; WX 600 ; N H ; B 20 0 699 562 ;
+C 73 ; WX 600 ; N I ; B 77 0 642 562 ;
+C 74 ; WX 600 ; N J ; B 59 -18 720 562 ;
+C 75 ; WX 600 ; N K ; B 21 0 691 562 ;
+C 76 ; WX 600 ; N L ; B 39 0 635 562 ;
+C 77 ; WX 600 ; N M ; B -2 0 721 562 ;
+C 78 ; WX 600 ; N N ; B 8 -12 729 562 ;
+C 79 ; WX 600 ; N O ; B 74 -18 645 580 ;
+C 80 ; WX 600 ; N P ; B 48 0 642 562 ;
+C 81 ; WX 600 ; N Q ; B 84 -138 636 580 ;
+C 82 ; WX 600 ; N R ; B 24 0 617 562 ;
+C 83 ; WX 600 ; N S ; B 54 -22 672 582 ;
+C 84 ; WX 600 ; N T ; B 86 0 678 562 ;
+C 85 ; WX 600 ; N U ; B 101 -18 715 562 ;
+C 86 ; WX 600 ; N V ; B 84 0 732 562 ;
+C 87 ; WX 600 ; N W ; B 84 0 737 562 ;
+C 88 ; WX 600 ; N X ; B 12 0 689 562 ;
+C 89 ; WX 600 ; N Y ; B 109 0 708 562 ;
+C 90 ; WX 600 ; N Z ; B 62 0 636 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ;
+C 92 ; WX 600 ; N backslash ; B 223 -77 496 626 ;
+C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ;
+C 94 ; WX 600 ; N asciicircum ; B 171 250 555 616 ;
+C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 297 277 487 562 ;
+C 97 ; WX 600 ; N a ; B 62 -15 592 454 ;
+C 98 ; WX 600 ; N b ; B 13 -15 636 626 ;
+C 99 ; WX 600 ; N c ; B 81 -15 631 459 ;
+C 100 ; WX 600 ; N d ; B 61 -15 644 626 ;
+C 101 ; WX 600 ; N e ; B 81 -15 604 454 ;
+C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 41 -146 673 454 ;
+C 104 ; WX 600 ; N h ; B 18 0 614 626 ;
+C 105 ; WX 600 ; N i ; B 77 0 545 658 ;
+C 106 ; WX 600 ; N j ; B 37 -146 580 658 ;
+C 107 ; WX 600 ; N k ; B 33 0 642 626 ;
+C 108 ; WX 600 ; N l ; B 77 0 545 626 ;
+C 109 ; WX 600 ; N m ; B -22 0 648 454 ;
+C 110 ; WX 600 ; N n ; B 18 0 614 454 ;
+C 111 ; WX 600 ; N o ; B 71 -15 622 454 ;
+C 112 ; WX 600 ; N p ; B -31 -142 622 454 ;
+C 113 ; WX 600 ; N q ; B 61 -142 684 454 ;
+C 114 ; WX 600 ; N r ; B 47 0 654 454 ;
+C 115 ; WX 600 ; N s ; B 67 -17 607 459 ;
+C 116 ; WX 600 ; N t ; B 118 -15 566 562 ;
+C 117 ; WX 600 ; N u ; B 70 -15 591 439 ;
+C 118 ; WX 600 ; N v ; B 70 0 694 439 ;
+C 119 ; WX 600 ; N w ; B 53 0 711 439 ;
+C 120 ; WX 600 ; N x ; B 6 0 670 439 ;
+C 121 ; WX 600 ; N y ; B -20 -142 694 439 ;
+C 122 ; WX 600 ; N z ; B 81 0 613 439 ;
+C 123 ; WX 600 ; N braceleft ; B 204 -102 595 616 ;
+C 124 ; WX 600 ; N bar ; B 202 -250 504 750 ;
+C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ;
+C 126 ; WX 600 ; N asciitilde ; B 120 153 589 356 ;
+C 161 ; WX 600 ; N exclamdown ; B 197 -146 477 449 ;
+C 162 ; WX 600 ; N cent ; B 121 -49 604 614 ;
+C 163 ; WX 600 ; N sterling ; B 107 -28 650 611 ;
+C 164 ; WX 600 ; N fraction ; B 22 -60 707 661 ;
+C 165 ; WX 600 ; N yen ; B 98 0 709 562 ;
+C 166 ; WX 600 ; N florin ; B -56 -131 701 616 ;
+C 167 ; WX 600 ; N section ; B 74 -70 619 580 ;
+C 168 ; WX 600 ; N currency ; B 77 49 643 517 ;
+C 169 ; WX 600 ; N quotesingle ; B 304 277 492 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 63 70 638 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 196 70 544 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 166 70 514 446 ;
+C 174 ; WX 600 ; N fi ; B 12 0 643 626 ;
+C 175 ; WX 600 ; N fl ; B 12 0 643 626 ;
+C 177 ; WX 600 ; N endash ; B 108 203 602 313 ;
+C 178 ; WX 600 ; N dagger ; B 176 -70 586 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 122 -70 586 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 249 165 461 351 ;
+C 182 ; WX 600 ; N paragraph ; B 61 -70 699 580 ;
+C 183 ; WX 600 ; N bullet ; B 197 132 523 430 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 145 -142 457 143 ;
+C 185 ; WX 600 ; N quotedblbase ; B 35 -142 559 143 ;
+C 186 ; WX 600 ; N quotedblright ; B 120 277 644 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 72 70 647 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 35 -15 586 116 ;
+C 189 ; WX 600 ; N perthousand ; B -44 -15 742 616 ;
+C 191 ; WX 600 ; N questiondown ; B 101 -146 509 449 ;
+C 193 ; WX 600 ; N grave ; B 272 508 503 661 ;
+C 194 ; WX 600 ; N acute ; B 313 508 608 661 ;
+C 195 ; WX 600 ; N circumflex ; B 212 483 606 657 ;
+C 196 ; WX 600 ; N tilde ; B 200 493 642 636 ;
+C 197 ; WX 600 ; N macron ; B 195 505 636 585 ;
+C 198 ; WX 600 ; N breve ; B 217 468 651 631 ;
+C 199 ; WX 600 ; N dotaccent ; B 346 485 490 625 ;
+C 200 ; WX 600 ; N dieresis ; B 244 485 592 625 ;
+C 202 ; WX 600 ; N ring ; B 319 481 528 678 ;
+C 203 ; WX 600 ; N cedilla ; B 169 -206 367 0 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 172 488 728 661 ;
+C 206 ; WX 600 ; N ogonek ; B 144 -199 350 0 ;
+C 207 ; WX 600 ; N caron ; B 238 493 632 667 ;
+C 208 ; WX 600 ; N emdash ; B 33 203 677 313 ;
+C 225 ; WX 600 ; N AE ; B -29 0 707 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 189 196 526 580 ;
+C 232 ; WX 600 ; N Lslash ; B 39 0 635 562 ;
+C 233 ; WX 600 ; N Oslash ; B 48 -22 672 584 ;
+C 234 ; WX 600 ; N OE ; B 26 0 700 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 189 196 542 580 ;
+C 241 ; WX 600 ; N ae ; B 21 -15 651 454 ;
+C 245 ; WX 600 ; N dotlessi ; B 77 0 545 439 ;
+C 248 ; WX 600 ; N lslash ; B 77 0 578 626 ;
+C 249 ; WX 600 ; N oslash ; B 55 -24 637 463 ;
+C 250 ; WX 600 ; N oe ; B 19 -15 661 454 ;
+C 251 ; WX 600 ; N germandbls ; B 22 -15 628 626 ;
+C -1 ; WX 600 ; N Odieresis ; B 74 -18 645 748 ;
+C -1 ; WX 600 ; N logicalnot ; B 135 103 617 413 ;
+C -1 ; WX 600 ; N minus ; B 114 203 596 313 ;
+C -1 ; WX 600 ; N merge ; B 168 -15 533 487 ;
+C -1 ; WX 600 ; N degree ; B 173 243 569 616 ;
+C -1 ; WX 600 ; N dectab ; B 8 0 615 320 ;
+C -1 ; WX 600 ; N ll ; B 1 0 653 626 ;
+C -1 ; WX 600 ; N IJ ; B -8 -18 741 562 ;
+C -1 ; WX 600 ; N Eacute ; B 25 0 669 784 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ;
+C -1 ; WX 600 ; N ucircumflex ; B 70 -15 591 657 ;
+C -1 ; WX 600 ; N left ; B 109 44 589 371 ;
+C -1 ; WX 600 ; N threesuperior ; B 193 222 525 616 ;
+C -1 ; WX 600 ; N up ; B 196 0 523 447 ;
+C -1 ; WX 600 ; N multiply ; B 105 39 606 478 ;
+C -1 ; WX 600 ; N Scaron ; B 54 -22 672 790 ;
+C -1 ; WX 600 ; N tab ; B 19 0 641 562 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 101 -18 715 780 ;
+C -1 ; WX 600 ; N divide ; B 114 16 596 500 ;
+C -1 ; WX 600 ; N Acircumflex ; B -9 0 631 780 ;
+C -1 ; WX 600 ; N eacute ; B 81 -15 608 661 ;
+C -1 ; WX 600 ; N uacute ; B 70 -15 608 661 ;
+C -1 ; WX 600 ; N Aacute ; B -9 0 665 784 ;
+C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N twosuperior ; B 192 230 541 616 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 25 0 669 780 ;
+C -1 ; WX 600 ; N ntilde ; B 18 0 642 636 ;
+C -1 ; WX 600 ; N down ; B 168 -15 496 439 ;
+C -1 ; WX 600 ; N center ; B 103 14 623 580 ;
+C -1 ; WX 600 ; N onesuperior ; B 213 230 514 616 ;
+C -1 ; WX 600 ; N ij ; B 6 -146 714 658 ;
+C -1 ; WX 600 ; N edieresis ; B 81 -15 604 625 ;
+C -1 ; WX 600 ; N graybox ; B 76 0 652 599 ;
+C -1 ; WX 600 ; N odieresis ; B 71 -15 622 625 ;
+C -1 ; WX 600 ; N Ograve ; B 74 -18 645 784 ;
+C -1 ; WX 600 ; N threequarters ; B 8 -60 698 661 ;
+C -1 ; WX 600 ; N plusminus ; B 76 24 614 515 ;
+C -1 ; WX 600 ; N prescription ; B 24 -15 632 562 ;
+C -1 ; WX 600 ; N eth ; B 93 -27 661 626 ;
+C -1 ; WX 600 ; N largebullet ; B 307 229 413 333 ;
+C -1 ; WX 600 ; N egrave ; B 81 -15 604 661 ;
+C -1 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ;
+C -1 ; WX 600 ; N notegraphic ; B 91 -15 619 572 ;
+C -1 ; WX 600 ; N Udieresis ; B 101 -18 715 748 ;
+C -1 ; WX 600 ; N Gcaron ; B 75 -18 674 790 ;
+C -1 ; WX 600 ; N arrowdown ; B 174 -15 486 608 ;
+C -1 ; WX 600 ; N format ; B -26 -146 243 601 ;
+C -1 ; WX 600 ; N Otilde ; B 74 -18 668 759 ;
+C -1 ; WX 600 ; N Idieresis ; B 77 0 642 748 ;
+C -1 ; WX 600 ; N adieresis ; B 62 -15 592 625 ;
+C -1 ; WX 600 ; N ecircumflex ; B 81 -15 606 657 ;
+C -1 ; WX 600 ; N Eth ; B 30 0 664 562 ;
+C -1 ; WX 600 ; N onequarter ; B 14 -60 706 661 ;
+C -1 ; WX 600 ; N LL ; B -45 0 694 562 ;
+C -1 ; WX 600 ; N agrave ; B 62 -15 592 661 ;
+C -1 ; WX 600 ; N Zcaron ; B 62 0 659 790 ;
+C -1 ; WX 600 ; N Scedilla ; B 54 -206 672 582 ;
+C -1 ; WX 600 ; N Idot ; B 77 0 642 748 ;
+C -1 ; WX 600 ; N Iacute ; B 77 0 642 784 ;
+C -1 ; WX 600 ; N indent ; B 99 45 579 372 ;
+C -1 ; WX 600 ; N Ugrave ; B 101 -18 715 784 ;
+C -1 ; WX 600 ; N scaron ; B 67 -17 632 667 ;
+C -1 ; WX 600 ; N overscore ; B 123 579 734 629 ;
+C -1 ; WX 600 ; N Aring ; B -9 0 631 801 ;
+C -1 ; WX 600 ; N Ccedilla ; B 74 -206 674 580 ;
+C -1 ; WX 600 ; N Igrave ; B 77 0 642 784 ;
+C -1 ; WX 600 ; N brokenbar ; B 218 -175 488 675 ;
+C -1 ; WX 600 ; N Oacute ; B 74 -18 645 784 ;
+C -1 ; WX 600 ; N otilde ; B 71 -15 642 636 ;
+C -1 ; WX 600 ; N Yacute ; B 109 0 708 784 ;
+C -1 ; WX 600 ; N lira ; B 107 -28 650 611 ;
+C -1 ; WX 600 ; N Icircumflex ; B 77 0 642 780 ;
+C -1 ; WX 600 ; N Atilde ; B -9 0 638 759 ;
+C -1 ; WX 600 ; N Uacute ; B 101 -18 715 784 ;
+C -1 ; WX 600 ; N Ydieresis ; B 109 0 708 748 ;
+C -1 ; WX 600 ; N ydieresis ; B -20 -142 694 625 ;
+C -1 ; WX 600 ; N idieresis ; B 77 0 552 625 ;
+C -1 ; WX 600 ; N Adieresis ; B -9 0 631 748 ;
+C -1 ; WX 600 ; N mu ; B 50 -142 591 439 ;
+C -1 ; WX 600 ; N trademark ; B 86 230 868 562 ;
+C -1 ; WX 600 ; N oacute ; B 71 -15 622 661 ;
+C -1 ; WX 600 ; N acircumflex ; B 62 -15 592 657 ;
+C -1 ; WX 600 ; N Agrave ; B -9 0 631 784 ;
+C -1 ; WX 600 ; N return ; B 79 0 700 562 ;
+C -1 ; WX 600 ; N atilde ; B 62 -15 642 636 ;
+C -1 ; WX 600 ; N square ; B 19 0 700 562 ;
+C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N stop ; B 19 0 700 562 ;
+C -1 ; WX 600 ; N udieresis ; B 70 -15 591 625 ;
+C -1 ; WX 600 ; N arrowup ; B 244 3 556 626 ;
+C -1 ; WX 600 ; N igrave ; B 77 0 545 661 ;
+C -1 ; WX 600 ; N Edieresis ; B 25 0 669 748 ;
+C -1 ; WX 600 ; N zcaron ; B 81 0 632 667 ;
+C -1 ; WX 600 ; N arrowboth ; B 40 143 688 455 ;
+C -1 ; WX 600 ; N gcaron ; B 41 -146 673 667 ;
+C -1 ; WX 600 ; N arrowleft ; B 40 143 708 455 ;
+C -1 ; WX 600 ; N aacute ; B 62 -15 608 661 ;
+C -1 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ;
+C -1 ; WX 600 ; N scedilla ; B 67 -206 607 459 ;
+C -1 ; WX 600 ; N ograve ; B 71 -15 622 661 ;
+C -1 ; WX 600 ; N onehalf ; B 23 -60 715 661 ;
+C -1 ; WX 600 ; N ugrave ; B 70 -15 591 661 ;
+C -1 ; WX 600 ; N Ntilde ; B 8 -12 729 759 ;
+C -1 ; WX 600 ; N iacute ; B 77 0 608 661 ;
+C -1 ; WX 600 ; N arrowright ; B 20 143 688 455 ;
+C -1 ; WX 600 ; N Thorn ; B 48 0 619 562 ;
+C -1 ; WX 600 ; N Egrave ; B 25 0 669 784 ;
+C -1 ; WX 600 ; N thorn ; B -31 -142 622 626 ;
+C -1 ; WX 600 ; N aring ; B 62 -15 592 678 ;
+C -1 ; WX 600 ; N yacute ; B -20 -142 694 661 ;
+C -1 ; WX 600 ; N icircumflex ; B 77 0 566 657 ;
+EndCharMetrics
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 56 123 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -4 123 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 6 123 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave -24 123 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 16 123 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde -4 123 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 56 123 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 26 123 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 26 123 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 26 123 ;
+CC Gcaron 2 ; PCC G 0 0 ; PCC caron 36 123 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 26 123 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 26 123 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 26 123 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 26 123 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 26 123 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 26 123 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 26 123 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 26 123 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 26 123 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 26 123 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 26 123 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 56 123 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 26 123 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 26 123 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave -4 123 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 56 123 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 26 123 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 26 123 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex -20 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis -10 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave -30 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC gcaron 2 ; PCC g 0 0 ; PCC caron -40 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -40 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -40 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -20 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis -20 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 30 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 10 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Courier-Oblique.afm b/tlt3.0/library/afm/Courier-Oblique.afm
new file mode 100644
index 0000000..79bb0c3
--- /dev/null
+++ b/tlt3.0/library/afm/Courier-Oblique.afm
@@ -0,0 +1,345 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved.
+Comment Creation Date: Tue Sep 17 09:42:19 1991
+Comment UniqueID 36350
+Comment VMusage 9174 52297
+FontName Courier-Oblique
+FullName Courier Oblique
+FamilyName Courier
+Weight Medium
+ItalicAngle -12
+IsFixedPitch true
+FontBBox -28 -250 742 805
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.004
+Notice Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 426
+Ascender 629
+Descender -157
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ;
+C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ;
+C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ;
+C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ;
+C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ;
+C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ;
+C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ;
+C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ;
+C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ;
+C 43 ; WX 600 ; N plus ; B 129 44 580 470 ;
+C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ;
+C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ;
+C 46 ; WX 600 ; N period ; B 238 -15 382 109 ;
+C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ;
+C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ;
+C 49 ; WX 600 ; N one ; B 98 0 515 622 ;
+C 50 ; WX 600 ; N two ; B 70 0 568 622 ;
+C 51 ; WX 600 ; N three ; B 82 -15 538 622 ;
+C 52 ; WX 600 ; N four ; B 108 0 541 622 ;
+C 53 ; WX 600 ; N five ; B 99 -15 589 607 ;
+C 54 ; WX 600 ; N six ; B 155 -15 629 622 ;
+C 55 ; WX 600 ; N seven ; B 182 0 612 607 ;
+C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ;
+C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ;
+C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ;
+C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ;
+C 60 ; WX 600 ; N less ; B 96 42 610 472 ;
+C 61 ; WX 600 ; N equal ; B 109 138 600 376 ;
+C 62 ; WX 600 ; N greater ; B 85 42 599 472 ;
+C 63 ; WX 600 ; N question ; B 222 -15 583 572 ;
+C 64 ; WX 600 ; N at ; B 127 -15 582 622 ;
+C 65 ; WX 600 ; N A ; B 3 0 607 562 ;
+C 66 ; WX 600 ; N B ; B 43 0 616 562 ;
+C 67 ; WX 600 ; N C ; B 93 -18 655 580 ;
+C 68 ; WX 600 ; N D ; B 43 0 645 562 ;
+C 69 ; WX 600 ; N E ; B 53 0 660 562 ;
+C 70 ; WX 600 ; N F ; B 53 0 660 562 ;
+C 71 ; WX 600 ; N G ; B 83 -18 645 580 ;
+C 72 ; WX 600 ; N H ; B 32 0 687 562 ;
+C 73 ; WX 600 ; N I ; B 96 0 623 562 ;
+C 74 ; WX 600 ; N J ; B 52 -18 685 562 ;
+C 75 ; WX 600 ; N K ; B 38 0 671 562 ;
+C 76 ; WX 600 ; N L ; B 47 0 607 562 ;
+C 77 ; WX 600 ; N M ; B 4 0 715 562 ;
+C 78 ; WX 600 ; N N ; B 7 -13 712 562 ;
+C 79 ; WX 600 ; N O ; B 94 -18 625 580 ;
+C 80 ; WX 600 ; N P ; B 79 0 644 562 ;
+C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ;
+C 82 ; WX 600 ; N R ; B 38 0 598 562 ;
+C 83 ; WX 600 ; N S ; B 76 -20 650 580 ;
+C 84 ; WX 600 ; N T ; B 108 0 665 562 ;
+C 85 ; WX 600 ; N U ; B 125 -18 702 562 ;
+C 86 ; WX 600 ; N V ; B 105 -13 723 562 ;
+C 87 ; WX 600 ; N W ; B 106 -13 722 562 ;
+C 88 ; WX 600 ; N X ; B 23 0 675 562 ;
+C 89 ; WX 600 ; N Y ; B 133 0 695 562 ;
+C 90 ; WX 600 ; N Z ; B 86 0 610 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ;
+C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ;
+C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ;
+C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ;
+C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 343 328 457 562 ;
+C 97 ; WX 600 ; N a ; B 76 -15 569 441 ;
+C 98 ; WX 600 ; N b ; B 29 -15 625 629 ;
+C 99 ; WX 600 ; N c ; B 106 -15 608 441 ;
+C 100 ; WX 600 ; N d ; B 85 -15 640 629 ;
+C 101 ; WX 600 ; N e ; B 106 -15 598 441 ;
+C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 61 -157 657 441 ;
+C 104 ; WX 600 ; N h ; B 33 0 592 629 ;
+C 105 ; WX 600 ; N i ; B 95 0 515 657 ;
+C 106 ; WX 600 ; N j ; B 52 -157 550 657 ;
+C 107 ; WX 600 ; N k ; B 58 0 633 629 ;
+C 108 ; WX 600 ; N l ; B 95 0 515 629 ;
+C 109 ; WX 600 ; N m ; B -5 0 615 441 ;
+C 110 ; WX 600 ; N n ; B 26 0 585 441 ;
+C 111 ; WX 600 ; N o ; B 102 -15 588 441 ;
+C 112 ; WX 600 ; N p ; B -24 -157 605 441 ;
+C 113 ; WX 600 ; N q ; B 85 -157 682 441 ;
+C 114 ; WX 600 ; N r ; B 60 0 636 441 ;
+C 115 ; WX 600 ; N s ; B 78 -15 584 441 ;
+C 116 ; WX 600 ; N t ; B 167 -15 561 561 ;
+C 117 ; WX 600 ; N u ; B 101 -15 572 426 ;
+C 118 ; WX 600 ; N v ; B 90 -10 681 426 ;
+C 119 ; WX 600 ; N w ; B 76 -10 695 426 ;
+C 120 ; WX 600 ; N x ; B 20 0 655 426 ;
+C 121 ; WX 600 ; N y ; B -4 -157 683 426 ;
+C 122 ; WX 600 ; N z ; B 99 0 593 426 ;
+C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ;
+C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ;
+C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ;
+C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ;
+C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ;
+C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ;
+C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ;
+C 164 ; WX 600 ; N fraction ; B 84 -57 646 665 ;
+C 165 ; WX 600 ; N yen ; B 120 0 693 562 ;
+C 166 ; WX 600 ; N florin ; B -26 -143 671 622 ;
+C 167 ; WX 600 ; N section ; B 104 -78 590 580 ;
+C 168 ; WX 600 ; N currency ; B 94 58 628 506 ;
+C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ;
+C 174 ; WX 600 ; N fi ; B 3 0 619 629 ;
+C 175 ; WX 600 ; N fl ; B 3 0 619 629 ;
+C 177 ; WX 600 ; N endash ; B 124 231 586 285 ;
+C 178 ; WX 600 ; N dagger ; B 217 -78 546 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 275 189 434 327 ;
+C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ;
+C 183 ; WX 600 ; N bullet ; B 224 130 485 383 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ;
+C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ;
+C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ;
+C 189 ; WX 600 ; N perthousand ; B 59 -15 627 622 ;
+C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ;
+C 193 ; WX 600 ; N grave ; B 294 497 484 672 ;
+C 194 ; WX 600 ; N acute ; B 348 497 612 672 ;
+C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ;
+C 196 ; WX 600 ; N tilde ; B 212 489 629 606 ;
+C 197 ; WX 600 ; N macron ; B 232 525 600 565 ;
+C 198 ; WX 600 ; N breve ; B 279 501 576 609 ;
+C 199 ; WX 600 ; N dotaccent ; B 360 477 466 580 ;
+C 200 ; WX 600 ; N dieresis ; B 262 492 570 595 ;
+C 202 ; WX 600 ; N ring ; B 332 463 500 627 ;
+C 203 ; WX 600 ; N cedilla ; B 197 -151 344 10 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ;
+C 206 ; WX 600 ; N ogonek ; B 207 -151 348 0 ;
+C 207 ; WX 600 ; N caron ; B 262 492 614 669 ;
+C 208 ; WX 600 ; N emdash ; B 49 231 661 285 ;
+C 225 ; WX 600 ; N AE ; B 3 0 655 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ;
+C 232 ; WX 600 ; N Lslash ; B 47 0 607 562 ;
+C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ;
+C 234 ; WX 600 ; N OE ; B 59 0 672 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ;
+C 241 ; WX 600 ; N ae ; B 41 -15 626 441 ;
+C 245 ; WX 600 ; N dotlessi ; B 95 0 515 426 ;
+C 248 ; WX 600 ; N lslash ; B 95 0 583 629 ;
+C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ;
+C 250 ; WX 600 ; N oe ; B 54 -15 615 441 ;
+C 251 ; WX 600 ; N germandbls ; B 48 -15 617 629 ;
+C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 731 ;
+C -1 ; WX 600 ; N logicalnot ; B 155 108 591 369 ;
+C -1 ; WX 600 ; N minus ; B 129 232 580 283 ;
+C -1 ; WX 600 ; N merge ; B 187 -15 503 436 ;
+C -1 ; WX 600 ; N degree ; B 214 269 576 622 ;
+C -1 ; WX 600 ; N dectab ; B 18 0 593 227 ;
+C -1 ; WX 600 ; N ll ; B 33 0 616 629 ;
+C -1 ; WX 600 ; N IJ ; B 32 -18 702 562 ;
+C -1 ; WX 600 ; N Eacute ; B 53 0 668 793 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 775 ;
+C -1 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ;
+C -1 ; WX 600 ; N left ; B 114 68 580 348 ;
+C -1 ; WX 600 ; N threesuperior ; B 213 240 501 622 ;
+C -1 ; WX 600 ; N up ; B 223 0 503 437 ;
+C -1 ; WX 600 ; N multiply ; B 103 43 607 470 ;
+C -1 ; WX 600 ; N Scaron ; B 76 -20 673 805 ;
+C -1 ; WX 600 ; N tab ; B 19 0 641 562 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 125 -18 702 775 ;
+C -1 ; WX 600 ; N divide ; B 136 48 573 467 ;
+C -1 ; WX 600 ; N Acircumflex ; B 3 0 607 775 ;
+C -1 ; WX 600 ; N eacute ; B 106 -15 612 672 ;
+C -1 ; WX 600 ; N uacute ; B 101 -15 602 672 ;
+C -1 ; WX 600 ; N Aacute ; B 3 0 658 793 ;
+C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N twosuperior ; B 230 249 535 622 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 53 0 660 775 ;
+C -1 ; WX 600 ; N ntilde ; B 26 0 629 606 ;
+C -1 ; WX 600 ; N down ; B 187 -15 467 426 ;
+C -1 ; WX 600 ; N center ; B 103 14 623 580 ;
+C -1 ; WX 600 ; N onesuperior ; B 231 249 491 622 ;
+C -1 ; WX 600 ; N ij ; B 37 -157 630 657 ;
+C -1 ; WX 600 ; N edieresis ; B 106 -15 598 595 ;
+C -1 ; WX 600 ; N graybox ; B 76 0 652 599 ;
+C -1 ; WX 600 ; N odieresis ; B 102 -15 588 595 ;
+C -1 ; WX 600 ; N Ograve ; B 94 -18 625 793 ;
+C -1 ; WX 600 ; N threequarters ; B 73 -56 659 666 ;
+C -1 ; WX 600 ; N plusminus ; B 96 44 594 558 ;
+C -1 ; WX 600 ; N prescription ; B 27 -15 617 562 ;
+C -1 ; WX 600 ; N eth ; B 102 -15 639 629 ;
+C -1 ; WX 600 ; N largebullet ; B 315 220 395 297 ;
+C -1 ; WX 600 ; N egrave ; B 106 -15 598 672 ;
+C -1 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ;
+C -1 ; WX 600 ; N notegraphic ; B 143 -15 564 572 ;
+C -1 ; WX 600 ; N Udieresis ; B 125 -18 702 731 ;
+C -1 ; WX 600 ; N Gcaron ; B 83 -18 645 805 ;
+C -1 ; WX 600 ; N arrowdown ; B 152 -15 520 608 ;
+C -1 ; WX 600 ; N format ; B -28 -157 185 607 ;
+C -1 ; WX 600 ; N Otilde ; B 94 -18 656 732 ;
+C -1 ; WX 600 ; N Idieresis ; B 96 0 623 731 ;
+C -1 ; WX 600 ; N adieresis ; B 76 -15 570 595 ;
+C -1 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ;
+C -1 ; WX 600 ; N Eth ; B 43 0 645 562 ;
+C -1 ; WX 600 ; N onequarter ; B 65 -57 674 665 ;
+C -1 ; WX 600 ; N LL ; B 8 0 647 562 ;
+C -1 ; WX 600 ; N agrave ; B 76 -15 569 672 ;
+C -1 ; WX 600 ; N Zcaron ; B 86 0 643 805 ;
+C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ;
+C -1 ; WX 600 ; N Idot ; B 96 0 623 716 ;
+C -1 ; WX 600 ; N Iacute ; B 96 0 638 793 ;
+C -1 ; WX 600 ; N indent ; B 108 68 574 348 ;
+C -1 ; WX 600 ; N Ugrave ; B 125 -18 702 793 ;
+C -1 ; WX 600 ; N scaron ; B 78 -15 614 669 ;
+C -1 ; WX 600 ; N overscore ; B 123 579 734 629 ;
+C -1 ; WX 600 ; N Aring ; B 3 0 607 753 ;
+C -1 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ;
+C -1 ; WX 600 ; N Igrave ; B 96 0 623 793 ;
+C -1 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ;
+C -1 ; WX 600 ; N Oacute ; B 94 -18 638 793 ;
+C -1 ; WX 600 ; N otilde ; B 102 -15 629 606 ;
+C -1 ; WX 600 ; N Yacute ; B 133 0 695 793 ;
+C -1 ; WX 600 ; N lira ; B 118 -21 621 611 ;
+C -1 ; WX 600 ; N Icircumflex ; B 96 0 623 775 ;
+C -1 ; WX 600 ; N Atilde ; B 3 0 656 732 ;
+C -1 ; WX 600 ; N Uacute ; B 125 -18 702 793 ;
+C -1 ; WX 600 ; N Ydieresis ; B 133 0 695 731 ;
+C -1 ; WX 600 ; N ydieresis ; B -4 -157 683 595 ;
+C -1 ; WX 600 ; N idieresis ; B 95 0 540 595 ;
+C -1 ; WX 600 ; N Adieresis ; B 3 0 607 731 ;
+C -1 ; WX 600 ; N mu ; B 72 -157 572 426 ;
+C -1 ; WX 600 ; N trademark ; B 75 263 742 562 ;
+C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ;
+C -1 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ;
+C -1 ; WX 600 ; N Agrave ; B 3 0 607 793 ;
+C -1 ; WX 600 ; N return ; B 79 0 700 562 ;
+C -1 ; WX 600 ; N atilde ; B 76 -15 629 606 ;
+C -1 ; WX 600 ; N square ; B 19 0 700 562 ;
+C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
+C -1 ; WX 600 ; N stop ; B 19 0 700 562 ;
+C -1 ; WX 600 ; N udieresis ; B 101 -15 572 595 ;
+C -1 ; WX 600 ; N arrowup ; B 209 0 577 623 ;
+C -1 ; WX 600 ; N igrave ; B 95 0 515 672 ;
+C -1 ; WX 600 ; N Edieresis ; B 53 0 660 731 ;
+C -1 ; WX 600 ; N zcaron ; B 99 0 624 669 ;
+C -1 ; WX 600 ; N arrowboth ; B 36 115 692 483 ;
+C -1 ; WX 600 ; N gcaron ; B 61 -157 657 669 ;
+C -1 ; WX 600 ; N arrowleft ; B 40 115 693 483 ;
+C -1 ; WX 600 ; N aacute ; B 76 -15 612 672 ;
+C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ;
+C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ;
+C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ;
+C -1 ; WX 600 ; N onehalf ; B 65 -57 669 665 ;
+C -1 ; WX 600 ; N ugrave ; B 101 -15 572 672 ;
+C -1 ; WX 600 ; N Ntilde ; B 7 -13 712 732 ;
+C -1 ; WX 600 ; N iacute ; B 95 0 612 672 ;
+C -1 ; WX 600 ; N arrowright ; B 34 115 688 483 ;
+C -1 ; WX 600 ; N Thorn ; B 79 0 606 562 ;
+C -1 ; WX 600 ; N Egrave ; B 53 0 660 793 ;
+C -1 ; WX 600 ; N thorn ; B -24 -157 605 629 ;
+C -1 ; WX 600 ; N aring ; B 76 -15 569 627 ;
+C -1 ; WX 600 ; N yacute ; B -4 -157 683 672 ;
+C -1 ; WX 600 ; N icircumflex ; B 95 0 551 654 ;
+EndCharMetrics
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 46 121 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -4 121 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -1 136 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave -4 121 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 12 126 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 27 126 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 56 121 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 26 121 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 29 136 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 26 121 ;
+CC Gcaron 2 ; PCC G 0 0 ; PCC caron 29 136 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 26 121 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 26 121 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 29 136 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 26 121 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 27 126 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 26 121 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 26 121 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 29 136 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 26 121 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 27 126 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 59 136 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 56 121 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 26 121 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 29 136 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave -4 121 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 56 121 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 29 136 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 29 136 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC gcaron 2 ; PCC g 0 0 ; PCC caron -30 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -30 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -30 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -30 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute -10 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -10 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute -20 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis -10 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 10 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Courier.afm b/tlt3.0/library/afm/Courier.afm
new file mode 100644
index 0000000..e65ecdf
--- /dev/null
+++ b/tlt3.0/library/afm/Courier.afm
@@ -0,0 +1,345 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved.
+Comment Creation Date: Tue Sep 17 07:47:21 1991
+Comment UniqueID 36347
+Comment VMusage 31037 39405
+FontName Courier
+FullName Courier
+FamilyName Courier
+Weight Medium
+ItalicAngle 0
+IsFixedPitch true
+FontBBox -28 -250 628 805
+UnderlinePosition -100
+UnderlineThickness 50
+Version 002.004
+Notice Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 562
+XHeight 426
+Ascender 629
+Descender -157
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ;
+C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ;
+C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ;
+C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ;
+C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ;
+C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ;
+C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ;
+C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ;
+C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ;
+C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ;
+C 43 ; WX 600 ; N plus ; B 80 44 520 470 ;
+C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ;
+C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ;
+C 46 ; WX 600 ; N period ; B 229 -15 371 109 ;
+C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ;
+C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ;
+C 49 ; WX 600 ; N one ; B 96 0 505 622 ;
+C 50 ; WX 600 ; N two ; B 70 0 471 622 ;
+C 51 ; WX 600 ; N three ; B 75 -15 466 622 ;
+C 52 ; WX 600 ; N four ; B 78 0 500 622 ;
+C 53 ; WX 600 ; N five ; B 92 -15 497 607 ;
+C 54 ; WX 600 ; N six ; B 111 -15 497 622 ;
+C 55 ; WX 600 ; N seven ; B 82 0 483 607 ;
+C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ;
+C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ;
+C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ;
+C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ;
+C 60 ; WX 600 ; N less ; B 41 42 519 472 ;
+C 61 ; WX 600 ; N equal ; B 80 138 520 376 ;
+C 62 ; WX 600 ; N greater ; B 66 42 544 472 ;
+C 63 ; WX 600 ; N question ; B 129 -15 492 572 ;
+C 64 ; WX 600 ; N at ; B 77 -15 533 622 ;
+C 65 ; WX 600 ; N A ; B 3 0 597 562 ;
+C 66 ; WX 600 ; N B ; B 43 0 559 562 ;
+C 67 ; WX 600 ; N C ; B 41 -18 540 580 ;
+C 68 ; WX 600 ; N D ; B 43 0 574 562 ;
+C 69 ; WX 600 ; N E ; B 53 0 550 562 ;
+C 70 ; WX 600 ; N F ; B 53 0 545 562 ;
+C 71 ; WX 600 ; N G ; B 31 -18 575 580 ;
+C 72 ; WX 600 ; N H ; B 32 0 568 562 ;
+C 73 ; WX 600 ; N I ; B 96 0 504 562 ;
+C 74 ; WX 600 ; N J ; B 34 -18 566 562 ;
+C 75 ; WX 600 ; N K ; B 38 0 582 562 ;
+C 76 ; WX 600 ; N L ; B 47 0 554 562 ;
+C 77 ; WX 600 ; N M ; B 4 0 596 562 ;
+C 78 ; WX 600 ; N N ; B 7 -13 593 562 ;
+C 79 ; WX 600 ; N O ; B 43 -18 557 580 ;
+C 80 ; WX 600 ; N P ; B 79 0 558 562 ;
+C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ;
+C 82 ; WX 600 ; N R ; B 38 0 588 562 ;
+C 83 ; WX 600 ; N S ; B 72 -20 529 580 ;
+C 84 ; WX 600 ; N T ; B 38 0 563 562 ;
+C 85 ; WX 600 ; N U ; B 17 -18 583 562 ;
+C 86 ; WX 600 ; N V ; B -4 -13 604 562 ;
+C 87 ; WX 600 ; N W ; B -3 -13 603 562 ;
+C 88 ; WX 600 ; N X ; B 23 0 577 562 ;
+C 89 ; WX 600 ; N Y ; B 24 0 576 562 ;
+C 90 ; WX 600 ; N Z ; B 86 0 514 562 ;
+C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ;
+C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ;
+C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ;
+C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ;
+C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ;
+C 97 ; WX 600 ; N a ; B 53 -15 559 441 ;
+C 98 ; WX 600 ; N b ; B 14 -15 575 629 ;
+C 99 ; WX 600 ; N c ; B 66 -15 529 441 ;
+C 100 ; WX 600 ; N d ; B 45 -15 591 629 ;
+C 101 ; WX 600 ; N e ; B 66 -15 548 441 ;
+C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 45 -157 566 441 ;
+C 104 ; WX 600 ; N h ; B 18 0 582 629 ;
+C 105 ; WX 600 ; N i ; B 95 0 505 657 ;
+C 106 ; WX 600 ; N j ; B 82 -157 410 657 ;
+C 107 ; WX 600 ; N k ; B 43 0 580 629 ;
+C 108 ; WX 600 ; N l ; B 95 0 505 629 ;
+C 109 ; WX 600 ; N m ; B -5 0 605 441 ;
+C 110 ; WX 600 ; N n ; B 26 0 575 441 ;
+C 111 ; WX 600 ; N o ; B 62 -15 538 441 ;
+C 112 ; WX 600 ; N p ; B 9 -157 555 441 ;
+C 113 ; WX 600 ; N q ; B 45 -157 591 441 ;
+C 114 ; WX 600 ; N r ; B 60 0 559 441 ;
+C 115 ; WX 600 ; N s ; B 80 -15 513 441 ;
+C 116 ; WX 600 ; N t ; B 87 -15 530 561 ;
+C 117 ; WX 600 ; N u ; B 21 -15 562 426 ;
+C 118 ; WX 600 ; N v ; B 10 -10 590 426 ;
+C 119 ; WX 600 ; N w ; B -4 -10 604 426 ;
+C 120 ; WX 600 ; N x ; B 20 0 580 426 ;
+C 121 ; WX 600 ; N y ; B 7 -157 592 426 ;
+C 122 ; WX 600 ; N z ; B 99 0 502 426 ;
+C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ;
+C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ;
+C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ;
+C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ;
+C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ;
+C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ;
+C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ;
+C 164 ; WX 600 ; N fraction ; B 92 -57 509 665 ;
+C 165 ; WX 600 ; N yen ; B 26 0 574 562 ;
+C 166 ; WX 600 ; N florin ; B 4 -143 539 622 ;
+C 167 ; WX 600 ; N section ; B 113 -78 488 580 ;
+C 168 ; WX 600 ; N currency ; B 73 58 527 506 ;
+C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ;
+C 170 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ;
+C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ;
+C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ;
+C 174 ; WX 600 ; N fi ; B 3 0 597 629 ;
+C 175 ; WX 600 ; N fl ; B 3 0 597 629 ;
+C 177 ; WX 600 ; N endash ; B 75 231 525 285 ;
+C 178 ; WX 600 ; N dagger ; B 141 -78 459 580 ;
+C 179 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ;
+C 180 ; WX 600 ; N periodcentered ; B 222 189 378 327 ;
+C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ;
+C 183 ; WX 600 ; N bullet ; B 172 130 428 383 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ;
+C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ;
+C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ;
+C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ;
+C 188 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ;
+C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ;
+C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ;
+C 193 ; WX 600 ; N grave ; B 151 497 378 672 ;
+C 194 ; WX 600 ; N acute ; B 242 497 469 672 ;
+C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ;
+C 196 ; WX 600 ; N tilde ; B 105 489 503 606 ;
+C 197 ; WX 600 ; N macron ; B 120 525 480 565 ;
+C 198 ; WX 600 ; N breve ; B 153 501 447 609 ;
+C 199 ; WX 600 ; N dotaccent ; B 249 477 352 580 ;
+C 200 ; WX 600 ; N dieresis ; B 148 492 453 595 ;
+C 202 ; WX 600 ; N ring ; B 218 463 382 627 ;
+C 203 ; WX 600 ; N cedilla ; B 224 -151 362 10 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ;
+C 206 ; WX 600 ; N ogonek ; B 227 -151 370 0 ;
+C 207 ; WX 600 ; N caron ; B 124 492 476 669 ;
+C 208 ; WX 600 ; N emdash ; B 0 231 600 285 ;
+C 225 ; WX 600 ; N AE ; B 3 0 550 562 ;
+C 227 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ;
+C 232 ; WX 600 ; N Lslash ; B 47 0 554 562 ;
+C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ;
+C 234 ; WX 600 ; N OE ; B 7 0 567 562 ;
+C 235 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ;
+C 241 ; WX 600 ; N ae ; B 19 -15 570 441 ;
+C 245 ; WX 600 ; N dotlessi ; B 95 0 505 426 ;
+C 248 ; WX 600 ; N lslash ; B 95 0 505 629 ;
+C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ;
+C 250 ; WX 600 ; N oe ; B 19 -15 559 441 ;
+C 251 ; WX 600 ; N germandbls ; B 48 -15 588 629 ;
+C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 731 ;
+C -1 ; WX 600 ; N logicalnot ; B 87 108 513 369 ;
+C -1 ; WX 600 ; N minus ; B 80 232 520 283 ;
+C -1 ; WX 600 ; N merge ; B 160 -15 440 436 ;
+C -1 ; WX 600 ; N degree ; B 123 269 477 622 ;
+C -1 ; WX 600 ; N dectab ; B 18 0 582 227 ;
+C -1 ; WX 600 ; N ll ; B 18 0 567 629 ;
+C -1 ; WX 600 ; N IJ ; B 32 -18 583 562 ;
+C -1 ; WX 600 ; N Eacute ; B 53 0 550 793 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 775 ;
+C -1 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ;
+C -1 ; WX 600 ; N left ; B 70 68 530 348 ;
+C -1 ; WX 600 ; N threesuperior ; B 155 240 406 622 ;
+C -1 ; WX 600 ; N up ; B 160 0 440 437 ;
+C -1 ; WX 600 ; N multiply ; B 87 43 515 470 ;
+C -1 ; WX 600 ; N Scaron ; B 72 -20 529 805 ;
+C -1 ; WX 600 ; N tab ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 17 -18 583 775 ;
+C -1 ; WX 600 ; N divide ; B 87 48 513 467 ;
+C -1 ; WX 600 ; N Acircumflex ; B 3 0 597 775 ;
+C -1 ; WX 600 ; N eacute ; B 66 -15 548 672 ;
+C -1 ; WX 600 ; N uacute ; B 21 -15 562 672 ;
+C -1 ; WX 600 ; N Aacute ; B 3 0 597 793 ;
+C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N twosuperior ; B 177 249 424 622 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 53 0 550 775 ;
+C -1 ; WX 600 ; N ntilde ; B 26 0 575 606 ;
+C -1 ; WX 600 ; N down ; B 160 -15 440 426 ;
+C -1 ; WX 600 ; N center ; B 40 14 560 580 ;
+C -1 ; WX 600 ; N onesuperior ; B 172 249 428 622 ;
+C -1 ; WX 600 ; N ij ; B 37 -157 490 657 ;
+C -1 ; WX 600 ; N edieresis ; B 66 -15 548 595 ;
+C -1 ; WX 600 ; N graybox ; B 76 0 525 599 ;
+C -1 ; WX 600 ; N odieresis ; B 62 -15 538 595 ;
+C -1 ; WX 600 ; N Ograve ; B 43 -18 557 793 ;
+C -1 ; WX 600 ; N threequarters ; B 8 -56 593 666 ;
+C -1 ; WX 600 ; N plusminus ; B 87 44 513 558 ;
+C -1 ; WX 600 ; N prescription ; B 27 -15 577 562 ;
+C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ;
+C -1 ; WX 600 ; N largebullet ; B 261 220 339 297 ;
+C -1 ; WX 600 ; N egrave ; B 66 -15 548 672 ;
+C -1 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ;
+C -1 ; WX 600 ; N notegraphic ; B 136 -15 464 572 ;
+C -1 ; WX 600 ; N Udieresis ; B 17 -18 583 731 ;
+C -1 ; WX 600 ; N Gcaron ; B 31 -18 575 805 ;
+C -1 ; WX 600 ; N arrowdown ; B 116 -15 484 608 ;
+C -1 ; WX 600 ; N format ; B 5 -157 56 607 ;
+C -1 ; WX 600 ; N Otilde ; B 43 -18 557 732 ;
+C -1 ; WX 600 ; N Idieresis ; B 96 0 504 731 ;
+C -1 ; WX 600 ; N adieresis ; B 53 -15 559 595 ;
+C -1 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ;
+C -1 ; WX 600 ; N Eth ; B 30 0 574 562 ;
+C -1 ; WX 600 ; N onequarter ; B 0 -57 600 665 ;
+C -1 ; WX 600 ; N LL ; B 8 0 592 562 ;
+C -1 ; WX 600 ; N agrave ; B 53 -15 559 672 ;
+C -1 ; WX 600 ; N Zcaron ; B 86 0 514 805 ;
+C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ;
+C -1 ; WX 600 ; N Idot ; B 96 0 504 716 ;
+C -1 ; WX 600 ; N Iacute ; B 96 0 504 793 ;
+C -1 ; WX 600 ; N indent ; B 70 68 530 348 ;
+C -1 ; WX 600 ; N Ugrave ; B 17 -18 583 793 ;
+C -1 ; WX 600 ; N scaron ; B 80 -15 513 669 ;
+C -1 ; WX 600 ; N overscore ; B 0 579 600 629 ;
+C -1 ; WX 600 ; N Aring ; B 3 0 597 753 ;
+C -1 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ;
+C -1 ; WX 600 ; N Igrave ; B 96 0 504 793 ;
+C -1 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ;
+C -1 ; WX 600 ; N Oacute ; B 43 -18 557 793 ;
+C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ;
+C -1 ; WX 600 ; N Yacute ; B 24 0 576 793 ;
+C -1 ; WX 600 ; N lira ; B 73 -21 521 611 ;
+C -1 ; WX 600 ; N Icircumflex ; B 96 0 504 775 ;
+C -1 ; WX 600 ; N Atilde ; B 3 0 597 732 ;
+C -1 ; WX 600 ; N Uacute ; B 17 -18 583 793 ;
+C -1 ; WX 600 ; N Ydieresis ; B 24 0 576 731 ;
+C -1 ; WX 600 ; N ydieresis ; B 7 -157 592 595 ;
+C -1 ; WX 600 ; N idieresis ; B 95 0 505 595 ;
+C -1 ; WX 600 ; N Adieresis ; B 3 0 597 731 ;
+C -1 ; WX 600 ; N mu ; B 21 -157 562 426 ;
+C -1 ; WX 600 ; N trademark ; B -23 263 623 562 ;
+C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ;
+C -1 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ;
+C -1 ; WX 600 ; N Agrave ; B 3 0 597 793 ;
+C -1 ; WX 600 ; N return ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N atilde ; B 53 -15 559 606 ;
+C -1 ; WX 600 ; N square ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
+C -1 ; WX 600 ; N stop ; B 19 0 581 562 ;
+C -1 ; WX 600 ; N udieresis ; B 21 -15 562 595 ;
+C -1 ; WX 600 ; N arrowup ; B 116 0 484 623 ;
+C -1 ; WX 600 ; N igrave ; B 95 0 505 672 ;
+C -1 ; WX 600 ; N Edieresis ; B 53 0 550 731 ;
+C -1 ; WX 600 ; N zcaron ; B 99 0 502 669 ;
+C -1 ; WX 600 ; N arrowboth ; B -28 115 628 483 ;
+C -1 ; WX 600 ; N gcaron ; B 45 -157 566 669 ;
+C -1 ; WX 600 ; N arrowleft ; B -24 115 624 483 ;
+C -1 ; WX 600 ; N aacute ; B 53 -15 559 672 ;
+C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ;
+C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ;
+C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ;
+C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ;
+C -1 ; WX 600 ; N ugrave ; B 21 -15 562 672 ;
+C -1 ; WX 600 ; N Ntilde ; B 7 -13 593 732 ;
+C -1 ; WX 600 ; N iacute ; B 95 0 505 672 ;
+C -1 ; WX 600 ; N arrowright ; B -24 115 624 483 ;
+C -1 ; WX 600 ; N Thorn ; B 79 0 538 562 ;
+C -1 ; WX 600 ; N Egrave ; B 53 0 550 793 ;
+C -1 ; WX 600 ; N thorn ; B -6 -157 555 629 ;
+C -1 ; WX 600 ; N aring ; B 53 -15 559 627 ;
+C -1 ; WX 600 ; N yacute ; B 7 -157 592 672 ;
+C -1 ; WX 600 ; N icircumflex ; B 94 0 505 654 ;
+EndCharMetrics
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 20 121 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -30 121 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -30 136 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave -30 121 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring -15 126 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 126 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 30 121 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 121 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 136 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 121 ;
+CC Gcaron 2 ; PCC G 0 0 ; PCC caron 0 136 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 121 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 121 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 136 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 121 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 126 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 121 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 121 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 136 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 121 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 126 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 30 136 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 30 121 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 121 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 136 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave -30 121 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 30 121 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 136 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 136 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC gcaron 2 ; PCC g 0 0 ; PCC caron -30 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -30 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -30 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -30 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute -10 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -10 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute -20 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis -10 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 10 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-Bold.afm b/tlt3.0/library/afm/Helvetica-Bold.afm
new file mode 100644
index 0000000..f428198
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-Bold.afm
@@ -0,0 +1,571 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Thu Mar 15 09:43:00 1990
+Comment UniqueID 28357
+Comment VMusage 26878 33770
+FontName Helvetica-Bold
+FullName Helvetica Bold
+FamilyName Helvetica
+Weight Bold
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -170 -228 1003 962
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 532
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 90 0 244 718 ;
+C 34 ; WX 474 ; N quotedbl ; B 98 447 376 718 ;
+C 35 ; WX 556 ; N numbersign ; B 18 0 538 698 ;
+C 36 ; WX 556 ; N dollar ; B 30 -115 523 775 ;
+C 37 ; WX 889 ; N percent ; B 28 -19 861 710 ;
+C 38 ; WX 722 ; N ampersand ; B 54 -19 701 718 ;
+C 39 ; WX 278 ; N quoteright ; B 69 445 209 718 ;
+C 40 ; WX 333 ; N parenleft ; B 35 -208 314 734 ;
+C 41 ; WX 333 ; N parenright ; B 19 -208 298 734 ;
+C 42 ; WX 389 ; N asterisk ; B 27 387 362 718 ;
+C 43 ; WX 584 ; N plus ; B 40 0 544 506 ;
+C 44 ; WX 278 ; N comma ; B 64 -168 214 146 ;
+C 45 ; WX 333 ; N hyphen ; B 27 215 306 345 ;
+C 46 ; WX 278 ; N period ; B 64 0 214 146 ;
+C 47 ; WX 278 ; N slash ; B -33 -19 311 737 ;
+C 48 ; WX 556 ; N zero ; B 32 -19 524 710 ;
+C 49 ; WX 556 ; N one ; B 69 0 378 710 ;
+C 50 ; WX 556 ; N two ; B 26 0 511 710 ;
+C 51 ; WX 556 ; N three ; B 27 -19 516 710 ;
+C 52 ; WX 556 ; N four ; B 27 0 526 710 ;
+C 53 ; WX 556 ; N five ; B 27 -19 516 698 ;
+C 54 ; WX 556 ; N six ; B 31 -19 520 710 ;
+C 55 ; WX 556 ; N seven ; B 25 0 528 698 ;
+C 56 ; WX 556 ; N eight ; B 32 -19 524 710 ;
+C 57 ; WX 556 ; N nine ; B 30 -19 522 710 ;
+C 58 ; WX 333 ; N colon ; B 92 0 242 512 ;
+C 59 ; WX 333 ; N semicolon ; B 92 -168 242 512 ;
+C 60 ; WX 584 ; N less ; B 38 -8 546 514 ;
+C 61 ; WX 584 ; N equal ; B 40 87 544 419 ;
+C 62 ; WX 584 ; N greater ; B 38 -8 546 514 ;
+C 63 ; WX 611 ; N question ; B 60 0 556 727 ;
+C 64 ; WX 975 ; N at ; B 118 -19 856 737 ;
+C 65 ; WX 722 ; N A ; B 20 0 702 718 ;
+C 66 ; WX 722 ; N B ; B 76 0 669 718 ;
+C 67 ; WX 722 ; N C ; B 44 -19 684 737 ;
+C 68 ; WX 722 ; N D ; B 76 0 685 718 ;
+C 69 ; WX 667 ; N E ; B 76 0 621 718 ;
+C 70 ; WX 611 ; N F ; B 76 0 587 718 ;
+C 71 ; WX 778 ; N G ; B 44 -19 713 737 ;
+C 72 ; WX 722 ; N H ; B 71 0 651 718 ;
+C 73 ; WX 278 ; N I ; B 64 0 214 718 ;
+C 74 ; WX 556 ; N J ; B 22 -18 484 718 ;
+C 75 ; WX 722 ; N K ; B 87 0 722 718 ;
+C 76 ; WX 611 ; N L ; B 76 0 583 718 ;
+C 77 ; WX 833 ; N M ; B 69 0 765 718 ;
+C 78 ; WX 722 ; N N ; B 69 0 654 718 ;
+C 79 ; WX 778 ; N O ; B 44 -19 734 737 ;
+C 80 ; WX 667 ; N P ; B 76 0 627 718 ;
+C 81 ; WX 778 ; N Q ; B 44 -52 737 737 ;
+C 82 ; WX 722 ; N R ; B 76 0 677 718 ;
+C 83 ; WX 667 ; N S ; B 39 -19 629 737 ;
+C 84 ; WX 611 ; N T ; B 14 0 598 718 ;
+C 85 ; WX 722 ; N U ; B 72 -19 651 718 ;
+C 86 ; WX 667 ; N V ; B 19 0 648 718 ;
+C 87 ; WX 944 ; N W ; B 16 0 929 718 ;
+C 88 ; WX 667 ; N X ; B 14 0 653 718 ;
+C 89 ; WX 667 ; N Y ; B 15 0 653 718 ;
+C 90 ; WX 611 ; N Z ; B 25 0 586 718 ;
+C 91 ; WX 333 ; N bracketleft ; B 63 -196 309 722 ;
+C 92 ; WX 278 ; N backslash ; B -33 -19 311 737 ;
+C 93 ; WX 333 ; N bracketright ; B 24 -196 270 722 ;
+C 94 ; WX 584 ; N asciicircum ; B 62 323 522 698 ;
+C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 69 454 209 727 ;
+C 97 ; WX 556 ; N a ; B 29 -14 527 546 ;
+C 98 ; WX 611 ; N b ; B 61 -14 578 718 ;
+C 99 ; WX 556 ; N c ; B 34 -14 524 546 ;
+C 100 ; WX 611 ; N d ; B 34 -14 551 718 ;
+C 101 ; WX 556 ; N e ; B 23 -14 528 546 ;
+C 102 ; WX 333 ; N f ; B 10 0 318 727 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 40 -217 553 546 ;
+C 104 ; WX 611 ; N h ; B 65 0 546 718 ;
+C 105 ; WX 278 ; N i ; B 69 0 209 725 ;
+C 106 ; WX 278 ; N j ; B 3 -214 209 725 ;
+C 107 ; WX 556 ; N k ; B 69 0 562 718 ;
+C 108 ; WX 278 ; N l ; B 69 0 209 718 ;
+C 109 ; WX 889 ; N m ; B 64 0 826 546 ;
+C 110 ; WX 611 ; N n ; B 65 0 546 546 ;
+C 111 ; WX 611 ; N o ; B 34 -14 578 546 ;
+C 112 ; WX 611 ; N p ; B 62 -207 578 546 ;
+C 113 ; WX 611 ; N q ; B 34 -207 552 546 ;
+C 114 ; WX 389 ; N r ; B 64 0 373 546 ;
+C 115 ; WX 556 ; N s ; B 30 -14 519 546 ;
+C 116 ; WX 333 ; N t ; B 10 -6 309 676 ;
+C 117 ; WX 611 ; N u ; B 66 -14 545 532 ;
+C 118 ; WX 556 ; N v ; B 13 0 543 532 ;
+C 119 ; WX 778 ; N w ; B 10 0 769 532 ;
+C 120 ; WX 556 ; N x ; B 15 0 541 532 ;
+C 121 ; WX 556 ; N y ; B 10 -214 539 532 ;
+C 122 ; WX 500 ; N z ; B 20 0 480 532 ;
+C 123 ; WX 389 ; N braceleft ; B 48 -196 365 722 ;
+C 124 ; WX 280 ; N bar ; B 84 -19 196 737 ;
+C 125 ; WX 389 ; N braceright ; B 24 -196 341 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 61 163 523 343 ;
+C 161 ; WX 333 ; N exclamdown ; B 90 -186 244 532 ;
+C 162 ; WX 556 ; N cent ; B 34 -118 524 628 ;
+C 163 ; WX 556 ; N sterling ; B 28 -16 541 718 ;
+C 164 ; WX 167 ; N fraction ; B -170 -19 336 710 ;
+C 165 ; WX 556 ; N yen ; B -9 0 565 698 ;
+C 166 ; WX 556 ; N florin ; B -10 -210 516 737 ;
+C 167 ; WX 556 ; N section ; B 34 -184 522 727 ;
+C 168 ; WX 556 ; N currency ; B -3 76 559 636 ;
+C 169 ; WX 238 ; N quotesingle ; B 70 447 168 718 ;
+C 170 ; WX 500 ; N quotedblleft ; B 64 454 436 727 ;
+C 171 ; WX 556 ; N guillemotleft ; B 88 76 468 484 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 83 76 250 484 ;
+C 173 ; WX 333 ; N guilsinglright ; B 83 76 250 484 ;
+C 174 ; WX 611 ; N fi ; B 10 0 542 727 ;
+C 175 ; WX 611 ; N fl ; B 10 0 542 727 ;
+C 177 ; WX 556 ; N endash ; B 0 227 556 333 ;
+C 178 ; WX 556 ; N dagger ; B 36 -171 520 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 36 -171 520 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 58 172 220 334 ;
+C 182 ; WX 556 ; N paragraph ; B -8 -191 539 700 ;
+C 183 ; WX 350 ; N bullet ; B 10 194 340 524 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 69 -146 209 127 ;
+C 185 ; WX 500 ; N quotedblbase ; B 64 -146 436 127 ;
+C 186 ; WX 500 ; N quotedblright ; B 64 445 436 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 88 76 468 484 ;
+C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ;
+C 189 ; WX 1000 ; N perthousand ; B -3 -19 1003 710 ;
+C 191 ; WX 611 ; N questiondown ; B 55 -195 551 532 ;
+C 193 ; WX 333 ; N grave ; B -23 604 225 750 ;
+C 194 ; WX 333 ; N acute ; B 108 604 356 750 ;
+C 195 ; WX 333 ; N circumflex ; B -10 604 343 750 ;
+C 196 ; WX 333 ; N tilde ; B -17 610 350 737 ;
+C 197 ; WX 333 ; N macron ; B -6 604 339 678 ;
+C 198 ; WX 333 ; N breve ; B -2 604 335 750 ;
+C 199 ; WX 333 ; N dotaccent ; B 104 614 230 729 ;
+C 200 ; WX 333 ; N dieresis ; B 6 614 327 729 ;
+C 202 ; WX 333 ; N ring ; B 59 568 275 776 ;
+C 203 ; WX 333 ; N cedilla ; B 6 -228 245 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 9 604 486 750 ;
+C 206 ; WX 333 ; N ogonek ; B 71 -228 304 0 ;
+C 207 ; WX 333 ; N caron ; B -10 604 343 750 ;
+C 208 ; WX 1000 ; N emdash ; B 0 227 1000 333 ;
+C 225 ; WX 1000 ; N AE ; B 5 0 954 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 22 276 347 737 ;
+C 232 ; WX 611 ; N Lslash ; B -20 0 583 718 ;
+C 233 ; WX 778 ; N Oslash ; B 33 -27 744 745 ;
+C 234 ; WX 1000 ; N OE ; B 37 -19 961 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 6 276 360 737 ;
+C 241 ; WX 889 ; N ae ; B 29 -14 858 546 ;
+C 245 ; WX 278 ; N dotlessi ; B 69 0 209 532 ;
+C 248 ; WX 278 ; N lslash ; B -18 0 296 718 ;
+C 249 ; WX 611 ; N oslash ; B 22 -29 589 560 ;
+C 250 ; WX 944 ; N oe ; B 34 -14 912 546 ;
+C 251 ; WX 611 ; N germandbls ; B 69 -14 579 731 ;
+C -1 ; WX 611 ; N Zcaron ; B 25 0 586 936 ;
+C -1 ; WX 556 ; N ccedilla ; B 34 -228 524 546 ;
+C -1 ; WX 556 ; N ydieresis ; B 10 -214 539 729 ;
+C -1 ; WX 556 ; N atilde ; B 29 -14 527 737 ;
+C -1 ; WX 278 ; N icircumflex ; B -37 0 316 750 ;
+C -1 ; WX 333 ; N threesuperior ; B 8 271 326 710 ;
+C -1 ; WX 556 ; N ecircumflex ; B 23 -14 528 750 ;
+C -1 ; WX 611 ; N thorn ; B 62 -208 578 718 ;
+C -1 ; WX 556 ; N egrave ; B 23 -14 528 750 ;
+C -1 ; WX 333 ; N twosuperior ; B 9 283 324 710 ;
+C -1 ; WX 556 ; N eacute ; B 23 -14 528 750 ;
+C -1 ; WX 611 ; N otilde ; B 34 -14 578 737 ;
+C -1 ; WX 722 ; N Aacute ; B 20 0 702 936 ;
+C -1 ; WX 611 ; N ocircumflex ; B 34 -14 578 750 ;
+C -1 ; WX 556 ; N yacute ; B 10 -214 539 750 ;
+C -1 ; WX 611 ; N udieresis ; B 66 -14 545 729 ;
+C -1 ; WX 834 ; N threequarters ; B 16 -19 799 710 ;
+C -1 ; WX 556 ; N acircumflex ; B 29 -14 527 750 ;
+C -1 ; WX 722 ; N Eth ; B -5 0 685 718 ;
+C -1 ; WX 556 ; N edieresis ; B 23 -14 528 729 ;
+C -1 ; WX 611 ; N ugrave ; B 66 -14 545 750 ;
+C -1 ; WX 1000 ; N trademark ; B 44 306 956 718 ;
+C -1 ; WX 611 ; N ograve ; B 34 -14 578 750 ;
+C -1 ; WX 556 ; N scaron ; B 30 -14 519 750 ;
+C -1 ; WX 278 ; N Idieresis ; B -21 0 300 915 ;
+C -1 ; WX 611 ; N uacute ; B 66 -14 545 750 ;
+C -1 ; WX 556 ; N agrave ; B 29 -14 527 750 ;
+C -1 ; WX 611 ; N ntilde ; B 65 0 546 737 ;
+C -1 ; WX 556 ; N aring ; B 29 -14 527 776 ;
+C -1 ; WX 500 ; N zcaron ; B 20 0 480 750 ;
+C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 936 ;
+C -1 ; WX 722 ; N Ntilde ; B 69 0 654 923 ;
+C -1 ; WX 611 ; N ucircumflex ; B 66 -14 545 750 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 76 0 621 936 ;
+C -1 ; WX 278 ; N Iacute ; B 64 0 329 936 ;
+C -1 ; WX 722 ; N Ccedilla ; B 44 -228 684 737 ;
+C -1 ; WX 778 ; N Odieresis ; B 44 -19 734 915 ;
+C -1 ; WX 667 ; N Scaron ; B 39 -19 629 936 ;
+C -1 ; WX 667 ; N Edieresis ; B 76 0 621 915 ;
+C -1 ; WX 278 ; N Igrave ; B -50 0 214 936 ;
+C -1 ; WX 556 ; N adieresis ; B 29 -14 527 729 ;
+C -1 ; WX 778 ; N Ograve ; B 44 -19 734 936 ;
+C -1 ; WX 667 ; N Egrave ; B 76 0 621 936 ;
+C -1 ; WX 667 ; N Ydieresis ; B 15 0 653 915 ;
+C -1 ; WX 737 ; N registered ; B -11 -19 748 737 ;
+C -1 ; WX 778 ; N Otilde ; B 44 -19 734 923 ;
+C -1 ; WX 834 ; N onequarter ; B 26 -19 766 710 ;
+C -1 ; WX 722 ; N Ugrave ; B 72 -19 651 936 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 72 -19 651 936 ;
+C -1 ; WX 667 ; N Thorn ; B 76 0 627 718 ;
+C -1 ; WX 584 ; N divide ; B 40 -42 544 548 ;
+C -1 ; WX 722 ; N Atilde ; B 20 0 702 923 ;
+C -1 ; WX 722 ; N Uacute ; B 72 -19 651 936 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 44 -19 734 936 ;
+C -1 ; WX 584 ; N logicalnot ; B 40 108 544 419 ;
+C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ;
+C -1 ; WX 278 ; N idieresis ; B -21 0 300 729 ;
+C -1 ; WX 278 ; N iacute ; B 69 0 329 750 ;
+C -1 ; WX 556 ; N aacute ; B 29 -14 527 750 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 544 506 ;
+C -1 ; WX 584 ; N multiply ; B 40 1 545 505 ;
+C -1 ; WX 722 ; N Udieresis ; B 72 -19 651 915 ;
+C -1 ; WX 584 ; N minus ; B 40 197 544 309 ;
+C -1 ; WX 333 ; N onesuperior ; B 26 283 237 710 ;
+C -1 ; WX 667 ; N Eacute ; B 76 0 621 936 ;
+C -1 ; WX 722 ; N Acircumflex ; B 20 0 702 936 ;
+C -1 ; WX 737 ; N copyright ; B -11 -19 749 737 ;
+C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ;
+C -1 ; WX 611 ; N odieresis ; B 34 -14 578 729 ;
+C -1 ; WX 611 ; N oacute ; B 34 -14 578 750 ;
+C -1 ; WX 400 ; N degree ; B 57 426 343 712 ;
+C -1 ; WX 278 ; N igrave ; B -50 0 209 750 ;
+C -1 ; WX 611 ; N mu ; B 66 -207 545 532 ;
+C -1 ; WX 778 ; N Oacute ; B 44 -19 734 936 ;
+C -1 ; WX 611 ; N eth ; B 34 -14 578 737 ;
+C -1 ; WX 722 ; N Adieresis ; B 20 0 702 915 ;
+C -1 ; WX 667 ; N Yacute ; B 15 0 653 936 ;
+C -1 ; WX 280 ; N brokenbar ; B 84 -19 196 737 ;
+C -1 ; WX 834 ; N onehalf ; B 26 -19 794 710 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 209
+
+KPX A y -30
+KPX A w -30
+KPX A v -40
+KPX A u -30
+KPX A Y -110
+KPX A W -60
+KPX A V -80
+KPX A U -50
+KPX A T -90
+KPX A Q -40
+KPX A O -40
+KPX A G -50
+KPX A C -40
+
+KPX B U -10
+KPX B A -30
+
+KPX D period -30
+KPX D comma -30
+KPX D Y -70
+KPX D W -40
+KPX D V -40
+KPX D A -40
+
+KPX F period -100
+KPX F comma -100
+KPX F a -20
+KPX F A -80
+
+KPX J u -20
+KPX J period -20
+KPX J comma -20
+KPX J A -20
+
+KPX K y -40
+KPX K u -30
+KPX K o -35
+KPX K e -15
+KPX K O -30
+
+KPX L y -30
+KPX L quoteright -140
+KPX L quotedblright -140
+KPX L Y -120
+KPX L W -80
+KPX L V -110
+KPX L T -90
+
+KPX O period -40
+KPX O comma -40
+KPX O Y -70
+KPX O X -50
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -50
+
+KPX P period -120
+KPX P o -40
+KPX P e -30
+KPX P comma -120
+KPX P a -30
+KPX P A -100
+
+KPX Q period 20
+KPX Q comma 20
+KPX Q U -10
+
+KPX R Y -50
+KPX R W -40
+KPX R V -50
+KPX R U -20
+KPX R T -20
+KPX R O -20
+
+KPX T y -60
+KPX T w -60
+KPX T u -90
+KPX T semicolon -40
+KPX T r -80
+KPX T period -80
+KPX T o -80
+KPX T hyphen -120
+KPX T e -60
+KPX T comma -80
+KPX T colon -40
+KPX T a -80
+KPX T O -40
+KPX T A -90
+
+KPX U period -30
+KPX U comma -30
+KPX U A -50
+
+KPX V u -60
+KPX V semicolon -40
+KPX V period -120
+KPX V o -90
+KPX V hyphen -80
+KPX V e -50
+KPX V comma -120
+KPX V colon -40
+KPX V a -60
+KPX V O -50
+KPX V G -50
+KPX V A -80
+
+KPX W y -20
+KPX W u -45
+KPX W semicolon -10
+KPX W period -80
+KPX W o -60
+KPX W hyphen -40
+KPX W e -35
+KPX W comma -80
+KPX W colon -10
+KPX W a -40
+KPX W O -20
+KPX W A -60
+
+KPX Y u -100
+KPX Y semicolon -50
+KPX Y period -100
+KPX Y o -100
+KPX Y e -80
+KPX Y comma -100
+KPX Y colon -50
+KPX Y a -90
+KPX Y O -70
+KPX Y A -110
+
+KPX a y -20
+KPX a w -15
+KPX a v -15
+KPX a g -10
+
+KPX b y -20
+KPX b v -20
+KPX b u -20
+KPX b l -10
+
+KPX c y -10
+KPX c l -20
+KPX c k -20
+KPX c h -10
+
+KPX colon space -40
+
+KPX comma space -40
+KPX comma quoteright -120
+KPX comma quotedblright -120
+
+KPX d y -15
+KPX d w -15
+KPX d v -15
+KPX d d -10
+
+KPX e y -15
+KPX e x -15
+KPX e w -15
+KPX e v -15
+KPX e period 20
+KPX e comma 10
+
+KPX f quoteright 30
+KPX f quotedblright 30
+KPX f period -10
+KPX f o -20
+KPX f e -10
+KPX f comma -10
+
+KPX g g -10
+KPX g e 10
+
+KPX h y -20
+
+KPX k o -15
+
+KPX l y -15
+KPX l w -15
+
+KPX m y -30
+KPX m u -20
+
+KPX n y -20
+KPX n v -40
+KPX n u -10
+
+KPX o y -20
+KPX o x -30
+KPX o w -15
+KPX o v -20
+
+KPX p y -15
+
+KPX period space -40
+KPX period quoteright -120
+KPX period quotedblright -120
+
+KPX quotedblright space -80
+
+KPX quoteleft quoteleft -46
+
+KPX quoteright v -20
+KPX quoteright space -80
+KPX quoteright s -60
+KPX quoteright r -40
+KPX quoteright quoteright -46
+KPX quoteright l -20
+KPX quoteright d -80
+
+KPX r y 10
+KPX r v 10
+KPX r t 20
+KPX r s -15
+KPX r q -20
+KPX r period -60
+KPX r o -20
+KPX r hyphen -20
+KPX r g -15
+KPX r d -20
+KPX r comma -60
+KPX r c -20
+
+KPX s w -15
+
+KPX semicolon space -40
+
+KPX space quoteleft -60
+KPX space quotedblleft -80
+KPX space Y -120
+KPX space W -80
+KPX space V -80
+KPX space T -100
+
+KPX v period -80
+KPX v o -30
+KPX v comma -80
+KPX v a -20
+
+KPX w period -40
+KPX w o -20
+KPX w comma -40
+
+KPX x e -10
+
+KPX y period -80
+KPX y o -25
+KPX y e -10
+KPX y comma -80
+KPX y a -30
+
+KPX z e 10
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 186 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 186 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 186 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 186 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 195 186 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 186 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 215 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 186 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 186 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 186 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 186 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 186 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 186 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 186 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 186 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 186 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 186 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 186 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 186 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 186 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 186 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 186 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 186 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 186 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 186 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 186 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 186 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 186 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 186 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 132 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 112 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 112 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-BoldOblique.afm b/tlt3.0/library/afm/Helvetica-BoldOblique.afm
new file mode 100644
index 0000000..0df5aaf
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-BoldOblique.afm
@@ -0,0 +1,571 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Thu Mar 15 10:44:33 1990
+Comment UniqueID 28371
+Comment VMusage 7614 43068
+FontName Helvetica-BoldOblique
+FullName Helvetica Bold Oblique
+FamilyName Helvetica
+Weight Bold
+ItalicAngle -12
+IsFixedPitch false
+FontBBox -174 -228 1114 962
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 532
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 94 0 397 718 ;
+C 34 ; WX 474 ; N quotedbl ; B 193 447 529 718 ;
+C 35 ; WX 556 ; N numbersign ; B 60 0 644 698 ;
+C 36 ; WX 556 ; N dollar ; B 67 -115 622 775 ;
+C 37 ; WX 889 ; N percent ; B 136 -19 901 710 ;
+C 38 ; WX 722 ; N ampersand ; B 89 -19 732 718 ;
+C 39 ; WX 278 ; N quoteright ; B 167 445 362 718 ;
+C 40 ; WX 333 ; N parenleft ; B 76 -208 470 734 ;
+C 41 ; WX 333 ; N parenright ; B -25 -208 369 734 ;
+C 42 ; WX 389 ; N asterisk ; B 146 387 481 718 ;
+C 43 ; WX 584 ; N plus ; B 82 0 610 506 ;
+C 44 ; WX 278 ; N comma ; B 28 -168 245 146 ;
+C 45 ; WX 333 ; N hyphen ; B 73 215 379 345 ;
+C 46 ; WX 278 ; N period ; B 64 0 245 146 ;
+C 47 ; WX 278 ; N slash ; B -37 -19 468 737 ;
+C 48 ; WX 556 ; N zero ; B 86 -19 617 710 ;
+C 49 ; WX 556 ; N one ; B 173 0 529 710 ;
+C 50 ; WX 556 ; N two ; B 26 0 619 710 ;
+C 51 ; WX 556 ; N three ; B 65 -19 608 710 ;
+C 52 ; WX 556 ; N four ; B 60 0 598 710 ;
+C 53 ; WX 556 ; N five ; B 64 -19 636 698 ;
+C 54 ; WX 556 ; N six ; B 85 -19 619 710 ;
+C 55 ; WX 556 ; N seven ; B 125 0 676 698 ;
+C 56 ; WX 556 ; N eight ; B 69 -19 616 710 ;
+C 57 ; WX 556 ; N nine ; B 78 -19 615 710 ;
+C 58 ; WX 333 ; N colon ; B 92 0 351 512 ;
+C 59 ; WX 333 ; N semicolon ; B 56 -168 351 512 ;
+C 60 ; WX 584 ; N less ; B 82 -8 655 514 ;
+C 61 ; WX 584 ; N equal ; B 58 87 633 419 ;
+C 62 ; WX 584 ; N greater ; B 36 -8 609 514 ;
+C 63 ; WX 611 ; N question ; B 165 0 671 727 ;
+C 64 ; WX 975 ; N at ; B 186 -19 954 737 ;
+C 65 ; WX 722 ; N A ; B 20 0 702 718 ;
+C 66 ; WX 722 ; N B ; B 76 0 764 718 ;
+C 67 ; WX 722 ; N C ; B 107 -19 789 737 ;
+C 68 ; WX 722 ; N D ; B 76 0 777 718 ;
+C 69 ; WX 667 ; N E ; B 76 0 757 718 ;
+C 70 ; WX 611 ; N F ; B 76 0 740 718 ;
+C 71 ; WX 778 ; N G ; B 108 -19 817 737 ;
+C 72 ; WX 722 ; N H ; B 71 0 804 718 ;
+C 73 ; WX 278 ; N I ; B 64 0 367 718 ;
+C 74 ; WX 556 ; N J ; B 60 -18 637 718 ;
+C 75 ; WX 722 ; N K ; B 87 0 858 718 ;
+C 76 ; WX 611 ; N L ; B 76 0 611 718 ;
+C 77 ; WX 833 ; N M ; B 69 0 918 718 ;
+C 78 ; WX 722 ; N N ; B 69 0 807 718 ;
+C 79 ; WX 778 ; N O ; B 107 -19 823 737 ;
+C 80 ; WX 667 ; N P ; B 76 0 738 718 ;
+C 81 ; WX 778 ; N Q ; B 107 -52 823 737 ;
+C 82 ; WX 722 ; N R ; B 76 0 778 718 ;
+C 83 ; WX 667 ; N S ; B 81 -19 718 737 ;
+C 84 ; WX 611 ; N T ; B 140 0 751 718 ;
+C 85 ; WX 722 ; N U ; B 116 -19 804 718 ;
+C 86 ; WX 667 ; N V ; B 172 0 801 718 ;
+C 87 ; WX 944 ; N W ; B 169 0 1082 718 ;
+C 88 ; WX 667 ; N X ; B 14 0 791 718 ;
+C 89 ; WX 667 ; N Y ; B 168 0 806 718 ;
+C 90 ; WX 611 ; N Z ; B 25 0 737 718 ;
+C 91 ; WX 333 ; N bracketleft ; B 21 -196 462 722 ;
+C 92 ; WX 278 ; N backslash ; B 124 -19 307 737 ;
+C 93 ; WX 333 ; N bracketright ; B -18 -196 423 722 ;
+C 94 ; WX 584 ; N asciicircum ; B 131 323 591 698 ;
+C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 165 454 361 727 ;
+C 97 ; WX 556 ; N a ; B 55 -14 583 546 ;
+C 98 ; WX 611 ; N b ; B 61 -14 645 718 ;
+C 99 ; WX 556 ; N c ; B 79 -14 599 546 ;
+C 100 ; WX 611 ; N d ; B 82 -14 704 718 ;
+C 101 ; WX 556 ; N e ; B 70 -14 593 546 ;
+C 102 ; WX 333 ; N f ; B 87 0 469 727 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 38 -217 666 546 ;
+C 104 ; WX 611 ; N h ; B 65 0 629 718 ;
+C 105 ; WX 278 ; N i ; B 69 0 363 725 ;
+C 106 ; WX 278 ; N j ; B -42 -214 363 725 ;
+C 107 ; WX 556 ; N k ; B 69 0 670 718 ;
+C 108 ; WX 278 ; N l ; B 69 0 362 718 ;
+C 109 ; WX 889 ; N m ; B 64 0 909 546 ;
+C 110 ; WX 611 ; N n ; B 65 0 629 546 ;
+C 111 ; WX 611 ; N o ; B 82 -14 643 546 ;
+C 112 ; WX 611 ; N p ; B 18 -207 645 546 ;
+C 113 ; WX 611 ; N q ; B 80 -207 665 546 ;
+C 114 ; WX 389 ; N r ; B 64 0 489 546 ;
+C 115 ; WX 556 ; N s ; B 63 -14 584 546 ;
+C 116 ; WX 333 ; N t ; B 100 -6 422 676 ;
+C 117 ; WX 611 ; N u ; B 98 -14 658 532 ;
+C 118 ; WX 556 ; N v ; B 126 0 656 532 ;
+C 119 ; WX 778 ; N w ; B 123 0 882 532 ;
+C 120 ; WX 556 ; N x ; B 15 0 648 532 ;
+C 121 ; WX 556 ; N y ; B 42 -214 652 532 ;
+C 122 ; WX 500 ; N z ; B 20 0 583 532 ;
+C 123 ; WX 389 ; N braceleft ; B 94 -196 518 722 ;
+C 124 ; WX 280 ; N bar ; B 80 -19 353 737 ;
+C 125 ; WX 389 ; N braceright ; B -18 -196 407 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 115 163 577 343 ;
+C 161 ; WX 333 ; N exclamdown ; B 50 -186 353 532 ;
+C 162 ; WX 556 ; N cent ; B 79 -118 599 628 ;
+C 163 ; WX 556 ; N sterling ; B 50 -16 635 718 ;
+C 164 ; WX 167 ; N fraction ; B -174 -19 487 710 ;
+C 165 ; WX 556 ; N yen ; B 60 0 713 698 ;
+C 166 ; WX 556 ; N florin ; B -50 -210 669 737 ;
+C 167 ; WX 556 ; N section ; B 61 -184 598 727 ;
+C 168 ; WX 556 ; N currency ; B 27 76 680 636 ;
+C 169 ; WX 238 ; N quotesingle ; B 165 447 321 718 ;
+C 170 ; WX 500 ; N quotedblleft ; B 160 454 588 727 ;
+C 171 ; WX 556 ; N guillemotleft ; B 135 76 571 484 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 130 76 353 484 ;
+C 173 ; WX 333 ; N guilsinglright ; B 99 76 322 484 ;
+C 174 ; WX 611 ; N fi ; B 87 0 696 727 ;
+C 175 ; WX 611 ; N fl ; B 87 0 695 727 ;
+C 177 ; WX 556 ; N endash ; B 48 227 627 333 ;
+C 178 ; WX 556 ; N dagger ; B 118 -171 626 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 46 -171 628 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 110 172 276 334 ;
+C 182 ; WX 556 ; N paragraph ; B 98 -191 688 700 ;
+C 183 ; WX 350 ; N bullet ; B 83 194 420 524 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 41 -146 236 127 ;
+C 185 ; WX 500 ; N quotedblbase ; B 36 -146 463 127 ;
+C 186 ; WX 500 ; N quotedblright ; B 162 445 589 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 104 76 540 484 ;
+C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ;
+C 189 ; WX 1000 ; N perthousand ; B 76 -19 1038 710 ;
+C 191 ; WX 611 ; N questiondown ; B 53 -195 559 532 ;
+C 193 ; WX 333 ; N grave ; B 136 604 353 750 ;
+C 194 ; WX 333 ; N acute ; B 236 604 515 750 ;
+C 195 ; WX 333 ; N circumflex ; B 118 604 471 750 ;
+C 196 ; WX 333 ; N tilde ; B 113 610 507 737 ;
+C 197 ; WX 333 ; N macron ; B 122 604 483 678 ;
+C 198 ; WX 333 ; N breve ; B 156 604 494 750 ;
+C 199 ; WX 333 ; N dotaccent ; B 235 614 385 729 ;
+C 200 ; WX 333 ; N dieresis ; B 137 614 482 729 ;
+C 202 ; WX 333 ; N ring ; B 200 568 420 776 ;
+C 203 ; WX 333 ; N cedilla ; B -37 -228 220 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 137 604 645 750 ;
+C 206 ; WX 333 ; N ogonek ; B 41 -228 264 0 ;
+C 207 ; WX 333 ; N caron ; B 149 604 502 750 ;
+C 208 ; WX 1000 ; N emdash ; B 48 227 1071 333 ;
+C 225 ; WX 1000 ; N AE ; B 5 0 1100 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 92 276 465 737 ;
+C 232 ; WX 611 ; N Lslash ; B 34 0 611 718 ;
+C 233 ; WX 778 ; N Oslash ; B 35 -27 894 745 ;
+C 234 ; WX 1000 ; N OE ; B 99 -19 1114 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 92 276 485 737 ;
+C 241 ; WX 889 ; N ae ; B 56 -14 923 546 ;
+C 245 ; WX 278 ; N dotlessi ; B 69 0 322 532 ;
+C 248 ; WX 278 ; N lslash ; B 40 0 407 718 ;
+C 249 ; WX 611 ; N oslash ; B 22 -29 701 560 ;
+C 250 ; WX 944 ; N oe ; B 82 -14 977 546 ;
+C 251 ; WX 611 ; N germandbls ; B 69 -14 657 731 ;
+C -1 ; WX 611 ; N Zcaron ; B 25 0 737 936 ;
+C -1 ; WX 556 ; N ccedilla ; B 79 -228 599 546 ;
+C -1 ; WX 556 ; N ydieresis ; B 42 -214 652 729 ;
+C -1 ; WX 556 ; N atilde ; B 55 -14 619 737 ;
+C -1 ; WX 278 ; N icircumflex ; B 69 0 444 750 ;
+C -1 ; WX 333 ; N threesuperior ; B 91 271 441 710 ;
+C -1 ; WX 556 ; N ecircumflex ; B 70 -14 593 750 ;
+C -1 ; WX 611 ; N thorn ; B 18 -208 645 718 ;
+C -1 ; WX 556 ; N egrave ; B 70 -14 593 750 ;
+C -1 ; WX 333 ; N twosuperior ; B 69 283 449 710 ;
+C -1 ; WX 556 ; N eacute ; B 70 -14 627 750 ;
+C -1 ; WX 611 ; N otilde ; B 82 -14 646 737 ;
+C -1 ; WX 722 ; N Aacute ; B 20 0 750 936 ;
+C -1 ; WX 611 ; N ocircumflex ; B 82 -14 643 750 ;
+C -1 ; WX 556 ; N yacute ; B 42 -214 652 750 ;
+C -1 ; WX 611 ; N udieresis ; B 98 -14 658 729 ;
+C -1 ; WX 834 ; N threequarters ; B 99 -19 839 710 ;
+C -1 ; WX 556 ; N acircumflex ; B 55 -14 583 750 ;
+C -1 ; WX 722 ; N Eth ; B 62 0 777 718 ;
+C -1 ; WX 556 ; N edieresis ; B 70 -14 594 729 ;
+C -1 ; WX 611 ; N ugrave ; B 98 -14 658 750 ;
+C -1 ; WX 1000 ; N trademark ; B 179 306 1109 718 ;
+C -1 ; WX 611 ; N ograve ; B 82 -14 643 750 ;
+C -1 ; WX 556 ; N scaron ; B 63 -14 614 750 ;
+C -1 ; WX 278 ; N Idieresis ; B 64 0 494 915 ;
+C -1 ; WX 611 ; N uacute ; B 98 -14 658 750 ;
+C -1 ; WX 556 ; N agrave ; B 55 -14 583 750 ;
+C -1 ; WX 611 ; N ntilde ; B 65 0 646 737 ;
+C -1 ; WX 556 ; N aring ; B 55 -14 583 776 ;
+C -1 ; WX 500 ; N zcaron ; B 20 0 586 750 ;
+C -1 ; WX 278 ; N Icircumflex ; B 64 0 484 936 ;
+C -1 ; WX 722 ; N Ntilde ; B 69 0 807 923 ;
+C -1 ; WX 611 ; N ucircumflex ; B 98 -14 658 750 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 76 0 757 936 ;
+C -1 ; WX 278 ; N Iacute ; B 64 0 528 936 ;
+C -1 ; WX 722 ; N Ccedilla ; B 107 -228 789 737 ;
+C -1 ; WX 778 ; N Odieresis ; B 107 -19 823 915 ;
+C -1 ; WX 667 ; N Scaron ; B 81 -19 718 936 ;
+C -1 ; WX 667 ; N Edieresis ; B 76 0 757 915 ;
+C -1 ; WX 278 ; N Igrave ; B 64 0 367 936 ;
+C -1 ; WX 556 ; N adieresis ; B 55 -14 594 729 ;
+C -1 ; WX 778 ; N Ograve ; B 107 -19 823 936 ;
+C -1 ; WX 667 ; N Egrave ; B 76 0 757 936 ;
+C -1 ; WX 667 ; N Ydieresis ; B 168 0 806 915 ;
+C -1 ; WX 737 ; N registered ; B 55 -19 834 737 ;
+C -1 ; WX 778 ; N Otilde ; B 107 -19 823 923 ;
+C -1 ; WX 834 ; N onequarter ; B 132 -19 806 710 ;
+C -1 ; WX 722 ; N Ugrave ; B 116 -19 804 936 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 116 -19 804 936 ;
+C -1 ; WX 667 ; N Thorn ; B 76 0 716 718 ;
+C -1 ; WX 584 ; N divide ; B 82 -42 610 548 ;
+C -1 ; WX 722 ; N Atilde ; B 20 0 741 923 ;
+C -1 ; WX 722 ; N Uacute ; B 116 -19 804 936 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 107 -19 823 936 ;
+C -1 ; WX 584 ; N logicalnot ; B 105 108 633 419 ;
+C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ;
+C -1 ; WX 278 ; N idieresis ; B 69 0 455 729 ;
+C -1 ; WX 278 ; N iacute ; B 69 0 488 750 ;
+C -1 ; WX 556 ; N aacute ; B 55 -14 627 750 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 625 506 ;
+C -1 ; WX 584 ; N multiply ; B 57 1 635 505 ;
+C -1 ; WX 722 ; N Udieresis ; B 116 -19 804 915 ;
+C -1 ; WX 584 ; N minus ; B 82 197 610 309 ;
+C -1 ; WX 333 ; N onesuperior ; B 148 283 388 710 ;
+C -1 ; WX 667 ; N Eacute ; B 76 0 757 936 ;
+C -1 ; WX 722 ; N Acircumflex ; B 20 0 706 936 ;
+C -1 ; WX 737 ; N copyright ; B 56 -19 835 737 ;
+C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ;
+C -1 ; WX 611 ; N odieresis ; B 82 -14 643 729 ;
+C -1 ; WX 611 ; N oacute ; B 82 -14 654 750 ;
+C -1 ; WX 400 ; N degree ; B 175 426 467 712 ;
+C -1 ; WX 278 ; N igrave ; B 69 0 326 750 ;
+C -1 ; WX 611 ; N mu ; B 22 -207 658 532 ;
+C -1 ; WX 778 ; N Oacute ; B 107 -19 823 936 ;
+C -1 ; WX 611 ; N eth ; B 82 -14 670 737 ;
+C -1 ; WX 722 ; N Adieresis ; B 20 0 716 915 ;
+C -1 ; WX 667 ; N Yacute ; B 168 0 806 936 ;
+C -1 ; WX 280 ; N brokenbar ; B 80 -19 353 737 ;
+C -1 ; WX 834 ; N onehalf ; B 132 -19 858 710 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 209
+
+KPX A y -30
+KPX A w -30
+KPX A v -40
+KPX A u -30
+KPX A Y -110
+KPX A W -60
+KPX A V -80
+KPX A U -50
+KPX A T -90
+KPX A Q -40
+KPX A O -40
+KPX A G -50
+KPX A C -40
+
+KPX B U -10
+KPX B A -30
+
+KPX D period -30
+KPX D comma -30
+KPX D Y -70
+KPX D W -40
+KPX D V -40
+KPX D A -40
+
+KPX F period -100
+KPX F comma -100
+KPX F a -20
+KPX F A -80
+
+KPX J u -20
+KPX J period -20
+KPX J comma -20
+KPX J A -20
+
+KPX K y -40
+KPX K u -30
+KPX K o -35
+KPX K e -15
+KPX K O -30
+
+KPX L y -30
+KPX L quoteright -140
+KPX L quotedblright -140
+KPX L Y -120
+KPX L W -80
+KPX L V -110
+KPX L T -90
+
+KPX O period -40
+KPX O comma -40
+KPX O Y -70
+KPX O X -50
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -50
+
+KPX P period -120
+KPX P o -40
+KPX P e -30
+KPX P comma -120
+KPX P a -30
+KPX P A -100
+
+KPX Q period 20
+KPX Q comma 20
+KPX Q U -10
+
+KPX R Y -50
+KPX R W -40
+KPX R V -50
+KPX R U -20
+KPX R T -20
+KPX R O -20
+
+KPX T y -60
+KPX T w -60
+KPX T u -90
+KPX T semicolon -40
+KPX T r -80
+KPX T period -80
+KPX T o -80
+KPX T hyphen -120
+KPX T e -60
+KPX T comma -80
+KPX T colon -40
+KPX T a -80
+KPX T O -40
+KPX T A -90
+
+KPX U period -30
+KPX U comma -30
+KPX U A -50
+
+KPX V u -60
+KPX V semicolon -40
+KPX V period -120
+KPX V o -90
+KPX V hyphen -80
+KPX V e -50
+KPX V comma -120
+KPX V colon -40
+KPX V a -60
+KPX V O -50
+KPX V G -50
+KPX V A -80
+
+KPX W y -20
+KPX W u -45
+KPX W semicolon -10
+KPX W period -80
+KPX W o -60
+KPX W hyphen -40
+KPX W e -35
+KPX W comma -80
+KPX W colon -10
+KPX W a -40
+KPX W O -20
+KPX W A -60
+
+KPX Y u -100
+KPX Y semicolon -50
+KPX Y period -100
+KPX Y o -100
+KPX Y e -80
+KPX Y comma -100
+KPX Y colon -50
+KPX Y a -90
+KPX Y O -70
+KPX Y A -110
+
+KPX a y -20
+KPX a w -15
+KPX a v -15
+KPX a g -10
+
+KPX b y -20
+KPX b v -20
+KPX b u -20
+KPX b l -10
+
+KPX c y -10
+KPX c l -20
+KPX c k -20
+KPX c h -10
+
+KPX colon space -40
+
+KPX comma space -40
+KPX comma quoteright -120
+KPX comma quotedblright -120
+
+KPX d y -15
+KPX d w -15
+KPX d v -15
+KPX d d -10
+
+KPX e y -15
+KPX e x -15
+KPX e w -15
+KPX e v -15
+KPX e period 20
+KPX e comma 10
+
+KPX f quoteright 30
+KPX f quotedblright 30
+KPX f period -10
+KPX f o -20
+KPX f e -10
+KPX f comma -10
+
+KPX g g -10
+KPX g e 10
+
+KPX h y -20
+
+KPX k o -15
+
+KPX l y -15
+KPX l w -15
+
+KPX m y -30
+KPX m u -20
+
+KPX n y -20
+KPX n v -40
+KPX n u -10
+
+KPX o y -20
+KPX o x -30
+KPX o w -15
+KPX o v -20
+
+KPX p y -15
+
+KPX period space -40
+KPX period quoteright -120
+KPX period quotedblright -120
+
+KPX quotedblright space -80
+
+KPX quoteleft quoteleft -46
+
+KPX quoteright v -20
+KPX quoteright space -80
+KPX quoteright s -60
+KPX quoteright r -40
+KPX quoteright quoteright -46
+KPX quoteright l -20
+KPX quoteright d -80
+
+KPX r y 10
+KPX r v 10
+KPX r t 20
+KPX r s -15
+KPX r q -20
+KPX r period -60
+KPX r o -20
+KPX r hyphen -20
+KPX r g -15
+KPX r d -20
+KPX r comma -60
+KPX r c -20
+
+KPX s w -15
+
+KPX semicolon space -40
+
+KPX space quoteleft -60
+KPX space quotedblleft -80
+KPX space Y -120
+KPX space W -80
+KPX space V -80
+KPX space T -100
+
+KPX v period -80
+KPX v o -30
+KPX v comma -80
+KPX v a -20
+
+KPX w period -40
+KPX w o -20
+KPX w comma -40
+
+KPX x e -10
+
+KPX y period -80
+KPX y o -25
+KPX y e -10
+KPX y comma -80
+KPX y a -30
+
+KPX z e 10
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 235 186 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 235 186 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 235 186 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 235 186 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 235 186 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 235 186 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 215 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 207 186 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 207 186 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 207 186 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 207 186 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 13 186 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 13 186 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 13 186 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 13 186 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 235 186 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 263 186 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 263 186 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 263 186 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 263 186 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 263 186 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 207 186 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 235 186 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 235 186 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 186 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 235 186 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 207 186 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 207 186 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 186 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 132 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 112 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 112 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-Condensed-Bold.afm b/tlt3.0/library/afm/Helvetica-Condensed-Bold.afm
new file mode 100644
index 0000000..4f0c660
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-Condensed-Bold.afm
@@ -0,0 +1,419 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Wed Sep  4 17:42:59 1991
+Comment UniqueID 36188
+Comment VMusage 27402 34294
+FontName Helvetica-Condensed-Bold
+FullName Helvetica Condensed Bold
+FamilyName Helvetica
+Weight Bold
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -169 -250 1091 991
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.004
+Notice Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 750
+XHeight 564
+Ascender 750
+Descender -189
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 101 0 232 750 ;
+C 34 ; WX 333 ; N quotedbl ; B 16 468 318 739 ;
+C 35 ; WX 500 ; N numbersign ; B 31 0 469 738 ;
+C 36 ; WX 500 ; N dollar ; B 35 -124 466 803 ;
+C 37 ; WX 833 ; N percent ; B 31 -15 803 750 ;
+C 38 ; WX 667 ; N ampersand ; B 63 -18 615 768 ;
+C 39 ; WX 278 ; N quoteright ; B 81 479 202 750 ;
+C 40 ; WX 333 ; N parenleft ; B 52 -198 281 768 ;
+C 41 ; WX 333 ; N parenright ; B 52 -198 281 768 ;
+C 42 ; WX 500 ; N asterisk ; B 79 412 422 738 ;
+C 43 ; WX 500 ; N plus ; B 26 0 475 492 ;
+C 44 ; WX 333 ; N comma ; B 101 -145 233 132 ;
+C 45 ; WX 333 ; N hyphen ; B 48 255 286 370 ;
+C 46 ; WX 333 ; N period ; B 101 0 233 132 ;
+C 47 ; WX 278 ; N slash ; B -11 -94 312 750 ;
+C 48 ; WX 500 ; N zero ; B 48 -15 453 753 ;
+C 49 ; WX 500 ; N one ; B 44 0 353 750 ;
+C 50 ; WX 500 ; N two ; B 32 0 453 753 ;
+C 51 ; WX 500 ; N three ; B 28 -15 453 753 ;
+C 52 ; WX 500 ; N four ; B 23 0 470 738 ;
+C 53 ; WX 500 ; N five ; B 37 -15 458 738 ;
+C 54 ; WX 500 ; N six ; B 42 -15 459 753 ;
+C 55 ; WX 500 ; N seven ; B 32 0 454 738 ;
+C 56 ; WX 500 ; N eight ; B 41 -15 460 753 ;
+C 57 ; WX 500 ; N nine ; B 42 -15 459 753 ;
+C 58 ; WX 278 ; N colon ; B 73 0 205 556 ;
+C 59 ; WX 278 ; N semicolon ; B 73 -145 205 556 ;
+C 60 ; WX 500 ; N less ; B 42 -24 459 527 ;
+C 61 ; WX 500 ; N equal ; B 26 96 475 401 ;
+C 62 ; WX 500 ; N greater ; B 42 -24 459 527 ;
+C 63 ; WX 500 ; N question ; B 51 0 440 768 ;
+C 64 ; WX 833 ; N at ; B 38 -18 795 768 ;
+C 65 ; WX 556 ; N A ; B 9 0 547 750 ;
+C 66 ; WX 556 ; N B ; B 65 0 506 750 ;
+C 67 ; WX 556 ; N C ; B 55 -18 512 768 ;
+C 68 ; WX 611 ; N D ; B 72 0 550 750 ;
+C 69 ; WX 500 ; N E ; B 64 0 458 750 ;
+C 70 ; WX 500 ; N F ; B 73 0 470 750 ;
+C 71 ; WX 611 ; N G ; B 55 -18 542 768 ;
+C 72 ; WX 611 ; N H ; B 68 0 544 750 ;
+C 73 ; WX 278 ; N I ; B 69 0 209 750 ;
+C 74 ; WX 444 ; N J ; B 7 -18 384 750 ;
+C 75 ; WX 556 ; N K ; B 68 0 547 750 ;
+C 76 ; WX 500 ; N L ; B 68 0 468 750 ;
+C 77 ; WX 778 ; N M ; B 67 0 712 750 ;
+C 78 ; WX 611 ; N N ; B 68 0 543 750 ;
+C 79 ; WX 611 ; N O ; B 61 -18 551 768 ;
+C 80 ; WX 556 ; N P ; B 68 0 529 750 ;
+C 81 ; WX 611 ; N Q ; B 61 -71 587 768 ;
+C 82 ; WX 611 ; N R ; B 66 0 567 750 ;
+C 83 ; WX 556 ; N S ; B 49 -18 508 768 ;
+C 84 ; WX 500 ; N T ; B 17 0 484 750 ;
+C 85 ; WX 611 ; N U ; B 68 -18 544 750 ;
+C 86 ; WX 556 ; N V ; B 21 0 536 750 ;
+C 87 ; WX 833 ; N W ; B 24 0 810 750 ;
+C 88 ; WX 556 ; N X ; B 11 0 545 750 ;
+C 89 ; WX 556 ; N Y ; B 12 0 545 750 ;
+C 90 ; WX 500 ; N Z ; B 33 0 468 750 ;
+C 91 ; WX 333 ; N bracketleft ; B 81 -94 280 750 ;
+C 92 ; WX 250 ; N backslash ; B -89 0 340 750 ;
+C 93 ; WX 333 ; N bracketright ; B 53 -94 252 750 ;
+C 94 ; WX 500 ; N asciicircum ; B 10 326 490 750 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 76 495 197 766 ;
+C 97 ; WX 500 ; N a ; B 42 -15 440 579 ;
+C 98 ; WX 500 ; N b ; B 64 -15 444 750 ;
+C 99 ; WX 444 ; N c ; B 49 -15 403 579 ;
+C 100 ; WX 500 ; N d ; B 53 -15 433 750 ;
+C 101 ; WX 500 ; N e ; B 53 -15 443 579 ;
+C 102 ; WX 278 ; N f ; B 21 0 257 750 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 53 -190 433 579 ;
+C 104 ; WX 500 ; N h ; B 61 0 440 750 ;
+C 105 ; WX 278 ; N i ; B 74 0 204 750 ;
+C 106 ; WX 278 ; N j ; B 31 -192 210 750 ;
+C 107 ; WX 444 ; N k ; B 48 0 443 750 ;
+C 108 ; WX 278 ; N l ; B 74 0 204 750 ;
+C 109 ; WX 778 ; N m ; B 66 0 712 579 ;
+C 110 ; WX 500 ; N n ; B 61 0 440 579 ;
+C 111 ; WX 500 ; N o ; B 53 -15 447 579 ;
+C 112 ; WX 500 ; N p ; B 58 -189 438 579 ;
+C 113 ; WX 500 ; N q ; B 50 -188 430 579 ;
+C 114 ; WX 333 ; N r ; B 60 0 319 574 ;
+C 115 ; WX 444 ; N s ; B 28 -15 407 579 ;
+C 116 ; WX 278 ; N t ; B 14 -7 252 719 ;
+C 117 ; WX 500 ; N u ; B 58 -15 431 564 ;
+C 118 ; WX 444 ; N v ; B 10 0 434 564 ;
+C 119 ; WX 667 ; N w ; B 11 0 645 564 ;
+C 120 ; WX 444 ; N x ; B 8 0 436 564 ;
+C 121 ; WX 444 ; N y ; B 5 -195 429 564 ;
+C 122 ; WX 389 ; N z ; B 23 0 367 564 ;
+C 123 ; WX 274 ; N braceleft ; B -32 -92 240 750 ;
+C 124 ; WX 250 ; N bar ; B 75 -250 175 750 ;
+C 125 ; WX 274 ; N braceright ; B 34 -94 306 750 ;
+C 126 ; WX 500 ; N asciitilde ; B 26 153 475 359 ;
+C 161 ; WX 333 ; N exclamdown ; B 102 -170 232 579 ;
+C 162 ; WX 500 ; N cent ; B 72 -122 428 671 ;
+C 163 ; WX 500 ; N sterling ; B 35 -15 487 768 ;
+C 164 ; WX 167 ; N fraction ; B -169 0 331 738 ;
+C 165 ; WX 500 ; N yen ; B -18 0 518 750 ;
+C 166 ; WX 500 ; N florin ; B 9 -185 492 763 ;
+C 167 ; WX 500 ; N section ; B 37 -183 463 768 ;
+C 168 ; WX 500 ; N currency ; B 9 58 492 560 ;
+C 169 ; WX 250 ; N quotesingle ; B 66 468 185 739 ;
+C 170 ; WX 500 ; N quotedblleft ; B 87 495 405 766 ;
+C 171 ; WX 500 ; N guillemotleft ; B 74 62 419 447 ;
+C 172 ; WX 278 ; N guilsinglleft ; B 58 62 215 447 ;
+C 173 ; WX 278 ; N guilsinglright ; B 63 62 220 447 ;
+C 174 ; WX 500 ; N fi ; B 10 0 446 750 ;
+C 175 ; WX 500 ; N fl ; B 10 0 443 750 ;
+C 177 ; WX 500 ; N endash ; B 0 259 500 369 ;
+C 178 ; WX 500 ; N dagger ; B 37 -155 463 768 ;
+C 179 ; WX 500 ; N daggerdbl ; B 35 -161 466 768 ;
+C 180 ; WX 333 ; N periodcentered ; B 101 183 233 315 ;
+C 182 ; WX 550 ; N paragraph ; B 23 -116 526 750 ;
+C 183 ; WX 420 ; N bullet ; B 22 186 398 562 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 87 -138 207 132 ;
+C 185 ; WX 500 ; N quotedblbase ; B 96 -138 413 132 ;
+C 186 ; WX 500 ; N quotedblright ; B 95 479 413 750 ;
+C 187 ; WX 500 ; N guillemotright ; B 81 62 426 447 ;
+C 188 ; WX 1000 ; N ellipsis ; B 101 0 899 132 ;
+C 189 ; WX 1111 ; N perthousand ; B 21 -18 1091 748 ;
+C 191 ; WX 500 ; N questiondown ; B 60 -190 449 579 ;
+C 193 ; WX 333 ; N grave ; B 1 629 250 775 ;
+C 194 ; WX 333 ; N acute ; B 83 629 332 775 ;
+C 195 ; WX 333 ; N circumflex ; B -10 644 343 790 ;
+C 196 ; WX 333 ; N tilde ; B -16 636 350 764 ;
+C 197 ; WX 333 ; N macron ; B -6 666 340 740 ;
+C 198 ; WX 333 ; N breve ; B -1 635 335 780 ;
+C 199 ; WX 333 ; N dotaccent ; B 103 644 230 759 ;
+C 200 ; WX 333 ; N dieresis ; B 5 644 328 759 ;
+C 202 ; WX 333 ; N ring ; B 60 632 273 845 ;
+C 203 ; WX 333 ; N cedilla ; B 39 -228 275 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -17 634 447 780 ;
+C 206 ; WX 333 ; N ogonek ; B 88 -205 278 0 ;
+C 207 ; WX 333 ; N caron ; B -10 634 343 780 ;
+C 208 ; WX 1000 ; N emdash ; B 0 259 1000 369 ;
+C 225 ; WX 778 ; N AE ; B -22 0 750 750 ;
+C 227 ; WX 300 ; N ordfeminine ; B 22 412 281 768 ;
+C 232 ; WX 500 ; N Lslash ; B 0 0 474 750 ;
+C 233 ; WX 611 ; N Oslash ; B 36 -38 578 779 ;
+C 234 ; WX 833 ; N OE ; B 61 -18 792 768 ;
+C 235 ; WX 300 ; N ordmasculine ; B 22 412 278 768 ;
+C 241 ; WX 722 ; N ae ; B 44 -15 672 579 ;
+C 245 ; WX 278 ; N dotlessi ; B 74 0 204 564 ;
+C 248 ; WX 278 ; N lslash ; B 2 0 272 750 ;
+C 249 ; WX 500 ; N oslash ; B 7 -58 492 617 ;
+C 250 ; WX 722 ; N oe ; B 46 -15 678 579 ;
+C 251 ; WX 500 ; N germandbls ; B 60 -15 445 768 ;
+C -1 ; WX 500 ; N ecircumflex ; B 53 -15 443 770 ;
+C -1 ; WX 500 ; N edieresis ; B 53 -15 443 759 ;
+C -1 ; WX 500 ; N aacute ; B 42 -15 440 775 ;
+C -1 ; WX 830 ; N registered ; B 22 -18 808 768 ;
+C -1 ; WX 278 ; N icircumflex ; B -47 0 306 770 ;
+C -1 ; WX 500 ; N udieresis ; B 58 -15 431 759 ;
+C -1 ; WX 500 ; N ograve ; B 53 -15 447 775 ;
+C -1 ; WX 500 ; N uacute ; B 58 -15 431 775 ;
+C -1 ; WX 500 ; N ucircumflex ; B 58 -15 431 780 ;
+C -1 ; WX 556 ; N Aacute ; B 9 0 547 961 ;
+C -1 ; WX 278 ; N igrave ; B -26 0 223 775 ;
+C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 956 ;
+C -1 ; WX 444 ; N ccedilla ; B 49 -228 403 579 ;
+C -1 ; WX 500 ; N adieresis ; B 42 -15 440 759 ;
+C -1 ; WX 500 ; N Ecircumflex ; B 64 0 458 956 ;
+C -1 ; WX 444 ; N scaron ; B 28 -15 407 760 ;
+C -1 ; WX 500 ; N thorn ; B 58 -189 438 750 ;
+C -1 ; WX 860 ; N trademark ; B 1 346 774 750 ;
+C -1 ; WX 500 ; N egrave ; B 53 -15 443 775 ;
+C -1 ; WX 300 ; N threesuperior ; B 12 290 288 751 ;
+C -1 ; WX 389 ; N zcaron ; B 18 0 371 760 ;
+C -1 ; WX 500 ; N atilde ; B 42 -15 440 744 ;
+C -1 ; WX 500 ; N aring ; B 42 -15 440 835 ;
+C -1 ; WX 500 ; N ocircumflex ; B 53 -15 447 770 ;
+C -1 ; WX 500 ; N Edieresis ; B 64 0 458 945 ;
+C -1 ; WX 750 ; N threequarters ; B 12 0 739 751 ;
+C -1 ; WX 444 ; N ydieresis ; B 5 -195 429 759 ;
+C -1 ; WX 444 ; N yacute ; B 5 -195 429 775 ;
+C -1 ; WX 278 ; N iacute ; B 56 0 305 775 ;
+C -1 ; WX 556 ; N Acircumflex ; B 9 0 547 956 ;
+C -1 ; WX 611 ; N Uacute ; B 68 -18 544 961 ;
+C -1 ; WX 500 ; N eacute ; B 53 -15 443 775 ;
+C -1 ; WX 611 ; N Ograve ; B 61 -18 551 961 ;
+C -1 ; WX 500 ; N agrave ; B 42 -15 440 775 ;
+C -1 ; WX 611 ; N Udieresis ; B 68 -18 544 945 ;
+C -1 ; WX 500 ; N acircumflex ; B 42 -15 440 770 ;
+C -1 ; WX 278 ; N Igrave ; B -26 0 223 961 ;
+C -1 ; WX 300 ; N twosuperior ; B 13 300 287 752 ;
+C -1 ; WX 611 ; N Ugrave ; B 68 -18 544 961 ;
+C -1 ; WX 750 ; N onequarter ; B 20 0 729 750 ;
+C -1 ; WX 611 ; N Ucircumflex ; B 68 -18 544 956 ;
+C -1 ; WX 556 ; N Scaron ; B 49 -18 508 946 ;
+C -1 ; WX 278 ; N Idieresis ; B -22 0 301 945 ;
+C -1 ; WX 278 ; N idieresis ; B -22 0 301 759 ;
+C -1 ; WX 500 ; N Egrave ; B 64 0 458 961 ;
+C -1 ; WX 611 ; N Oacute ; B 61 -18 551 961 ;
+C -1 ; WX 500 ; N divide ; B 26 6 475 492 ;
+C -1 ; WX 556 ; N Atilde ; B 9 0 547 930 ;
+C -1 ; WX 556 ; N Aring ; B 9 0 547 991 ;
+C -1 ; WX 611 ; N Odieresis ; B 61 -18 551 945 ;
+C -1 ; WX 556 ; N Adieresis ; B 9 0 547 945 ;
+C -1 ; WX 611 ; N Ntilde ; B 68 0 543 930 ;
+C -1 ; WX 500 ; N Zcaron ; B 33 0 468 946 ;
+C -1 ; WX 556 ; N Thorn ; B 68 0 529 750 ;
+C -1 ; WX 278 ; N Iacute ; B 56 0 305 961 ;
+C -1 ; WX 500 ; N plusminus ; B 26 -15 475 513 ;
+C -1 ; WX 500 ; N multiply ; B 26 22 475 476 ;
+C -1 ; WX 500 ; N Eacute ; B 64 0 458 961 ;
+C -1 ; WX 556 ; N Ydieresis ; B 12 0 545 945 ;
+C -1 ; WX 300 ; N onesuperior ; B 50 300 251 750 ;
+C -1 ; WX 500 ; N ugrave ; B 58 -15 431 775 ;
+C -1 ; WX 500 ; N logicalnot ; B 26 105 475 401 ;
+C -1 ; WX 500 ; N ntilde ; B 61 0 440 744 ;
+C -1 ; WX 611 ; N Otilde ; B 61 -18 551 930 ;
+C -1 ; WX 500 ; N otilde ; B 53 -15 447 744 ;
+C -1 ; WX 556 ; N Ccedilla ; B 55 -228 512 768 ;
+C -1 ; WX 556 ; N Agrave ; B 9 0 547 961 ;
+C -1 ; WX 750 ; N onehalf ; B 12 0 739 750 ;
+C -1 ; WX 611 ; N Eth ; B 20 0 550 750 ;
+C -1 ; WX 400 ; N degree ; B 50 450 350 750 ;
+C -1 ; WX 556 ; N Yacute ; B 12 0 545 961 ;
+C -1 ; WX 611 ; N Ocircumflex ; B 61 -18 551 956 ;
+C -1 ; WX 500 ; N oacute ; B 53 -15 447 775 ;
+C -1 ; WX 500 ; N mu ; B 58 -189 431 564 ;
+C -1 ; WX 500 ; N minus ; B 26 194 475 304 ;
+C -1 ; WX 500 ; N eth ; B 53 -15 447 779 ;
+C -1 ; WX 500 ; N odieresis ; B 53 -15 447 759 ;
+C -1 ; WX 830 ; N copyright ; B 22 -18 808 768 ;
+C -1 ; WX 250 ; N brokenbar ; B 75 -175 175 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 88
+
+KPX A y -18
+KPX A w -18
+KPX A v -18
+KPX A quoteright -55
+KPX A Y -55
+KPX A W -37
+KPX A V -37
+KPX A T -55
+
+KPX F period -111
+KPX F comma -111
+KPX F A -37
+
+KPX L y -37
+KPX L quoteright -92
+KPX L Y -92
+KPX L W -74
+KPX L V -74
+KPX L T -74
+
+KPX P period -129
+KPX P comma -129
+KPX P A -37
+
+KPX R Y -18
+KPX R T -18
+
+KPX T y -55
+KPX T w -74
+KPX T u -74
+KPX T semicolon -74
+KPX T s -74
+KPX T r -74
+KPX T period -92
+KPX T o -74
+KPX T i -18
+KPX T hyphen -55
+KPX T e -74
+KPX T comma -92
+KPX T colon -74
+KPX T c -74
+KPX T a -74
+KPX T A -55
+
+KPX V u -18
+KPX V semicolon -18
+KPX V r -18
+KPX V period -92
+KPX V o -18
+KPX V hyphen -18
+KPX V e -18
+KPX V comma -92
+KPX V colon -18
+KPX V a -18
+KPX V A -37
+
+KPX W period -74
+KPX W o -18
+KPX W hyphen -18
+KPX W e -18
+KPX W comma -74
+KPX W a -18
+KPX W A -18
+
+KPX Y v -18
+KPX Y u -37
+KPX Y semicolon -37
+KPX Y q -55
+KPX Y period -111
+KPX Y p -37
+KPX Y o -55
+KPX Y i -18
+KPX Y hyphen -74
+KPX Y e -55
+KPX Y comma -111
+KPX Y colon -37
+KPX Y a -55
+KPX Y A -55
+
+KPX f quoteright 18
+
+KPX quoteleft quoteleft -18
+
+KPX quoteright s -55
+KPX quoteright quoteright -18
+
+KPX r z 20
+KPX r y 18
+KPX r x 20
+KPX r w 18
+KPX r v 18
+KPX r period -74
+KPX r hyphen -37
+KPX r comma -74
+
+KPX v period -55
+KPX v comma -55
+
+KPX w period -37
+KPX w comma -37
+
+KPX y period -55
+KPX y comma -55
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 112 186 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 102 166 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 112 186 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 112 186 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 112 146 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 112 166 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 84 186 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 84 166 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 84 186 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 84 186 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 186 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 166 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 186 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 186 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 139 166 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 139 186 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 139 166 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 139 186 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 139 186 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 139 166 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 166 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 139 186 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 139 166 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 139 186 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 139 186 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 112 186 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 112 186 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 84 166 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 -20 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 84 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 69 -10 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 -20 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 84 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 84 -20 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 84 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 84 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -37 -20 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 -20 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 -20 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 -20 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 46 -20 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 -10 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 56 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 28 -20 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-Condensed-BoldObl.afm b/tlt3.0/library/afm/Helvetica-Condensed-BoldObl.afm
new file mode 100644
index 0000000..08c7c21
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-Condensed-BoldObl.afm
@@ -0,0 +1,419 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Wed Sep  4 17:46:28 1991
+Comment UniqueID 36191
+Comment VMusage 8125 43764
+FontName Helvetica-Condensed-BoldObl
+FullName Helvetica Condensed Bold Oblique
+FamilyName Helvetica
+Weight Bold
+ItalicAngle -12
+IsFixedPitch false
+FontBBox -169 -250 1141 991
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.004
+Notice Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 750
+XHeight 564
+Ascender 750
+Descender -189
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 102 0 390 750 ;
+C 34 ; WX 333 ; N quotedbl ; B 115 468 475 739 ;
+C 35 ; WX 500 ; N numbersign ; B 81 0 580 738 ;
+C 36 ; WX 500 ; N dollar ; B 68 -124 576 803 ;
+C 37 ; WX 833 ; N percent ; B 138 -15 853 750 ;
+C 38 ; WX 667 ; N ampersand ; B 101 -18 676 768 ;
+C 39 ; WX 278 ; N quoteright ; B 183 479 361 750 ;
+C 40 ; WX 333 ; N parenleft ; B 91 -198 442 768 ;
+C 41 ; WX 333 ; N parenright ; B 12 -198 363 768 ;
+C 42 ; WX 500 ; N asterisk ; B 203 412 546 738 ;
+C 43 ; WX 500 ; N plus ; B 67 0 540 492 ;
+C 44 ; WX 333 ; N comma ; B 70 -145 261 132 ;
+C 45 ; WX 333 ; N hyphen ; B 102 255 365 370 ;
+C 46 ; WX 333 ; N period ; B 101 0 261 132 ;
+C 47 ; WX 278 ; N slash ; B -31 -94 471 750 ;
+C 48 ; WX 500 ; N zero ; B 82 -15 576 753 ;
+C 49 ; WX 500 ; N one ; B 155 0 512 750 ;
+C 50 ; WX 500 ; N two ; B 32 0 577 753 ;
+C 51 ; WX 500 ; N three ; B 61 -15 563 753 ;
+C 52 ; WX 500 ; N four ; B 55 0 563 738 ;
+C 53 ; WX 500 ; N five ; B 72 -15 581 738 ;
+C 54 ; WX 500 ; N six ; B 83 -15 575 753 ;
+C 55 ; WX 500 ; N seven ; B 126 0 611 738 ;
+C 56 ; WX 500 ; N eight ; B 76 -15 570 753 ;
+C 57 ; WX 500 ; N nine ; B 84 -15 575 753 ;
+C 58 ; WX 278 ; N colon ; B 73 0 323 556 ;
+C 59 ; WX 278 ; N semicolon ; B 42 -145 323 556 ;
+C 60 ; WX 500 ; N less ; B 85 -24 571 527 ;
+C 61 ; WX 500 ; N equal ; B 46 96 560 401 ;
+C 62 ; WX 500 ; N greater ; B 37 -24 523 527 ;
+C 63 ; WX 500 ; N question ; B 147 0 569 768 ;
+C 64 ; WX 833 ; N at ; B 109 -18 897 768 ;
+C 65 ; WX 556 ; N A ; B 9 0 547 750 ;
+C 66 ; WX 556 ; N B ; B 65 0 615 750 ;
+C 67 ; WX 556 ; N C ; B 99 -18 630 768 ;
+C 68 ; WX 611 ; N D ; B 72 0 662 750 ;
+C 69 ; WX 500 ; N E ; B 64 0 617 750 ;
+C 70 ; WX 500 ; N F ; B 73 0 629 750 ;
+C 71 ; WX 611 ; N G ; B 99 -18 664 768 ;
+C 72 ; WX 611 ; N H ; B 68 0 703 750 ;
+C 73 ; WX 278 ; N I ; B 69 0 368 750 ;
+C 74 ; WX 444 ; N J ; B 36 -18 543 750 ;
+C 75 ; WX 556 ; N K ; B 68 0 697 750 ;
+C 76 ; WX 500 ; N L ; B 68 0 491 750 ;
+C 77 ; WX 778 ; N M ; B 67 0 871 750 ;
+C 78 ; WX 611 ; N N ; B 68 0 702 750 ;
+C 79 ; WX 611 ; N O ; B 105 -18 664 768 ;
+C 80 ; WX 556 ; N P ; B 68 0 651 750 ;
+C 81 ; WX 611 ; N Q ; B 105 -71 664 768 ;
+C 82 ; WX 611 ; N R ; B 66 0 671 750 ;
+C 83 ; WX 556 ; N S ; B 85 -18 613 768 ;
+C 84 ; WX 500 ; N T ; B 153 0 643 750 ;
+C 85 ; WX 611 ; N U ; B 105 -18 703 750 ;
+C 86 ; WX 556 ; N V ; B 180 0 695 750 ;
+C 87 ; WX 833 ; N W ; B 167 0 969 750 ;
+C 88 ; WX 556 ; N X ; B 11 0 698 750 ;
+C 89 ; WX 556 ; N Y ; B 171 0 704 750 ;
+C 90 ; WX 500 ; N Z ; B 33 0 618 750 ;
+C 91 ; WX 333 ; N bracketleft ; B 61 -94 439 750 ;
+C 92 ; WX 250 ; N backslash ; B 70 0 340 750 ;
+C 93 ; WX 333 ; N bracketright ; B 33 -94 411 750 ;
+C 94 ; WX 500 ; N asciicircum ; B 89 326 569 750 ;
+C 95 ; WX 500 ; N underscore ; B -27 -125 484 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 181 495 360 766 ;
+C 97 ; WX 500 ; N a ; B 68 -15 525 579 ;
+C 98 ; WX 500 ; N b ; B 64 -15 534 750 ;
+C 99 ; WX 444 ; N c ; B 79 -15 496 579 ;
+C 100 ; WX 500 ; N d ; B 83 -15 592 750 ;
+C 101 ; WX 500 ; N e ; B 88 -15 530 579 ;
+C 102 ; WX 278 ; N f ; B 71 0 416 750 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 44 -190 553 579 ;
+C 104 ; WX 500 ; N h ; B 61 0 539 750 ;
+C 105 ; WX 278 ; N i ; B 74 0 363 750 ;
+C 106 ; WX 278 ; N j ; B -9 -192 368 750 ;
+C 107 ; WX 444 ; N k ; B 48 0 563 750 ;
+C 108 ; WX 278 ; N l ; B 74 0 363 750 ;
+C 109 ; WX 778 ; N m ; B 66 0 812 579 ;
+C 110 ; WX 500 ; N n ; B 61 0 539 579 ;
+C 111 ; WX 500 ; N o ; B 88 -15 531 579 ;
+C 112 ; WX 500 ; N p ; B 18 -189 528 579 ;
+C 113 ; WX 500 ; N q ; B 80 -188 550 579 ;
+C 114 ; WX 333 ; N r ; B 60 0 441 574 ;
+C 115 ; WX 444 ; N s ; B 56 -15 498 579 ;
+C 116 ; WX 278 ; N t ; B 83 -7 372 719 ;
+C 117 ; WX 500 ; N u ; B 78 -15 551 564 ;
+C 118 ; WX 444 ; N v ; B 130 0 554 564 ;
+C 119 ; WX 667 ; N w ; B 127 0 765 564 ;
+C 120 ; WX 444 ; N x ; B 8 0 553 564 ;
+C 121 ; WX 444 ; N y ; B 36 -195 549 564 ;
+C 122 ; WX 389 ; N z ; B 23 0 487 564 ;
+C 123 ; WX 274 ; N braceleft ; B 37 -92 399 750 ;
+C 124 ; WX 250 ; N bar ; B 22 -250 334 750 ;
+C 125 ; WX 274 ; N braceright ; B 14 -94 375 750 ;
+C 126 ; WX 500 ; N asciitilde ; B 74 153 536 359 ;
+C 161 ; WX 333 ; N exclamdown ; B 66 -170 355 579 ;
+C 162 ; WX 500 ; N cent ; B 103 -122 521 671 ;
+C 163 ; WX 500 ; N sterling ; B 52 -15 603 768 ;
+C 164 ; WX 167 ; N fraction ; B -169 0 488 738 ;
+C 165 ; WX 500 ; N yen ; B 89 0 677 750 ;
+C 166 ; WX 500 ; N florin ; B -28 -185 651 763 ;
+C 167 ; WX 500 ; N section ; B 48 -183 572 768 ;
+C 168 ; WX 500 ; N currency ; B 38 58 594 560 ;
+C 169 ; WX 250 ; N quotesingle ; B 165 468 342 739 ;
+C 170 ; WX 500 ; N quotedblleft ; B 192 495 568 766 ;
+C 171 ; WX 500 ; N guillemotleft ; B 117 62 514 447 ;
+C 172 ; WX 278 ; N guilsinglleft ; B 101 62 310 447 ;
+C 173 ; WX 278 ; N guilsinglright ; B 76 62 285 447 ;
+C 174 ; WX 500 ; N fi ; B 60 0 605 750 ;
+C 175 ; WX 500 ; N fl ; B 60 0 602 750 ;
+C 177 ; WX 500 ; N endash ; B 55 259 578 369 ;
+C 178 ; WX 500 ; N dagger ; B 127 -155 577 768 ;
+C 179 ; WX 500 ; N daggerdbl ; B 51 -161 579 768 ;
+C 180 ; WX 333 ; N periodcentered ; B 140 183 300 315 ;
+C 182 ; WX 550 ; N paragraph ; B 139 -116 685 750 ;
+C 183 ; WX 420 ; N bullet ; B 97 186 482 562 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 58 -138 235 132 ;
+C 185 ; WX 500 ; N quotedblbase ; B 67 -138 441 132 ;
+C 186 ; WX 500 ; N quotedblright ; B 197 479 572 750 ;
+C 187 ; WX 500 ; N guillemotright ; B 94 62 491 447 ;
+C 188 ; WX 1000 ; N ellipsis ; B 101 0 927 132 ;
+C 189 ; WX 1111 ; N perthousand ; B 128 -18 1141 748 ;
+C 191 ; WX 500 ; N questiondown ; B 54 -190 476 579 ;
+C 193 ; WX 333 ; N grave ; B 166 629 384 775 ;
+C 194 ; WX 333 ; N acute ; B 217 629 497 775 ;
+C 195 ; WX 333 ; N circumflex ; B 127 644 480 790 ;
+C 196 ; WX 333 ; N tilde ; B 119 636 512 764 ;
+C 197 ; WX 333 ; N macron ; B 136 666 497 740 ;
+C 198 ; WX 333 ; N breve ; B 161 635 501 780 ;
+C 199 ; WX 333 ; N dotaccent ; B 240 644 391 759 ;
+C 200 ; WX 333 ; N dieresis ; B 142 644 489 759 ;
+C 202 ; WX 333 ; N ring ; B 215 632 432 845 ;
+C 203 ; WX 333 ; N cedilla ; B -4 -228 248 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 118 634 613 780 ;
+C 206 ; WX 333 ; N ogonek ; B 63 -205 256 0 ;
+C 207 ; WX 333 ; N caron ; B 156 634 509 780 ;
+C 208 ; WX 1000 ; N emdash ; B 55 259 1078 369 ;
+C 225 ; WX 778 ; N AE ; B -22 0 909 750 ;
+C 227 ; WX 300 ; N ordfeminine ; B 127 412 421 768 ;
+C 232 ; WX 500 ; N Lslash ; B 49 0 497 750 ;
+C 233 ; WX 611 ; N Oslash ; B 34 -38 736 779 ;
+C 234 ; WX 833 ; N OE ; B 111 -18 951 768 ;
+C 235 ; WX 300 ; N ordmasculine ; B 133 412 417 768 ;
+C 241 ; WX 722 ; N ae ; B 69 -15 762 579 ;
+C 245 ; WX 278 ; N dotlessi ; B 74 0 324 564 ;
+C 248 ; WX 278 ; N lslash ; B 68 0 391 750 ;
+C 249 ; WX 500 ; N oslash ; B 2 -58 616 617 ;
+C 250 ; WX 722 ; N oe ; B 81 -15 763 579 ;
+C 251 ; WX 500 ; N germandbls ; B 60 -15 561 768 ;
+C -1 ; WX 500 ; N ecircumflex ; B 88 -15 560 770 ;
+C -1 ; WX 500 ; N edieresis ; B 88 -15 573 759 ;
+C -1 ; WX 500 ; N aacute ; B 68 -15 581 775 ;
+C -1 ; WX 830 ; N registered ; B 93 -18 897 768 ;
+C -1 ; WX 278 ; N icircumflex ; B 74 0 439 770 ;
+C -1 ; WX 500 ; N udieresis ; B 78 -15 573 759 ;
+C -1 ; WX 500 ; N ograve ; B 88 -15 531 775 ;
+C -1 ; WX 500 ; N uacute ; B 78 -15 581 775 ;
+C -1 ; WX 500 ; N ucircumflex ; B 78 -15 562 780 ;
+C -1 ; WX 556 ; N Aacute ; B 9 0 648 961 ;
+C -1 ; WX 278 ; N igrave ; B 74 0 357 775 ;
+C -1 ; WX 278 ; N Icircumflex ; B 69 0 488 956 ;
+C -1 ; WX 444 ; N ccedilla ; B 66 -228 496 579 ;
+C -1 ; WX 500 ; N adieresis ; B 68 -15 573 759 ;
+C -1 ; WX 500 ; N Ecircumflex ; B 64 0 617 956 ;
+C -1 ; WX 444 ; N scaron ; B 56 -15 551 760 ;
+C -1 ; WX 500 ; N thorn ; B 18 -189 529 750 ;
+C -1 ; WX 860 ; N trademark ; B 144 346 933 750 ;
+C -1 ; WX 500 ; N egrave ; B 88 -15 530 775 ;
+C -1 ; WX 300 ; N threesuperior ; B 96 290 416 751 ;
+C -1 ; WX 389 ; N zcaron ; B 23 0 533 760 ;
+C -1 ; WX 500 ; N atilde ; B 68 -15 592 744 ;
+C -1 ; WX 500 ; N aring ; B 68 -15 525 835 ;
+C -1 ; WX 500 ; N ocircumflex ; B 88 -15 560 770 ;
+C -1 ; WX 500 ; N Edieresis ; B 64 0 617 945 ;
+C -1 ; WX 750 ; N threequarters ; B 96 0 816 751 ;
+C -1 ; WX 444 ; N ydieresis ; B 36 -195 549 759 ;
+C -1 ; WX 444 ; N yacute ; B 36 -195 553 775 ;
+C -1 ; WX 278 ; N iacute ; B 74 0 470 775 ;
+C -1 ; WX 556 ; N Acircumflex ; B 9 0 617 956 ;
+C -1 ; WX 611 ; N Uacute ; B 105 -18 703 961 ;
+C -1 ; WX 500 ; N eacute ; B 88 -15 581 775 ;
+C -1 ; WX 611 ; N Ograve ; B 105 -18 664 961 ;
+C -1 ; WX 500 ; N agrave ; B 68 -15 525 775 ;
+C -1 ; WX 611 ; N Udieresis ; B 105 -18 703 945 ;
+C -1 ; WX 500 ; N acircumflex ; B 68 -15 560 770 ;
+C -1 ; WX 278 ; N Igrave ; B 69 0 396 961 ;
+C -1 ; WX 300 ; N twosuperior ; B 77 300 425 752 ;
+C -1 ; WX 611 ; N Ugrave ; B 105 -18 703 961 ;
+C -1 ; WX 750 ; N onequarter ; B 131 0 788 750 ;
+C -1 ; WX 611 ; N Ucircumflex ; B 105 -18 703 956 ;
+C -1 ; WX 556 ; N Scaron ; B 85 -18 656 946 ;
+C -1 ; WX 278 ; N Idieresis ; B 69 0 502 945 ;
+C -1 ; WX 278 ; N idieresis ; B 74 0 462 759 ;
+C -1 ; WX 500 ; N Egrave ; B 64 0 617 961 ;
+C -1 ; WX 611 ; N Oacute ; B 105 -18 675 961 ;
+C -1 ; WX 500 ; N divide ; B 67 6 540 492 ;
+C -1 ; WX 556 ; N Atilde ; B 9 0 660 930 ;
+C -1 ; WX 556 ; N Aring ; B 9 0 575 991 ;
+C -1 ; WX 611 ; N Odieresis ; B 105 -18 668 945 ;
+C -1 ; WX 556 ; N Adieresis ; B 9 0 641 945 ;
+C -1 ; WX 611 ; N Ntilde ; B 68 0 702 930 ;
+C -1 ; WX 500 ; N Zcaron ; B 33 0 628 946 ;
+C -1 ; WX 556 ; N Thorn ; B 68 0 625 750 ;
+C -1 ; WX 278 ; N Iacute ; B 69 0 509 961 ;
+C -1 ; WX 500 ; N plusminus ; B 23 -15 556 513 ;
+C -1 ; WX 500 ; N multiply ; B 48 22 560 476 ;
+C -1 ; WX 500 ; N Eacute ; B 64 0 620 961 ;
+C -1 ; WX 556 ; N Ydieresis ; B 171 0 704 945 ;
+C -1 ; WX 300 ; N onesuperior ; B 180 300 410 750 ;
+C -1 ; WX 500 ; N ugrave ; B 78 -15 551 775 ;
+C -1 ; WX 500 ; N logicalnot ; B 88 105 560 401 ;
+C -1 ; WX 500 ; N ntilde ; B 61 0 592 744 ;
+C -1 ; WX 611 ; N Otilde ; B 105 -18 687 930 ;
+C -1 ; WX 500 ; N otilde ; B 88 -15 592 744 ;
+C -1 ; WX 556 ; N Ccedilla ; B 99 -228 630 768 ;
+C -1 ; WX 556 ; N Agrave ; B 9 0 547 961 ;
+C -1 ; WX 750 ; N onehalf ; B 108 0 813 750 ;
+C -1 ; WX 611 ; N Eth ; B 72 0 662 750 ;
+C -1 ; WX 400 ; N degree ; B 174 450 481 750 ;
+C -1 ; WX 556 ; N Yacute ; B 171 0 704 961 ;
+C -1 ; WX 611 ; N Ocircumflex ; B 105 -18 664 956 ;
+C -1 ; WX 500 ; N oacute ; B 88 -15 581 775 ;
+C -1 ; WX 500 ; N mu ; B 18 -189 551 564 ;
+C -1 ; WX 500 ; N minus ; B 67 194 540 304 ;
+C -1 ; WX 500 ; N eth ; B 88 -15 540 779 ;
+C -1 ; WX 500 ; N odieresis ; B 88 -15 573 759 ;
+C -1 ; WX 830 ; N copyright ; B 93 -18 897 768 ;
+C -1 ; WX 250 ; N brokenbar ; B 38 -175 318 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 88
+
+KPX A y -18
+KPX A w -18
+KPX A v -18
+KPX A quoteright -55
+KPX A Y -55
+KPX A W -37
+KPX A V -37
+KPX A T -55
+
+KPX F period -111
+KPX F comma -111
+KPX F A -37
+
+KPX L y -37
+KPX L quoteright -92
+KPX L Y -92
+KPX L W -74
+KPX L V -74
+KPX L T -74
+
+KPX P period -129
+KPX P comma -129
+KPX P A -37
+
+KPX R Y -18
+KPX R T -18
+
+KPX T y -55
+KPX T w -74
+KPX T u -74
+KPX T semicolon -74
+KPX T s -74
+KPX T r -74
+KPX T period -92
+KPX T o -74
+KPX T i -18
+KPX T hyphen -55
+KPX T e -74
+KPX T comma -92
+KPX T colon -74
+KPX T c -74
+KPX T a -74
+KPX T A -55
+
+KPX V u -18
+KPX V semicolon -18
+KPX V r -18
+KPX V period -92
+KPX V o -18
+KPX V hyphen -18
+KPX V e -18
+KPX V comma -92
+KPX V colon -18
+KPX V a -18
+KPX V A -37
+
+KPX W period -74
+KPX W o -18
+KPX W hyphen -18
+KPX W e -18
+KPX W comma -74
+KPX W a -18
+KPX W A -18
+
+KPX Y v -18
+KPX Y u -37
+KPX Y semicolon -37
+KPX Y q -55
+KPX Y period -111
+KPX Y p -37
+KPX Y o -55
+KPX Y i -18
+KPX Y hyphen -74
+KPX Y e -55
+KPX Y comma -111
+KPX Y colon -37
+KPX Y a -55
+KPX Y A -55
+
+KPX f quoteright 18
+
+KPX quoteleft quoteleft -18
+
+KPX quoteright s -55
+KPX quoteright quoteright -18
+
+KPX r z 20
+KPX r y 18
+KPX r x 20
+KPX r w 18
+KPX r v 18
+KPX r period -74
+KPX r hyphen -37
+KPX r comma -74
+
+KPX v period -55
+KPX v comma -55
+
+KPX w period -37
+KPX w comma -37
+
+KPX y period -55
+KPX y comma -55
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 152 186 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 137 166 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 152 186 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 152 186 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 143 146 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 147 166 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 124 186 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 119 166 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 124 186 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 124 186 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 13 186 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 8 166 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 13 186 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 13 186 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 174 166 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 179 186 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 174 166 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 179 186 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 179 186 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 174 166 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 147 166 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 179 186 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 174 166 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 179 186 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 179 186 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 152 186 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 152 186 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 119 166 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 80 -20 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 84 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 67 -10 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 80 -20 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 84 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 80 -20 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 84 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 84 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -41 -20 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 80 -20 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 80 -20 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 80 -20 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 42 -20 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 82 -10 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 56 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 24 -20 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-Condensed-Oblique.afm b/tlt3.0/library/afm/Helvetica-Condensed-Oblique.afm
new file mode 100644
index 0000000..44da649
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-Condensed-Oblique.afm
@@ -0,0 +1,421 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Wed Sep  4 17:59:46 1991
+Comment UniqueID 36200
+Comment VMusage 7672 41967
+FontName Helvetica-Condensed-Oblique
+FullName Helvetica Condensed Oblique
+FamilyName Helvetica
+Weight Medium
+ItalicAngle -12
+IsFixedPitch false
+FontBBox -174 -250 1118 990
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.003
+Notice Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 750
+XHeight 556
+Ascender 750
+Descender -188
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 121 0 371 750 ;
+C 34 ; WX 250 ; N quotedbl ; B 153 513 364 739 ;
+C 35 ; WX 500 ; N numbersign ; B 33 0 621 750 ;
+C 36 ; WX 500 ; N dollar ; B 69 -116 569 815 ;
+C 37 ; WX 833 ; N percent ; B 164 -15 803 750 ;
+C 38 ; WX 667 ; N ampersand ; B 111 -18 648 750 ;
+C 39 ; WX 222 ; N quoteright ; B 171 504 317 750 ;
+C 40 ; WX 333 ; N parenleft ; B 115 -215 443 750 ;
+C 41 ; WX 333 ; N parenright ; B 3 -215 331 750 ;
+C 42 ; WX 500 ; N asterisk ; B 229 455 537 750 ;
+C 43 ; WX 500 ; N plus ; B 91 0 518 505 ;
+C 44 ; WX 250 ; N comma ; B 49 -146 192 100 ;
+C 45 ; WX 333 ; N hyphen ; B 103 275 364 358 ;
+C 46 ; WX 250 ; N period ; B 80 0 192 100 ;
+C 47 ; WX 278 ; N slash ; B -19 -27 450 750 ;
+C 48 ; WX 500 ; N zero ; B 98 -15 563 750 ;
+C 49 ; WX 500 ; N one ; B 190 0 476 750 ;
+C 50 ; WX 500 ; N two ; B 44 0 562 750 ;
+C 51 ; WX 500 ; N three ; B 73 -15 552 750 ;
+C 52 ; WX 500 ; N four ; B 68 0 543 750 ;
+C 53 ; WX 500 ; N five ; B 75 -15 575 735 ;
+C 54 ; WX 500 ; N six ; B 91 -15 566 750 ;
+C 55 ; WX 500 ; N seven ; B 116 0 612 735 ;
+C 56 ; WX 500 ; N eight ; B 83 -15 559 750 ;
+C 57 ; WX 500 ; N nine ; B 91 -15 566 750 ;
+C 58 ; WX 250 ; N colon ; B 80 0 287 547 ;
+C 59 ; WX 250 ; N semicolon ; B 49 -146 287 547 ;
+C 60 ; WX 500 ; N less ; B 89 -10 569 518 ;
+C 61 ; WX 500 ; N equal ; B 70 124 539 384 ;
+C 62 ; WX 500 ; N greater ; B 40 -10 520 518 ;
+C 63 ; WX 500 ; N question ; B 169 0 586 750 ;
+C 64 ; WX 800 ; N at ; B 106 -15 863 750 ;
+C 65 ; WX 556 ; N A ; B 11 0 546 750 ;
+C 66 ; WX 556 ; N B ; B 80 0 610 750 ;
+C 67 ; WX 556 ; N C ; B 106 -18 624 765 ;
+C 68 ; WX 611 ; N D ; B 82 0 653 750 ;
+C 69 ; WX 500 ; N E ; B 74 0 608 750 ;
+C 70 ; WX 444 ; N F ; B 74 0 585 750 ;
+C 71 ; WX 611 ; N G ; B 109 -18 646 765 ;
+C 72 ; WX 611 ; N H ; B 79 0 691 750 ;
+C 73 ; WX 278 ; N I ; B 98 0 340 750 ;
+C 74 ; WX 444 ; N J ; B 52 -15 527 750 ;
+C 75 ; WX 556 ; N K ; B 79 0 698 750 ;
+C 76 ; WX 500 ; N L ; B 83 0 488 750 ;
+C 77 ; WX 778 ; N M ; B 76 0 861 750 ;
+C 78 ; WX 611 ; N N ; B 77 0 693 750 ;
+C 79 ; WX 611 ; N O ; B 116 -18 658 765 ;
+C 80 ; WX 556 ; N P ; B 86 0 641 750 ;
+C 81 ; WX 611 ; N Q ; B 116 -34 659 765 ;
+C 82 ; WX 611 ; N R ; B 86 0 655 750 ;
+C 83 ; WX 556 ; N S ; B 86 -18 611 765 ;
+C 84 ; WX 500 ; N T ; B 158 0 645 750 ;
+C 85 ; WX 611 ; N U ; B 114 -18 690 750 ;
+C 86 ; WX 556 ; N V ; B 170 0 704 750 ;
+C 87 ; WX 833 ; N W ; B 176 0 975 750 ;
+C 88 ; WX 556 ; N X ; B 17 0 692 750 ;
+C 89 ; WX 556 ; N Y ; B 170 0 705 750 ;
+C 90 ; WX 500 ; N Z ; B 28 0 627 750 ;
+C 91 ; WX 333 ; N bracketleft ; B 56 -209 434 750 ;
+C 92 ; WX 250 ; N backslash ; B 128 0 281 750 ;
+C 93 ; WX 333 ; N bracketright ; B 14 -209 392 750 ;
+C 94 ; WX 500 ; N asciicircum ; B 141 333 502 750 ;
+C 95 ; WX 500 ; N underscore ; B -27 -125 484 -75 ;
+C 96 ; WX 222 ; N quoteleft ; B 175 521 321 767 ;
+C 97 ; WX 444 ; N a ; B 55 -15 465 571 ;
+C 98 ; WX 500 ; N b ; B 75 -15 525 750 ;
+C 99 ; WX 444 ; N c ; B 85 -15 488 571 ;
+C 100 ; WX 500 ; N d ; B 88 -15 583 750 ;
+C 101 ; WX 444 ; N e ; B 86 -15 476 571 ;
+C 102 ; WX 278 ; N f ; B 93 0 418 752 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 53 -189 544 571 ;
+C 104 ; WX 500 ; N h ; B 73 0 524 750 ;
+C 105 ; WX 222 ; N i ; B 72 0 310 750 ;
+C 106 ; WX 222 ; N j ; B -27 -190 313 750 ;
+C 107 ; WX 444 ; N k ; B 69 0 552 750 ;
+C 108 ; WX 222 ; N l ; B 72 0 310 750 ;
+C 109 ; WX 778 ; N m ; B 76 0 799 571 ;
+C 110 ; WX 500 ; N n ; B 73 0 524 571 ;
+C 111 ; WX 500 ; N o ; B 96 -15 524 571 ;
+C 112 ; WX 500 ; N p ; B 32 -188 524 571 ;
+C 113 ; WX 500 ; N q ; B 100 -184 544 571 ;
+C 114 ; WX 333 ; N r ; B 81 0 441 563 ;
+C 115 ; WX 444 ; N s ; B 68 -15 473 571 ;
+C 116 ; WX 278 ; N t ; B 101 0 375 707 ;
+C 117 ; WX 500 ; N u ; B 99 -15 542 556 ;
+C 118 ; WX 444 ; N v ; B 131 0 549 556 ;
+C 119 ; WX 667 ; N w ; B 137 0 767 556 ;
+C 120 ; WX 444 ; N x ; B 9 0 548 556 ;
+C 121 ; WX 444 ; N y ; B -13 -190 543 556 ;
+C 122 ; WX 389 ; N z ; B 24 0 482 556 ;
+C 123 ; WX 274 ; N braceleft ; B 77 -95 425 750 ;
+C 124 ; WX 250 ; N bar ; B 40 -250 316 750 ;
+C 125 ; WX 274 ; N braceright ; B -12 -95 337 750 ;
+C 126 ; WX 500 ; N asciitilde ; B 89 166 520 345 ;
+C 161 ; WX 333 ; N exclamdown ; B 83 -179 333 571 ;
+C 162 ; WX 500 ; N cent ; B 94 -137 499 667 ;
+C 163 ; WX 500 ; N sterling ; B 40 -15 589 750 ;
+C 164 ; WX 167 ; N fraction ; B -174 0 500 750 ;
+C 165 ; WX 500 ; N yen ; B 88 0 677 750 ;
+C 166 ; WX 500 ; N florin ; B -28 -192 645 750 ;
+C 167 ; WX 500 ; N section ; B 51 -208 552 750 ;
+C 168 ; WX 500 ; N currency ; B 51 50 576 553 ;
+C 169 ; WX 250 ; N quotesingle ; B 208 513 308 739 ;
+C 170 ; WX 389 ; N quotedblleft ; B 173 521 490 767 ;
+C 171 ; WX 500 ; N guillemotleft ; B 145 125 520 495 ;
+C 172 ; WX 278 ; N guilsinglleft ; B 124 125 320 495 ;
+C 173 ; WX 278 ; N guilsinglright ; B 90 125 286 495 ;
+C 174 ; WX 500 ; N fi ; B 93 0 584 752 ;
+C 175 ; WX 500 ; N fl ; B 93 0 584 752 ;
+C 177 ; WX 500 ; N endash ; B 58 275 573 345 ;
+C 178 ; WX 500 ; N dagger ; B 137 -176 573 750 ;
+C 179 ; WX 500 ; N daggerdbl ; B 50 -176 572 750 ;
+C 180 ; WX 250 ; N periodcentered ; B 123 204 236 304 ;
+C 182 ; WX 440 ; N paragraph ; B 113 -116 550 750 ;
+C 183 ; WX 333 ; N bullet ; B 91 222 401 529 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 33 -146 179 100 ;
+C 185 ; WX 389 ; N quotedblbase ; B 31 -146 348 100 ;
+C 186 ; WX 389 ; N quotedblright ; B 169 504 486 750 ;
+C 187 ; WX 500 ; N guillemotright ; B 112 125 487 495 ;
+C 188 ; WX 1000 ; N ellipsis ; B 121 0 899 100 ;
+C 189 ; WX 1111 ; N perthousand ; B 157 -16 1118 750 ;
+C 191 ; WX 500 ; N questiondown ; B 33 -190 450 559 ;
+C 193 ; WX 333 ; N grave ; B 198 624 366 765 ;
+C 194 ; WX 333 ; N acute ; B 233 624 461 765 ;
+C 195 ; WX 333 ; N circumflex ; B 154 624 446 765 ;
+C 196 ; WX 333 ; N tilde ; B 132 633 496 749 ;
+C 197 ; WX 333 ; N macron ; B 150 657 475 715 ;
+C 198 ; WX 333 ; N breve ; B 172 629 484 765 ;
+C 199 ; WX 250 ; N dotaccent ; B 224 650 324 750 ;
+C 200 ; WX 333 ; N dieresis ; B 190 650 440 750 ;
+C 202 ; WX 250 ; N ring ; B 169 593 377 796 ;
+C 203 ; WX 333 ; N cedilla ; B 23 -224 255 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 194 624 603 765 ;
+C 206 ; WX 333 ; N ogonek ; B -23 -191 188 13 ;
+C 207 ; WX 333 ; N caron ; B 184 624 476 765 ;
+C 208 ; WX 1000 ; N emdash ; B 58 275 1073 345 ;
+C 225 ; WX 833 ; N AE ; B 0 0 944 750 ;
+C 227 ; WX 300 ; N ordfeminine ; B 129 413 392 765 ;
+C 232 ; WX 500 ; N Lslash ; B 39 0 488 750 ;
+C 233 ; WX 611 ; N Oslash ; B 25 -43 738 796 ;
+C 234 ; WX 833 ; N OE ; B 113 -18 946 765 ;
+C 235 ; WX 300 ; N ordmasculine ; B 138 413 413 765 ;
+C 241 ; WX 667 ; N ae ; B 50 -15 711 571 ;
+C 245 ; WX 222 ; N dotlessi ; B 72 0 269 556 ;
+C 248 ; WX 222 ; N lslash ; B 59 0 347 750 ;
+C 249 ; WX 500 ; N oslash ; B 19 -46 591 582 ;
+C 250 ; WX 722 ; N oe ; B 81 -15 758 571 ;
+C 251 ; WX 500 ; N germandbls ; B 71 -5 548 765 ;
+C -1 ; WX 444 ; N ecircumflex ; B 86 -15 502 765 ;
+C -1 ; WX 444 ; N edieresis ; B 86 -15 496 750 ;
+C -1 ; WX 444 ; N aacute ; B 55 -15 517 765 ;
+C -1 ; WX 800 ; N registered ; B 79 -18 881 765 ;
+C -1 ; WX 222 ; N icircumflex ; B 72 0 391 765 ;
+C -1 ; WX 500 ; N udieresis ; B 99 -15 542 750 ;
+C -1 ; WX 500 ; N ograve ; B 96 -15 524 765 ;
+C -1 ; WX 500 ; N uacute ; B 99 -15 545 765 ;
+C -1 ; WX 500 ; N ucircumflex ; B 99 -15 542 765 ;
+C -1 ; WX 556 ; N Aacute ; B 11 0 614 959 ;
+C -1 ; WX 222 ; N igrave ; B 72 0 311 765 ;
+C -1 ; WX 278 ; N Icircumflex ; B 98 0 460 959 ;
+C -1 ; WX 444 ; N ccedilla ; B 79 -224 488 571 ;
+C -1 ; WX 444 ; N adieresis ; B 55 -15 496 750 ;
+C -1 ; WX 500 ; N Ecircumflex ; B 74 0 608 959 ;
+C -1 ; WX 444 ; N scaron ; B 68 -15 532 765 ;
+C -1 ; WX 500 ; N thorn ; B 32 -188 523 750 ;
+C -1 ; WX 750 ; N trademark ; B 147 329 878 750 ;
+C -1 ; WX 444 ; N egrave ; B 86 -15 476 765 ;
+C -1 ; WX 300 ; N threesuperior ; B 102 291 409 750 ;
+C -1 ; WX 389 ; N zcaron ; B 24 0 504 765 ;
+C -1 ; WX 444 ; N atilde ; B 55 -15 552 749 ;
+C -1 ; WX 444 ; N aring ; B 55 -15 465 826 ;
+C -1 ; WX 500 ; N ocircumflex ; B 96 -15 530 765 ;
+C -1 ; WX 500 ; N Edieresis ; B 74 0 608 944 ;
+C -1 ; WX 750 ; N threequarters ; B 106 0 831 750 ;
+C -1 ; WX 444 ; N ydieresis ; B -13 -190 543 750 ;
+C -1 ; WX 444 ; N yacute ; B -13 -190 543 765 ;
+C -1 ; WX 222 ; N iacute ; B 72 0 406 765 ;
+C -1 ; WX 556 ; N Acircumflex ; B 11 0 599 959 ;
+C -1 ; WX 611 ; N Uacute ; B 114 -18 690 959 ;
+C -1 ; WX 444 ; N eacute ; B 86 -15 517 765 ;
+C -1 ; WX 611 ; N Ograve ; B 116 -18 658 959 ;
+C -1 ; WX 444 ; N agrave ; B 55 -15 465 765 ;
+C -1 ; WX 611 ; N Udieresis ; B 114 -18 690 944 ;
+C -1 ; WX 444 ; N acircumflex ; B 55 -15 502 765 ;
+C -1 ; WX 278 ; N Igrave ; B 98 0 380 959 ;
+C -1 ; WX 300 ; N twosuperior ; B 83 300 413 750 ;
+C -1 ; WX 611 ; N Ugrave ; B 114 -18 690 959 ;
+C -1 ; WX 750 ; N onequarter ; B 143 0 817 750 ;
+C -1 ; WX 611 ; N Ucircumflex ; B 114 -18 690 959 ;
+C -1 ; WX 556 ; N Scaron ; B 86 -18 629 959 ;
+C -1 ; WX 278 ; N Idieresis ; B 98 0 455 944 ;
+C -1 ; WX 222 ; N idieresis ; B 72 0 385 750 ;
+C -1 ; WX 500 ; N Egrave ; B 74 0 608 959 ;
+C -1 ; WX 611 ; N Oacute ; B 116 -18 658 959 ;
+C -1 ; WX 500 ; N divide ; B 91 3 518 505 ;
+C -1 ; WX 556 ; N Atilde ; B 11 0 649 943 ;
+C -1 ; WX 556 ; N Aring ; B 11 0 571 990 ;
+C -1 ; WX 611 ; N Odieresis ; B 116 -18 658 944 ;
+C -1 ; WX 556 ; N Adieresis ; B 11 0 594 944 ;
+C -1 ; WX 611 ; N Ntilde ; B 77 0 693 943 ;
+C -1 ; WX 500 ; N Zcaron ; B 28 0 627 959 ;
+C -1 ; WX 556 ; N Thorn ; B 86 0 618 750 ;
+C -1 ; WX 278 ; N Iacute ; B 98 0 475 959 ;
+C -1 ; WX 500 ; N plusminus ; B 44 0 531 505 ;
+C -1 ; WX 500 ; N multiply ; B 65 48 544 461 ;
+C -1 ; WX 500 ; N Eacute ; B 74 0 608 959 ;
+C -1 ; WX 556 ; N Ydieresis ; B 170 0 705 944 ;
+C -1 ; WX 300 ; N onesuperior ; B 200 300 392 750 ;
+C -1 ; WX 500 ; N ugrave ; B 99 -15 542 765 ;
+C -1 ; WX 500 ; N logicalnot ; B 111 117 539 384 ;
+C -1 ; WX 500 ; N ntilde ; B 73 0 580 749 ;
+C -1 ; WX 611 ; N Otilde ; B 116 -18 676 943 ;
+C -1 ; WX 500 ; N otilde ; B 96 -15 580 749 ;
+C -1 ; WX 556 ; N Ccedilla ; B 106 -224 624 765 ;
+C -1 ; WX 556 ; N Agrave ; B 11 0 546 959 ;
+C -1 ; WX 750 ; N onehalf ; B 91 0 777 750 ;
+C -1 ; WX 611 ; N Eth ; B 82 0 650 750 ;
+C -1 ; WX 400 ; N degree ; B 174 450 481 750 ;
+C -1 ; WX 556 ; N Yacute ; B 170 0 705 959 ;
+C -1 ; WX 611 ; N Ocircumflex ; B 116 -18 658 959 ;
+C -1 ; WX 500 ; N oacute ; B 96 -15 545 765 ;
+C -1 ; WX 500 ; N mu ; B 35 -189 540 556 ;
+C -1 ; WX 500 ; N minus ; B 91 219 518 289 ;
+C -1 ; WX 500 ; N eth ; B 96 -15 525 831 ;
+C -1 ; WX 500 ; N odieresis ; B 96 -15 524 750 ;
+C -1 ; WX 800 ; N copyright ; B 79 -18 880 765 ;
+C -1 ; WX 250 ; N brokenbar ; B 56 -175 300 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 90
+
+KPX A y -18
+KPX A w -18
+KPX A v -18
+KPX A quoteright -55
+KPX A Y -55
+KPX A W -37
+KPX A V -37
+KPX A T -55
+
+KPX F period -111
+KPX F comma -111
+KPX F A -37
+
+KPX L y -37
+KPX L quoteright -92
+KPX L Y -92
+KPX L W -74
+KPX L V -74
+KPX L T -74
+
+KPX P period -129
+KPX P comma -129
+KPX P A -37
+
+KPX R Y -18
+KPX R T -18
+
+KPX T y -55
+KPX T w -74
+KPX T u -74
+KPX T semicolon -74
+KPX T s -74
+KPX T r -74
+KPX T period -92
+KPX T o -74
+KPX T i -18
+KPX T hyphen -55
+KPX T e -74
+KPX T comma -92
+KPX T colon -74
+KPX T c -74
+KPX T a -74
+KPX T A -55
+
+KPX V u -18
+KPX V semicolon -18
+KPX V r -18
+KPX V period -92
+KPX V o -18
+KPX V hyphen -18
+KPX V e -18
+KPX V comma -92
+KPX V colon -18
+KPX V a -18
+KPX V A -37
+
+KPX W period -74
+KPX W o -18
+KPX W hyphen -18
+KPX W e -18
+KPX W comma -74
+KPX W a -18
+KPX W A -18
+
+KPX Y v -18
+KPX Y u -37
+KPX Y semicolon -37
+KPX Y q -55
+KPX Y period -111
+KPX Y p -37
+KPX Y o -55
+KPX Y i -18
+KPX Y hyphen -74
+KPX Y e -55
+KPX Y comma -111
+KPX Y colon -37
+KPX Y a -55
+KPX Y A -55
+
+KPX f quoteright 18
+
+KPX quoteleft quoteleft -18
+
+KPX quoteright s -55
+KPX quoteright quoteright -18
+
+KPX r z 20
+KPX r y 18
+KPX r x 20
+KPX r w 18
+KPX r v 18
+KPX r period -74
+KPX r hyphen -37
+KPX r f 20
+KPX r comma -74
+KPX r c -20
+
+KPX v period -55
+KPX v comma -55
+
+KPX w period -37
+KPX w comma -37
+
+KPX y period -55
+KPX y comma -55
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 153 194 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 153 194 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 153 194 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 153 194 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 194 194 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 153 194 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 125 194 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 125 194 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 125 194 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 125 194 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 14 194 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 14 194 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 14 194 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 14 194 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 180 194 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 180 194 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 180 194 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 180 194 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 180 194 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 180 194 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 153 194 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 180 194 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 180 194 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 180 194 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 180 194 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 153 194 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 153 194 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 125 194 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 56 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 56 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 88 30 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -55 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -55 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -55 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -55 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 56 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 56 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 28 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-Condensed.afm b/tlt3.0/library/afm/Helvetica-Condensed.afm
new file mode 100644
index 0000000..f22040c
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-Condensed.afm
@@ -0,0 +1,421 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Wed Sep  4 17:26:31 1991
+Comment UniqueID 36179
+Comment VMusage 26415 33307
+FontName Helvetica-Condensed
+FullName Helvetica Condensed Medium
+FamilyName Helvetica
+Weight Medium
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -174 -250 1071 990
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.003
+Notice Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 750
+XHeight 556
+Ascender 750
+Descender -188
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 121 0 212 750 ;
+C 34 ; WX 250 ; N quotedbl ; B 44 513 207 739 ;
+C 35 ; WX 500 ; N numbersign ; B 5 0 495 750 ;
+C 36 ; WX 500 ; N dollar ; B 35 -116 465 815 ;
+C 37 ; WX 833 ; N percent ; B 55 -15 756 750 ;
+C 38 ; WX 667 ; N ampersand ; B 75 -18 620 750 ;
+C 39 ; WX 222 ; N quoteright ; B 64 504 158 750 ;
+C 40 ; WX 333 ; N parenleft ; B 76 -215 289 750 ;
+C 41 ; WX 333 ; N parenright ; B 44 -215 257 750 ;
+C 42 ; WX 500 ; N asterisk ; B 96 455 405 750 ;
+C 43 ; WX 500 ; N plus ; B 44 0 457 505 ;
+C 44 ; WX 250 ; N comma ; B 80 -146 171 100 ;
+C 45 ; WX 333 ; N hyphen ; B 45 275 288 358 ;
+C 46 ; WX 250 ; N period ; B 80 0 171 100 ;
+C 47 ; WX 278 ; N slash ; B -13 -27 291 750 ;
+C 48 ; WX 500 ; N zero ; B 46 -15 455 750 ;
+C 49 ; WX 500 ; N one ; B 74 0 317 750 ;
+C 50 ; WX 500 ; N two ; B 44 0 447 750 ;
+C 51 ; WX 500 ; N three ; B 38 -15 447 750 ;
+C 52 ; WX 500 ; N four ; B 28 0 451 750 ;
+C 53 ; WX 500 ; N five ; B 43 -15 446 735 ;
+C 54 ; WX 500 ; N six ; B 43 -15 458 750 ;
+C 55 ; WX 500 ; N seven ; B 44 0 456 735 ;
+C 56 ; WX 500 ; N eight ; B 46 -15 454 750 ;
+C 57 ; WX 500 ; N nine ; B 43 -15 458 750 ;
+C 58 ; WX 250 ; N colon ; B 80 0 171 547 ;
+C 59 ; WX 250 ; N semicolon ; B 80 -146 171 547 ;
+C 60 ; WX 500 ; N less ; B 42 -10 459 518 ;
+C 61 ; WX 500 ; N equal ; B 44 124 457 384 ;
+C 62 ; WX 500 ; N greater ; B 42 -10 459 518 ;
+C 63 ; WX 500 ; N question ; B 60 0 462 750 ;
+C 64 ; WX 800 ; N at ; B 36 -15 764 750 ;
+C 65 ; WX 556 ; N A ; B 11 0 546 750 ;
+C 66 ; WX 556 ; N B ; B 80 0 503 750 ;
+C 67 ; WX 556 ; N C ; B 53 -18 503 765 ;
+C 68 ; WX 611 ; N D ; B 82 0 548 750 ;
+C 69 ; WX 500 ; N E ; B 74 0 451 750 ;
+C 70 ; WX 444 ; N F ; B 74 0 426 750 ;
+C 71 ; WX 611 ; N G ; B 54 -18 532 765 ;
+C 72 ; WX 611 ; N H ; B 79 0 532 750 ;
+C 73 ; WX 278 ; N I ; B 98 0 181 750 ;
+C 74 ; WX 444 ; N J ; B 21 -15 368 750 ;
+C 75 ; WX 556 ; N K ; B 79 0 546 750 ;
+C 76 ; WX 500 ; N L ; B 83 0 472 750 ;
+C 77 ; WX 778 ; N M ; B 76 0 702 750 ;
+C 78 ; WX 611 ; N N ; B 77 0 534 750 ;
+C 79 ; WX 611 ; N O ; B 59 -18 553 765 ;
+C 80 ; WX 556 ; N P ; B 86 0 519 750 ;
+C 81 ; WX 611 ; N Q ; B 59 -34 582 765 ;
+C 82 ; WX 611 ; N R ; B 86 0 565 750 ;
+C 83 ; WX 556 ; N S ; B 51 -18 505 765 ;
+C 84 ; WX 500 ; N T ; B 15 0 486 750 ;
+C 85 ; WX 611 ; N U ; B 81 -18 531 750 ;
+C 86 ; WX 556 ; N V ; B 11 0 545 750 ;
+C 87 ; WX 833 ; N W ; B 17 0 816 750 ;
+C 88 ; WX 556 ; N X ; B 17 0 539 750 ;
+C 89 ; WX 556 ; N Y ; B 11 0 546 750 ;
+C 90 ; WX 500 ; N Z ; B 28 0 473 750 ;
+C 91 ; WX 333 ; N bracketleft ; B 100 -209 275 750 ;
+C 92 ; WX 250 ; N backslash ; B -31 0 281 750 ;
+C 93 ; WX 333 ; N bracketright ; B 58 -209 233 750 ;
+C 94 ; WX 500 ; N asciicircum ; B 70 333 431 750 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 222 ; N quoteleft ; B 64 521 158 767 ;
+C 97 ; WX 444 ; N a ; B 31 -15 417 571 ;
+C 98 ; WX 500 ; N b ; B 75 -15 447 750 ;
+C 99 ; WX 444 ; N c ; B 44 -15 405 571 ;
+C 100 ; WX 500 ; N d ; B 48 -15 424 750 ;
+C 101 ; WX 444 ; N e ; B 43 -15 395 571 ;
+C 102 ; WX 278 ; N f ; B 12 0 259 752 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 45 -189 426 571 ;
+C 104 ; WX 500 ; N h ; B 73 0 428 750 ;
+C 105 ; WX 222 ; N i ; B 72 0 151 750 ;
+C 106 ; WX 222 ; N j ; B 13 -190 154 750 ;
+C 107 ; WX 444 ; N k ; B 69 0 439 750 ;
+C 108 ; WX 222 ; N l ; B 72 0 151 750 ;
+C 109 ; WX 778 ; N m ; B 76 0 703 571 ;
+C 110 ; WX 500 ; N n ; B 73 0 428 571 ;
+C 111 ; WX 500 ; N o ; B 51 -15 449 571 ;
+C 112 ; WX 500 ; N p ; B 72 -188 447 571 ;
+C 113 ; WX 500 ; N q ; B 55 -184 426 571 ;
+C 114 ; WX 333 ; N r ; B 81 0 322 563 ;
+C 115 ; WX 444 ; N s ; B 43 -15 400 571 ;
+C 116 ; WX 278 ; N t ; B 9 0 257 707 ;
+C 117 ; WX 500 ; N u ; B 77 -15 424 556 ;
+C 118 ; WX 444 ; N v ; B 13 0 431 556 ;
+C 119 ; WX 667 ; N w ; B 19 0 649 556 ;
+C 120 ; WX 444 ; N x ; B 9 0 436 556 ;
+C 121 ; WX 444 ; N y ; B 5 -190 425 556 ;
+C 122 ; WX 389 ; N z ; B 24 0 366 556 ;
+C 123 ; WX 274 ; N braceleft ; B 7 -95 266 750 ;
+C 124 ; WX 250 ; N bar ; B 93 -250 157 750 ;
+C 125 ; WX 274 ; N braceright ; B 8 -95 267 750 ;
+C 126 ; WX 500 ; N asciitilde ; B 44 166 457 345 ;
+C 161 ; WX 333 ; N exclamdown ; B 121 -179 212 571 ;
+C 162 ; WX 500 ; N cent ; B 58 -137 418 667 ;
+C 163 ; WX 500 ; N sterling ; B 30 -15 485 750 ;
+C 164 ; WX 167 ; N fraction ; B -174 0 341 750 ;
+C 165 ; WX 500 ; N yen ; B -17 0 518 750 ;
+C 166 ; WX 500 ; N florin ; B 10 -192 488 750 ;
+C 167 ; WX 500 ; N section ; B 35 -208 466 750 ;
+C 168 ; WX 500 ; N currency ; B 24 50 475 553 ;
+C 169 ; WX 250 ; N quotesingle ; B 99 513 151 739 ;
+C 170 ; WX 389 ; N quotedblleft ; B 62 521 327 767 ;
+C 171 ; WX 500 ; N guillemotleft ; B 85 125 415 495 ;
+C 172 ; WX 278 ; N guilsinglleft ; B 64 125 215 495 ;
+C 173 ; WX 278 ; N guilsinglright ; B 63 125 214 495 ;
+C 174 ; WX 500 ; N fi ; B 12 0 427 752 ;
+C 175 ; WX 500 ; N fl ; B 12 0 425 752 ;
+C 177 ; WX 500 ; N endash ; B 0 275 500 345 ;
+C 178 ; WX 500 ; N dagger ; B 40 -176 461 750 ;
+C 179 ; WX 500 ; N daggerdbl ; B 39 -176 462 750 ;
+C 180 ; WX 250 ; N periodcentered ; B 80 204 171 304 ;
+C 182 ; WX 440 ; N paragraph ; B 0 -116 391 750 ;
+C 183 ; WX 333 ; N bullet ; B 15 222 318 529 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 64 -146 158 100 ;
+C 185 ; WX 389 ; N quotedblbase ; B 62 -146 327 100 ;
+C 186 ; WX 389 ; N quotedblright ; B 62 504 327 750 ;
+C 187 ; WX 500 ; N guillemotright ; B 85 125 415 495 ;
+C 188 ; WX 1000 ; N ellipsis ; B 121 0 878 100 ;
+C 189 ; WX 1111 ; N perthousand ; B 47 -16 1071 750 ;
+C 191 ; WX 500 ; N questiondown ; B 38 -190 440 559 ;
+C 193 ; WX 333 ; N grave ; B 35 624 233 765 ;
+C 194 ; WX 333 ; N acute ; B 100 624 298 765 ;
+C 195 ; WX 333 ; N circumflex ; B 21 624 313 765 ;
+C 196 ; WX 333 ; N tilde ; B -3 633 337 749 ;
+C 197 ; WX 333 ; N macron ; B 10 657 323 715 ;
+C 198 ; WX 333 ; N breve ; B 12 629 321 765 ;
+C 199 ; WX 250 ; N dotaccent ; B 86 650 165 750 ;
+C 200 ; WX 333 ; N dieresis ; B 52 650 281 750 ;
+C 202 ; WX 250 ; N ring ; B 23 593 227 796 ;
+C 203 ; WX 333 ; N cedilla ; B 66 -224 281 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 61 624 440 765 ;
+C 206 ; WX 333 ; N ogonek ; B 0 -191 208 13 ;
+C 207 ; WX 333 ; N caron ; B 21 624 313 765 ;
+C 208 ; WX 1000 ; N emdash ; B 0 275 1000 345 ;
+C 225 ; WX 833 ; N AE ; B 0 0 785 750 ;
+C 227 ; WX 300 ; N ordfeminine ; B 25 413 276 765 ;
+C 232 ; WX 500 ; N Lslash ; B -13 0 472 750 ;
+C 233 ; WX 611 ; N Oslash ; B 29 -43 573 796 ;
+C 234 ; WX 833 ; N OE ; B 56 -18 787 765 ;
+C 235 ; WX 300 ; N ordmasculine ; B 20 413 279 765 ;
+C 241 ; WX 667 ; N ae ; B 26 -15 630 571 ;
+C 245 ; WX 222 ; N dotlessi ; B 72 0 151 556 ;
+C 248 ; WX 222 ; N lslash ; B -8 0 231 750 ;
+C 249 ; WX 500 ; N oslash ; B 25 -46 472 582 ;
+C 250 ; WX 722 ; N oe ; B 40 -15 676 571 ;
+C 251 ; WX 500 ; N germandbls ; B 71 -5 445 765 ;
+C -1 ; WX 444 ; N ecircumflex ; B 43 -15 395 765 ;
+C -1 ; WX 444 ; N edieresis ; B 43 -15 395 750 ;
+C -1 ; WX 444 ; N aacute ; B 31 -15 417 765 ;
+C -1 ; WX 800 ; N registered ; B 8 -18 792 765 ;
+C -1 ; WX 222 ; N icircumflex ; B -34 0 258 765 ;
+C -1 ; WX 500 ; N udieresis ; B 77 -15 424 750 ;
+C -1 ; WX 500 ; N ograve ; B 51 -15 449 765 ;
+C -1 ; WX 500 ; N uacute ; B 77 -15 424 765 ;
+C -1 ; WX 500 ; N ucircumflex ; B 77 -15 424 765 ;
+C -1 ; WX 556 ; N Aacute ; B 11 0 546 959 ;
+C -1 ; WX 222 ; N igrave ; B -20 0 178 765 ;
+C -1 ; WX 278 ; N Icircumflex ; B -6 0 286 959 ;
+C -1 ; WX 444 ; N ccedilla ; B 44 -224 405 571 ;
+C -1 ; WX 444 ; N adieresis ; B 31 -15 417 750 ;
+C -1 ; WX 500 ; N Ecircumflex ; B 74 0 451 959 ;
+C -1 ; WX 444 ; N scaron ; B 43 -15 400 765 ;
+C -1 ; WX 500 ; N thorn ; B 72 -188 447 750 ;
+C -1 ; WX 750 ; N trademark ; B 0 329 719 750 ;
+C -1 ; WX 444 ; N egrave ; B 43 -15 395 765 ;
+C -1 ; WX 300 ; N threesuperior ; B 17 291 283 750 ;
+C -1 ; WX 389 ; N zcaron ; B 24 0 366 765 ;
+C -1 ; WX 444 ; N atilde ; B 31 -15 417 749 ;
+C -1 ; WX 444 ; N aring ; B 31 -15 417 826 ;
+C -1 ; WX 500 ; N ocircumflex ; B 51 -15 449 765 ;
+C -1 ; WX 500 ; N Edieresis ; B 74 0 451 944 ;
+C -1 ; WX 750 ; N threequarters ; B 21 0 730 750 ;
+C -1 ; WX 444 ; N ydieresis ; B 5 -190 425 750 ;
+C -1 ; WX 444 ; N yacute ; B 5 -190 425 765 ;
+C -1 ; WX 222 ; N iacute ; B 45 0 243 765 ;
+C -1 ; WX 556 ; N Acircumflex ; B 11 0 546 959 ;
+C -1 ; WX 611 ; N Uacute ; B 81 -18 531 959 ;
+C -1 ; WX 444 ; N eacute ; B 43 -15 395 765 ;
+C -1 ; WX 611 ; N Ograve ; B 59 -18 553 959 ;
+C -1 ; WX 444 ; N agrave ; B 31 -15 417 765 ;
+C -1 ; WX 611 ; N Udieresis ; B 81 -18 531 944 ;
+C -1 ; WX 444 ; N acircumflex ; B 31 -15 417 765 ;
+C -1 ; WX 278 ; N Igrave ; B 8 0 206 959 ;
+C -1 ; WX 300 ; N twosuperior ; B 19 300 281 750 ;
+C -1 ; WX 611 ; N Ugrave ; B 81 -18 531 959 ;
+C -1 ; WX 750 ; N onequarter ; B 34 0 716 750 ;
+C -1 ; WX 611 ; N Ucircumflex ; B 81 -18 531 959 ;
+C -1 ; WX 556 ; N Scaron ; B 51 -18 505 959 ;
+C -1 ; WX 278 ; N Idieresis ; B 25 0 254 944 ;
+C -1 ; WX 222 ; N idieresis ; B -3 0 226 750 ;
+C -1 ; WX 500 ; N Egrave ; B 74 0 451 959 ;
+C -1 ; WX 611 ; N Oacute ; B 59 -18 553 959 ;
+C -1 ; WX 500 ; N divide ; B 44 3 457 505 ;
+C -1 ; WX 556 ; N Atilde ; B 11 0 546 943 ;
+C -1 ; WX 556 ; N Aring ; B 11 0 546 990 ;
+C -1 ; WX 611 ; N Odieresis ; B 59 -18 553 944 ;
+C -1 ; WX 556 ; N Adieresis ; B 11 0 546 944 ;
+C -1 ; WX 611 ; N Ntilde ; B 77 0 534 943 ;
+C -1 ; WX 500 ; N Zcaron ; B 28 0 473 959 ;
+C -1 ; WX 556 ; N Thorn ; B 86 0 519 750 ;
+C -1 ; WX 278 ; N Iacute ; B 73 0 271 959 ;
+C -1 ; WX 500 ; N plusminus ; B 44 0 457 505 ;
+C -1 ; WX 500 ; N multiply ; B 44 48 457 461 ;
+C -1 ; WX 500 ; N Eacute ; B 74 0 451 959 ;
+C -1 ; WX 556 ; N Ydieresis ; B 11 0 546 944 ;
+C -1 ; WX 300 ; N onesuperior ; B 67 300 233 750 ;
+C -1 ; WX 500 ; N ugrave ; B 77 -15 424 765 ;
+C -1 ; WX 500 ; N logicalnot ; B 44 117 457 384 ;
+C -1 ; WX 500 ; N ntilde ; B 73 0 428 749 ;
+C -1 ; WX 611 ; N Otilde ; B 59 -18 553 943 ;
+C -1 ; WX 500 ; N otilde ; B 51 -15 449 749 ;
+C -1 ; WX 556 ; N Ccedilla ; B 53 -224 503 765 ;
+C -1 ; WX 556 ; N Agrave ; B 11 0 546 959 ;
+C -1 ; WX 750 ; N onehalf ; B 42 0 709 750 ;
+C -1 ; WX 611 ; N Eth ; B 9 0 548 750 ;
+C -1 ; WX 400 ; N degree ; B 50 450 350 750 ;
+C -1 ; WX 556 ; N Yacute ; B 11 0 546 959 ;
+C -1 ; WX 611 ; N Ocircumflex ; B 59 -18 553 959 ;
+C -1 ; WX 500 ; N oacute ; B 51 -15 449 765 ;
+C -1 ; WX 500 ; N mu ; B 75 -189 422 556 ;
+C -1 ; WX 500 ; N minus ; B 44 219 457 289 ;
+C -1 ; WX 500 ; N eth ; B 51 -15 449 831 ;
+C -1 ; WX 500 ; N odieresis ; B 51 -15 449 750 ;
+C -1 ; WX 800 ; N copyright ; B 8 -18 792 765 ;
+C -1 ; WX 250 ; N brokenbar ; B 93 -175 157 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 90
+
+KPX A y -18
+KPX A w -18
+KPX A v -18
+KPX A quoteright -55
+KPX A Y -55
+KPX A W -37
+KPX A V -37
+KPX A T -55
+
+KPX F period -111
+KPX F comma -111
+KPX F A -37
+
+KPX L y -37
+KPX L quoteright -92
+KPX L Y -92
+KPX L W -74
+KPX L V -74
+KPX L T -74
+
+KPX P period -129
+KPX P comma -129
+KPX P A -37
+
+KPX R Y -18
+KPX R T -18
+
+KPX T y -55
+KPX T w -74
+KPX T u -74
+KPX T semicolon -74
+KPX T s -74
+KPX T r -74
+KPX T period -92
+KPX T o -74
+KPX T i -18
+KPX T hyphen -55
+KPX T e -74
+KPX T comma -92
+KPX T colon -74
+KPX T c -74
+KPX T a -74
+KPX T A -55
+
+KPX V u -18
+KPX V semicolon -18
+KPX V r -18
+KPX V period -92
+KPX V o -18
+KPX V hyphen -18
+KPX V e -18
+KPX V comma -92
+KPX V colon -18
+KPX V a -18
+KPX V A -37
+
+KPX W period -74
+KPX W o -18
+KPX W hyphen -18
+KPX W e -18
+KPX W comma -74
+KPX W a -18
+KPX W A -18
+
+KPX Y v -18
+KPX Y u -37
+KPX Y semicolon -37
+KPX Y q -55
+KPX Y period -111
+KPX Y p -37
+KPX Y o -55
+KPX Y i -18
+KPX Y hyphen -74
+KPX Y e -55
+KPX Y comma -111
+KPX Y colon -37
+KPX Y a -55
+KPX Y A -55
+
+KPX f quoteright 18
+
+KPX quoteleft quoteleft -18
+
+KPX quoteright s -55
+KPX quoteright quoteright -18
+
+KPX r z 20
+KPX r y 18
+KPX r x 20
+KPX r w 18
+KPX r v 18
+KPX r period -74
+KPX r hyphen -37
+KPX r f 20
+KPX r comma -74
+KPX r c -20
+
+KPX v period -55
+KPX v comma -55
+
+KPX w period -37
+KPX w comma -37
+
+KPX y period -55
+KPX y comma -55
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 112 194 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 112 194 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 112 194 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 112 194 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 153 194 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 112 194 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 84 194 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 84 194 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 84 194 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 84 194 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 194 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 194 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 194 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 194 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 139 194 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 139 194 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 139 194 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 139 194 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 139 194 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 139 194 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 194 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 139 194 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 139 194 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 139 194 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 139 194 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 112 194 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 112 194 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 84 194 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 56 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 56 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 82 30 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -55 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -55 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -55 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -55 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 56 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 56 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 28 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-Narrow-Bold.afm b/tlt3.0/library/afm/Helvetica-Narrow-Bold.afm
new file mode 100644
index 0000000..3fdd6ef
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-Narrow-Bold.afm
@@ -0,0 +1,571 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Thu Mar 15 11:47:27 1990
+Comment UniqueID 28398
+Comment VMusage 7614 43068
+FontName Helvetica-Narrow-Bold
+FullName Helvetica Narrow Bold
+FamilyName Helvetica
+Weight Bold
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -139 -228 822 962
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 532
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 228 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 273 ; N exclam ; B 74 0 200 718 ;
+C 34 ; WX 389 ; N quotedbl ; B 80 447 308 718 ;
+C 35 ; WX 456 ; N numbersign ; B 15 0 441 698 ;
+C 36 ; WX 456 ; N dollar ; B 25 -115 429 775 ;
+C 37 ; WX 729 ; N percent ; B 23 -19 706 710 ;
+C 38 ; WX 592 ; N ampersand ; B 44 -19 575 718 ;
+C 39 ; WX 228 ; N quoteright ; B 57 445 171 718 ;
+C 40 ; WX 273 ; N parenleft ; B 29 -208 257 734 ;
+C 41 ; WX 273 ; N parenright ; B 16 -208 244 734 ;
+C 42 ; WX 319 ; N asterisk ; B 22 387 297 718 ;
+C 43 ; WX 479 ; N plus ; B 33 0 446 506 ;
+C 44 ; WX 228 ; N comma ; B 52 -168 175 146 ;
+C 45 ; WX 273 ; N hyphen ; B 22 215 251 345 ;
+C 46 ; WX 228 ; N period ; B 52 0 175 146 ;
+C 47 ; WX 228 ; N slash ; B -27 -19 255 737 ;
+C 48 ; WX 456 ; N zero ; B 26 -19 430 710 ;
+C 49 ; WX 456 ; N one ; B 57 0 310 710 ;
+C 50 ; WX 456 ; N two ; B 21 0 419 710 ;
+C 51 ; WX 456 ; N three ; B 22 -19 423 710 ;
+C 52 ; WX 456 ; N four ; B 22 0 431 710 ;
+C 53 ; WX 456 ; N five ; B 22 -19 423 698 ;
+C 54 ; WX 456 ; N six ; B 25 -19 426 710 ;
+C 55 ; WX 456 ; N seven ; B 20 0 433 698 ;
+C 56 ; WX 456 ; N eight ; B 26 -19 430 710 ;
+C 57 ; WX 456 ; N nine ; B 25 -19 428 710 ;
+C 58 ; WX 273 ; N colon ; B 75 0 198 512 ;
+C 59 ; WX 273 ; N semicolon ; B 75 -168 198 512 ;
+C 60 ; WX 479 ; N less ; B 31 -8 448 514 ;
+C 61 ; WX 479 ; N equal ; B 33 87 446 419 ;
+C 62 ; WX 479 ; N greater ; B 31 -8 448 514 ;
+C 63 ; WX 501 ; N question ; B 49 0 456 727 ;
+C 64 ; WX 800 ; N at ; B 97 -19 702 737 ;
+C 65 ; WX 592 ; N A ; B 16 0 576 718 ;
+C 66 ; WX 592 ; N B ; B 62 0 549 718 ;
+C 67 ; WX 592 ; N C ; B 36 -19 561 737 ;
+C 68 ; WX 592 ; N D ; B 62 0 562 718 ;
+C 69 ; WX 547 ; N E ; B 62 0 509 718 ;
+C 70 ; WX 501 ; N F ; B 62 0 481 718 ;
+C 71 ; WX 638 ; N G ; B 36 -19 585 737 ;
+C 72 ; WX 592 ; N H ; B 58 0 534 718 ;
+C 73 ; WX 228 ; N I ; B 52 0 175 718 ;
+C 74 ; WX 456 ; N J ; B 18 -18 397 718 ;
+C 75 ; WX 592 ; N K ; B 71 0 592 718 ;
+C 76 ; WX 501 ; N L ; B 62 0 478 718 ;
+C 77 ; WX 683 ; N M ; B 57 0 627 718 ;
+C 78 ; WX 592 ; N N ; B 57 0 536 718 ;
+C 79 ; WX 638 ; N O ; B 36 -19 602 737 ;
+C 80 ; WX 547 ; N P ; B 62 0 514 718 ;
+C 81 ; WX 638 ; N Q ; B 36 -52 604 737 ;
+C 82 ; WX 592 ; N R ; B 62 0 555 718 ;
+C 83 ; WX 547 ; N S ; B 32 -19 516 737 ;
+C 84 ; WX 501 ; N T ; B 11 0 490 718 ;
+C 85 ; WX 592 ; N U ; B 59 -19 534 718 ;
+C 86 ; WX 547 ; N V ; B 16 0 531 718 ;
+C 87 ; WX 774 ; N W ; B 13 0 762 718 ;
+C 88 ; WX 547 ; N X ; B 11 0 535 718 ;
+C 89 ; WX 547 ; N Y ; B 12 0 535 718 ;
+C 90 ; WX 501 ; N Z ; B 20 0 481 718 ;
+C 91 ; WX 273 ; N bracketleft ; B 52 -196 253 722 ;
+C 92 ; WX 228 ; N backslash ; B -27 -19 255 737 ;
+C 93 ; WX 273 ; N bracketright ; B 20 -196 221 722 ;
+C 94 ; WX 479 ; N asciicircum ; B 51 323 428 698 ;
+C 95 ; WX 456 ; N underscore ; B 0 -125 456 -75 ;
+C 96 ; WX 228 ; N quoteleft ; B 57 454 171 727 ;
+C 97 ; WX 456 ; N a ; B 24 -14 432 546 ;
+C 98 ; WX 501 ; N b ; B 50 -14 474 718 ;
+C 99 ; WX 456 ; N c ; B 28 -14 430 546 ;
+C 100 ; WX 501 ; N d ; B 28 -14 452 718 ;
+C 101 ; WX 456 ; N e ; B 19 -14 433 546 ;
+C 102 ; WX 273 ; N f ; B 8 0 261 727 ; L i fi ; L l fl ;
+C 103 ; WX 501 ; N g ; B 33 -217 453 546 ;
+C 104 ; WX 501 ; N h ; B 53 0 448 718 ;
+C 105 ; WX 228 ; N i ; B 57 0 171 725 ;
+C 106 ; WX 228 ; N j ; B 2 -214 171 725 ;
+C 107 ; WX 456 ; N k ; B 57 0 461 718 ;
+C 108 ; WX 228 ; N l ; B 57 0 171 718 ;
+C 109 ; WX 729 ; N m ; B 52 0 677 546 ;
+C 110 ; WX 501 ; N n ; B 53 0 448 546 ;
+C 111 ; WX 501 ; N o ; B 28 -14 474 546 ;
+C 112 ; WX 501 ; N p ; B 51 -207 474 546 ;
+C 113 ; WX 501 ; N q ; B 28 -207 453 546 ;
+C 114 ; WX 319 ; N r ; B 52 0 306 546 ;
+C 115 ; WX 456 ; N s ; B 25 -14 426 546 ;
+C 116 ; WX 273 ; N t ; B 8 -6 253 676 ;
+C 117 ; WX 501 ; N u ; B 54 -14 447 532 ;
+C 118 ; WX 456 ; N v ; B 11 0 445 532 ;
+C 119 ; WX 638 ; N w ; B 8 0 631 532 ;
+C 120 ; WX 456 ; N x ; B 12 0 444 532 ;
+C 121 ; WX 456 ; N y ; B 8 -214 442 532 ;
+C 122 ; WX 410 ; N z ; B 16 0 394 532 ;
+C 123 ; WX 319 ; N braceleft ; B 39 -196 299 722 ;
+C 124 ; WX 230 ; N bar ; B 69 -19 161 737 ;
+C 125 ; WX 319 ; N braceright ; B 20 -196 280 722 ;
+C 126 ; WX 479 ; N asciitilde ; B 50 163 429 343 ;
+C 161 ; WX 273 ; N exclamdown ; B 74 -186 200 532 ;
+C 162 ; WX 456 ; N cent ; B 28 -118 430 628 ;
+C 163 ; WX 456 ; N sterling ; B 23 -16 444 718 ;
+C 164 ; WX 137 ; N fraction ; B -139 -19 276 710 ;
+C 165 ; WX 456 ; N yen ; B -7 0 463 698 ;
+C 166 ; WX 456 ; N florin ; B -8 -210 423 737 ;
+C 167 ; WX 456 ; N section ; B 28 -184 428 727 ;
+C 168 ; WX 456 ; N currency ; B -2 76 458 636 ;
+C 169 ; WX 195 ; N quotesingle ; B 57 447 138 718 ;
+C 170 ; WX 410 ; N quotedblleft ; B 52 454 358 727 ;
+C 171 ; WX 456 ; N guillemotleft ; B 72 76 384 484 ;
+C 172 ; WX 273 ; N guilsinglleft ; B 68 76 205 484 ;
+C 173 ; WX 273 ; N guilsinglright ; B 68 76 205 484 ;
+C 174 ; WX 501 ; N fi ; B 8 0 444 727 ;
+C 175 ; WX 501 ; N fl ; B 8 0 444 727 ;
+C 177 ; WX 456 ; N endash ; B 0 227 456 333 ;
+C 178 ; WX 456 ; N dagger ; B 30 -171 426 718 ;
+C 179 ; WX 456 ; N daggerdbl ; B 30 -171 426 718 ;
+C 180 ; WX 228 ; N periodcentered ; B 48 172 180 334 ;
+C 182 ; WX 456 ; N paragraph ; B -7 -191 442 700 ;
+C 183 ; WX 287 ; N bullet ; B 8 194 279 524 ;
+C 184 ; WX 228 ; N quotesinglbase ; B 57 -146 171 127 ;
+C 185 ; WX 410 ; N quotedblbase ; B 52 -146 358 127 ;
+C 186 ; WX 410 ; N quotedblright ; B 52 445 358 718 ;
+C 187 ; WX 456 ; N guillemotright ; B 72 76 384 484 ;
+C 188 ; WX 820 ; N ellipsis ; B 75 0 745 146 ;
+C 189 ; WX 820 ; N perthousand ; B -2 -19 822 710 ;
+C 191 ; WX 501 ; N questiondown ; B 45 -195 452 532 ;
+C 193 ; WX 273 ; N grave ; B -19 604 184 750 ;
+C 194 ; WX 273 ; N acute ; B 89 604 292 750 ;
+C 195 ; WX 273 ; N circumflex ; B -8 604 281 750 ;
+C 196 ; WX 273 ; N tilde ; B -14 610 287 737 ;
+C 197 ; WX 273 ; N macron ; B -5 604 278 678 ;
+C 198 ; WX 273 ; N breve ; B -2 604 275 750 ;
+C 199 ; WX 273 ; N dotaccent ; B 85 614 189 729 ;
+C 200 ; WX 273 ; N dieresis ; B 5 614 268 729 ;
+C 202 ; WX 273 ; N ring ; B 48 568 225 776 ;
+C 203 ; WX 273 ; N cedilla ; B 5 -228 201 0 ;
+C 205 ; WX 273 ; N hungarumlaut ; B 7 604 399 750 ;
+C 206 ; WX 273 ; N ogonek ; B 58 -228 249 0 ;
+C 207 ; WX 273 ; N caron ; B -8 604 281 750 ;
+C 208 ; WX 820 ; N emdash ; B 0 227 820 333 ;
+C 225 ; WX 820 ; N AE ; B 4 0 782 718 ;
+C 227 ; WX 303 ; N ordfeminine ; B 18 276 285 737 ;
+C 232 ; WX 501 ; N Lslash ; B -16 0 478 718 ;
+C 233 ; WX 638 ; N Oslash ; B 27 -27 610 745 ;
+C 234 ; WX 820 ; N OE ; B 30 -19 788 737 ;
+C 235 ; WX 299 ; N ordmasculine ; B 5 276 295 737 ;
+C 241 ; WX 729 ; N ae ; B 24 -14 704 546 ;
+C 245 ; WX 228 ; N dotlessi ; B 57 0 171 532 ;
+C 248 ; WX 228 ; N lslash ; B -15 0 243 718 ;
+C 249 ; WX 501 ; N oslash ; B 18 -29 483 560 ;
+C 250 ; WX 774 ; N oe ; B 28 -14 748 546 ;
+C 251 ; WX 501 ; N germandbls ; B 57 -14 475 731 ;
+C -1 ; WX 501 ; N Zcaron ; B 20 0 481 936 ;
+C -1 ; WX 456 ; N ccedilla ; B 28 -228 430 546 ;
+C -1 ; WX 456 ; N ydieresis ; B 8 -214 442 729 ;
+C -1 ; WX 456 ; N atilde ; B 24 -14 432 737 ;
+C -1 ; WX 228 ; N icircumflex ; B -30 0 259 750 ;
+C -1 ; WX 273 ; N threesuperior ; B 7 271 267 710 ;
+C -1 ; WX 456 ; N ecircumflex ; B 19 -14 433 750 ;
+C -1 ; WX 501 ; N thorn ; B 51 -208 474 718 ;
+C -1 ; WX 456 ; N egrave ; B 19 -14 433 750 ;
+C -1 ; WX 273 ; N twosuperior ; B 7 283 266 710 ;
+C -1 ; WX 456 ; N eacute ; B 19 -14 433 750 ;
+C -1 ; WX 501 ; N otilde ; B 28 -14 474 737 ;
+C -1 ; WX 592 ; N Aacute ; B 16 0 576 936 ;
+C -1 ; WX 501 ; N ocircumflex ; B 28 -14 474 750 ;
+C -1 ; WX 456 ; N yacute ; B 8 -214 442 750 ;
+C -1 ; WX 501 ; N udieresis ; B 54 -14 447 729 ;
+C -1 ; WX 684 ; N threequarters ; B 13 -19 655 710 ;
+C -1 ; WX 456 ; N acircumflex ; B 24 -14 432 750 ;
+C -1 ; WX 592 ; N Eth ; B -4 0 562 718 ;
+C -1 ; WX 456 ; N edieresis ; B 19 -14 433 729 ;
+C -1 ; WX 501 ; N ugrave ; B 54 -14 447 750 ;
+C -1 ; WX 820 ; N trademark ; B 36 306 784 718 ;
+C -1 ; WX 501 ; N ograve ; B 28 -14 474 750 ;
+C -1 ; WX 456 ; N scaron ; B 25 -14 426 750 ;
+C -1 ; WX 228 ; N Idieresis ; B -17 0 246 915 ;
+C -1 ; WX 501 ; N uacute ; B 54 -14 447 750 ;
+C -1 ; WX 456 ; N agrave ; B 24 -14 432 750 ;
+C -1 ; WX 501 ; N ntilde ; B 53 0 448 737 ;
+C -1 ; WX 456 ; N aring ; B 24 -14 432 776 ;
+C -1 ; WX 410 ; N zcaron ; B 16 0 394 750 ;
+C -1 ; WX 228 ; N Icircumflex ; B -30 0 259 936 ;
+C -1 ; WX 592 ; N Ntilde ; B 57 0 536 923 ;
+C -1 ; WX 501 ; N ucircumflex ; B 54 -14 447 750 ;
+C -1 ; WX 547 ; N Ecircumflex ; B 62 0 509 936 ;
+C -1 ; WX 228 ; N Iacute ; B 52 0 270 936 ;
+C -1 ; WX 592 ; N Ccedilla ; B 36 -228 561 737 ;
+C -1 ; WX 638 ; N Odieresis ; B 36 -19 602 915 ;
+C -1 ; WX 547 ; N Scaron ; B 32 -19 516 936 ;
+C -1 ; WX 547 ; N Edieresis ; B 62 0 509 915 ;
+C -1 ; WX 228 ; N Igrave ; B -41 0 175 936 ;
+C -1 ; WX 456 ; N adieresis ; B 24 -14 432 729 ;
+C -1 ; WX 638 ; N Ograve ; B 36 -19 602 936 ;
+C -1 ; WX 547 ; N Egrave ; B 62 0 509 936 ;
+C -1 ; WX 547 ; N Ydieresis ; B 12 0 535 915 ;
+C -1 ; WX 604 ; N registered ; B -9 -19 613 737 ;
+C -1 ; WX 638 ; N Otilde ; B 36 -19 602 923 ;
+C -1 ; WX 684 ; N onequarter ; B 21 -19 628 710 ;
+C -1 ; WX 592 ; N Ugrave ; B 59 -19 534 936 ;
+C -1 ; WX 592 ; N Ucircumflex ; B 59 -19 534 936 ;
+C -1 ; WX 547 ; N Thorn ; B 62 0 514 718 ;
+C -1 ; WX 479 ; N divide ; B 33 -42 446 548 ;
+C -1 ; WX 592 ; N Atilde ; B 16 0 576 923 ;
+C -1 ; WX 592 ; N Uacute ; B 59 -19 534 936 ;
+C -1 ; WX 638 ; N Ocircumflex ; B 36 -19 602 936 ;
+C -1 ; WX 479 ; N logicalnot ; B 33 108 446 419 ;
+C -1 ; WX 592 ; N Aring ; B 16 0 576 962 ;
+C -1 ; WX 228 ; N idieresis ; B -17 0 246 729 ;
+C -1 ; WX 228 ; N iacute ; B 57 0 270 750 ;
+C -1 ; WX 456 ; N aacute ; B 24 -14 432 750 ;
+C -1 ; WX 479 ; N plusminus ; B 33 0 446 506 ;
+C -1 ; WX 479 ; N multiply ; B 33 1 447 505 ;
+C -1 ; WX 592 ; N Udieresis ; B 59 -19 534 915 ;
+C -1 ; WX 479 ; N minus ; B 33 197 446 309 ;
+C -1 ; WX 273 ; N onesuperior ; B 21 283 194 710 ;
+C -1 ; WX 547 ; N Eacute ; B 62 0 509 936 ;
+C -1 ; WX 592 ; N Acircumflex ; B 16 0 576 936 ;
+C -1 ; WX 604 ; N copyright ; B -9 -19 614 737 ;
+C -1 ; WX 592 ; N Agrave ; B 16 0 576 936 ;
+C -1 ; WX 501 ; N odieresis ; B 28 -14 474 729 ;
+C -1 ; WX 501 ; N oacute ; B 28 -14 474 750 ;
+C -1 ; WX 328 ; N degree ; B 47 426 281 712 ;
+C -1 ; WX 228 ; N igrave ; B -41 0 171 750 ;
+C -1 ; WX 501 ; N mu ; B 54 -207 447 532 ;
+C -1 ; WX 638 ; N Oacute ; B 36 -19 602 936 ;
+C -1 ; WX 501 ; N eth ; B 28 -14 474 737 ;
+C -1 ; WX 592 ; N Adieresis ; B 16 0 576 915 ;
+C -1 ; WX 547 ; N Yacute ; B 12 0 535 936 ;
+C -1 ; WX 230 ; N brokenbar ; B 69 -19 161 737 ;
+C -1 ; WX 684 ; N onehalf ; B 21 -19 651 710 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 209
+
+KPX A y -24
+KPX A w -24
+KPX A v -32
+KPX A u -24
+KPX A Y -89
+KPX A W -48
+KPX A V -65
+KPX A U -40
+KPX A T -73
+KPX A Q -32
+KPX A O -32
+KPX A G -40
+KPX A C -32
+
+KPX B U -7
+KPX B A -24
+
+KPX D period -24
+KPX D comma -24
+KPX D Y -56
+KPX D W -32
+KPX D V -32
+KPX D A -32
+
+KPX F period -81
+KPX F comma -81
+KPX F a -15
+KPX F A -65
+
+KPX J u -15
+KPX J period -15
+KPX J comma -15
+KPX J A -15
+
+KPX K y -32
+KPX K u -24
+KPX K o -28
+KPX K e -11
+KPX K O -24
+
+KPX L y -24
+KPX L quoteright -114
+KPX L quotedblright -114
+KPX L Y -97
+KPX L W -65
+KPX L V -89
+KPX L T -73
+
+KPX O period -32
+KPX O comma -32
+KPX O Y -56
+KPX O X -40
+KPX O W -40
+KPX O V -40
+KPX O T -32
+KPX O A -40
+
+KPX P period -97
+KPX P o -32
+KPX P e -24
+KPX P comma -97
+KPX P a -24
+KPX P A -81
+
+KPX Q period 16
+KPX Q comma 16
+KPX Q U -7
+
+KPX R Y -40
+KPX R W -32
+KPX R V -40
+KPX R U -15
+KPX R T -15
+KPX R O -15
+
+KPX T y -48
+KPX T w -48
+KPX T u -73
+KPX T semicolon -32
+KPX T r -65
+KPX T period -65
+KPX T o -65
+KPX T hyphen -97
+KPX T e -48
+KPX T comma -65
+KPX T colon -32
+KPX T a -65
+KPX T O -32
+KPX T A -73
+
+KPX U period -24
+KPX U comma -24
+KPX U A -40
+
+KPX V u -48
+KPX V semicolon -32
+KPX V period -97
+KPX V o -73
+KPX V hyphen -65
+KPX V e -40
+KPX V comma -97
+KPX V colon -32
+KPX V a -48
+KPX V O -40
+KPX V G -40
+KPX V A -65
+
+KPX W y -15
+KPX W u -36
+KPX W semicolon -7
+KPX W period -65
+KPX W o -48
+KPX W hyphen -32
+KPX W e -28
+KPX W comma -65
+KPX W colon -7
+KPX W a -32
+KPX W O -15
+KPX W A -48
+
+KPX Y u -81
+KPX Y semicolon -40
+KPX Y period -81
+KPX Y o -81
+KPX Y e -65
+KPX Y comma -81
+KPX Y colon -40
+KPX Y a -73
+KPX Y O -56
+KPX Y A -89
+
+KPX a y -15
+KPX a w -11
+KPX a v -11
+KPX a g -7
+
+KPX b y -15
+KPX b v -15
+KPX b u -15
+KPX b l -7
+
+KPX c y -7
+KPX c l -15
+KPX c k -15
+KPX c h -7
+
+KPX colon space -32
+
+KPX comma space -32
+KPX comma quoteright -97
+KPX comma quotedblright -97
+
+KPX d y -11
+KPX d w -11
+KPX d v -11
+KPX d d -7
+
+KPX e y -11
+KPX e x -11
+KPX e w -11
+KPX e v -11
+KPX e period 16
+KPX e comma 8
+
+KPX f quoteright 25
+KPX f quotedblright 25
+KPX f period -7
+KPX f o -15
+KPX f e -7
+KPX f comma -7
+
+KPX g g -7
+KPX g e 8
+
+KPX h y -15
+
+KPX k o -11
+
+KPX l y -11
+KPX l w -11
+
+KPX m y -24
+KPX m u -15
+
+KPX n y -15
+KPX n v -32
+KPX n u -7
+
+KPX o y -15
+KPX o x -24
+KPX o w -11
+KPX o v -15
+
+KPX p y -11
+
+KPX period space -32
+KPX period quoteright -97
+KPX period quotedblright -97
+
+KPX quotedblright space -65
+
+KPX quoteleft quoteleft -37
+
+KPX quoteright v -15
+KPX quoteright space -65
+KPX quoteright s -48
+KPX quoteright r -32
+KPX quoteright quoteright -37
+KPX quoteright l -15
+KPX quoteright d -65
+
+KPX r y 8
+KPX r v 8
+KPX r t 16
+KPX r s -11
+KPX r q -15
+KPX r period -48
+KPX r o -15
+KPX r hyphen -15
+KPX r g -11
+KPX r d -15
+KPX r comma -48
+KPX r c -15
+
+KPX s w -11
+
+KPX semicolon space -32
+
+KPX space quoteleft -48
+KPX space quotedblleft -65
+KPX space Y -97
+KPX space W -65
+KPX space V -65
+KPX space T -81
+
+KPX v period -65
+KPX v o -24
+KPX v comma -65
+KPX v a -15
+
+KPX w period -32
+KPX w o -15
+KPX w comma -32
+
+KPX x e -7
+
+KPX y period -65
+KPX y o -20
+KPX y e -7
+KPX y comma -65
+KPX y a -24
+
+KPX z e 8
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 186 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 160 186 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 160 186 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 186 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 160 186 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 160 186 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 137 186 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 137 186 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 137 186 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 137 186 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -22 186 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -22 186 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -22 186 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -22 186 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 160 186 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 183 186 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 183 186 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 183 186 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 183 186 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 183 186 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 137 186 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 186 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 160 186 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 160 186 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 160 186 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 137 186 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 137 186 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 114 186 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 92 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 108 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 114 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 114 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 114 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 114 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 114 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 114 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 92 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 114 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 114 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 114 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 114 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 92 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 92 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-Narrow-BoldOblique.afm b/tlt3.0/library/afm/Helvetica-Narrow-BoldOblique.afm
new file mode 100644
index 0000000..ff859b3
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-Narrow-BoldOblique.afm
@@ -0,0 +1,571 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Thu Mar 15 12:08:57 1990
+Comment UniqueID 28407
+Comment VMusage 7614 43068
+FontName Helvetica-Narrow-BoldOblique
+FullName Helvetica Narrow Bold Oblique
+FamilyName Helvetica
+Weight Bold
+ItalicAngle -12
+IsFixedPitch false
+FontBBox -143 -228 913 962
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 532
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 228 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 273 ; N exclam ; B 77 0 325 718 ;
+C 34 ; WX 389 ; N quotedbl ; B 158 447 433 718 ;
+C 35 ; WX 456 ; N numbersign ; B 49 0 528 698 ;
+C 36 ; WX 456 ; N dollar ; B 55 -115 510 775 ;
+C 37 ; WX 729 ; N percent ; B 112 -19 739 710 ;
+C 38 ; WX 592 ; N ampersand ; B 73 -19 600 718 ;
+C 39 ; WX 228 ; N quoteright ; B 137 445 297 718 ;
+C 40 ; WX 273 ; N parenleft ; B 62 -208 385 734 ;
+C 41 ; WX 273 ; N parenright ; B -21 -208 302 734 ;
+C 42 ; WX 319 ; N asterisk ; B 120 387 394 718 ;
+C 43 ; WX 479 ; N plus ; B 67 0 500 506 ;
+C 44 ; WX 228 ; N comma ; B 23 -168 201 146 ;
+C 45 ; WX 273 ; N hyphen ; B 60 215 311 345 ;
+C 46 ; WX 228 ; N period ; B 52 0 201 146 ;
+C 47 ; WX 228 ; N slash ; B -30 -19 383 737 ;
+C 48 ; WX 456 ; N zero ; B 71 -19 506 710 ;
+C 49 ; WX 456 ; N one ; B 142 0 434 710 ;
+C 50 ; WX 456 ; N two ; B 21 0 508 710 ;
+C 51 ; WX 456 ; N three ; B 54 -19 499 710 ;
+C 52 ; WX 456 ; N four ; B 50 0 490 710 ;
+C 53 ; WX 456 ; N five ; B 53 -19 522 698 ;
+C 54 ; WX 456 ; N six ; B 70 -19 507 710 ;
+C 55 ; WX 456 ; N seven ; B 102 0 555 698 ;
+C 56 ; WX 456 ; N eight ; B 57 -19 505 710 ;
+C 57 ; WX 456 ; N nine ; B 64 -19 504 710 ;
+C 58 ; WX 273 ; N colon ; B 75 0 288 512 ;
+C 59 ; WX 273 ; N semicolon ; B 46 -168 288 512 ;
+C 60 ; WX 479 ; N less ; B 67 -8 537 514 ;
+C 61 ; WX 479 ; N equal ; B 48 87 519 419 ;
+C 62 ; WX 479 ; N greater ; B 30 -8 500 514 ;
+C 63 ; WX 501 ; N question ; B 135 0 550 727 ;
+C 64 ; WX 800 ; N at ; B 152 -19 782 737 ;
+C 65 ; WX 592 ; N A ; B 16 0 576 718 ;
+C 66 ; WX 592 ; N B ; B 62 0 626 718 ;
+C 67 ; WX 592 ; N C ; B 88 -19 647 737 ;
+C 68 ; WX 592 ; N D ; B 62 0 637 718 ;
+C 69 ; WX 547 ; N E ; B 62 0 620 718 ;
+C 70 ; WX 501 ; N F ; B 62 0 606 718 ;
+C 71 ; WX 638 ; N G ; B 89 -19 670 737 ;
+C 72 ; WX 592 ; N H ; B 58 0 659 718 ;
+C 73 ; WX 228 ; N I ; B 52 0 301 718 ;
+C 74 ; WX 456 ; N J ; B 49 -18 522 718 ;
+C 75 ; WX 592 ; N K ; B 71 0 703 718 ;
+C 76 ; WX 501 ; N L ; B 62 0 501 718 ;
+C 77 ; WX 683 ; N M ; B 57 0 752 718 ;
+C 78 ; WX 592 ; N N ; B 57 0 661 718 ;
+C 79 ; WX 638 ; N O ; B 88 -19 675 737 ;
+C 80 ; WX 547 ; N P ; B 62 0 605 718 ;
+C 81 ; WX 638 ; N Q ; B 88 -52 675 737 ;
+C 82 ; WX 592 ; N R ; B 62 0 638 718 ;
+C 83 ; WX 547 ; N S ; B 66 -19 588 737 ;
+C 84 ; WX 501 ; N T ; B 114 0 615 718 ;
+C 85 ; WX 592 ; N U ; B 96 -19 659 718 ;
+C 86 ; WX 547 ; N V ; B 141 0 656 718 ;
+C 87 ; WX 774 ; N W ; B 138 0 887 718 ;
+C 88 ; WX 547 ; N X ; B 11 0 648 718 ;
+C 89 ; WX 547 ; N Y ; B 137 0 661 718 ;
+C 90 ; WX 501 ; N Z ; B 20 0 604 718 ;
+C 91 ; WX 273 ; N bracketleft ; B 17 -196 379 722 ;
+C 92 ; WX 228 ; N backslash ; B 101 -19 252 737 ;
+C 93 ; WX 273 ; N bracketright ; B -14 -196 347 722 ;
+C 94 ; WX 479 ; N asciicircum ; B 107 323 484 698 ;
+C 95 ; WX 456 ; N underscore ; B -22 -125 443 -75 ;
+C 96 ; WX 228 ; N quoteleft ; B 136 454 296 727 ;
+C 97 ; WX 456 ; N a ; B 45 -14 478 546 ;
+C 98 ; WX 501 ; N b ; B 50 -14 529 718 ;
+C 99 ; WX 456 ; N c ; B 65 -14 491 546 ;
+C 100 ; WX 501 ; N d ; B 67 -14 577 718 ;
+C 101 ; WX 456 ; N e ; B 58 -14 486 546 ;
+C 102 ; WX 273 ; N f ; B 71 0 385 727 ; L i fi ; L l fl ;
+C 103 ; WX 501 ; N g ; B 31 -217 546 546 ;
+C 104 ; WX 501 ; N h ; B 53 0 516 718 ;
+C 105 ; WX 228 ; N i ; B 57 0 298 725 ;
+C 106 ; WX 228 ; N j ; B -35 -214 298 725 ;
+C 107 ; WX 456 ; N k ; B 57 0 549 718 ;
+C 108 ; WX 228 ; N l ; B 57 0 297 718 ;
+C 109 ; WX 729 ; N m ; B 52 0 746 546 ;
+C 110 ; WX 501 ; N n ; B 53 0 516 546 ;
+C 111 ; WX 501 ; N o ; B 67 -14 527 546 ;
+C 112 ; WX 501 ; N p ; B 15 -207 529 546 ;
+C 113 ; WX 501 ; N q ; B 66 -207 545 546 ;
+C 114 ; WX 319 ; N r ; B 52 0 401 546 ;
+C 115 ; WX 456 ; N s ; B 52 -14 479 546 ;
+C 116 ; WX 273 ; N t ; B 82 -6 346 676 ;
+C 117 ; WX 501 ; N u ; B 80 -14 540 532 ;
+C 118 ; WX 456 ; N v ; B 103 0 538 532 ;
+C 119 ; WX 638 ; N w ; B 101 0 723 532 ;
+C 120 ; WX 456 ; N x ; B 12 0 531 532 ;
+C 121 ; WX 456 ; N y ; B 34 -214 535 532 ;
+C 122 ; WX 410 ; N z ; B 16 0 478 532 ;
+C 123 ; WX 319 ; N braceleft ; B 77 -196 425 722 ;
+C 124 ; WX 230 ; N bar ; B 66 -19 289 737 ;
+C 125 ; WX 319 ; N braceright ; B -14 -196 333 722 ;
+C 126 ; WX 479 ; N asciitilde ; B 94 163 473 343 ;
+C 161 ; WX 273 ; N exclamdown ; B 41 -186 290 532 ;
+C 162 ; WX 456 ; N cent ; B 65 -118 491 628 ;
+C 163 ; WX 456 ; N sterling ; B 41 -16 520 718 ;
+C 164 ; WX 137 ; N fraction ; B -143 -19 399 710 ;
+C 165 ; WX 456 ; N yen ; B 49 0 585 698 ;
+C 166 ; WX 456 ; N florin ; B -41 -210 548 737 ;
+C 167 ; WX 456 ; N section ; B 50 -184 491 727 ;
+C 168 ; WX 456 ; N currency ; B 22 76 558 636 ;
+C 169 ; WX 195 ; N quotesingle ; B 135 447 263 718 ;
+C 170 ; WX 410 ; N quotedblleft ; B 132 454 482 727 ;
+C 171 ; WX 456 ; N guillemotleft ; B 111 76 468 484 ;
+C 172 ; WX 273 ; N guilsinglleft ; B 106 76 289 484 ;
+C 173 ; WX 273 ; N guilsinglright ; B 81 76 264 484 ;
+C 174 ; WX 501 ; N fi ; B 71 0 571 727 ;
+C 175 ; WX 501 ; N fl ; B 71 0 570 727 ;
+C 177 ; WX 456 ; N endash ; B 40 227 514 333 ;
+C 178 ; WX 456 ; N dagger ; B 97 -171 513 718 ;
+C 179 ; WX 456 ; N daggerdbl ; B 38 -171 515 718 ;
+C 180 ; WX 228 ; N periodcentered ; B 90 172 226 334 ;
+C 182 ; WX 456 ; N paragraph ; B 80 -191 564 700 ;
+C 183 ; WX 287 ; N bullet ; B 68 194 345 524 ;
+C 184 ; WX 228 ; N quotesinglbase ; B 34 -146 194 127 ;
+C 185 ; WX 410 ; N quotedblbase ; B 29 -146 380 127 ;
+C 186 ; WX 410 ; N quotedblright ; B 132 445 483 718 ;
+C 187 ; WX 456 ; N guillemotright ; B 85 76 443 484 ;
+C 188 ; WX 820 ; N ellipsis ; B 75 0 770 146 ;
+C 189 ; WX 820 ; N perthousand ; B 62 -19 851 710 ;
+C 191 ; WX 501 ; N questiondown ; B 44 -195 459 532 ;
+C 193 ; WX 273 ; N grave ; B 112 604 290 750 ;
+C 194 ; WX 273 ; N acute ; B 194 604 423 750 ;
+C 195 ; WX 273 ; N circumflex ; B 97 604 387 750 ;
+C 196 ; WX 273 ; N tilde ; B 92 610 415 737 ;
+C 197 ; WX 273 ; N macron ; B 100 604 396 678 ;
+C 198 ; WX 273 ; N breve ; B 128 604 405 750 ;
+C 199 ; WX 273 ; N dotaccent ; B 192 614 316 729 ;
+C 200 ; WX 273 ; N dieresis ; B 112 614 395 729 ;
+C 202 ; WX 273 ; N ring ; B 164 568 344 776 ;
+C 203 ; WX 273 ; N cedilla ; B -30 -228 180 0 ;
+C 205 ; WX 273 ; N hungarumlaut ; B 113 604 529 750 ;
+C 206 ; WX 273 ; N ogonek ; B 33 -228 216 0 ;
+C 207 ; WX 273 ; N caron ; B 123 604 412 750 ;
+C 208 ; WX 820 ; N emdash ; B 40 227 878 333 ;
+C 225 ; WX 820 ; N AE ; B 4 0 902 718 ;
+C 227 ; WX 303 ; N ordfeminine ; B 75 276 381 737 ;
+C 232 ; WX 501 ; N Lslash ; B 28 0 501 718 ;
+C 233 ; WX 638 ; N Oslash ; B 29 -27 733 745 ;
+C 234 ; WX 820 ; N OE ; B 81 -19 913 737 ;
+C 235 ; WX 299 ; N ordmasculine ; B 75 276 398 737 ;
+C 241 ; WX 729 ; N ae ; B 46 -14 757 546 ;
+C 245 ; WX 228 ; N dotlessi ; B 57 0 264 532 ;
+C 248 ; WX 228 ; N lslash ; B 33 0 334 718 ;
+C 249 ; WX 501 ; N oslash ; B 18 -29 575 560 ;
+C 250 ; WX 774 ; N oe ; B 67 -14 801 546 ;
+C 251 ; WX 501 ; N germandbls ; B 57 -14 539 731 ;
+C -1 ; WX 501 ; N Zcaron ; B 20 0 604 936 ;
+C -1 ; WX 456 ; N ccedilla ; B 65 -228 491 546 ;
+C -1 ; WX 456 ; N ydieresis ; B 34 -214 535 729 ;
+C -1 ; WX 456 ; N atilde ; B 45 -14 507 737 ;
+C -1 ; WX 228 ; N icircumflex ; B 57 0 364 750 ;
+C -1 ; WX 273 ; N threesuperior ; B 75 271 361 710 ;
+C -1 ; WX 456 ; N ecircumflex ; B 58 -14 486 750 ;
+C -1 ; WX 501 ; N thorn ; B 15 -208 529 718 ;
+C -1 ; WX 456 ; N egrave ; B 58 -14 486 750 ;
+C -1 ; WX 273 ; N twosuperior ; B 57 283 368 710 ;
+C -1 ; WX 456 ; N eacute ; B 58 -14 514 750 ;
+C -1 ; WX 501 ; N otilde ; B 67 -14 529 737 ;
+C -1 ; WX 592 ; N Aacute ; B 16 0 615 936 ;
+C -1 ; WX 501 ; N ocircumflex ; B 67 -14 527 750 ;
+C -1 ; WX 456 ; N yacute ; B 34 -214 535 750 ;
+C -1 ; WX 501 ; N udieresis ; B 80 -14 540 729 ;
+C -1 ; WX 684 ; N threequarters ; B 82 -19 688 710 ;
+C -1 ; WX 456 ; N acircumflex ; B 45 -14 478 750 ;
+C -1 ; WX 592 ; N Eth ; B 51 0 637 718 ;
+C -1 ; WX 456 ; N edieresis ; B 58 -14 487 729 ;
+C -1 ; WX 501 ; N ugrave ; B 80 -14 540 750 ;
+C -1 ; WX 820 ; N trademark ; B 146 306 909 718 ;
+C -1 ; WX 501 ; N ograve ; B 67 -14 527 750 ;
+C -1 ; WX 456 ; N scaron ; B 52 -14 504 750 ;
+C -1 ; WX 228 ; N Idieresis ; B 52 0 405 915 ;
+C -1 ; WX 501 ; N uacute ; B 80 -14 540 750 ;
+C -1 ; WX 456 ; N agrave ; B 45 -14 478 750 ;
+C -1 ; WX 501 ; N ntilde ; B 53 0 529 737 ;
+C -1 ; WX 456 ; N aring ; B 45 -14 478 776 ;
+C -1 ; WX 410 ; N zcaron ; B 16 0 481 750 ;
+C -1 ; WX 228 ; N Icircumflex ; B 52 0 397 936 ;
+C -1 ; WX 592 ; N Ntilde ; B 57 0 661 923 ;
+C -1 ; WX 501 ; N ucircumflex ; B 80 -14 540 750 ;
+C -1 ; WX 547 ; N Ecircumflex ; B 62 0 620 936 ;
+C -1 ; WX 228 ; N Iacute ; B 52 0 433 936 ;
+C -1 ; WX 592 ; N Ccedilla ; B 88 -228 647 737 ;
+C -1 ; WX 638 ; N Odieresis ; B 88 -19 675 915 ;
+C -1 ; WX 547 ; N Scaron ; B 66 -19 588 936 ;
+C -1 ; WX 547 ; N Edieresis ; B 62 0 620 915 ;
+C -1 ; WX 228 ; N Igrave ; B 52 0 301 936 ;
+C -1 ; WX 456 ; N adieresis ; B 45 -14 487 729 ;
+C -1 ; WX 638 ; N Ograve ; B 88 -19 675 936 ;
+C -1 ; WX 547 ; N Egrave ; B 62 0 620 936 ;
+C -1 ; WX 547 ; N Ydieresis ; B 137 0 661 915 ;
+C -1 ; WX 604 ; N registered ; B 45 -19 684 737 ;
+C -1 ; WX 638 ; N Otilde ; B 88 -19 675 923 ;
+C -1 ; WX 684 ; N onequarter ; B 108 -19 661 710 ;
+C -1 ; WX 592 ; N Ugrave ; B 96 -19 659 936 ;
+C -1 ; WX 592 ; N Ucircumflex ; B 96 -19 659 936 ;
+C -1 ; WX 547 ; N Thorn ; B 62 0 588 718 ;
+C -1 ; WX 479 ; N divide ; B 67 -42 500 548 ;
+C -1 ; WX 592 ; N Atilde ; B 16 0 608 923 ;
+C -1 ; WX 592 ; N Uacute ; B 96 -19 659 936 ;
+C -1 ; WX 638 ; N Ocircumflex ; B 88 -19 675 936 ;
+C -1 ; WX 479 ; N logicalnot ; B 86 108 519 419 ;
+C -1 ; WX 592 ; N Aring ; B 16 0 576 962 ;
+C -1 ; WX 228 ; N idieresis ; B 57 0 373 729 ;
+C -1 ; WX 228 ; N iacute ; B 57 0 400 750 ;
+C -1 ; WX 456 ; N aacute ; B 45 -14 514 750 ;
+C -1 ; WX 479 ; N plusminus ; B 33 0 512 506 ;
+C -1 ; WX 479 ; N multiply ; B 47 1 520 505 ;
+C -1 ; WX 592 ; N Udieresis ; B 96 -19 659 915 ;
+C -1 ; WX 479 ; N minus ; B 67 197 500 309 ;
+C -1 ; WX 273 ; N onesuperior ; B 121 283 318 710 ;
+C -1 ; WX 547 ; N Eacute ; B 62 0 620 936 ;
+C -1 ; WX 592 ; N Acircumflex ; B 16 0 579 936 ;
+C -1 ; WX 604 ; N copyright ; B 46 -19 685 737 ;
+C -1 ; WX 592 ; N Agrave ; B 16 0 576 936 ;
+C -1 ; WX 501 ; N odieresis ; B 67 -14 527 729 ;
+C -1 ; WX 501 ; N oacute ; B 67 -14 537 750 ;
+C -1 ; WX 328 ; N degree ; B 143 426 383 712 ;
+C -1 ; WX 228 ; N igrave ; B 57 0 268 750 ;
+C -1 ; WX 501 ; N mu ; B 18 -207 540 532 ;
+C -1 ; WX 638 ; N Oacute ; B 88 -19 675 936 ;
+C -1 ; WX 501 ; N eth ; B 67 -14 549 737 ;
+C -1 ; WX 592 ; N Adieresis ; B 16 0 588 915 ;
+C -1 ; WX 547 ; N Yacute ; B 137 0 661 936 ;
+C -1 ; WX 230 ; N brokenbar ; B 66 -19 289 737 ;
+C -1 ; WX 684 ; N onehalf ; B 108 -19 704 710 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 209
+
+KPX A y -30
+KPX A w -30
+KPX A v -40
+KPX A u -30
+KPX A Y -110
+KPX A W -60
+KPX A V -80
+KPX A U -50
+KPX A T -90
+KPX A Q -40
+KPX A O -40
+KPX A G -50
+KPX A C -40
+
+KPX B U -10
+KPX B A -30
+
+KPX D period -30
+KPX D comma -30
+KPX D Y -70
+KPX D W -40
+KPX D V -40
+KPX D A -40
+
+KPX F period -100
+KPX F comma -100
+KPX F a -20
+KPX F A -80
+
+KPX J u -20
+KPX J period -20
+KPX J comma -20
+KPX J A -20
+
+KPX K y -40
+KPX K u -30
+KPX K o -35
+KPX K e -15
+KPX K O -30
+
+KPX L y -30
+KPX L quoteright -140
+KPX L quotedblright -140
+KPX L Y -120
+KPX L W -80
+KPX L V -110
+KPX L T -90
+
+KPX O period -40
+KPX O comma -40
+KPX O Y -70
+KPX O X -50
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -50
+
+KPX P period -120
+KPX P o -40
+KPX P e -30
+KPX P comma -120
+KPX P a -30
+KPX P A -100
+
+KPX Q period 20
+KPX Q comma 20
+KPX Q U -10
+
+KPX R Y -50
+KPX R W -40
+KPX R V -50
+KPX R U -20
+KPX R T -20
+KPX R O -20
+
+KPX T y -60
+KPX T w -60
+KPX T u -90
+KPX T semicolon -40
+KPX T r -80
+KPX T period -80
+KPX T o -80
+KPX T hyphen -120
+KPX T e -60
+KPX T comma -80
+KPX T colon -40
+KPX T a -80
+KPX T O -40
+KPX T A -90
+
+KPX U period -30
+KPX U comma -30
+KPX U A -50
+
+KPX V u -60
+KPX V semicolon -40
+KPX V period -120
+KPX V o -90
+KPX V hyphen -80
+KPX V e -50
+KPX V comma -120
+KPX V colon -40
+KPX V a -60
+KPX V O -50
+KPX V G -50
+KPX V A -80
+
+KPX W y -20
+KPX W u -45
+KPX W semicolon -10
+KPX W period -80
+KPX W o -60
+KPX W hyphen -40
+KPX W e -35
+KPX W comma -80
+KPX W colon -10
+KPX W a -40
+KPX W O -20
+KPX W A -60
+
+KPX Y u -100
+KPX Y semicolon -50
+KPX Y period -100
+KPX Y o -100
+KPX Y e -80
+KPX Y comma -100
+KPX Y colon -50
+KPX Y a -90
+KPX Y O -70
+KPX Y A -110
+
+KPX a y -20
+KPX a w -15
+KPX a v -15
+KPX a g -10
+
+KPX b y -20
+KPX b v -20
+KPX b u -20
+KPX b l -10
+
+KPX c y -10
+KPX c l -20
+KPX c k -20
+KPX c h -10
+
+KPX colon space -40
+
+KPX comma space -40
+KPX comma quoteright -120
+KPX comma quotedblright -120
+
+KPX d y -15
+KPX d w -15
+KPX d v -15
+KPX d d -10
+
+KPX e y -15
+KPX e x -15
+KPX e w -15
+KPX e v -15
+KPX e period 20
+KPX e comma 10
+
+KPX f quoteright 30
+KPX f quotedblright 30
+KPX f period -10
+KPX f o -20
+KPX f e -10
+KPX f comma -10
+
+KPX g g -10
+KPX g e 10
+
+KPX h y -20
+
+KPX k o -15
+
+KPX l y -15
+KPX l w -15
+
+KPX m y -30
+KPX m u -20
+
+KPX n y -20
+KPX n v -40
+KPX n u -10
+
+KPX o y -20
+KPX o x -30
+KPX o w -15
+KPX o v -20
+
+KPX p y -15
+
+KPX period space -40
+KPX period quoteright -120
+KPX period quotedblright -120
+
+KPX quotedblright space -80
+
+KPX quoteleft quoteleft -46
+
+KPX quoteright v -20
+KPX quoteright space -80
+KPX quoteright s -60
+KPX quoteright r -40
+KPX quoteright quoteright -46
+KPX quoteright l -20
+KPX quoteright d -80
+
+KPX r y 10
+KPX r v 10
+KPX r t 20
+KPX r s -15
+KPX r q -20
+KPX r period -60
+KPX r o -20
+KPX r hyphen -20
+KPX r g -15
+KPX r d -20
+KPX r comma -60
+KPX r c -20
+
+KPX s w -15
+
+KPX semicolon space -40
+
+KPX space quoteleft -60
+KPX space quotedblleft -80
+KPX space Y -120
+KPX space W -80
+KPX space V -80
+KPX space T -100
+
+KPX v period -80
+KPX v o -30
+KPX v comma -80
+KPX v a -20
+
+KPX w period -40
+KPX w o -20
+KPX w comma -40
+
+KPX x e -10
+
+KPX y period -80
+KPX y o -25
+KPX y e -10
+KPX y comma -80
+KPX y a -30
+
+KPX z e 10
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 192 186 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 192 186 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 192 186 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 192 186 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 192 186 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 192 186 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 169 186 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 169 186 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 169 186 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 169 186 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 10 186 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 10 186 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 10 186 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 10 186 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 192 186 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 215 186 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 215 186 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 215 186 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 215 186 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 186 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 169 186 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 192 186 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 192 186 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 192 186 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 192 186 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 169 186 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 169 186 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 146 186 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 92 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 108 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 114 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 114 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 114 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 114 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 114 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 114 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 92 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 114 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 114 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 114 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 114 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 92 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 92 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-Narrow-Oblique.afm b/tlt3.0/library/afm/Helvetica-Narrow-Oblique.afm
new file mode 100644
index 0000000..0a8cb32
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-Narrow-Oblique.afm
@@ -0,0 +1,613 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.
+Comment Creation Date: Thu Mar 15 11:25:48 1990
+Comment UniqueID 28389
+Comment VMusage 7572 42473
+FontName Helvetica-Narrow-Oblique
+FullName Helvetica Narrow Oblique
+FamilyName Helvetica
+Weight Medium
+ItalicAngle -12
+IsFixedPitch false
+FontBBox -139 -225 915 931
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.006
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 523
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 228 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 228 ; N exclam ; B 74 0 278 718 ;
+C 34 ; WX 291 ; N quotedbl ; B 138 463 359 718 ;
+C 35 ; WX 456 ; N numbersign ; B 60 0 517 688 ;
+C 36 ; WX 456 ; N dollar ; B 57 -115 506 775 ;
+C 37 ; WX 729 ; N percent ; B 120 -19 729 703 ;
+C 38 ; WX 547 ; N ampersand ; B 63 -15 530 718 ;
+C 39 ; WX 182 ; N quoteright ; B 124 463 254 718 ;
+C 40 ; WX 273 ; N parenleft ; B 89 -207 372 733 ;
+C 41 ; WX 273 ; N parenright ; B -7 -207 276 733 ;
+C 42 ; WX 319 ; N asterisk ; B 135 431 389 718 ;
+C 43 ; WX 479 ; N plus ; B 70 0 497 505 ;
+C 44 ; WX 228 ; N comma ; B 46 -147 175 106 ;
+C 45 ; WX 273 ; N hyphen ; B 77 232 293 322 ;
+C 46 ; WX 228 ; N period ; B 71 0 175 106 ;
+C 47 ; WX 228 ; N slash ; B -17 -19 370 737 ;
+C 48 ; WX 456 ; N zero ; B 77 -19 499 703 ;
+C 49 ; WX 456 ; N one ; B 170 0 417 703 ;
+C 50 ; WX 456 ; N two ; B 21 0 506 703 ;
+C 51 ; WX 456 ; N three ; B 61 -19 500 703 ;
+C 52 ; WX 456 ; N four ; B 50 0 472 703 ;
+C 53 ; WX 456 ; N five ; B 55 -19 509 688 ;
+C 54 ; WX 456 ; N six ; B 74 -19 504 703 ;
+C 55 ; WX 456 ; N seven ; B 112 0 549 688 ;
+C 56 ; WX 456 ; N eight ; B 60 -19 497 703 ;
+C 57 ; WX 456 ; N nine ; B 67 -19 499 703 ;
+C 58 ; WX 228 ; N colon ; B 71 0 247 516 ;
+C 59 ; WX 228 ; N semicolon ; B 46 -147 247 516 ;
+C 60 ; WX 479 ; N less ; B 77 11 526 495 ;
+C 61 ; WX 479 ; N equal ; B 52 115 515 390 ;
+C 62 ; WX 479 ; N greater ; B 41 11 490 495 ;
+C 63 ; WX 456 ; N question ; B 132 0 500 727 ;
+C 64 ; WX 832 ; N at ; B 176 -19 791 737 ;
+C 65 ; WX 547 ; N A ; B 11 0 536 718 ;
+C 66 ; WX 547 ; N B ; B 61 0 583 718 ;
+C 67 ; WX 592 ; N C ; B 88 -19 640 737 ;
+C 68 ; WX 592 ; N D ; B 66 0 626 718 ;
+C 69 ; WX 547 ; N E ; B 71 0 625 718 ;
+C 70 ; WX 501 ; N F ; B 71 0 603 718 ;
+C 71 ; WX 638 ; N G ; B 91 -19 655 737 ;
+C 72 ; WX 592 ; N H ; B 63 0 655 718 ;
+C 73 ; WX 228 ; N I ; B 75 0 279 718 ;
+C 74 ; WX 410 ; N J ; B 39 -19 476 718 ;
+C 75 ; WX 547 ; N K ; B 62 0 662 718 ;
+C 76 ; WX 456 ; N L ; B 62 0 455 718 ;
+C 77 ; WX 683 ; N M ; B 60 0 749 718 ;
+C 78 ; WX 592 ; N N ; B 62 0 655 718 ;
+C 79 ; WX 638 ; N O ; B 86 -19 677 737 ;
+C 80 ; WX 547 ; N P ; B 71 0 604 718 ;
+C 81 ; WX 638 ; N Q ; B 86 -56 677 737 ;
+C 82 ; WX 592 ; N R ; B 72 0 634 718 ;
+C 83 ; WX 547 ; N S ; B 74 -19 584 737 ;
+C 84 ; WX 501 ; N T ; B 122 0 615 718 ;
+C 85 ; WX 592 ; N U ; B 101 -19 653 718 ;
+C 86 ; WX 547 ; N V ; B 142 0 656 718 ;
+C 87 ; WX 774 ; N W ; B 138 0 886 718 ;
+C 88 ; WX 547 ; N X ; B 16 0 647 718 ;
+C 89 ; WX 547 ; N Y ; B 137 0 661 718 ;
+C 90 ; WX 501 ; N Z ; B 19 0 607 718 ;
+C 91 ; WX 228 ; N bracketleft ; B 17 -196 331 722 ;
+C 92 ; WX 228 ; N backslash ; B 115 -19 239 737 ;
+C 93 ; WX 228 ; N bracketright ; B -11 -196 302 722 ;
+C 94 ; WX 385 ; N asciicircum ; B 35 264 442 688 ;
+C 95 ; WX 456 ; N underscore ; B -22 -125 443 -75 ;
+C 96 ; WX 182 ; N quoteleft ; B 135 470 265 725 ;
+C 97 ; WX 456 ; N a ; B 50 -15 458 538 ;
+C 98 ; WX 456 ; N b ; B 48 -15 479 718 ;
+C 99 ; WX 410 ; N c ; B 61 -15 454 538 ;
+C 100 ; WX 456 ; N d ; B 69 -15 534 718 ;
+C 101 ; WX 456 ; N e ; B 69 -15 474 538 ;
+C 102 ; WX 228 ; N f ; B 71 0 341 728 ; L i fi ; L l fl ;
+C 103 ; WX 456 ; N g ; B 34 -220 500 538 ;
+C 104 ; WX 456 ; N h ; B 53 0 470 718 ;
+C 105 ; WX 182 ; N i ; B 55 0 252 718 ;
+C 106 ; WX 182 ; N j ; B -49 -210 252 718 ;
+C 107 ; WX 410 ; N k ; B 55 0 492 718 ;
+C 108 ; WX 182 ; N l ; B 55 0 252 718 ;
+C 109 ; WX 683 ; N m ; B 53 0 699 538 ;
+C 110 ; WX 456 ; N n ; B 53 0 470 538 ;
+C 111 ; WX 456 ; N o ; B 68 -14 479 538 ;
+C 112 ; WX 456 ; N p ; B 11 -207 479 538 ;
+C 113 ; WX 456 ; N q ; B 69 -207 496 538 ;
+C 114 ; WX 273 ; N r ; B 63 0 365 538 ;
+C 115 ; WX 410 ; N s ; B 52 -15 434 538 ;
+C 116 ; WX 228 ; N t ; B 84 -7 302 669 ;
+C 117 ; WX 456 ; N u ; B 77 -15 492 523 ;
+C 118 ; WX 410 ; N v ; B 98 0 495 523 ;
+C 119 ; WX 592 ; N w ; B 103 0 673 523 ;
+C 120 ; WX 410 ; N x ; B 9 0 487 523 ;
+C 121 ; WX 410 ; N y ; B 12 -214 492 523 ;
+C 122 ; WX 410 ; N z ; B 25 0 468 523 ;
+C 123 ; WX 274 ; N braceleft ; B 75 -196 365 722 ;
+C 124 ; WX 213 ; N bar ; B 74 -19 265 737 ;
+C 125 ; WX 274 ; N braceright ; B 0 -196 291 722 ;
+C 126 ; WX 479 ; N asciitilde ; B 91 180 476 326 ;
+C 161 ; WX 273 ; N exclamdown ; B 63 -195 267 523 ;
+C 162 ; WX 456 ; N cent ; B 78 -115 479 623 ;
+C 163 ; WX 456 ; N sterling ; B 40 -16 520 718 ;
+C 164 ; WX 137 ; N fraction ; B -139 -19 396 703 ;
+C 165 ; WX 456 ; N yen ; B 67 0 573 688 ;
+C 166 ; WX 456 ; N florin ; B -43 -207 537 737 ;
+C 167 ; WX 456 ; N section ; B 63 -191 479 737 ;
+C 168 ; WX 456 ; N currency ; B 49 99 530 603 ;
+C 169 ; WX 157 ; N quotesingle ; B 129 463 233 718 ;
+C 170 ; WX 273 ; N quotedblleft ; B 113 470 378 725 ;
+C 171 ; WX 456 ; N guillemotleft ; B 120 108 454 446 ;
+C 172 ; WX 273 ; N guilsinglleft ; B 112 108 279 446 ;
+C 173 ; WX 273 ; N guilsinglright ; B 91 108 257 446 ;
+C 174 ; WX 410 ; N fi ; B 71 0 481 728 ;
+C 175 ; WX 410 ; N fl ; B 71 0 479 728 ;
+C 177 ; WX 456 ; N endash ; B 42 240 510 313 ;
+C 178 ; WX 456 ; N dagger ; B 110 -159 510 718 ;
+C 179 ; WX 456 ; N daggerdbl ; B 43 -159 511 718 ;
+C 180 ; WX 228 ; N periodcentered ; B 106 190 211 315 ;
+C 182 ; WX 440 ; N paragraph ; B 103 -173 533 718 ;
+C 183 ; WX 287 ; N bullet ; B 74 202 339 517 ;
+C 184 ; WX 182 ; N quotesinglbase ; B 17 -149 147 106 ;
+C 185 ; WX 273 ; N quotedblbase ; B -5 -149 260 106 ;
+C 186 ; WX 273 ; N quotedblright ; B 102 463 367 718 ;
+C 187 ; WX 456 ; N guillemotright ; B 98 108 433 446 ;
+C 188 ; WX 820 ; N ellipsis ; B 94 0 744 106 ;
+C 189 ; WX 820 ; N perthousand ; B 72 -19 844 703 ;
+C 191 ; WX 501 ; N questiondown ; B 70 -201 438 525 ;
+C 193 ; WX 273 ; N grave ; B 139 593 276 734 ;
+C 194 ; WX 273 ; N acute ; B 203 593 390 734 ;
+C 195 ; WX 273 ; N circumflex ; B 121 593 359 734 ;
+C 196 ; WX 273 ; N tilde ; B 102 606 402 722 ;
+C 197 ; WX 273 ; N macron ; B 117 627 384 684 ;
+C 198 ; WX 273 ; N breve ; B 137 595 391 731 ;
+C 199 ; WX 273 ; N dotaccent ; B 204 604 297 706 ;
+C 200 ; WX 273 ; N dieresis ; B 138 604 363 706 ;
+C 202 ; WX 273 ; N ring ; B 175 572 330 756 ;
+C 203 ; WX 273 ; N cedilla ; B 2 -225 191 0 ;
+C 205 ; WX 273 ; N hungarumlaut ; B 129 593 463 734 ;
+C 206 ; WX 273 ; N ogonek ; B 35 -225 204 0 ;
+C 207 ; WX 273 ; N caron ; B 145 593 384 734 ;
+C 208 ; WX 820 ; N emdash ; B 42 240 875 313 ;
+C 225 ; WX 820 ; N AE ; B 7 0 899 718 ;
+C 227 ; WX 303 ; N ordfeminine ; B 82 304 368 737 ;
+C 232 ; WX 456 ; N Lslash ; B 34 0 455 718 ;
+C 233 ; WX 638 ; N Oslash ; B 35 -19 730 737 ;
+C 234 ; WX 820 ; N OE ; B 80 -19 915 737 ;
+C 235 ; WX 299 ; N ordmasculine ; B 82 304 384 737 ;
+C 241 ; WX 729 ; N ae ; B 50 -15 746 538 ;
+C 245 ; WX 228 ; N dotlessi ; B 78 0 241 523 ;
+C 248 ; WX 182 ; N lslash ; B 34 0 284 718 ;
+C 249 ; WX 501 ; N oslash ; B 24 -22 531 545 ;
+C 250 ; WX 774 ; N oe ; B 68 -15 791 538 ;
+C 251 ; WX 501 ; N germandbls ; B 55 -15 539 728 ;
+C -1 ; WX 501 ; N Zcaron ; B 19 0 607 929 ;
+C -1 ; WX 410 ; N ccedilla ; B 61 -225 454 538 ;
+C -1 ; WX 410 ; N ydieresis ; B 12 -214 492 706 ;
+C -1 ; WX 456 ; N atilde ; B 50 -15 486 722 ;
+C -1 ; WX 228 ; N icircumflex ; B 78 0 337 734 ;
+C -1 ; WX 273 ; N threesuperior ; B 74 270 358 703 ;
+C -1 ; WX 456 ; N ecircumflex ; B 69 -15 474 734 ;
+C -1 ; WX 456 ; N thorn ; B 11 -207 479 718 ;
+C -1 ; WX 456 ; N egrave ; B 69 -15 474 734 ;
+C -1 ; WX 273 ; N twosuperior ; B 52 281 368 703 ;
+C -1 ; WX 456 ; N eacute ; B 69 -15 481 734 ;
+C -1 ; WX 456 ; N otilde ; B 68 -14 494 722 ;
+C -1 ; WX 547 ; N Aacute ; B 11 0 560 929 ;
+C -1 ; WX 456 ; N ocircumflex ; B 68 -14 479 734 ;
+C -1 ; WX 410 ; N yacute ; B 12 -214 492 734 ;
+C -1 ; WX 456 ; N udieresis ; B 77 -15 492 706 ;
+C -1 ; WX 684 ; N threequarters ; B 106 -19 706 703 ;
+C -1 ; WX 456 ; N acircumflex ; B 50 -15 458 734 ;
+C -1 ; WX 592 ; N Eth ; B 57 0 626 718 ;
+C -1 ; WX 456 ; N edieresis ; B 69 -15 474 706 ;
+C -1 ; WX 456 ; N ugrave ; B 77 -15 492 734 ;
+C -1 ; WX 820 ; N trademark ; B 152 306 866 718 ;
+C -1 ; WX 456 ; N ograve ; B 68 -14 479 734 ;
+C -1 ; WX 410 ; N scaron ; B 52 -15 453 734 ;
+C -1 ; WX 228 ; N Idieresis ; B 75 0 375 901 ;
+C -1 ; WX 456 ; N uacute ; B 77 -15 492 734 ;
+C -1 ; WX 456 ; N agrave ; B 50 -15 458 734 ;
+C -1 ; WX 456 ; N ntilde ; B 53 0 486 722 ;
+C -1 ; WX 456 ; N aring ; B 50 -15 458 756 ;
+C -1 ; WX 410 ; N zcaron ; B 25 0 468 734 ;
+C -1 ; WX 228 ; N Icircumflex ; B 75 0 371 929 ;
+C -1 ; WX 592 ; N Ntilde ; B 62 0 655 917 ;
+C -1 ; WX 456 ; N ucircumflex ; B 77 -15 492 734 ;
+C -1 ; WX 547 ; N Ecircumflex ; B 71 0 625 929 ;
+C -1 ; WX 228 ; N Iacute ; B 75 0 401 929 ;
+C -1 ; WX 592 ; N Ccedilla ; B 88 -225 640 737 ;
+C -1 ; WX 638 ; N Odieresis ; B 86 -19 677 901 ;
+C -1 ; WX 547 ; N Scaron ; B 74 -19 584 929 ;
+C -1 ; WX 547 ; N Edieresis ; B 71 0 625 901 ;
+C -1 ; WX 228 ; N Igrave ; B 75 0 288 929 ;
+C -1 ; WX 456 ; N adieresis ; B 50 -15 458 706 ;
+C -1 ; WX 638 ; N Ograve ; B 86 -19 677 929 ;
+C -1 ; WX 547 ; N Egrave ; B 71 0 625 929 ;
+C -1 ; WX 547 ; N Ydieresis ; B 137 0 661 901 ;
+C -1 ; WX 604 ; N registered ; B 44 -19 687 737 ;
+C -1 ; WX 638 ; N Otilde ; B 86 -19 677 917 ;
+C -1 ; WX 684 ; N onequarter ; B 123 -19 658 703 ;
+C -1 ; WX 592 ; N Ugrave ; B 101 -19 653 929 ;
+C -1 ; WX 592 ; N Ucircumflex ; B 101 -19 653 929 ;
+C -1 ; WX 547 ; N Thorn ; B 71 0 584 718 ;
+C -1 ; WX 479 ; N divide ; B 70 -19 497 524 ;
+C -1 ; WX 547 ; N Atilde ; B 11 0 573 917 ;
+C -1 ; WX 592 ; N Uacute ; B 101 -19 653 929 ;
+C -1 ; WX 638 ; N Ocircumflex ; B 86 -19 677 929 ;
+C -1 ; WX 479 ; N logicalnot ; B 87 108 515 390 ;
+C -1 ; WX 547 ; N Aring ; B 11 0 536 931 ;
+C -1 ; WX 228 ; N idieresis ; B 78 0 341 706 ;
+C -1 ; WX 228 ; N iacute ; B 78 0 367 734 ;
+C -1 ; WX 456 ; N aacute ; B 50 -15 481 734 ;
+C -1 ; WX 479 ; N plusminus ; B 32 0 507 506 ;
+C -1 ; WX 479 ; N multiply ; B 41 0 526 506 ;
+C -1 ; WX 592 ; N Udieresis ; B 101 -19 653 901 ;
+C -1 ; WX 479 ; N minus ; B 70 216 497 289 ;
+C -1 ; WX 273 ; N onesuperior ; B 136 281 305 703 ;
+C -1 ; WX 547 ; N Eacute ; B 71 0 625 929 ;
+C -1 ; WX 547 ; N Acircumflex ; B 11 0 536 929 ;
+C -1 ; WX 604 ; N copyright ; B 44 -19 687 737 ;
+C -1 ; WX 547 ; N Agrave ; B 11 0 536 929 ;
+C -1 ; WX 456 ; N odieresis ; B 68 -14 479 706 ;
+C -1 ; WX 456 ; N oacute ; B 68 -14 481 734 ;
+C -1 ; WX 328 ; N degree ; B 138 411 384 703 ;
+C -1 ; WX 228 ; N igrave ; B 78 0 254 734 ;
+C -1 ; WX 456 ; N mu ; B 20 -207 492 523 ;
+C -1 ; WX 638 ; N Oacute ; B 86 -19 677 929 ;
+C -1 ; WX 456 ; N eth ; B 67 -15 506 737 ;
+C -1 ; WX 547 ; N Adieresis ; B 11 0 536 901 ;
+C -1 ; WX 547 ; N Yacute ; B 137 0 661 929 ;
+C -1 ; WX 213 ; N brokenbar ; B 74 -19 265 737 ;
+C -1 ; WX 684 ; N onehalf ; B 93 -19 688 703 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 250
+
+KPX A y -40
+KPX A w -40
+KPX A v -40
+KPX A u -30
+KPX A Y -100
+KPX A W -50
+KPX A V -70
+KPX A U -50
+KPX A T -120
+KPX A Q -30
+KPX A O -30
+KPX A G -30
+KPX A C -30
+
+KPX B period -20
+KPX B comma -20
+KPX B U -10
+
+KPX C period -30
+KPX C comma -30
+
+KPX D period -70
+KPX D comma -70
+KPX D Y -90
+KPX D W -40
+KPX D V -70
+KPX D A -40
+
+KPX F r -45
+KPX F period -150
+KPX F o -30
+KPX F e -30
+KPX F comma -150
+KPX F a -50
+KPX F A -80
+
+KPX J u -20
+KPX J period -30
+KPX J comma -30
+KPX J a -20
+KPX J A -20
+
+KPX K y -50
+KPX K u -30
+KPX K o -40
+KPX K e -40
+KPX K O -50
+
+KPX L y -30
+KPX L quoteright -160
+KPX L quotedblright -140
+KPX L Y -140
+KPX L W -70
+KPX L V -110
+KPX L T -110
+
+KPX O period -40
+KPX O comma -40
+KPX O Y -70
+KPX O X -60
+KPX O W -30
+KPX O V -50
+KPX O T -40
+KPX O A -20
+
+KPX P period -180
+KPX P o -50
+KPX P e -50
+KPX P comma -180
+KPX P a -40
+KPX P A -120
+
+KPX Q U -10
+
+KPX R Y -50
+KPX R W -30
+KPX R V -50
+KPX R U -40
+KPX R T -30
+KPX R O -20
+
+KPX S period -20
+KPX S comma -20
+
+KPX T y -120
+KPX T w -120
+KPX T u -120
+KPX T semicolon -20
+KPX T r -120
+KPX T period -120
+KPX T o -120
+KPX T hyphen -140
+KPX T e -120
+KPX T comma -120
+KPX T colon -20
+KPX T a -120
+KPX T O -40
+KPX T A -120
+
+KPX U period -40
+KPX U comma -40
+KPX U A -40
+
+KPX V u -70
+KPX V semicolon -40
+KPX V period -125
+KPX V o -80
+KPX V hyphen -80
+KPX V e -80
+KPX V comma -125
+KPX V colon -40
+KPX V a -70
+KPX V O -40
+KPX V G -40
+KPX V A -80
+
+KPX W y -20
+KPX W u -30
+KPX W period -80
+KPX W o -30
+KPX W hyphen -40
+KPX W e -30
+KPX W comma -80
+KPX W a -40
+KPX W O -20
+KPX W A -50
+
+KPX Y u -110
+KPX Y semicolon -60
+KPX Y period -140
+KPX Y o -140
+KPX Y i -20
+KPX Y hyphen -140
+KPX Y e -140
+KPX Y comma -140
+KPX Y colon -60
+KPX Y a -140
+KPX Y O -85
+KPX Y A -110
+
+KPX a y -30
+KPX a w -20
+KPX a v -20
+
+KPX b y -20
+KPX b v -20
+KPX b u -20
+KPX b period -40
+KPX b l -20
+KPX b comma -40
+KPX b b -10
+
+KPX c k -20
+KPX c comma -15
+
+KPX colon space -50
+
+KPX comma quoteright -100
+KPX comma quotedblright -100
+
+KPX e y -20
+KPX e x -30
+KPX e w -20
+KPX e v -30
+KPX e period -15
+KPX e comma -15
+
+KPX f quoteright 50
+KPX f quotedblright 60
+KPX f period -30
+KPX f o -30
+KPX f e -30
+KPX f dotlessi -28
+KPX f comma -30
+KPX f a -30
+
+KPX g r -10
+
+KPX h y -30
+
+KPX k o -20
+KPX k e -20
+
+KPX m y -15
+KPX m u -10
+
+KPX n y -15
+KPX n v -20
+KPX n u -10
+
+KPX o y -30
+KPX o x -30
+KPX o w -15
+KPX o v -15
+KPX o period -40
+KPX o comma -40
+
+KPX oslash z -55
+KPX oslash y -70
+KPX oslash x -85
+KPX oslash w -70
+KPX oslash v -70
+KPX oslash u -55
+KPX oslash t -55
+KPX oslash s -55
+KPX oslash r -55
+KPX oslash q -55
+KPX oslash period -95
+KPX oslash p -55
+KPX oslash o -55
+KPX oslash n -55
+KPX oslash m -55
+KPX oslash l -55
+KPX oslash k -55
+KPX oslash j -55
+KPX oslash i -55
+KPX oslash h -55
+KPX oslash g -55
+KPX oslash f -55
+KPX oslash e -55
+KPX oslash d -55
+KPX oslash comma -95
+KPX oslash c -55
+KPX oslash b -55
+KPX oslash a -55
+
+KPX p y -30
+KPX p period -35
+KPX p comma -35
+
+KPX period space -60
+KPX period quoteright -100
+KPX period quotedblright -100
+
+KPX quotedblright space -40
+
+KPX quoteleft quoteleft -57
+
+KPX quoteright space -70
+KPX quoteright s -50
+KPX quoteright r -50
+KPX quoteright quoteright -57
+KPX quoteright d -50
+
+KPX r y 30
+KPX r v 30
+KPX r u 15
+KPX r t 40
+KPX r semicolon 30
+KPX r period -50
+KPX r p 30
+KPX r n 25
+KPX r m 25
+KPX r l 15
+KPX r k 15
+KPX r i 15
+KPX r comma -50
+KPX r colon 30
+KPX r a -10
+
+KPX s w -30
+KPX s period -15
+KPX s comma -15
+
+KPX semicolon space -50
+
+KPX space quoteleft -60
+KPX space quotedblleft -30
+KPX space Y -90
+KPX space W -40
+KPX space V -50
+KPX space T -50
+
+KPX v period -80
+KPX v o -25
+KPX v e -25
+KPX v comma -80
+KPX v a -25
+
+KPX w period -60
+KPX w o -10
+KPX w e -10
+KPX w comma -60
+KPX w a -15
+
+KPX x e -30
+
+KPX y period -100
+KPX y o -20
+KPX y e -20
+KPX y comma -100
+KPX y a -20
+
+KPX z o -15
+KPX z e -15
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 171 195 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 171 195 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 171 195 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 171 195 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 167 175 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 171 195 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 160 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 171 195 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 171 195 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 171 195 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 171 195 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 12 195 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 12 195 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 12 195 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 12 195 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 202 195 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 217 195 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 217 195 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 217 195 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 217 195 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 217 195 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 171 195 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 195 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 195 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 195 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 195 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 171 195 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 171 195 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 148 195 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 92 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 92 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 92 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 92 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 92 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 69 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 92 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 92 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 92 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 92 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 69 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 69 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-Narrow.afm b/tlt3.0/library/afm/Helvetica-Narrow.afm
new file mode 100644
index 0000000..2afeb75
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-Narrow.afm
@@ -0,0 +1,613 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.
+Comment Creation Date: Thu Mar 15 11:04:57 1990
+Comment UniqueID 28380
+Comment VMusage 7572 42473
+FontName Helvetica-Narrow
+FullName Helvetica Narrow
+FamilyName Helvetica
+Weight Medium
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -136 -225 820 931
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.006
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 523
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 228 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 228 ; N exclam ; B 74 0 153 718 ;
+C 34 ; WX 291 ; N quotedbl ; B 57 463 234 718 ;
+C 35 ; WX 456 ; N numbersign ; B 23 0 434 688 ;
+C 36 ; WX 456 ; N dollar ; B 26 -115 426 775 ;
+C 37 ; WX 729 ; N percent ; B 32 -19 697 703 ;
+C 38 ; WX 547 ; N ampersand ; B 36 -15 529 718 ;
+C 39 ; WX 182 ; N quoteright ; B 43 463 129 718 ;
+C 40 ; WX 273 ; N parenleft ; B 56 -207 245 733 ;
+C 41 ; WX 273 ; N parenright ; B 28 -207 217 733 ;
+C 42 ; WX 319 ; N asterisk ; B 32 431 286 718 ;
+C 43 ; WX 479 ; N plus ; B 32 0 447 505 ;
+C 44 ; WX 228 ; N comma ; B 71 -147 157 106 ;
+C 45 ; WX 273 ; N hyphen ; B 36 232 237 322 ;
+C 46 ; WX 228 ; N period ; B 71 0 157 106 ;
+C 47 ; WX 228 ; N slash ; B -14 -19 242 737 ;
+C 48 ; WX 456 ; N zero ; B 30 -19 426 703 ;
+C 49 ; WX 456 ; N one ; B 83 0 294 703 ;
+C 50 ; WX 456 ; N two ; B 21 0 416 703 ;
+C 51 ; WX 456 ; N three ; B 28 -19 428 703 ;
+C 52 ; WX 456 ; N four ; B 20 0 429 703 ;
+C 53 ; WX 456 ; N five ; B 26 -19 421 688 ;
+C 54 ; WX 456 ; N six ; B 31 -19 425 703 ;
+C 55 ; WX 456 ; N seven ; B 30 0 429 688 ;
+C 56 ; WX 456 ; N eight ; B 31 -19 424 703 ;
+C 57 ; WX 456 ; N nine ; B 34 -19 421 703 ;
+C 58 ; WX 228 ; N colon ; B 71 0 157 516 ;
+C 59 ; WX 228 ; N semicolon ; B 71 -147 157 516 ;
+C 60 ; WX 479 ; N less ; B 39 11 440 495 ;
+C 61 ; WX 479 ; N equal ; B 32 115 447 390 ;
+C 62 ; WX 479 ; N greater ; B 39 11 440 495 ;
+C 63 ; WX 456 ; N question ; B 46 0 403 727 ;
+C 64 ; WX 832 ; N at ; B 121 -19 712 737 ;
+C 65 ; WX 547 ; N A ; B 11 0 536 718 ;
+C 66 ; WX 547 ; N B ; B 61 0 514 718 ;
+C 67 ; WX 592 ; N C ; B 36 -19 558 737 ;
+C 68 ; WX 592 ; N D ; B 66 0 553 718 ;
+C 69 ; WX 547 ; N E ; B 71 0 505 718 ;
+C 70 ; WX 501 ; N F ; B 71 0 478 718 ;
+C 71 ; WX 638 ; N G ; B 39 -19 577 737 ;
+C 72 ; WX 592 ; N H ; B 63 0 530 718 ;
+C 73 ; WX 228 ; N I ; B 75 0 154 718 ;
+C 74 ; WX 410 ; N J ; B 14 -19 351 718 ;
+C 75 ; WX 547 ; N K ; B 62 0 544 718 ;
+C 76 ; WX 456 ; N L ; B 62 0 440 718 ;
+C 77 ; WX 683 ; N M ; B 60 0 624 718 ;
+C 78 ; WX 592 ; N N ; B 62 0 530 718 ;
+C 79 ; WX 638 ; N O ; B 32 -19 606 737 ;
+C 80 ; WX 547 ; N P ; B 71 0 510 718 ;
+C 81 ; WX 638 ; N Q ; B 32 -56 606 737 ;
+C 82 ; WX 592 ; N R ; B 72 0 561 718 ;
+C 83 ; WX 547 ; N S ; B 40 -19 508 737 ;
+C 84 ; WX 501 ; N T ; B 11 0 490 718 ;
+C 85 ; WX 592 ; N U ; B 65 -19 528 718 ;
+C 86 ; WX 547 ; N V ; B 16 0 531 718 ;
+C 87 ; WX 774 ; N W ; B 13 0 761 718 ;
+C 88 ; WX 547 ; N X ; B 16 0 531 718 ;
+C 89 ; WX 547 ; N Y ; B 11 0 535 718 ;
+C 90 ; WX 501 ; N Z ; B 19 0 482 718 ;
+C 91 ; WX 228 ; N bracketleft ; B 52 -196 205 722 ;
+C 92 ; WX 228 ; N backslash ; B -14 -19 242 737 ;
+C 93 ; WX 228 ; N bracketright ; B 23 -196 176 722 ;
+C 94 ; WX 385 ; N asciicircum ; B -11 264 396 688 ;
+C 95 ; WX 456 ; N underscore ; B 0 -125 456 -75 ;
+C 96 ; WX 182 ; N quoteleft ; B 53 470 139 725 ;
+C 97 ; WX 456 ; N a ; B 30 -15 435 538 ;
+C 98 ; WX 456 ; N b ; B 48 -15 424 718 ;
+C 99 ; WX 410 ; N c ; B 25 -15 391 538 ;
+C 100 ; WX 456 ; N d ; B 29 -15 409 718 ;
+C 101 ; WX 456 ; N e ; B 33 -15 423 538 ;
+C 102 ; WX 228 ; N f ; B 11 0 215 728 ; L i fi ; L l fl ;
+C 103 ; WX 456 ; N g ; B 33 -220 409 538 ;
+C 104 ; WX 456 ; N h ; B 53 0 403 718 ;
+C 105 ; WX 182 ; N i ; B 55 0 127 718 ;
+C 106 ; WX 182 ; N j ; B -13 -210 127 718 ;
+C 107 ; WX 410 ; N k ; B 55 0 411 718 ;
+C 108 ; WX 182 ; N l ; B 55 0 127 718 ;
+C 109 ; WX 683 ; N m ; B 53 0 631 538 ;
+C 110 ; WX 456 ; N n ; B 53 0 403 538 ;
+C 111 ; WX 456 ; N o ; B 29 -14 427 538 ;
+C 112 ; WX 456 ; N p ; B 48 -207 424 538 ;
+C 113 ; WX 456 ; N q ; B 29 -207 405 538 ;
+C 114 ; WX 273 ; N r ; B 63 0 272 538 ;
+C 115 ; WX 410 ; N s ; B 26 -15 380 538 ;
+C 116 ; WX 228 ; N t ; B 11 -7 211 669 ;
+C 117 ; WX 456 ; N u ; B 56 -15 401 523 ;
+C 118 ; WX 410 ; N v ; B 7 0 403 523 ;
+C 119 ; WX 592 ; N w ; B 11 0 581 523 ;
+C 120 ; WX 410 ; N x ; B 9 0 402 523 ;
+C 121 ; WX 410 ; N y ; B 9 -214 401 523 ;
+C 122 ; WX 410 ; N z ; B 25 0 385 523 ;
+C 123 ; WX 274 ; N braceleft ; B 34 -196 239 722 ;
+C 124 ; WX 213 ; N bar ; B 77 -19 137 737 ;
+C 125 ; WX 274 ; N braceright ; B 34 -196 239 722 ;
+C 126 ; WX 479 ; N asciitilde ; B 50 180 429 326 ;
+C 161 ; WX 273 ; N exclamdown ; B 97 -195 176 523 ;
+C 162 ; WX 456 ; N cent ; B 42 -115 421 623 ;
+C 163 ; WX 456 ; N sterling ; B 27 -16 442 718 ;
+C 164 ; WX 137 ; N fraction ; B -136 -19 273 703 ;
+C 165 ; WX 456 ; N yen ; B 2 0 453 688 ;
+C 166 ; WX 456 ; N florin ; B -9 -207 411 737 ;
+C 167 ; WX 456 ; N section ; B 35 -191 420 737 ;
+C 168 ; WX 456 ; N currency ; B 23 99 433 603 ;
+C 169 ; WX 157 ; N quotesingle ; B 48 463 108 718 ;
+C 170 ; WX 273 ; N quotedblleft ; B 31 470 252 725 ;
+C 171 ; WX 456 ; N guillemotleft ; B 80 108 376 446 ;
+C 172 ; WX 273 ; N guilsinglleft ; B 72 108 201 446 ;
+C 173 ; WX 273 ; N guilsinglright ; B 72 108 201 446 ;
+C 174 ; WX 410 ; N fi ; B 11 0 356 728 ;
+C 175 ; WX 410 ; N fl ; B 11 0 354 728 ;
+C 177 ; WX 456 ; N endash ; B 0 240 456 313 ;
+C 178 ; WX 456 ; N dagger ; B 35 -159 421 718 ;
+C 179 ; WX 456 ; N daggerdbl ; B 35 -159 421 718 ;
+C 180 ; WX 228 ; N periodcentered ; B 63 190 166 315 ;
+C 182 ; WX 440 ; N paragraph ; B 15 -173 408 718 ;
+C 183 ; WX 287 ; N bullet ; B 15 202 273 517 ;
+C 184 ; WX 182 ; N quotesinglbase ; B 43 -149 129 106 ;
+C 185 ; WX 273 ; N quotedblbase ; B 21 -149 242 106 ;
+C 186 ; WX 273 ; N quotedblright ; B 21 463 242 718 ;
+C 187 ; WX 456 ; N guillemotright ; B 80 108 376 446 ;
+C 188 ; WX 820 ; N ellipsis ; B 94 0 726 106 ;
+C 189 ; WX 820 ; N perthousand ; B 6 -19 815 703 ;
+C 191 ; WX 501 ; N questiondown ; B 75 -201 432 525 ;
+C 193 ; WX 273 ; N grave ; B 11 593 173 734 ;
+C 194 ; WX 273 ; N acute ; B 100 593 262 734 ;
+C 195 ; WX 273 ; N circumflex ; B 17 593 256 734 ;
+C 196 ; WX 273 ; N tilde ; B -3 606 276 722 ;
+C 197 ; WX 273 ; N macron ; B 8 627 265 684 ;
+C 198 ; WX 273 ; N breve ; B 11 595 263 731 ;
+C 199 ; WX 273 ; N dotaccent ; B 99 604 174 706 ;
+C 200 ; WX 273 ; N dieresis ; B 33 604 240 706 ;
+C 202 ; WX 273 ; N ring ; B 61 572 212 756 ;
+C 203 ; WX 273 ; N cedilla ; B 37 -225 212 0 ;
+C 205 ; WX 273 ; N hungarumlaut ; B 25 593 335 734 ;
+C 206 ; WX 273 ; N ogonek ; B 60 -225 235 0 ;
+C 207 ; WX 273 ; N caron ; B 17 593 256 734 ;
+C 208 ; WX 820 ; N emdash ; B 0 240 820 313 ;
+C 225 ; WX 820 ; N AE ; B 7 0 780 718 ;
+C 227 ; WX 303 ; N ordfeminine ; B 20 304 284 737 ;
+C 232 ; WX 456 ; N Lslash ; B -16 0 440 718 ;
+C 233 ; WX 638 ; N Oslash ; B 32 -19 607 737 ;
+C 234 ; WX 820 ; N OE ; B 30 -19 791 737 ;
+C 235 ; WX 299 ; N ordmasculine ; B 20 304 280 737 ;
+C 241 ; WX 729 ; N ae ; B 30 -15 695 538 ;
+C 245 ; WX 228 ; N dotlessi ; B 78 0 150 523 ;
+C 248 ; WX 182 ; N lslash ; B -16 0 198 718 ;
+C 249 ; WX 501 ; N oslash ; B 23 -22 440 545 ;
+C 250 ; WX 774 ; N oe ; B 29 -15 740 538 ;
+C 251 ; WX 501 ; N germandbls ; B 55 -15 468 728 ;
+C -1 ; WX 501 ; N Zcaron ; B 19 0 482 929 ;
+C -1 ; WX 410 ; N ccedilla ; B 25 -225 391 538 ;
+C -1 ; WX 410 ; N ydieresis ; B 9 -214 401 706 ;
+C -1 ; WX 456 ; N atilde ; B 30 -15 435 722 ;
+C -1 ; WX 228 ; N icircumflex ; B -5 0 234 734 ;
+C -1 ; WX 273 ; N threesuperior ; B 4 270 266 703 ;
+C -1 ; WX 456 ; N ecircumflex ; B 33 -15 423 734 ;
+C -1 ; WX 456 ; N thorn ; B 48 -207 424 718 ;
+C -1 ; WX 456 ; N egrave ; B 33 -15 423 734 ;
+C -1 ; WX 273 ; N twosuperior ; B 3 281 265 703 ;
+C -1 ; WX 456 ; N eacute ; B 33 -15 423 734 ;
+C -1 ; WX 456 ; N otilde ; B 29 -14 427 722 ;
+C -1 ; WX 547 ; N Aacute ; B 11 0 536 929 ;
+C -1 ; WX 456 ; N ocircumflex ; B 29 -14 427 734 ;
+C -1 ; WX 410 ; N yacute ; B 9 -214 401 734 ;
+C -1 ; WX 456 ; N udieresis ; B 56 -15 401 706 ;
+C -1 ; WX 684 ; N threequarters ; B 37 -19 664 703 ;
+C -1 ; WX 456 ; N acircumflex ; B 30 -15 435 734 ;
+C -1 ; WX 592 ; N Eth ; B 0 0 553 718 ;
+C -1 ; WX 456 ; N edieresis ; B 33 -15 423 706 ;
+C -1 ; WX 456 ; N ugrave ; B 56 -15 401 734 ;
+C -1 ; WX 820 ; N trademark ; B 38 306 740 718 ;
+C -1 ; WX 456 ; N ograve ; B 29 -14 427 734 ;
+C -1 ; WX 410 ; N scaron ; B 26 -15 380 734 ;
+C -1 ; WX 228 ; N Idieresis ; B 11 0 218 901 ;
+C -1 ; WX 456 ; N uacute ; B 56 -15 401 734 ;
+C -1 ; WX 456 ; N agrave ; B 30 -15 435 734 ;
+C -1 ; WX 456 ; N ntilde ; B 53 0 403 722 ;
+C -1 ; WX 456 ; N aring ; B 30 -15 435 756 ;
+C -1 ; WX 410 ; N zcaron ; B 25 0 385 734 ;
+C -1 ; WX 228 ; N Icircumflex ; B -5 0 234 929 ;
+C -1 ; WX 592 ; N Ntilde ; B 62 0 530 917 ;
+C -1 ; WX 456 ; N ucircumflex ; B 56 -15 401 734 ;
+C -1 ; WX 547 ; N Ecircumflex ; B 71 0 505 929 ;
+C -1 ; WX 228 ; N Iacute ; B 75 0 239 929 ;
+C -1 ; WX 592 ; N Ccedilla ; B 36 -225 558 737 ;
+C -1 ; WX 638 ; N Odieresis ; B 32 -19 606 901 ;
+C -1 ; WX 547 ; N Scaron ; B 40 -19 508 929 ;
+C -1 ; WX 547 ; N Edieresis ; B 71 0 505 901 ;
+C -1 ; WX 228 ; N Igrave ; B -11 0 154 929 ;
+C -1 ; WX 456 ; N adieresis ; B 30 -15 435 706 ;
+C -1 ; WX 638 ; N Ograve ; B 32 -19 606 929 ;
+C -1 ; WX 547 ; N Egrave ; B 71 0 505 929 ;
+C -1 ; WX 547 ; N Ydieresis ; B 11 0 535 901 ;
+C -1 ; WX 604 ; N registered ; B -11 -19 617 737 ;
+C -1 ; WX 638 ; N Otilde ; B 32 -19 606 917 ;
+C -1 ; WX 684 ; N onequarter ; B 60 -19 620 703 ;
+C -1 ; WX 592 ; N Ugrave ; B 65 -19 528 929 ;
+C -1 ; WX 592 ; N Ucircumflex ; B 65 -19 528 929 ;
+C -1 ; WX 547 ; N Thorn ; B 71 0 510 718 ;
+C -1 ; WX 479 ; N divide ; B 32 -19 447 524 ;
+C -1 ; WX 547 ; N Atilde ; B 11 0 536 917 ;
+C -1 ; WX 592 ; N Uacute ; B 65 -19 528 929 ;
+C -1 ; WX 638 ; N Ocircumflex ; B 32 -19 606 929 ;
+C -1 ; WX 479 ; N logicalnot ; B 32 108 447 390 ;
+C -1 ; WX 547 ; N Aring ; B 11 0 536 931 ;
+C -1 ; WX 228 ; N idieresis ; B 11 0 218 706 ;
+C -1 ; WX 228 ; N iacute ; B 78 0 239 734 ;
+C -1 ; WX 456 ; N aacute ; B 30 -15 435 734 ;
+C -1 ; WX 479 ; N plusminus ; B 32 0 447 506 ;
+C -1 ; WX 479 ; N multiply ; B 32 0 447 506 ;
+C -1 ; WX 592 ; N Udieresis ; B 65 -19 528 901 ;
+C -1 ; WX 479 ; N minus ; B 32 216 447 289 ;
+C -1 ; WX 273 ; N onesuperior ; B 35 281 182 703 ;
+C -1 ; WX 547 ; N Eacute ; B 71 0 505 929 ;
+C -1 ; WX 547 ; N Acircumflex ; B 11 0 536 929 ;
+C -1 ; WX 604 ; N copyright ; B -11 -19 617 737 ;
+C -1 ; WX 547 ; N Agrave ; B 11 0 536 929 ;
+C -1 ; WX 456 ; N odieresis ; B 29 -14 427 706 ;
+C -1 ; WX 456 ; N oacute ; B 29 -14 427 734 ;
+C -1 ; WX 328 ; N degree ; B 44 411 284 703 ;
+C -1 ; WX 228 ; N igrave ; B -11 0 151 734 ;
+C -1 ; WX 456 ; N mu ; B 56 -207 401 523 ;
+C -1 ; WX 638 ; N Oacute ; B 32 -19 606 929 ;
+C -1 ; WX 456 ; N eth ; B 29 -15 428 737 ;
+C -1 ; WX 547 ; N Adieresis ; B 11 0 536 901 ;
+C -1 ; WX 547 ; N Yacute ; B 11 0 535 929 ;
+C -1 ; WX 213 ; N brokenbar ; B 77 -19 137 737 ;
+C -1 ; WX 684 ; N onehalf ; B 35 -19 634 703 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 250
+
+KPX A y -32
+KPX A w -32
+KPX A v -32
+KPX A u -24
+KPX A Y -81
+KPX A W -40
+KPX A V -56
+KPX A U -40
+KPX A T -97
+KPX A Q -24
+KPX A O -24
+KPX A G -24
+KPX A C -24
+
+KPX B period -15
+KPX B comma -15
+KPX B U -7
+
+KPX C period -24
+KPX C comma -24
+
+KPX D period -56
+KPX D comma -56
+KPX D Y -73
+KPX D W -32
+KPX D V -56
+KPX D A -32
+
+KPX F r -36
+KPX F period -122
+KPX F o -24
+KPX F e -24
+KPX F comma -122
+KPX F a -40
+KPX F A -65
+
+KPX J u -15
+KPX J period -24
+KPX J comma -24
+KPX J a -15
+KPX J A -15
+
+KPX K y -40
+KPX K u -24
+KPX K o -32
+KPX K e -32
+KPX K O -40
+
+KPX L y -24
+KPX L quoteright -130
+KPX L quotedblright -114
+KPX L Y -114
+KPX L W -56
+KPX L V -89
+KPX L T -89
+
+KPX O period -32
+KPX O comma -32
+KPX O Y -56
+KPX O X -48
+KPX O W -24
+KPX O V -40
+KPX O T -32
+KPX O A -15
+
+KPX P period -147
+KPX P o -40
+KPX P e -40
+KPX P comma -147
+KPX P a -32
+KPX P A -97
+
+KPX Q U -7
+
+KPX R Y -40
+KPX R W -24
+KPX R V -40
+KPX R U -32
+KPX R T -24
+KPX R O -15
+
+KPX S period -15
+KPX S comma -15
+
+KPX T y -97
+KPX T w -97
+KPX T u -97
+KPX T semicolon -15
+KPX T r -97
+KPX T period -97
+KPX T o -97
+KPX T hyphen -114
+KPX T e -97
+KPX T comma -97
+KPX T colon -15
+KPX T a -97
+KPX T O -32
+KPX T A -97
+
+KPX U period -32
+KPX U comma -32
+KPX U A -32
+
+KPX V u -56
+KPX V semicolon -32
+KPX V period -102
+KPX V o -65
+KPX V hyphen -65
+KPX V e -65
+KPX V comma -102
+KPX V colon -32
+KPX V a -56
+KPX V O -32
+KPX V G -32
+KPX V A -65
+
+KPX W y -15
+KPX W u -24
+KPX W period -65
+KPX W o -24
+KPX W hyphen -32
+KPX W e -24
+KPX W comma -65
+KPX W a -32
+KPX W O -15
+KPX W A -40
+
+KPX Y u -89
+KPX Y semicolon -48
+KPX Y period -114
+KPX Y o -114
+KPX Y i -15
+KPX Y hyphen -114
+KPX Y e -114
+KPX Y comma -114
+KPX Y colon -48
+KPX Y a -114
+KPX Y O -69
+KPX Y A -89
+
+KPX a y -24
+KPX a w -15
+KPX a v -15
+
+KPX b y -15
+KPX b v -15
+KPX b u -15
+KPX b period -32
+KPX b l -15
+KPX b comma -32
+KPX b b -7
+
+KPX c k -15
+KPX c comma -11
+
+KPX colon space -40
+
+KPX comma quoteright -81
+KPX comma quotedblright -81
+
+KPX e y -15
+KPX e x -24
+KPX e w -15
+KPX e v -24
+KPX e period -11
+KPX e comma -11
+
+KPX f quoteright 41
+KPX f quotedblright 49
+KPX f period -24
+KPX f o -24
+KPX f e -24
+KPX f dotlessi -22
+KPX f comma -24
+KPX f a -24
+
+KPX g r -7
+
+KPX h y -24
+
+KPX k o -15
+KPX k e -15
+
+KPX m y -11
+KPX m u -7
+
+KPX n y -11
+KPX n v -15
+KPX n u -7
+
+KPX o y -24
+KPX o x -24
+KPX o w -11
+KPX o v -11
+KPX o period -32
+KPX o comma -32
+
+KPX oslash z -44
+KPX oslash y -56
+KPX oslash x -69
+KPX oslash w -56
+KPX oslash v -56
+KPX oslash u -44
+KPX oslash t -44
+KPX oslash s -44
+KPX oslash r -44
+KPX oslash q -44
+KPX oslash period -77
+KPX oslash p -44
+KPX oslash o -44
+KPX oslash n -44
+KPX oslash m -44
+KPX oslash l -44
+KPX oslash k -44
+KPX oslash j -44
+KPX oslash i -44
+KPX oslash h -44
+KPX oslash g -44
+KPX oslash f -44
+KPX oslash e -44
+KPX oslash d -44
+KPX oslash comma -77
+KPX oslash c -44
+KPX oslash b -44
+KPX oslash a -44
+
+KPX p y -24
+KPX p period -28
+KPX p comma -28
+
+KPX period space -48
+KPX period quoteright -81
+KPX period quotedblright -81
+
+KPX quotedblright space -32
+
+KPX quoteleft quoteleft -46
+
+KPX quoteright space -56
+KPX quoteright s -40
+KPX quoteright r -40
+KPX quoteright quoteright -46
+KPX quoteright d -40
+
+KPX r y 25
+KPX r v 25
+KPX r u 12
+KPX r t 33
+KPX r semicolon 25
+KPX r period -40
+KPX r p 25
+KPX r n 21
+KPX r m 21
+KPX r l 12
+KPX r k 12
+KPX r i 12
+KPX r comma -40
+KPX r colon 25
+KPX r a -7
+
+KPX s w -24
+KPX s period -11
+KPX s comma -11
+
+KPX semicolon space -40
+
+KPX space quoteleft -48
+KPX space quotedblleft -24
+KPX space Y -73
+KPX space W -32
+KPX space V -40
+KPX space T -40
+
+KPX v period -65
+KPX v o -20
+KPX v e -20
+KPX v comma -65
+KPX v a -20
+
+KPX w period -48
+KPX w o -7
+KPX w e -7
+KPX w comma -48
+KPX w a -11
+
+KPX x e -24
+
+KPX y period -81
+KPX y o -15
+KPX y e -15
+KPX y comma -81
+KPX y a -15
+
+KPX z o -11
+KPX z e -11
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 137 195 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 137 195 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 137 195 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 137 195 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 137 175 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 137 195 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 160 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 137 195 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 137 195 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 137 195 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 137 195 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -22 195 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -22 195 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -22 195 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -22 195 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 168 195 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 183 195 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 183 195 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 183 195 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 183 195 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 183 195 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 137 195 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 195 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 160 195 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 160 195 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 160 195 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 137 195 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 137 195 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 114 195 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 92 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 92 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 92 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 92 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 92 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 69 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 92 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 92 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 92 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 92 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 69 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 69 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica-Oblique.afm b/tlt3.0/library/afm/Helvetica-Oblique.afm
new file mode 100644
index 0000000..4f0476f
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica-Oblique.afm
@@ -0,0 +1,613 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.
+Comment Creation Date: Thu Mar 15 10:24:18 1990
+Comment UniqueID 28362
+Comment VMusage 7572 42473
+FontName Helvetica-Oblique
+FullName Helvetica Oblique
+FamilyName Helvetica
+Weight Medium
+ItalicAngle -12
+IsFixedPitch false
+FontBBox -170 -225 1116 931
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.006
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 523
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 90 0 340 718 ;
+C 34 ; WX 355 ; N quotedbl ; B 168 463 438 718 ;
+C 35 ; WX 556 ; N numbersign ; B 73 0 631 688 ;
+C 36 ; WX 556 ; N dollar ; B 69 -115 617 775 ;
+C 37 ; WX 889 ; N percent ; B 147 -19 889 703 ;
+C 38 ; WX 667 ; N ampersand ; B 77 -15 647 718 ;
+C 39 ; WX 222 ; N quoteright ; B 151 463 310 718 ;
+C 40 ; WX 333 ; N parenleft ; B 108 -207 454 733 ;
+C 41 ; WX 333 ; N parenright ; B -9 -207 337 733 ;
+C 42 ; WX 389 ; N asterisk ; B 165 431 475 718 ;
+C 43 ; WX 584 ; N plus ; B 85 0 606 505 ;
+C 44 ; WX 278 ; N comma ; B 56 -147 214 106 ;
+C 45 ; WX 333 ; N hyphen ; B 93 232 357 322 ;
+C 46 ; WX 278 ; N period ; B 87 0 214 106 ;
+C 47 ; WX 278 ; N slash ; B -21 -19 452 737 ;
+C 48 ; WX 556 ; N zero ; B 93 -19 608 703 ;
+C 49 ; WX 556 ; N one ; B 207 0 508 703 ;
+C 50 ; WX 556 ; N two ; B 26 0 617 703 ;
+C 51 ; WX 556 ; N three ; B 75 -19 610 703 ;
+C 52 ; WX 556 ; N four ; B 61 0 576 703 ;
+C 53 ; WX 556 ; N five ; B 68 -19 621 688 ;
+C 54 ; WX 556 ; N six ; B 91 -19 615 703 ;
+C 55 ; WX 556 ; N seven ; B 137 0 669 688 ;
+C 56 ; WX 556 ; N eight ; B 74 -19 607 703 ;
+C 57 ; WX 556 ; N nine ; B 82 -19 609 703 ;
+C 58 ; WX 278 ; N colon ; B 87 0 301 516 ;
+C 59 ; WX 278 ; N semicolon ; B 56 -147 301 516 ;
+C 60 ; WX 584 ; N less ; B 94 11 641 495 ;
+C 61 ; WX 584 ; N equal ; B 63 115 628 390 ;
+C 62 ; WX 584 ; N greater ; B 50 11 597 495 ;
+C 63 ; WX 556 ; N question ; B 161 0 610 727 ;
+C 64 ; WX 1015 ; N at ; B 215 -19 965 737 ;
+C 65 ; WX 667 ; N A ; B 14 0 654 718 ;
+C 66 ; WX 667 ; N B ; B 74 0 712 718 ;
+C 67 ; WX 722 ; N C ; B 108 -19 782 737 ;
+C 68 ; WX 722 ; N D ; B 81 0 764 718 ;
+C 69 ; WX 667 ; N E ; B 86 0 762 718 ;
+C 70 ; WX 611 ; N F ; B 86 0 736 718 ;
+C 71 ; WX 778 ; N G ; B 111 -19 799 737 ;
+C 72 ; WX 722 ; N H ; B 77 0 799 718 ;
+C 73 ; WX 278 ; N I ; B 91 0 341 718 ;
+C 74 ; WX 500 ; N J ; B 47 -19 581 718 ;
+C 75 ; WX 667 ; N K ; B 76 0 808 718 ;
+C 76 ; WX 556 ; N L ; B 76 0 555 718 ;
+C 77 ; WX 833 ; N M ; B 73 0 914 718 ;
+C 78 ; WX 722 ; N N ; B 76 0 799 718 ;
+C 79 ; WX 778 ; N O ; B 105 -19 826 737 ;
+C 80 ; WX 667 ; N P ; B 86 0 737 718 ;
+C 81 ; WX 778 ; N Q ; B 105 -56 826 737 ;
+C 82 ; WX 722 ; N R ; B 88 0 773 718 ;
+C 83 ; WX 667 ; N S ; B 90 -19 713 737 ;
+C 84 ; WX 611 ; N T ; B 148 0 750 718 ;
+C 85 ; WX 722 ; N U ; B 123 -19 797 718 ;
+C 86 ; WX 667 ; N V ; B 173 0 800 718 ;
+C 87 ; WX 944 ; N W ; B 169 0 1081 718 ;
+C 88 ; WX 667 ; N X ; B 19 0 790 718 ;
+C 89 ; WX 667 ; N Y ; B 167 0 806 718 ;
+C 90 ; WX 611 ; N Z ; B 23 0 741 718 ;
+C 91 ; WX 278 ; N bracketleft ; B 21 -196 403 722 ;
+C 92 ; WX 278 ; N backslash ; B 140 -19 291 737 ;
+C 93 ; WX 278 ; N bracketright ; B -14 -196 368 722 ;
+C 94 ; WX 469 ; N asciicircum ; B 42 264 539 688 ;
+C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ;
+C 96 ; WX 222 ; N quoteleft ; B 165 470 323 725 ;
+C 97 ; WX 556 ; N a ; B 61 -15 559 538 ;
+C 98 ; WX 556 ; N b ; B 58 -15 584 718 ;
+C 99 ; WX 500 ; N c ; B 74 -15 553 538 ;
+C 100 ; WX 556 ; N d ; B 84 -15 652 718 ;
+C 101 ; WX 556 ; N e ; B 84 -15 578 538 ;
+C 102 ; WX 278 ; N f ; B 86 0 416 728 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 42 -220 610 538 ;
+C 104 ; WX 556 ; N h ; B 65 0 573 718 ;
+C 105 ; WX 222 ; N i ; B 67 0 308 718 ;
+C 106 ; WX 222 ; N j ; B -60 -210 308 718 ;
+C 107 ; WX 500 ; N k ; B 67 0 600 718 ;
+C 108 ; WX 222 ; N l ; B 67 0 308 718 ;
+C 109 ; WX 833 ; N m ; B 65 0 852 538 ;
+C 110 ; WX 556 ; N n ; B 65 0 573 538 ;
+C 111 ; WX 556 ; N o ; B 83 -14 585 538 ;
+C 112 ; WX 556 ; N p ; B 14 -207 584 538 ;
+C 113 ; WX 556 ; N q ; B 84 -207 605 538 ;
+C 114 ; WX 333 ; N r ; B 77 0 446 538 ;
+C 115 ; WX 500 ; N s ; B 63 -15 529 538 ;
+C 116 ; WX 278 ; N t ; B 102 -7 368 669 ;
+C 117 ; WX 556 ; N u ; B 94 -15 600 523 ;
+C 118 ; WX 500 ; N v ; B 119 0 603 523 ;
+C 119 ; WX 722 ; N w ; B 125 0 820 523 ;
+C 120 ; WX 500 ; N x ; B 11 0 594 523 ;
+C 121 ; WX 500 ; N y ; B 15 -214 600 523 ;
+C 122 ; WX 500 ; N z ; B 31 0 571 523 ;
+C 123 ; WX 334 ; N braceleft ; B 92 -196 445 722 ;
+C 124 ; WX 260 ; N bar ; B 90 -19 324 737 ;
+C 125 ; WX 334 ; N braceright ; B 0 -196 354 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 111 180 580 326 ;
+C 161 ; WX 333 ; N exclamdown ; B 77 -195 326 523 ;
+C 162 ; WX 556 ; N cent ; B 95 -115 584 623 ;
+C 163 ; WX 556 ; N sterling ; B 49 -16 634 718 ;
+C 164 ; WX 167 ; N fraction ; B -170 -19 482 703 ;
+C 165 ; WX 556 ; N yen ; B 81 0 699 688 ;
+C 166 ; WX 556 ; N florin ; B -52 -207 654 737 ;
+C 167 ; WX 556 ; N section ; B 76 -191 584 737 ;
+C 168 ; WX 556 ; N currency ; B 60 99 646 603 ;
+C 169 ; WX 191 ; N quotesingle ; B 157 463 285 718 ;
+C 170 ; WX 333 ; N quotedblleft ; B 138 470 461 725 ;
+C 171 ; WX 556 ; N guillemotleft ; B 146 108 554 446 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 137 108 340 446 ;
+C 173 ; WX 333 ; N guilsinglright ; B 111 108 314 446 ;
+C 174 ; WX 500 ; N fi ; B 86 0 587 728 ;
+C 175 ; WX 500 ; N fl ; B 86 0 585 728 ;
+C 177 ; WX 556 ; N endash ; B 51 240 623 313 ;
+C 178 ; WX 556 ; N dagger ; B 135 -159 622 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 52 -159 623 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 129 190 257 315 ;
+C 182 ; WX 537 ; N paragraph ; B 126 -173 650 718 ;
+C 183 ; WX 350 ; N bullet ; B 91 202 413 517 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 21 -149 180 106 ;
+C 185 ; WX 333 ; N quotedblbase ; B -6 -149 318 106 ;
+C 186 ; WX 333 ; N quotedblright ; B 124 463 448 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 120 108 528 446 ;
+C 188 ; WX 1000 ; N ellipsis ; B 115 0 908 106 ;
+C 189 ; WX 1000 ; N perthousand ; B 88 -19 1029 703 ;
+C 191 ; WX 611 ; N questiondown ; B 85 -201 534 525 ;
+C 193 ; WX 333 ; N grave ; B 170 593 337 734 ;
+C 194 ; WX 333 ; N acute ; B 248 593 475 734 ;
+C 195 ; WX 333 ; N circumflex ; B 147 593 438 734 ;
+C 196 ; WX 333 ; N tilde ; B 125 606 490 722 ;
+C 197 ; WX 333 ; N macron ; B 143 627 468 684 ;
+C 198 ; WX 333 ; N breve ; B 167 595 476 731 ;
+C 199 ; WX 333 ; N dotaccent ; B 249 604 362 706 ;
+C 200 ; WX 333 ; N dieresis ; B 168 604 443 706 ;
+C 202 ; WX 333 ; N ring ; B 214 572 402 756 ;
+C 203 ; WX 333 ; N cedilla ; B 2 -225 232 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 157 593 565 734 ;
+C 206 ; WX 333 ; N ogonek ; B 43 -225 249 0 ;
+C 207 ; WX 333 ; N caron ; B 177 593 468 734 ;
+C 208 ; WX 1000 ; N emdash ; B 51 240 1067 313 ;
+C 225 ; WX 1000 ; N AE ; B 8 0 1097 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 100 304 449 737 ;
+C 232 ; WX 556 ; N Lslash ; B 41 0 555 718 ;
+C 233 ; WX 778 ; N Oslash ; B 43 -19 890 737 ;
+C 234 ; WX 1000 ; N OE ; B 98 -19 1116 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 100 304 468 737 ;
+C 241 ; WX 889 ; N ae ; B 61 -15 909 538 ;
+C 245 ; WX 278 ; N dotlessi ; B 95 0 294 523 ;
+C 248 ; WX 222 ; N lslash ; B 41 0 347 718 ;
+C 249 ; WX 611 ; N oslash ; B 29 -22 647 545 ;
+C 250 ; WX 944 ; N oe ; B 83 -15 964 538 ;
+C 251 ; WX 611 ; N germandbls ; B 67 -15 658 728 ;
+C -1 ; WX 611 ; N Zcaron ; B 23 0 741 929 ;
+C -1 ; WX 500 ; N ccedilla ; B 74 -225 553 538 ;
+C -1 ; WX 500 ; N ydieresis ; B 15 -214 600 706 ;
+C -1 ; WX 556 ; N atilde ; B 61 -15 592 722 ;
+C -1 ; WX 278 ; N icircumflex ; B 95 0 411 734 ;
+C -1 ; WX 333 ; N threesuperior ; B 90 270 436 703 ;
+C -1 ; WX 556 ; N ecircumflex ; B 84 -15 578 734 ;
+C -1 ; WX 556 ; N thorn ; B 14 -207 584 718 ;
+C -1 ; WX 556 ; N egrave ; B 84 -15 578 734 ;
+C -1 ; WX 333 ; N twosuperior ; B 64 281 449 703 ;
+C -1 ; WX 556 ; N eacute ; B 84 -15 587 734 ;
+C -1 ; WX 556 ; N otilde ; B 83 -14 602 722 ;
+C -1 ; WX 667 ; N Aacute ; B 14 0 683 929 ;
+C -1 ; WX 556 ; N ocircumflex ; B 83 -14 585 734 ;
+C -1 ; WX 500 ; N yacute ; B 15 -214 600 734 ;
+C -1 ; WX 556 ; N udieresis ; B 94 -15 600 706 ;
+C -1 ; WX 834 ; N threequarters ; B 130 -19 861 703 ;
+C -1 ; WX 556 ; N acircumflex ; B 61 -15 559 734 ;
+C -1 ; WX 722 ; N Eth ; B 69 0 764 718 ;
+C -1 ; WX 556 ; N edieresis ; B 84 -15 578 706 ;
+C -1 ; WX 556 ; N ugrave ; B 94 -15 600 734 ;
+C -1 ; WX 1000 ; N trademark ; B 186 306 1056 718 ;
+C -1 ; WX 556 ; N ograve ; B 83 -14 585 734 ;
+C -1 ; WX 500 ; N scaron ; B 63 -15 552 734 ;
+C -1 ; WX 278 ; N Idieresis ; B 91 0 458 901 ;
+C -1 ; WX 556 ; N uacute ; B 94 -15 600 734 ;
+C -1 ; WX 556 ; N agrave ; B 61 -15 559 734 ;
+C -1 ; WX 556 ; N ntilde ; B 65 0 592 722 ;
+C -1 ; WX 556 ; N aring ; B 61 -15 559 756 ;
+C -1 ; WX 500 ; N zcaron ; B 31 0 571 734 ;
+C -1 ; WX 278 ; N Icircumflex ; B 91 0 452 929 ;
+C -1 ; WX 722 ; N Ntilde ; B 76 0 799 917 ;
+C -1 ; WX 556 ; N ucircumflex ; B 94 -15 600 734 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 86 0 762 929 ;
+C -1 ; WX 278 ; N Iacute ; B 91 0 489 929 ;
+C -1 ; WX 722 ; N Ccedilla ; B 108 -225 782 737 ;
+C -1 ; WX 778 ; N Odieresis ; B 105 -19 826 901 ;
+C -1 ; WX 667 ; N Scaron ; B 90 -19 713 929 ;
+C -1 ; WX 667 ; N Edieresis ; B 86 0 762 901 ;
+C -1 ; WX 278 ; N Igrave ; B 91 0 351 929 ;
+C -1 ; WX 556 ; N adieresis ; B 61 -15 559 706 ;
+C -1 ; WX 778 ; N Ograve ; B 105 -19 826 929 ;
+C -1 ; WX 667 ; N Egrave ; B 86 0 762 929 ;
+C -1 ; WX 667 ; N Ydieresis ; B 167 0 806 901 ;
+C -1 ; WX 737 ; N registered ; B 54 -19 837 737 ;
+C -1 ; WX 778 ; N Otilde ; B 105 -19 826 917 ;
+C -1 ; WX 834 ; N onequarter ; B 150 -19 802 703 ;
+C -1 ; WX 722 ; N Ugrave ; B 123 -19 797 929 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 123 -19 797 929 ;
+C -1 ; WX 667 ; N Thorn ; B 86 0 712 718 ;
+C -1 ; WX 584 ; N divide ; B 85 -19 606 524 ;
+C -1 ; WX 667 ; N Atilde ; B 14 0 699 917 ;
+C -1 ; WX 722 ; N Uacute ; B 123 -19 797 929 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 105 -19 826 929 ;
+C -1 ; WX 584 ; N logicalnot ; B 106 108 628 390 ;
+C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ;
+C -1 ; WX 278 ; N idieresis ; B 95 0 416 706 ;
+C -1 ; WX 278 ; N iacute ; B 95 0 448 734 ;
+C -1 ; WX 556 ; N aacute ; B 61 -15 587 734 ;
+C -1 ; WX 584 ; N plusminus ; B 39 0 618 506 ;
+C -1 ; WX 584 ; N multiply ; B 50 0 642 506 ;
+C -1 ; WX 722 ; N Udieresis ; B 123 -19 797 901 ;
+C -1 ; WX 584 ; N minus ; B 85 216 606 289 ;
+C -1 ; WX 333 ; N onesuperior ; B 166 281 371 703 ;
+C -1 ; WX 667 ; N Eacute ; B 86 0 762 929 ;
+C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ;
+C -1 ; WX 737 ; N copyright ; B 54 -19 837 737 ;
+C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ;
+C -1 ; WX 556 ; N odieresis ; B 83 -14 585 706 ;
+C -1 ; WX 556 ; N oacute ; B 83 -14 587 734 ;
+C -1 ; WX 400 ; N degree ; B 169 411 468 703 ;
+C -1 ; WX 278 ; N igrave ; B 95 0 310 734 ;
+C -1 ; WX 556 ; N mu ; B 24 -207 600 523 ;
+C -1 ; WX 778 ; N Oacute ; B 105 -19 826 929 ;
+C -1 ; WX 556 ; N eth ; B 81 -15 617 737 ;
+C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ;
+C -1 ; WX 667 ; N Yacute ; B 167 0 806 929 ;
+C -1 ; WX 260 ; N brokenbar ; B 90 -19 324 737 ;
+C -1 ; WX 834 ; N onehalf ; B 114 -19 839 703 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 250
+
+KPX A y -40
+KPX A w -40
+KPX A v -40
+KPX A u -30
+KPX A Y -100
+KPX A W -50
+KPX A V -70
+KPX A U -50
+KPX A T -120
+KPX A Q -30
+KPX A O -30
+KPX A G -30
+KPX A C -30
+
+KPX B period -20
+KPX B comma -20
+KPX B U -10
+
+KPX C period -30
+KPX C comma -30
+
+KPX D period -70
+KPX D comma -70
+KPX D Y -90
+KPX D W -40
+KPX D V -70
+KPX D A -40
+
+KPX F r -45
+KPX F period -150
+KPX F o -30
+KPX F e -30
+KPX F comma -150
+KPX F a -50
+KPX F A -80
+
+KPX J u -20
+KPX J period -30
+KPX J comma -30
+KPX J a -20
+KPX J A -20
+
+KPX K y -50
+KPX K u -30
+KPX K o -40
+KPX K e -40
+KPX K O -50
+
+KPX L y -30
+KPX L quoteright -160
+KPX L quotedblright -140
+KPX L Y -140
+KPX L W -70
+KPX L V -110
+KPX L T -110
+
+KPX O period -40
+KPX O comma -40
+KPX O Y -70
+KPX O X -60
+KPX O W -30
+KPX O V -50
+KPX O T -40
+KPX O A -20
+
+KPX P period -180
+KPX P o -50
+KPX P e -50
+KPX P comma -180
+KPX P a -40
+KPX P A -120
+
+KPX Q U -10
+
+KPX R Y -50
+KPX R W -30
+KPX R V -50
+KPX R U -40
+KPX R T -30
+KPX R O -20
+
+KPX S period -20
+KPX S comma -20
+
+KPX T y -120
+KPX T w -120
+KPX T u -120
+KPX T semicolon -20
+KPX T r -120
+KPX T period -120
+KPX T o -120
+KPX T hyphen -140
+KPX T e -120
+KPX T comma -120
+KPX T colon -20
+KPX T a -120
+KPX T O -40
+KPX T A -120
+
+KPX U period -40
+KPX U comma -40
+KPX U A -40
+
+KPX V u -70
+KPX V semicolon -40
+KPX V period -125
+KPX V o -80
+KPX V hyphen -80
+KPX V e -80
+KPX V comma -125
+KPX V colon -40
+KPX V a -70
+KPX V O -40
+KPX V G -40
+KPX V A -80
+
+KPX W y -20
+KPX W u -30
+KPX W period -80
+KPX W o -30
+KPX W hyphen -40
+KPX W e -30
+KPX W comma -80
+KPX W a -40
+KPX W O -20
+KPX W A -50
+
+KPX Y u -110
+KPX Y semicolon -60
+KPX Y period -140
+KPX Y o -140
+KPX Y i -20
+KPX Y hyphen -140
+KPX Y e -140
+KPX Y comma -140
+KPX Y colon -60
+KPX Y a -140
+KPX Y O -85
+KPX Y A -110
+
+KPX a y -30
+KPX a w -20
+KPX a v -20
+
+KPX b y -20
+KPX b v -20
+KPX b u -20
+KPX b period -40
+KPX b l -20
+KPX b comma -40
+KPX b b -10
+
+KPX c k -20
+KPX c comma -15
+
+KPX colon space -50
+
+KPX comma quoteright -100
+KPX comma quotedblright -100
+
+KPX e y -20
+KPX e x -30
+KPX e w -20
+KPX e v -30
+KPX e period -15
+KPX e comma -15
+
+KPX f quoteright 50
+KPX f quotedblright 60
+KPX f period -30
+KPX f o -30
+KPX f e -30
+KPX f dotlessi -28
+KPX f comma -30
+KPX f a -30
+
+KPX g r -10
+
+KPX h y -30
+
+KPX k o -20
+KPX k e -20
+
+KPX m y -15
+KPX m u -10
+
+KPX n y -15
+KPX n v -20
+KPX n u -10
+
+KPX o y -30
+KPX o x -30
+KPX o w -15
+KPX o v -15
+KPX o period -40
+KPX o comma -40
+
+KPX oslash z -55
+KPX oslash y -70
+KPX oslash x -85
+KPX oslash w -70
+KPX oslash v -70
+KPX oslash u -55
+KPX oslash t -55
+KPX oslash s -55
+KPX oslash r -55
+KPX oslash q -55
+KPX oslash period -95
+KPX oslash p -55
+KPX oslash o -55
+KPX oslash n -55
+KPX oslash m -55
+KPX oslash l -55
+KPX oslash k -55
+KPX oslash j -55
+KPX oslash i -55
+KPX oslash h -55
+KPX oslash g -55
+KPX oslash f -55
+KPX oslash e -55
+KPX oslash d -55
+KPX oslash comma -95
+KPX oslash c -55
+KPX oslash b -55
+KPX oslash a -55
+
+KPX p y -30
+KPX p period -35
+KPX p comma -35
+
+KPX period space -60
+KPX period quoteright -100
+KPX period quotedblright -100
+
+KPX quotedblright space -40
+
+KPX quoteleft quoteleft -57
+
+KPX quoteright space -70
+KPX quoteright s -50
+KPX quoteright r -50
+KPX quoteright quoteright -57
+KPX quoteright d -50
+
+KPX r y 30
+KPX r v 30
+KPX r u 15
+KPX r t 40
+KPX r semicolon 30
+KPX r period -50
+KPX r p 30
+KPX r n 25
+KPX r m 25
+KPX r l 15
+KPX r k 15
+KPX r i 15
+KPX r comma -50
+KPX r colon 30
+KPX r a -10
+
+KPX s w -30
+KPX s period -15
+KPX s comma -15
+
+KPX semicolon space -50
+
+KPX space quoteleft -60
+KPX space quotedblleft -30
+KPX space Y -90
+KPX space W -40
+KPX space V -50
+KPX space T -50
+
+KPX v period -80
+KPX v o -25
+KPX v e -25
+KPX v comma -80
+KPX v a -25
+
+KPX w period -60
+KPX w o -10
+KPX w e -10
+KPX w comma -60
+KPX w a -15
+
+KPX x e -30
+
+KPX y period -100
+KPX y o -20
+KPX y e -20
+KPX y comma -100
+KPX y a -20
+
+KPX z o -15
+KPX z e -15
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 208 195 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 208 195 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 208 195 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 208 195 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 204 175 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 208 195 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 208 195 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 208 195 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 208 195 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 208 195 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 14 195 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 14 195 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 14 195 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 14 195 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 246 195 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 264 195 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 264 195 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 264 195 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 264 195 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 264 195 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 208 195 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 236 195 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 236 195 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 236 195 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 236 195 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 208 195 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 208 195 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 180 195 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 102 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 84 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 102 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 112 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 112 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Helvetica.afm b/tlt3.0/library/afm/Helvetica.afm
new file mode 100644
index 0000000..80d8cff
--- /dev/null
+++ b/tlt3.0/library/afm/Helvetica.afm
@@ -0,0 +1,613 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.
+Comment Creation Date: Thu Mar 15 08:58:00 1990
+Comment UniqueID 28352
+Comment VMusage 26389 33281
+FontName Helvetica
+FullName Helvetica
+FamilyName Helvetica
+Weight Medium
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -166 -225 1000 931
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.006
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 718
+XHeight 523
+Ascender 718
+Descender -207
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 90 0 187 718 ;
+C 34 ; WX 355 ; N quotedbl ; B 70 463 285 718 ;
+C 35 ; WX 556 ; N numbersign ; B 28 0 529 688 ;
+C 36 ; WX 556 ; N dollar ; B 32 -115 520 775 ;
+C 37 ; WX 889 ; N percent ; B 39 -19 850 703 ;
+C 38 ; WX 667 ; N ampersand ; B 44 -15 645 718 ;
+C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ;
+C 40 ; WX 333 ; N parenleft ; B 68 -207 299 733 ;
+C 41 ; WX 333 ; N parenright ; B 34 -207 265 733 ;
+C 42 ; WX 389 ; N asterisk ; B 39 431 349 718 ;
+C 43 ; WX 584 ; N plus ; B 39 0 545 505 ;
+C 44 ; WX 278 ; N comma ; B 87 -147 191 106 ;
+C 45 ; WX 333 ; N hyphen ; B 44 232 289 322 ;
+C 46 ; WX 278 ; N period ; B 87 0 191 106 ;
+C 47 ; WX 278 ; N slash ; B -17 -19 295 737 ;
+C 48 ; WX 556 ; N zero ; B 37 -19 519 703 ;
+C 49 ; WX 556 ; N one ; B 101 0 359 703 ;
+C 50 ; WX 556 ; N two ; B 26 0 507 703 ;
+C 51 ; WX 556 ; N three ; B 34 -19 522 703 ;
+C 52 ; WX 556 ; N four ; B 25 0 523 703 ;
+C 53 ; WX 556 ; N five ; B 32 -19 514 688 ;
+C 54 ; WX 556 ; N six ; B 38 -19 518 703 ;
+C 55 ; WX 556 ; N seven ; B 37 0 523 688 ;
+C 56 ; WX 556 ; N eight ; B 38 -19 517 703 ;
+C 57 ; WX 556 ; N nine ; B 42 -19 514 703 ;
+C 58 ; WX 278 ; N colon ; B 87 0 191 516 ;
+C 59 ; WX 278 ; N semicolon ; B 87 -147 191 516 ;
+C 60 ; WX 584 ; N less ; B 48 11 536 495 ;
+C 61 ; WX 584 ; N equal ; B 39 115 545 390 ;
+C 62 ; WX 584 ; N greater ; B 48 11 536 495 ;
+C 63 ; WX 556 ; N question ; B 56 0 492 727 ;
+C 64 ; WX 1015 ; N at ; B 147 -19 868 737 ;
+C 65 ; WX 667 ; N A ; B 14 0 654 718 ;
+C 66 ; WX 667 ; N B ; B 74 0 627 718 ;
+C 67 ; WX 722 ; N C ; B 44 -19 681 737 ;
+C 68 ; WX 722 ; N D ; B 81 0 674 718 ;
+C 69 ; WX 667 ; N E ; B 86 0 616 718 ;
+C 70 ; WX 611 ; N F ; B 86 0 583 718 ;
+C 71 ; WX 778 ; N G ; B 48 -19 704 737 ;
+C 72 ; WX 722 ; N H ; B 77 0 646 718 ;
+C 73 ; WX 278 ; N I ; B 91 0 188 718 ;
+C 74 ; WX 500 ; N J ; B 17 -19 428 718 ;
+C 75 ; WX 667 ; N K ; B 76 0 663 718 ;
+C 76 ; WX 556 ; N L ; B 76 0 537 718 ;
+C 77 ; WX 833 ; N M ; B 73 0 761 718 ;
+C 78 ; WX 722 ; N N ; B 76 0 646 718 ;
+C 79 ; WX 778 ; N O ; B 39 -19 739 737 ;
+C 80 ; WX 667 ; N P ; B 86 0 622 718 ;
+C 81 ; WX 778 ; N Q ; B 39 -56 739 737 ;
+C 82 ; WX 722 ; N R ; B 88 0 684 718 ;
+C 83 ; WX 667 ; N S ; B 49 -19 620 737 ;
+C 84 ; WX 611 ; N T ; B 14 0 597 718 ;
+C 85 ; WX 722 ; N U ; B 79 -19 644 718 ;
+C 86 ; WX 667 ; N V ; B 20 0 647 718 ;
+C 87 ; WX 944 ; N W ; B 16 0 928 718 ;
+C 88 ; WX 667 ; N X ; B 19 0 648 718 ;
+C 89 ; WX 667 ; N Y ; B 14 0 653 718 ;
+C 90 ; WX 611 ; N Z ; B 23 0 588 718 ;
+C 91 ; WX 278 ; N bracketleft ; B 63 -196 250 722 ;
+C 92 ; WX 278 ; N backslash ; B -17 -19 295 737 ;
+C 93 ; WX 278 ; N bracketright ; B 28 -196 215 722 ;
+C 94 ; WX 469 ; N asciicircum ; B -14 264 483 688 ;
+C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
+C 96 ; WX 222 ; N quoteleft ; B 65 470 169 725 ;
+C 97 ; WX 556 ; N a ; B 36 -15 530 538 ;
+C 98 ; WX 556 ; N b ; B 58 -15 517 718 ;
+C 99 ; WX 500 ; N c ; B 30 -15 477 538 ;
+C 100 ; WX 556 ; N d ; B 35 -15 499 718 ;
+C 101 ; WX 556 ; N e ; B 40 -15 516 538 ;
+C 102 ; WX 278 ; N f ; B 14 0 262 728 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 40 -220 499 538 ;
+C 104 ; WX 556 ; N h ; B 65 0 491 718 ;
+C 105 ; WX 222 ; N i ; B 67 0 155 718 ;
+C 106 ; WX 222 ; N j ; B -16 -210 155 718 ;
+C 107 ; WX 500 ; N k ; B 67 0 501 718 ;
+C 108 ; WX 222 ; N l ; B 67 0 155 718 ;
+C 109 ; WX 833 ; N m ; B 65 0 769 538 ;
+C 110 ; WX 556 ; N n ; B 65 0 491 538 ;
+C 111 ; WX 556 ; N o ; B 35 -14 521 538 ;
+C 112 ; WX 556 ; N p ; B 58 -207 517 538 ;
+C 113 ; WX 556 ; N q ; B 35 -207 494 538 ;
+C 114 ; WX 333 ; N r ; B 77 0 332 538 ;
+C 115 ; WX 500 ; N s ; B 32 -15 464 538 ;
+C 116 ; WX 278 ; N t ; B 14 -7 257 669 ;
+C 117 ; WX 556 ; N u ; B 68 -15 489 523 ;
+C 118 ; WX 500 ; N v ; B 8 0 492 523 ;
+C 119 ; WX 722 ; N w ; B 14 0 709 523 ;
+C 120 ; WX 500 ; N x ; B 11 0 490 523 ;
+C 121 ; WX 500 ; N y ; B 11 -214 489 523 ;
+C 122 ; WX 500 ; N z ; B 31 0 469 523 ;
+C 123 ; WX 334 ; N braceleft ; B 42 -196 292 722 ;
+C 124 ; WX 260 ; N bar ; B 94 -19 167 737 ;
+C 125 ; WX 334 ; N braceright ; B 42 -196 292 722 ;
+C 126 ; WX 584 ; N asciitilde ; B 61 180 523 326 ;
+C 161 ; WX 333 ; N exclamdown ; B 118 -195 215 523 ;
+C 162 ; WX 556 ; N cent ; B 51 -115 513 623 ;
+C 163 ; WX 556 ; N sterling ; B 33 -16 539 718 ;
+C 164 ; WX 167 ; N fraction ; B -166 -19 333 703 ;
+C 165 ; WX 556 ; N yen ; B 3 0 553 688 ;
+C 166 ; WX 556 ; N florin ; B -11 -207 501 737 ;
+C 167 ; WX 556 ; N section ; B 43 -191 512 737 ;
+C 168 ; WX 556 ; N currency ; B 28 99 528 603 ;
+C 169 ; WX 191 ; N quotesingle ; B 59 463 132 718 ;
+C 170 ; WX 333 ; N quotedblleft ; B 38 470 307 725 ;
+C 171 ; WX 556 ; N guillemotleft ; B 97 108 459 446 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 88 108 245 446 ;
+C 173 ; WX 333 ; N guilsinglright ; B 88 108 245 446 ;
+C 174 ; WX 500 ; N fi ; B 14 0 434 728 ;
+C 175 ; WX 500 ; N fl ; B 14 0 432 728 ;
+C 177 ; WX 556 ; N endash ; B 0 240 556 313 ;
+C 178 ; WX 556 ; N dagger ; B 43 -159 514 718 ;
+C 179 ; WX 556 ; N daggerdbl ; B 43 -159 514 718 ;
+C 180 ; WX 278 ; N periodcentered ; B 77 190 202 315 ;
+C 182 ; WX 537 ; N paragraph ; B 18 -173 497 718 ;
+C 183 ; WX 350 ; N bullet ; B 18 202 333 517 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 53 -149 157 106 ;
+C 185 ; WX 333 ; N quotedblbase ; B 26 -149 295 106 ;
+C 186 ; WX 333 ; N quotedblright ; B 26 463 295 718 ;
+C 187 ; WX 556 ; N guillemotright ; B 97 108 459 446 ;
+C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 106 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 703 ;
+C 191 ; WX 611 ; N questiondown ; B 91 -201 527 525 ;
+C 193 ; WX 333 ; N grave ; B 14 593 211 734 ;
+C 194 ; WX 333 ; N acute ; B 122 593 319 734 ;
+C 195 ; WX 333 ; N circumflex ; B 21 593 312 734 ;
+C 196 ; WX 333 ; N tilde ; B -4 606 337 722 ;
+C 197 ; WX 333 ; N macron ; B 10 627 323 684 ;
+C 198 ; WX 333 ; N breve ; B 13 595 321 731 ;
+C 199 ; WX 333 ; N dotaccent ; B 121 604 212 706 ;
+C 200 ; WX 333 ; N dieresis ; B 40 604 293 706 ;
+C 202 ; WX 333 ; N ring ; B 75 572 259 756 ;
+C 203 ; WX 333 ; N cedilla ; B 45 -225 259 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 31 593 409 734 ;
+C 206 ; WX 333 ; N ogonek ; B 73 -225 287 0 ;
+C 207 ; WX 333 ; N caron ; B 21 593 312 734 ;
+C 208 ; WX 1000 ; N emdash ; B 0 240 1000 313 ;
+C 225 ; WX 1000 ; N AE ; B 8 0 951 718 ;
+C 227 ; WX 370 ; N ordfeminine ; B 24 304 346 737 ;
+C 232 ; WX 556 ; N Lslash ; B -20 0 537 718 ;
+C 233 ; WX 778 ; N Oslash ; B 39 -19 740 737 ;
+C 234 ; WX 1000 ; N OE ; B 36 -19 965 737 ;
+C 235 ; WX 365 ; N ordmasculine ; B 25 304 341 737 ;
+C 241 ; WX 889 ; N ae ; B 36 -15 847 538 ;
+C 245 ; WX 278 ; N dotlessi ; B 95 0 183 523 ;
+C 248 ; WX 222 ; N lslash ; B -20 0 242 718 ;
+C 249 ; WX 611 ; N oslash ; B 28 -22 537 545 ;
+C 250 ; WX 944 ; N oe ; B 35 -15 902 538 ;
+C 251 ; WX 611 ; N germandbls ; B 67 -15 571 728 ;
+C -1 ; WX 611 ; N Zcaron ; B 23 0 588 929 ;
+C -1 ; WX 500 ; N ccedilla ; B 30 -225 477 538 ;
+C -1 ; WX 500 ; N ydieresis ; B 11 -214 489 706 ;
+C -1 ; WX 556 ; N atilde ; B 36 -15 530 722 ;
+C -1 ; WX 278 ; N icircumflex ; B -6 0 285 734 ;
+C -1 ; WX 333 ; N threesuperior ; B 5 270 325 703 ;
+C -1 ; WX 556 ; N ecircumflex ; B 40 -15 516 734 ;
+C -1 ; WX 556 ; N thorn ; B 58 -207 517 718 ;
+C -1 ; WX 556 ; N egrave ; B 40 -15 516 734 ;
+C -1 ; WX 333 ; N twosuperior ; B 4 281 323 703 ;
+C -1 ; WX 556 ; N eacute ; B 40 -15 516 734 ;
+C -1 ; WX 556 ; N otilde ; B 35 -14 521 722 ;
+C -1 ; WX 667 ; N Aacute ; B 14 0 654 929 ;
+C -1 ; WX 556 ; N ocircumflex ; B 35 -14 521 734 ;
+C -1 ; WX 500 ; N yacute ; B 11 -214 489 734 ;
+C -1 ; WX 556 ; N udieresis ; B 68 -15 489 706 ;
+C -1 ; WX 834 ; N threequarters ; B 45 -19 810 703 ;
+C -1 ; WX 556 ; N acircumflex ; B 36 -15 530 734 ;
+C -1 ; WX 722 ; N Eth ; B 0 0 674 718 ;
+C -1 ; WX 556 ; N edieresis ; B 40 -15 516 706 ;
+C -1 ; WX 556 ; N ugrave ; B 68 -15 489 734 ;
+C -1 ; WX 1000 ; N trademark ; B 46 306 903 718 ;
+C -1 ; WX 556 ; N ograve ; B 35 -14 521 734 ;
+C -1 ; WX 500 ; N scaron ; B 32 -15 464 734 ;
+C -1 ; WX 278 ; N Idieresis ; B 13 0 266 901 ;
+C -1 ; WX 556 ; N uacute ; B 68 -15 489 734 ;
+C -1 ; WX 556 ; N agrave ; B 36 -15 530 734 ;
+C -1 ; WX 556 ; N ntilde ; B 65 0 491 722 ;
+C -1 ; WX 556 ; N aring ; B 36 -15 530 756 ;
+C -1 ; WX 500 ; N zcaron ; B 31 0 469 734 ;
+C -1 ; WX 278 ; N Icircumflex ; B -6 0 285 929 ;
+C -1 ; WX 722 ; N Ntilde ; B 76 0 646 917 ;
+C -1 ; WX 556 ; N ucircumflex ; B 68 -15 489 734 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 86 0 616 929 ;
+C -1 ; WX 278 ; N Iacute ; B 91 0 292 929 ;
+C -1 ; WX 722 ; N Ccedilla ; B 44 -225 681 737 ;
+C -1 ; WX 778 ; N Odieresis ; B 39 -19 739 901 ;
+C -1 ; WX 667 ; N Scaron ; B 49 -19 620 929 ;
+C -1 ; WX 667 ; N Edieresis ; B 86 0 616 901 ;
+C -1 ; WX 278 ; N Igrave ; B -13 0 188 929 ;
+C -1 ; WX 556 ; N adieresis ; B 36 -15 530 706 ;
+C -1 ; WX 778 ; N Ograve ; B 39 -19 739 929 ;
+C -1 ; WX 667 ; N Egrave ; B 86 0 616 929 ;
+C -1 ; WX 667 ; N Ydieresis ; B 14 0 653 901 ;
+C -1 ; WX 737 ; N registered ; B -14 -19 752 737 ;
+C -1 ; WX 778 ; N Otilde ; B 39 -19 739 917 ;
+C -1 ; WX 834 ; N onequarter ; B 73 -19 756 703 ;
+C -1 ; WX 722 ; N Ugrave ; B 79 -19 644 929 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 79 -19 644 929 ;
+C -1 ; WX 667 ; N Thorn ; B 86 0 622 718 ;
+C -1 ; WX 584 ; N divide ; B 39 -19 545 524 ;
+C -1 ; WX 667 ; N Atilde ; B 14 0 654 917 ;
+C -1 ; WX 722 ; N Uacute ; B 79 -19 644 929 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 39 -19 739 929 ;
+C -1 ; WX 584 ; N logicalnot ; B 39 108 545 390 ;
+C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ;
+C -1 ; WX 278 ; N idieresis ; B 13 0 266 706 ;
+C -1 ; WX 278 ; N iacute ; B 95 0 292 734 ;
+C -1 ; WX 556 ; N aacute ; B 36 -15 530 734 ;
+C -1 ; WX 584 ; N plusminus ; B 39 0 545 506 ;
+C -1 ; WX 584 ; N multiply ; B 39 0 545 506 ;
+C -1 ; WX 722 ; N Udieresis ; B 79 -19 644 901 ;
+C -1 ; WX 584 ; N minus ; B 39 216 545 289 ;
+C -1 ; WX 333 ; N onesuperior ; B 43 281 222 703 ;
+C -1 ; WX 667 ; N Eacute ; B 86 0 616 929 ;
+C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ;
+C -1 ; WX 737 ; N copyright ; B -14 -19 752 737 ;
+C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ;
+C -1 ; WX 556 ; N odieresis ; B 35 -14 521 706 ;
+C -1 ; WX 556 ; N oacute ; B 35 -14 521 734 ;
+C -1 ; WX 400 ; N degree ; B 54 411 346 703 ;
+C -1 ; WX 278 ; N igrave ; B -13 0 184 734 ;
+C -1 ; WX 556 ; N mu ; B 68 -207 489 523 ;
+C -1 ; WX 778 ; N Oacute ; B 39 -19 739 929 ;
+C -1 ; WX 556 ; N eth ; B 35 -15 522 737 ;
+C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ;
+C -1 ; WX 667 ; N Yacute ; B 14 0 653 929 ;
+C -1 ; WX 260 ; N brokenbar ; B 94 -19 167 737 ;
+C -1 ; WX 834 ; N onehalf ; B 43 -19 773 703 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 250
+
+KPX A y -40
+KPX A w -40
+KPX A v -40
+KPX A u -30
+KPX A Y -100
+KPX A W -50
+KPX A V -70
+KPX A U -50
+KPX A T -120
+KPX A Q -30
+KPX A O -30
+KPX A G -30
+KPX A C -30
+
+KPX B period -20
+KPX B comma -20
+KPX B U -10
+
+KPX C period -30
+KPX C comma -30
+
+KPX D period -70
+KPX D comma -70
+KPX D Y -90
+KPX D W -40
+KPX D V -70
+KPX D A -40
+
+KPX F r -45
+KPX F period -150
+KPX F o -30
+KPX F e -30
+KPX F comma -150
+KPX F a -50
+KPX F A -80
+
+KPX J u -20
+KPX J period -30
+KPX J comma -30
+KPX J a -20
+KPX J A -20
+
+KPX K y -50
+KPX K u -30
+KPX K o -40
+KPX K e -40
+KPX K O -50
+
+KPX L y -30
+KPX L quoteright -160
+KPX L quotedblright -140
+KPX L Y -140
+KPX L W -70
+KPX L V -110
+KPX L T -110
+
+KPX O period -40
+KPX O comma -40
+KPX O Y -70
+KPX O X -60
+KPX O W -30
+KPX O V -50
+KPX O T -40
+KPX O A -20
+
+KPX P period -180
+KPX P o -50
+KPX P e -50
+KPX P comma -180
+KPX P a -40
+KPX P A -120
+
+KPX Q U -10
+
+KPX R Y -50
+KPX R W -30
+KPX R V -50
+KPX R U -40
+KPX R T -30
+KPX R O -20
+
+KPX S period -20
+KPX S comma -20
+
+KPX T y -120
+KPX T w -120
+KPX T u -120
+KPX T semicolon -20
+KPX T r -120
+KPX T period -120
+KPX T o -120
+KPX T hyphen -140
+KPX T e -120
+KPX T comma -120
+KPX T colon -20
+KPX T a -120
+KPX T O -40
+KPX T A -120
+
+KPX U period -40
+KPX U comma -40
+KPX U A -40
+
+KPX V u -70
+KPX V semicolon -40
+KPX V period -125
+KPX V o -80
+KPX V hyphen -80
+KPX V e -80
+KPX V comma -125
+KPX V colon -40
+KPX V a -70
+KPX V O -40
+KPX V G -40
+KPX V A -80
+
+KPX W y -20
+KPX W u -30
+KPX W period -80
+KPX W o -30
+KPX W hyphen -40
+KPX W e -30
+KPX W comma -80
+KPX W a -40
+KPX W O -20
+KPX W A -50
+
+KPX Y u -110
+KPX Y semicolon -60
+KPX Y period -140
+KPX Y o -140
+KPX Y i -20
+KPX Y hyphen -140
+KPX Y e -140
+KPX Y comma -140
+KPX Y colon -60
+KPX Y a -140
+KPX Y O -85
+KPX Y A -110
+
+KPX a y -30
+KPX a w -20
+KPX a v -20
+
+KPX b y -20
+KPX b v -20
+KPX b u -20
+KPX b period -40
+KPX b l -20
+KPX b comma -40
+KPX b b -10
+
+KPX c k -20
+KPX c comma -15
+
+KPX colon space -50
+
+KPX comma quoteright -100
+KPX comma quotedblright -100
+
+KPX e y -20
+KPX e x -30
+KPX e w -20
+KPX e v -30
+KPX e period -15
+KPX e comma -15
+
+KPX f quoteright 50
+KPX f quotedblright 60
+KPX f period -30
+KPX f o -30
+KPX f e -30
+KPX f dotlessi -28
+KPX f comma -30
+KPX f a -30
+
+KPX g r -10
+
+KPX h y -30
+
+KPX k o -20
+KPX k e -20
+
+KPX m y -15
+KPX m u -10
+
+KPX n y -15
+KPX n v -20
+KPX n u -10
+
+KPX o y -30
+KPX o x -30
+KPX o w -15
+KPX o v -15
+KPX o period -40
+KPX o comma -40
+
+KPX oslash z -55
+KPX oslash y -70
+KPX oslash x -85
+KPX oslash w -70
+KPX oslash v -70
+KPX oslash u -55
+KPX oslash t -55
+KPX oslash s -55
+KPX oslash r -55
+KPX oslash q -55
+KPX oslash period -95
+KPX oslash p -55
+KPX oslash o -55
+KPX oslash n -55
+KPX oslash m -55
+KPX oslash l -55
+KPX oslash k -55
+KPX oslash j -55
+KPX oslash i -55
+KPX oslash h -55
+KPX oslash g -55
+KPX oslash f -55
+KPX oslash e -55
+KPX oslash d -55
+KPX oslash comma -95
+KPX oslash c -55
+KPX oslash b -55
+KPX oslash a -55
+
+KPX p y -30
+KPX p period -35
+KPX p comma -35
+
+KPX period space -60
+KPX period quoteright -100
+KPX period quotedblright -100
+
+KPX quotedblright space -40
+
+KPX quoteleft quoteleft -57
+
+KPX quoteright space -70
+KPX quoteright s -50
+KPX quoteright r -50
+KPX quoteright quoteright -57
+KPX quoteright d -50
+
+KPX r y 30
+KPX r v 30
+KPX r u 15
+KPX r t 40
+KPX r semicolon 30
+KPX r period -50
+KPX r p 30
+KPX r n 25
+KPX r m 25
+KPX r l 15
+KPX r k 15
+KPX r i 15
+KPX r comma -50
+KPX r colon 30
+KPX r a -10
+
+KPX s w -30
+KPX s period -15
+KPX s comma -15
+
+KPX semicolon space -50
+
+KPX space quoteleft -60
+KPX space quotedblleft -30
+KPX space Y -90
+KPX space W -40
+KPX space V -50
+KPX space T -50
+
+KPX v period -80
+KPX v o -25
+KPX v e -25
+KPX v comma -80
+KPX v a -25
+
+KPX w period -60
+KPX w o -10
+KPX w e -10
+KPX w comma -60
+KPX w a -15
+
+KPX x e -30
+
+KPX y period -100
+KPX y o -20
+KPX y e -20
+KPX y comma -100
+KPX y a -20
+
+KPX z o -15
+KPX z e -15
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 195 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 195 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 195 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 195 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 167 175 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 195 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 195 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 195 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 195 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 195 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 195 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 195 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 195 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 195 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 205 195 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 195 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 195 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 195 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 195 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 195 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 195 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 195 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 195 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 195 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 195 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 195 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 195 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 195 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 102 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 84 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 102 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 112 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 112 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/NewCenturySchlbk-Bold.afm b/tlt3.0/library/afm/NewCenturySchlbk-Bold.afm
new file mode 100644
index 0000000..6438f86
--- /dev/null
+++ b/tlt3.0/library/afm/NewCenturySchlbk-Bold.afm
@@ -0,0 +1,473 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1988, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue May 28 16:48:12 1991
+Comment UniqueID 35031
+Comment VMusage 30773 37665
+FontName NewCenturySchlbk-Bold
+FullName New Century Schoolbook Bold
+FamilyName New Century Schoolbook
+Weight Bold
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -165 -250 1000 988
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.009
+Notice Copyright (c) 1985, 1987, 1988, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 722
+XHeight 475
+Ascender 737
+Descender -205
+StartCharMetrics 228
+C 32 ; WX 287 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 296 ; N exclam ; B 53 -15 243 737 ;
+C 34 ; WX 333 ; N quotedbl ; B 0 378 333 737 ;
+C 35 ; WX 574 ; N numbersign ; B 36 0 538 690 ;
+C 36 ; WX 574 ; N dollar ; B 25 -141 549 810 ;
+C 37 ; WX 833 ; N percent ; B 14 -15 819 705 ;
+C 38 ; WX 852 ; N ampersand ; B 34 -15 818 737 ;
+C 39 ; WX 241 ; N quoteright ; B 22 378 220 737 ;
+C 40 ; WX 389 ; N parenleft ; B 77 -117 345 745 ;
+C 41 ; WX 389 ; N parenright ; B 44 -117 312 745 ;
+C 42 ; WX 500 ; N asterisk ; B 54 302 446 737 ;
+C 43 ; WX 606 ; N plus ; B 50 0 556 506 ;
+C 44 ; WX 278 ; N comma ; B 40 -184 238 175 ;
+C 45 ; WX 333 ; N hyphen ; B 42 174 291 302 ;
+C 46 ; WX 278 ; N period ; B 44 -15 234 175 ;
+C 47 ; WX 278 ; N slash ; B -42 -15 320 737 ;
+C 48 ; WX 574 ; N zero ; B 27 -15 547 705 ;
+C 49 ; WX 574 ; N one ; B 83 0 491 705 ;
+C 50 ; WX 574 ; N two ; B 19 0 531 705 ;
+C 51 ; WX 574 ; N three ; B 23 -15 531 705 ;
+C 52 ; WX 574 ; N four ; B 19 0 547 705 ;
+C 53 ; WX 574 ; N five ; B 32 -15 534 705 ;
+C 54 ; WX 574 ; N six ; B 27 -15 547 705 ;
+C 55 ; WX 574 ; N seven ; B 45 -15 547 705 ;
+C 56 ; WX 574 ; N eight ; B 27 -15 548 705 ;
+C 57 ; WX 574 ; N nine ; B 27 -15 547 705 ;
+C 58 ; WX 278 ; N colon ; B 44 -15 234 485 ;
+C 59 ; WX 278 ; N semicolon ; B 40 -184 238 485 ;
+C 60 ; WX 606 ; N less ; B 50 -9 556 515 ;
+C 61 ; WX 606 ; N equal ; B 50 103 556 403 ;
+C 62 ; WX 606 ; N greater ; B 50 -9 556 515 ;
+C 63 ; WX 500 ; N question ; B 23 -15 477 737 ;
+C 64 ; WX 747 ; N at ; B -2 -15 750 737 ;
+C 65 ; WX 759 ; N A ; B -19 0 778 737 ;
+C 66 ; WX 778 ; N B ; B 19 0 739 722 ;
+C 67 ; WX 778 ; N C ; B 39 -15 723 737 ;
+C 68 ; WX 833 ; N D ; B 19 0 794 722 ;
+C 69 ; WX 759 ; N E ; B 19 0 708 722 ;
+C 70 ; WX 722 ; N F ; B 19 0 697 722 ;
+C 71 ; WX 833 ; N G ; B 39 -15 818 737 ;
+C 72 ; WX 870 ; N H ; B 19 0 851 722 ;
+C 73 ; WX 444 ; N I ; B 29 0 415 722 ;
+C 74 ; WX 648 ; N J ; B 6 -15 642 722 ;
+C 75 ; WX 815 ; N K ; B 19 0 822 722 ;
+C 76 ; WX 722 ; N L ; B 19 0 703 722 ;
+C 77 ; WX 981 ; N M ; B 10 0 971 722 ;
+C 78 ; WX 833 ; N N ; B 5 -10 828 722 ;
+C 79 ; WX 833 ; N O ; B 39 -15 794 737 ;
+C 80 ; WX 759 ; N P ; B 24 0 735 722 ;
+C 81 ; WX 833 ; N Q ; B 39 -189 808 737 ;
+C 82 ; WX 815 ; N R ; B 19 -15 815 722 ;
+C 83 ; WX 667 ; N S ; B 51 -15 634 737 ;
+C 84 ; WX 722 ; N T ; B 16 0 706 722 ;
+C 85 ; WX 833 ; N U ; B 14 -15 825 722 ;
+C 86 ; WX 759 ; N V ; B -19 -10 778 722 ;
+C 87 ; WX 981 ; N W ; B 7 -10 974 722 ;
+C 88 ; WX 722 ; N X ; B -12 0 734 722 ;
+C 89 ; WX 722 ; N Y ; B -12 0 734 722 ;
+C 90 ; WX 667 ; N Z ; B 28 0 639 722 ;
+C 91 ; WX 389 ; N bracketleft ; B 84 -109 339 737 ;
+C 92 ; WX 606 ; N backslash ; B 122 -15 484 737 ;
+C 93 ; WX 389 ; N bracketright ; B 50 -109 305 737 ;
+C 94 ; WX 606 ; N asciicircum ; B 66 325 540 690 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 241 ; N quoteleft ; B 22 378 220 737 ;
+C 97 ; WX 611 ; N a ; B 40 -15 601 485 ;
+C 98 ; WX 648 ; N b ; B 4 -15 616 737 ;
+C 99 ; WX 556 ; N c ; B 32 -15 524 485 ;
+C 100 ; WX 667 ; N d ; B 32 -15 644 737 ;
+C 101 ; WX 574 ; N e ; B 32 -15 542 485 ;
+C 102 ; WX 389 ; N f ; B 11 0 461 737 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 30 -205 623 535 ;
+C 104 ; WX 685 ; N h ; B 17 0 662 737 ;
+C 105 ; WX 370 ; N i ; B 26 0 338 737 ;
+C 106 ; WX 352 ; N j ; B -86 -205 271 737 ;
+C 107 ; WX 667 ; N k ; B 17 0 662 737 ;
+C 108 ; WX 352 ; N l ; B 17 0 329 737 ;
+C 109 ; WX 963 ; N m ; B 17 0 940 485 ;
+C 110 ; WX 685 ; N n ; B 17 0 662 485 ;
+C 111 ; WX 611 ; N o ; B 32 -15 579 485 ;
+C 112 ; WX 667 ; N p ; B 17 -205 629 485 ;
+C 113 ; WX 648 ; N q ; B 32 -205 638 485 ;
+C 114 ; WX 519 ; N r ; B 17 0 516 485 ;
+C 115 ; WX 500 ; N s ; B 48 -15 476 485 ;
+C 116 ; WX 426 ; N t ; B 21 -15 405 675 ;
+C 117 ; WX 685 ; N u ; B 17 -15 668 475 ;
+C 118 ; WX 611 ; N v ; B 12 -10 599 475 ;
+C 119 ; WX 889 ; N w ; B 16 -10 873 475 ;
+C 120 ; WX 611 ; N x ; B 12 0 599 475 ;
+C 121 ; WX 611 ; N y ; B 12 -205 599 475 ;
+C 122 ; WX 537 ; N z ; B 38 0 499 475 ;
+C 123 ; WX 389 ; N braceleft ; B 36 -109 313 737 ;
+C 124 ; WX 606 ; N bar ; B 249 -250 357 750 ;
+C 125 ; WX 389 ; N braceright ; B 76 -109 353 737 ;
+C 126 ; WX 606 ; N asciitilde ; B 72 160 534 346 ;
+C 161 ; WX 296 ; N exclamdown ; B 53 -205 243 547 ;
+C 162 ; WX 574 ; N cent ; B 32 -102 528 572 ;
+C 163 ; WX 574 ; N sterling ; B 16 -15 558 705 ;
+C 164 ; WX 167 ; N fraction ; B -165 -15 332 705 ;
+C 165 ; WX 574 ; N yen ; B -10 0 584 690 ;
+C 166 ; WX 574 ; N florin ; B 14 -205 548 737 ;
+C 167 ; WX 500 ; N section ; B 62 -86 438 737 ;
+C 168 ; WX 574 ; N currency ; B 27 84 547 605 ;
+C 169 ; WX 241 ; N quotesingle ; B 53 378 189 737 ;
+C 170 ; WX 481 ; N quotedblleft ; B 22 378 459 737 ;
+C 171 ; WX 500 ; N guillemotleft ; B 46 79 454 397 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 62 79 271 397 ;
+C 173 ; WX 333 ; N guilsinglright ; B 62 79 271 397 ;
+C 174 ; WX 685 ; N fi ; B 11 0 666 737 ;
+C 175 ; WX 685 ; N fl ; B 11 0 666 737 ;
+C 177 ; WX 500 ; N endash ; B 0 184 500 292 ;
+C 178 ; WX 500 ; N dagger ; B 39 -101 461 737 ;
+C 179 ; WX 500 ; N daggerdbl ; B 39 -89 461 737 ;
+C 180 ; WX 278 ; N periodcentered ; B 53 200 225 372 ;
+C 182 ; WX 747 ; N paragraph ; B 96 -71 631 722 ;
+C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ;
+C 184 ; WX 241 ; N quotesinglbase ; B 22 -184 220 175 ;
+C 185 ; WX 481 ; N quotedblbase ; B 22 -184 459 175 ;
+C 186 ; WX 481 ; N quotedblright ; B 22 378 459 737 ;
+C 187 ; WX 500 ; N guillemotright ; B 46 79 454 397 ;
+C 188 ; WX 1000 ; N ellipsis ; B 72 -15 928 175 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -15 993 705 ;
+C 191 ; WX 500 ; N questiondown ; B 23 -205 477 547 ;
+C 193 ; WX 333 ; N grave ; B 2 547 249 737 ;
+C 194 ; WX 333 ; N acute ; B 84 547 331 737 ;
+C 195 ; WX 333 ; N circumflex ; B -10 547 344 725 ;
+C 196 ; WX 333 ; N tilde ; B -24 563 357 705 ;
+C 197 ; WX 333 ; N macron ; B -6 582 339 664 ;
+C 198 ; WX 333 ; N breve ; B 9 547 324 714 ;
+C 199 ; WX 333 ; N dotaccent ; B 95 552 237 694 ;
+C 200 ; WX 333 ; N dieresis ; B -12 552 345 694 ;
+C 202 ; WX 333 ; N ring ; B 58 545 274 761 ;
+C 203 ; WX 333 ; N cedilla ; B 17 -224 248 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -16 547 431 737 ;
+C 206 ; WX 333 ; N ogonek ; B 168 -163 346 3 ;
+C 207 ; WX 333 ; N caron ; B -10 547 344 725 ;
+C 208 ; WX 1000 ; N emdash ; B 0 184 1000 292 ;
+C 225 ; WX 981 ; N AE ; B -29 0 963 722 ;
+C 227 ; WX 367 ; N ordfeminine ; B 1 407 393 705 ;
+C 232 ; WX 722 ; N Lslash ; B 19 0 703 722 ;
+C 233 ; WX 833 ; N Oslash ; B 39 -53 794 775 ;
+C 234 ; WX 1000 ; N OE ; B 0 0 982 722 ;
+C 235 ; WX 367 ; N ordmasculine ; B 1 407 366 705 ;
+C 241 ; WX 870 ; N ae ; B 32 -15 838 485 ;
+C 245 ; WX 370 ; N dotlessi ; B 26 0 338 475 ;
+C 248 ; WX 352 ; N lslash ; B 17 0 329 737 ;
+C 249 ; WX 611 ; N oslash ; B 32 -103 579 573 ;
+C 250 ; WX 907 ; N oe ; B 32 -15 875 485 ;
+C 251 ; WX 611 ; N germandbls ; B -2 -15 580 737 ;
+C -1 ; WX 574 ; N ecircumflex ; B 32 -15 542 725 ;
+C -1 ; WX 574 ; N edieresis ; B 32 -15 542 694 ;
+C -1 ; WX 611 ; N aacute ; B 40 -15 601 737 ;
+C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ;
+C -1 ; WX 370 ; N icircumflex ; B 9 0 363 725 ;
+C -1 ; WX 685 ; N udieresis ; B 17 -15 668 694 ;
+C -1 ; WX 611 ; N ograve ; B 32 -15 579 737 ;
+C -1 ; WX 685 ; N uacute ; B 17 -15 668 737 ;
+C -1 ; WX 685 ; N ucircumflex ; B 17 -15 668 725 ;
+C -1 ; WX 759 ; N Aacute ; B -19 0 778 964 ;
+C -1 ; WX 370 ; N igrave ; B 21 0 338 737 ;
+C -1 ; WX 444 ; N Icircumflex ; B 29 0 415 952 ;
+C -1 ; WX 556 ; N ccedilla ; B 32 -224 524 485 ;
+C -1 ; WX 611 ; N adieresis ; B 40 -15 601 694 ;
+C -1 ; WX 759 ; N Ecircumflex ; B 19 0 708 952 ;
+C -1 ; WX 500 ; N scaron ; B 48 -15 476 725 ;
+C -1 ; WX 667 ; N thorn ; B 17 -205 629 737 ;
+C -1 ; WX 1000 ; N trademark ; B 6 317 982 722 ;
+C -1 ; WX 574 ; N egrave ; B 32 -15 542 737 ;
+C -1 ; WX 344 ; N threesuperior ; B -3 273 355 705 ;
+C -1 ; WX 537 ; N zcaron ; B 38 0 499 725 ;
+C -1 ; WX 611 ; N atilde ; B 40 -15 601 705 ;
+C -1 ; WX 611 ; N aring ; B 40 -15 601 761 ;
+C -1 ; WX 611 ; N ocircumflex ; B 32 -15 579 725 ;
+C -1 ; WX 759 ; N Edieresis ; B 19 0 708 921 ;
+C -1 ; WX 861 ; N threequarters ; B 15 -15 838 705 ;
+C -1 ; WX 611 ; N ydieresis ; B 12 -205 599 694 ;
+C -1 ; WX 611 ; N yacute ; B 12 -205 599 737 ;
+C -1 ; WX 370 ; N iacute ; B 26 0 350 737 ;
+C -1 ; WX 759 ; N Acircumflex ; B -19 0 778 952 ;
+C -1 ; WX 833 ; N Uacute ; B 14 -15 825 964 ;
+C -1 ; WX 574 ; N eacute ; B 32 -15 542 737 ;
+C -1 ; WX 833 ; N Ograve ; B 39 -15 794 964 ;
+C -1 ; WX 611 ; N agrave ; B 40 -15 601 737 ;
+C -1 ; WX 833 ; N Udieresis ; B 14 -15 825 921 ;
+C -1 ; WX 611 ; N acircumflex ; B 40 -15 601 725 ;
+C -1 ; WX 444 ; N Igrave ; B 29 0 415 964 ;
+C -1 ; WX 344 ; N twosuperior ; B -3 282 350 705 ;
+C -1 ; WX 833 ; N Ugrave ; B 14 -15 825 964 ;
+C -1 ; WX 861 ; N onequarter ; B 31 -15 838 705 ;
+C -1 ; WX 833 ; N Ucircumflex ; B 14 -15 825 952 ;
+C -1 ; WX 667 ; N Scaron ; B 51 -15 634 952 ;
+C -1 ; WX 444 ; N Idieresis ; B 29 0 415 921 ;
+C -1 ; WX 370 ; N idieresis ; B 7 0 364 694 ;
+C -1 ; WX 759 ; N Egrave ; B 19 0 708 964 ;
+C -1 ; WX 833 ; N Oacute ; B 39 -15 794 964 ;
+C -1 ; WX 606 ; N divide ; B 50 -40 556 546 ;
+C -1 ; WX 759 ; N Atilde ; B -19 0 778 932 ;
+C -1 ; WX 759 ; N Aring ; B -19 0 778 988 ;
+C -1 ; WX 833 ; N Odieresis ; B 39 -15 794 921 ;
+C -1 ; WX 759 ; N Adieresis ; B -19 0 778 921 ;
+C -1 ; WX 833 ; N Ntilde ; B 5 -10 828 932 ;
+C -1 ; WX 667 ; N Zcaron ; B 28 0 639 952 ;
+C -1 ; WX 759 ; N Thorn ; B 24 0 735 722 ;
+C -1 ; WX 444 ; N Iacute ; B 29 0 415 964 ;
+C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ;
+C -1 ; WX 606 ; N multiply ; B 65 15 541 491 ;
+C -1 ; WX 759 ; N Eacute ; B 19 0 708 964 ;
+C -1 ; WX 722 ; N Ydieresis ; B -12 0 734 921 ;
+C -1 ; WX 344 ; N onesuperior ; B 31 282 309 705 ;
+C -1 ; WX 685 ; N ugrave ; B 17 -15 668 737 ;
+C -1 ; WX 606 ; N logicalnot ; B 50 103 556 403 ;
+C -1 ; WX 685 ; N ntilde ; B 17 0 662 705 ;
+C -1 ; WX 833 ; N Otilde ; B 39 -15 794 932 ;
+C -1 ; WX 611 ; N otilde ; B 32 -15 579 705 ;
+C -1 ; WX 778 ; N Ccedilla ; B 39 -224 723 737 ;
+C -1 ; WX 759 ; N Agrave ; B -19 0 778 964 ;
+C -1 ; WX 861 ; N onehalf ; B 31 -15 838 705 ;
+C -1 ; WX 833 ; N Eth ; B 19 0 794 722 ;
+C -1 ; WX 400 ; N degree ; B 57 419 343 705 ;
+C -1 ; WX 722 ; N Yacute ; B -12 0 734 964 ;
+C -1 ; WX 833 ; N Ocircumflex ; B 39 -15 794 952 ;
+C -1 ; WX 611 ; N oacute ; B 32 -15 579 737 ;
+C -1 ; WX 685 ; N mu ; B 17 -205 668 475 ;
+C -1 ; WX 606 ; N minus ; B 50 199 556 307 ;
+C -1 ; WX 611 ; N eth ; B 32 -15 579 737 ;
+C -1 ; WX 611 ; N odieresis ; B 32 -15 579 694 ;
+C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ;
+C -1 ; WX 606 ; N brokenbar ; B 249 -175 357 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 128
+
+KPX A y -18
+KPX A w -18
+KPX A v -18
+KPX A quoteright -74
+KPX A quotedblright -74
+KPX A Y -91
+KPX A W -74
+KPX A V -74
+KPX A U -18
+KPX A T -55
+
+KPX C period -18
+KPX C comma -18
+
+KPX D period -25
+KPX D comma -25
+
+KPX F r -18
+KPX F period -125
+KPX F o -55
+KPX F i -18
+KPX F e -55
+KPX F comma -125
+KPX F a -74
+
+KPX J u -18
+KPX J period -55
+KPX J o -18
+KPX J e -18
+KPX J comma -55
+KPX J a -18
+KPX J A -18
+
+KPX K y -25
+KPX K u -18
+
+KPX L y -25
+KPX L quoteright -100
+KPX L quotedblright -100
+KPX L Y -74
+KPX L W -74
+KPX L V -100
+KPX L T -100
+
+KPX N period -18
+KPX N comma -18
+
+KPX O period -25
+KPX O comma -25
+KPX O T 10
+
+KPX P period -150
+KPX P o -55
+KPX P e -55
+KPX P comma -150
+KPX P a -55
+KPX P A -74
+
+KPX S period -18
+KPX S comma -18
+
+KPX T u -18
+KPX T r -18
+KPX T period -100
+KPX T o -74
+KPX T i -18
+KPX T hyphen -125
+KPX T e -74
+KPX T comma -100
+KPX T a -74
+KPX T O 10
+KPX T A -55
+
+KPX U period -25
+KPX U comma -25
+KPX U A -18
+
+KPX V u -55
+KPX V semicolon -37
+KPX V period -125
+KPX V o -74
+KPX V i -18
+KPX V hyphen -100
+KPX V e -74
+KPX V comma -125
+KPX V colon -37
+KPX V a -74
+KPX V A -74
+
+KPX W y -25
+KPX W u -37
+KPX W semicolon -55
+KPX W period -100
+KPX W o -74
+KPX W i -18
+KPX W hyphen -100
+KPX W e -74
+KPX W comma -100
+KPX W colon -55
+KPX W a -74
+KPX W A -74
+
+KPX Y u -55
+KPX Y semicolon -25
+KPX Y period -100
+KPX Y o -100
+KPX Y i -18
+KPX Y hyphen -125
+KPX Y e -100
+KPX Y comma -100
+KPX Y colon -25
+KPX Y a -100
+KPX Y A -91
+
+KPX colon space -18
+
+KPX comma space -18
+KPX comma quoteright -18
+KPX comma quotedblright -18
+
+KPX f quoteright 75
+KPX f quotedblright 75
+
+KPX period space -18
+KPX period quoteright -18
+KPX period quotedblright -18
+
+KPX quotedblleft A -74
+
+KPX quotedblright space -18
+
+KPX quoteleft A -74
+
+KPX quoteright s -25
+KPX quoteright d -25
+
+KPX r period -74
+KPX r comma -74
+
+KPX semicolon space -18
+
+KPX space quoteleft -18
+KPX space quotedblleft -18
+KPX space Y -18
+KPX space W -18
+KPX space V -18
+KPX space T -18
+KPX space A -18
+
+KPX v period -100
+KPX v comma -100
+
+KPX w period -100
+KPX w comma -100
+
+KPX y period -100
+KPX y comma -100
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 213 227 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 213 227 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 213 227 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 213 227 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 213 227 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 213 227 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 213 227 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 213 227 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 213 227 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 213 227 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 56 227 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 56 227 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 56 227 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 56 227 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 250 227 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 227 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 227 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 227 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 227 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 227 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 227 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 250 227 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 250 227 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 250 227 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 250 227 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 195 227 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 195 227 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 227 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 139 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 139 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 139 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 139 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 139 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 139 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 121 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 121 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 121 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 121 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 19 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 19 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 19 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 19 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 176 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 176 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 176 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 176 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 176 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 139 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 139 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 102 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/NewCenturySchlbk-BoldItalic.afm b/tlt3.0/library/afm/NewCenturySchlbk-BoldItalic.afm
new file mode 100644
index 0000000..41611c7
--- /dev/null
+++ b/tlt3.0/library/afm/NewCenturySchlbk-BoldItalic.afm
@@ -0,0 +1,603 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue May 28 16:56:07 1991
+Comment UniqueID 35034
+Comment VMusage 31030 37922
+FontName NewCenturySchlbk-BoldItalic
+FullName New Century Schoolbook Bold Italic
+FamilyName New Century Schoolbook
+Weight Bold
+ItalicAngle -16
+IsFixedPitch false
+FontBBox -205 -250 1147 991
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 722
+XHeight 477
+Ascender 737
+Descender -205
+StartCharMetrics 228
+C 32 ; WX 287 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 0 -15 333 737 ;
+C 34 ; WX 400 ; N quotedbl ; B 66 388 428 737 ;
+C 35 ; WX 574 ; N numbersign ; B 30 0 544 690 ;
+C 36 ; WX 574 ; N dollar ; B 9 -120 565 810 ;
+C 37 ; WX 889 ; N percent ; B 54 -28 835 727 ;
+C 38 ; WX 889 ; N ampersand ; B 32 -15 823 737 ;
+C 39 ; WX 259 ; N quoteright ; B 48 388 275 737 ;
+C 40 ; WX 407 ; N parenleft ; B 72 -117 454 745 ;
+C 41 ; WX 407 ; N parenright ; B -70 -117 310 745 ;
+C 42 ; WX 500 ; N asterisk ; B 58 301 498 737 ;
+C 43 ; WX 606 ; N plus ; B 50 0 556 506 ;
+C 44 ; WX 287 ; N comma ; B -57 -192 170 157 ;
+C 45 ; WX 333 ; N hyphen ; B 2 177 263 299 ;
+C 46 ; WX 287 ; N period ; B -20 -15 152 157 ;
+C 47 ; WX 278 ; N slash ; B -41 -15 320 737 ;
+C 48 ; WX 574 ; N zero ; B 21 -15 553 705 ;
+C 49 ; WX 574 ; N one ; B 25 0 489 705 ;
+C 50 ; WX 574 ; N two ; B -38 -3 538 705 ;
+C 51 ; WX 574 ; N three ; B -7 -15 536 705 ;
+C 52 ; WX 574 ; N four ; B -13 0 544 705 ;
+C 53 ; WX 574 ; N five ; B 0 -15 574 705 ;
+C 54 ; WX 574 ; N six ; B 31 -15 574 705 ;
+C 55 ; WX 574 ; N seven ; B 64 -15 593 705 ;
+C 56 ; WX 574 ; N eight ; B 0 -15 552 705 ;
+C 57 ; WX 574 ; N nine ; B 0 -15 543 705 ;
+C 58 ; WX 287 ; N colon ; B -20 -15 237 477 ;
+C 59 ; WX 287 ; N semicolon ; B -57 -192 237 477 ;
+C 60 ; WX 606 ; N less ; B 50 -9 556 515 ;
+C 61 ; WX 606 ; N equal ; B 50 103 556 403 ;
+C 62 ; WX 606 ; N greater ; B 50 -8 556 514 ;
+C 63 ; WX 481 ; N question ; B 79 -15 451 737 ;
+C 64 ; WX 747 ; N at ; B -4 -15 751 737 ;
+C 65 ; WX 741 ; N A ; B -75 0 716 737 ;
+C 66 ; WX 759 ; N B ; B -50 0 721 722 ;
+C 67 ; WX 759 ; N C ; B 37 -15 759 737 ;
+C 68 ; WX 833 ; N D ; B -47 0 796 722 ;
+C 69 ; WX 741 ; N E ; B -41 0 730 722 ;
+C 70 ; WX 704 ; N F ; B -41 0 730 722 ;
+C 71 ; WX 815 ; N G ; B 37 -15 805 737 ;
+C 72 ; WX 870 ; N H ; B -41 0 911 722 ;
+C 73 ; WX 444 ; N I ; B -41 0 485 722 ;
+C 74 ; WX 667 ; N J ; B -20 -15 708 722 ;
+C 75 ; WX 778 ; N K ; B -41 0 832 722 ;
+C 76 ; WX 704 ; N L ; B -41 0 670 722 ;
+C 77 ; WX 944 ; N M ; B -44 0 988 722 ;
+C 78 ; WX 852 ; N N ; B -61 -10 913 722 ;
+C 79 ; WX 833 ; N O ; B 37 -15 796 737 ;
+C 80 ; WX 741 ; N P ; B -41 0 730 722 ;
+C 81 ; WX 833 ; N Q ; B 37 -189 796 737 ;
+C 82 ; WX 796 ; N R ; B -41 -15 749 722 ;
+C 83 ; WX 685 ; N S ; B 1 -15 666 737 ;
+C 84 ; WX 722 ; N T ; B 41 0 759 722 ;
+C 85 ; WX 833 ; N U ; B 88 -15 900 722 ;
+C 86 ; WX 741 ; N V ; B 32 -10 802 722 ;
+C 87 ; WX 944 ; N W ; B 40 -10 1000 722 ;
+C 88 ; WX 741 ; N X ; B -82 0 801 722 ;
+C 89 ; WX 704 ; N Y ; B 13 0 775 722 ;
+C 90 ; WX 704 ; N Z ; B -33 0 711 722 ;
+C 91 ; WX 407 ; N bracketleft ; B 1 -109 464 737 ;
+C 92 ; WX 606 ; N backslash ; B 161 -15 445 737 ;
+C 93 ; WX 407 ; N bracketright ; B -101 -109 362 737 ;
+C 94 ; WX 606 ; N asciicircum ; B 66 325 540 690 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 259 ; N quoteleft ; B 47 388 274 737 ;
+C 97 ; WX 667 ; N a ; B 6 -15 636 477 ;
+C 98 ; WX 611 ; N b ; B 29 -15 557 737 ;
+C 99 ; WX 537 ; N c ; B 0 -15 482 477 ;
+C 100 ; WX 667 ; N d ; B 0 -15 660 737 ;
+C 101 ; WX 519 ; N e ; B 0 -15 479 477 ;
+C 102 ; WX 389 ; N f ; B -48 -205 550 737 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B -63 -205 604 528 ;
+C 104 ; WX 685 ; N h ; B 0 -15 639 737 ;
+C 105 ; WX 389 ; N i ; B 32 -15 345 737 ;
+C 106 ; WX 370 ; N j ; B -205 -205 347 737 ;
+C 107 ; WX 648 ; N k ; B -11 -15 578 737 ;
+C 108 ; WX 389 ; N l ; B 32 -15 375 737 ;
+C 109 ; WX 944 ; N m ; B 0 -15 909 477 ;
+C 110 ; WX 685 ; N n ; B 0 -15 639 477 ;
+C 111 ; WX 574 ; N o ; B 0 -15 530 477 ;
+C 112 ; WX 648 ; N p ; B -119 -205 590 477 ;
+C 113 ; WX 630 ; N q ; B 0 -205 587 477 ;
+C 114 ; WX 519 ; N r ; B 0 0 527 486 ;
+C 115 ; WX 481 ; N s ; B 0 -15 435 477 ;
+C 116 ; WX 407 ; N t ; B 24 -15 403 650 ;
+C 117 ; WX 685 ; N u ; B 30 -15 635 477 ;
+C 118 ; WX 556 ; N v ; B 30 -15 496 477 ;
+C 119 ; WX 833 ; N w ; B 30 -15 773 477 ;
+C 120 ; WX 574 ; N x ; B -46 -15 574 477 ;
+C 121 ; WX 519 ; N y ; B -66 -205 493 477 ;
+C 122 ; WX 519 ; N z ; B -19 -15 473 477 ;
+C 123 ; WX 407 ; N braceleft ; B 52 -109 408 737 ;
+C 124 ; WX 606 ; N bar ; B 249 -250 357 750 ;
+C 125 ; WX 407 ; N braceright ; B -25 -109 331 737 ;
+C 126 ; WX 606 ; N asciitilde ; B 72 160 534 346 ;
+C 161 ; WX 333 ; N exclamdown ; B -44 -205 289 547 ;
+C 162 ; WX 574 ; N cent ; B 30 -144 512 578 ;
+C 163 ; WX 574 ; N sterling ; B -18 -15 566 705 ;
+C 164 ; WX 167 ; N fraction ; B -166 -15 333 705 ;
+C 165 ; WX 574 ; N yen ; B 17 0 629 690 ;
+C 166 ; WX 574 ; N florin ; B -43 -205 575 737 ;
+C 167 ; WX 500 ; N section ; B -30 -146 515 737 ;
+C 168 ; WX 574 ; N currency ; B 27 84 547 605 ;
+C 169 ; WX 287 ; N quotesingle ; B 112 388 250 737 ;
+C 170 ; WX 481 ; N quotedblleft ; B 54 388 521 737 ;
+C 171 ; WX 481 ; N guillemotleft ; B -35 69 449 407 ;
+C 172 ; WX 278 ; N guilsinglleft ; B -25 69 244 407 ;
+C 173 ; WX 278 ; N guilsinglright ; B -26 69 243 407 ;
+C 174 ; WX 685 ; N fi ; B -70 -205 641 737 ;
+C 175 ; WX 685 ; N fl ; B -70 -205 671 737 ;
+C 177 ; WX 500 ; N endash ; B -47 189 479 287 ;
+C 178 ; WX 500 ; N dagger ; B 48 -146 508 737 ;
+C 179 ; WX 500 ; N daggerdbl ; B -60 -150 508 737 ;
+C 180 ; WX 287 ; N periodcentered ; B 57 200 229 372 ;
+C 182 ; WX 650 ; N paragraph ; B 25 -131 681 722 ;
+C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ;
+C 184 ; WX 259 ; N quotesinglbase ; B -57 -192 170 157 ;
+C 185 ; WX 481 ; N quotedblbase ; B -57 -192 412 157 ;
+C 186 ; WX 481 ; N quotedblright ; B 43 388 510 737 ;
+C 187 ; WX 481 ; N guillemotright ; B -31 69 453 407 ;
+C 188 ; WX 1000 ; N ellipsis ; B 81 -15 919 157 ;
+C 189 ; WX 1167 ; N perthousand ; B 20 -28 1147 727 ;
+C 191 ; WX 481 ; N questiondown ; B 0 -205 372 547 ;
+C 193 ; WX 333 ; N grave ; B 74 538 294 722 ;
+C 194 ; WX 333 ; N acute ; B 123 538 372 722 ;
+C 195 ; WX 333 ; N circumflex ; B 23 533 365 705 ;
+C 196 ; WX 333 ; N tilde ; B 28 561 398 690 ;
+C 197 ; WX 333 ; N macron ; B 47 573 404 649 ;
+C 198 ; WX 333 ; N breve ; B 67 535 390 698 ;
+C 199 ; WX 333 ; N dotaccent ; B 145 546 289 690 ;
+C 200 ; WX 333 ; N dieresis ; B 33 546 393 690 ;
+C 202 ; WX 333 ; N ring ; B 111 522 335 746 ;
+C 203 ; WX 333 ; N cedilla ; B -21 -220 225 3 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 15 538 480 722 ;
+C 206 ; WX 333 ; N ogonek ; B 68 -155 246 -10 ;
+C 207 ; WX 333 ; N caron ; B 60 531 403 705 ;
+C 208 ; WX 1000 ; N emdash ; B -47 189 979 287 ;
+C 225 ; WX 889 ; N AE ; B -86 0 915 722 ;
+C 227 ; WX 412 ; N ordfeminine ; B 47 407 460 705 ;
+C 232 ; WX 704 ; N Lslash ; B -41 0 670 722 ;
+C 233 ; WX 833 ; N Oslash ; B 35 -68 798 790 ;
+C 234 ; WX 963 ; N OE ; B 29 0 989 722 ;
+C 235 ; WX 356 ; N ordmasculine ; B 42 407 394 705 ;
+C 241 ; WX 815 ; N ae ; B -18 -15 775 477 ;
+C 245 ; WX 389 ; N dotlessi ; B 32 -15 345 477 ;
+C 248 ; WX 389 ; N lslash ; B 5 -15 390 737 ;
+C 249 ; WX 574 ; N oslash ; B 0 -121 530 583 ;
+C 250 ; WX 852 ; N oe ; B -6 -15 812 477 ;
+C 251 ; WX 574 ; N germandbls ; B -91 -205 540 737 ;
+C -1 ; WX 519 ; N ecircumflex ; B 0 -15 479 705 ;
+C -1 ; WX 519 ; N edieresis ; B 0 -15 486 690 ;
+C -1 ; WX 667 ; N aacute ; B 6 -15 636 722 ;
+C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ;
+C -1 ; WX 389 ; N icircumflex ; B 21 -15 363 698 ;
+C -1 ; WX 685 ; N udieresis ; B 30 -15 635 690 ;
+C -1 ; WX 574 ; N ograve ; B 0 -15 530 722 ;
+C -1 ; WX 685 ; N uacute ; B 30 -15 635 722 ;
+C -1 ; WX 685 ; N ucircumflex ; B 30 -15 635 705 ;
+C -1 ; WX 741 ; N Aacute ; B -75 0 716 947 ;
+C -1 ; WX 389 ; N igrave ; B 32 -15 345 715 ;
+C -1 ; WX 444 ; N Icircumflex ; B -41 0 485 930 ;
+C -1 ; WX 537 ; N ccedilla ; B 0 -220 482 477 ;
+C -1 ; WX 667 ; N adieresis ; B 6 -15 636 690 ;
+C -1 ; WX 741 ; N Ecircumflex ; B -41 0 730 930 ;
+C -1 ; WX 481 ; N scaron ; B 0 -15 477 705 ;
+C -1 ; WX 648 ; N thorn ; B -119 -205 590 737 ;
+C -1 ; WX 950 ; N trademark ; B 42 317 1017 722 ;
+C -1 ; WX 519 ; N egrave ; B 0 -15 479 722 ;
+C -1 ; WX 344 ; N threesuperior ; B 3 273 361 705 ;
+C -1 ; WX 519 ; N zcaron ; B -19 -15 473 695 ;
+C -1 ; WX 667 ; N atilde ; B 6 -15 636 690 ;
+C -1 ; WX 667 ; N aring ; B 6 -15 636 746 ;
+C -1 ; WX 574 ; N ocircumflex ; B 0 -15 530 705 ;
+C -1 ; WX 741 ; N Edieresis ; B -41 0 730 915 ;
+C -1 ; WX 861 ; N threequarters ; B 35 -15 789 705 ;
+C -1 ; WX 519 ; N ydieresis ; B -66 -205 493 690 ;
+C -1 ; WX 519 ; N yacute ; B -66 -205 493 722 ;
+C -1 ; WX 389 ; N iacute ; B 32 -15 370 715 ;
+C -1 ; WX 741 ; N Acircumflex ; B -75 0 716 930 ;
+C -1 ; WX 833 ; N Uacute ; B 88 -15 900 947 ;
+C -1 ; WX 519 ; N eacute ; B 0 -15 479 722 ;
+C -1 ; WX 833 ; N Ograve ; B 37 -15 796 947 ;
+C -1 ; WX 667 ; N agrave ; B 6 -15 636 722 ;
+C -1 ; WX 833 ; N Udieresis ; B 88 -15 900 915 ;
+C -1 ; WX 667 ; N acircumflex ; B 6 -15 636 705 ;
+C -1 ; WX 444 ; N Igrave ; B -41 0 485 947 ;
+C -1 ; WX 344 ; N twosuperior ; B -17 280 362 705 ;
+C -1 ; WX 833 ; N Ugrave ; B 88 -15 900 947 ;
+C -1 ; WX 861 ; N onequarter ; B 17 -15 789 705 ;
+C -1 ; WX 833 ; N Ucircumflex ; B 88 -15 900 930 ;
+C -1 ; WX 685 ; N Scaron ; B 1 -15 666 930 ;
+C -1 ; WX 444 ; N Idieresis ; B -41 0 509 915 ;
+C -1 ; WX 389 ; N idieresis ; B 31 -15 391 683 ;
+C -1 ; WX 741 ; N Egrave ; B -41 0 730 947 ;
+C -1 ; WX 833 ; N Oacute ; B 37 -15 796 947 ;
+C -1 ; WX 606 ; N divide ; B 50 -40 556 546 ;
+C -1 ; WX 741 ; N Atilde ; B -75 0 716 915 ;
+C -1 ; WX 741 ; N Aring ; B -75 0 716 991 ;
+C -1 ; WX 833 ; N Odieresis ; B 37 -15 796 915 ;
+C -1 ; WX 741 ; N Adieresis ; B -75 0 716 915 ;
+C -1 ; WX 852 ; N Ntilde ; B -61 -10 913 915 ;
+C -1 ; WX 704 ; N Zcaron ; B -33 0 711 930 ;
+C -1 ; WX 741 ; N Thorn ; B -41 0 690 722 ;
+C -1 ; WX 444 ; N Iacute ; B -41 0 488 947 ;
+C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ;
+C -1 ; WX 606 ; N multiply ; B 65 15 541 491 ;
+C -1 ; WX 741 ; N Eacute ; B -41 0 730 947 ;
+C -1 ; WX 704 ; N Ydieresis ; B 13 0 775 915 ;
+C -1 ; WX 344 ; N onesuperior ; B 19 282 326 705 ;
+C -1 ; WX 685 ; N ugrave ; B 30 -15 635 722 ;
+C -1 ; WX 606 ; N logicalnot ; B 50 103 556 403 ;
+C -1 ; WX 685 ; N ntilde ; B 0 -15 639 690 ;
+C -1 ; WX 833 ; N Otilde ; B 37 -15 796 915 ;
+C -1 ; WX 574 ; N otilde ; B 0 -15 530 690 ;
+C -1 ; WX 759 ; N Ccedilla ; B 37 -220 759 737 ;
+C -1 ; WX 741 ; N Agrave ; B -75 0 716 947 ;
+C -1 ; WX 861 ; N onehalf ; B 17 -15 798 705 ;
+C -1 ; WX 833 ; N Eth ; B -47 0 796 722 ;
+C -1 ; WX 400 ; N degree ; B 86 419 372 705 ;
+C -1 ; WX 704 ; N Yacute ; B 13 0 775 947 ;
+C -1 ; WX 833 ; N Ocircumflex ; B 37 -15 796 930 ;
+C -1 ; WX 574 ; N oacute ; B 0 -15 530 722 ;
+C -1 ; WX 685 ; N mu ; B -89 -205 635 477 ;
+C -1 ; WX 606 ; N minus ; B 50 199 556 307 ;
+C -1 ; WX 574 ; N eth ; B 0 -15 530 752 ;
+C -1 ; WX 574 ; N odieresis ; B 0 -15 530 690 ;
+C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ;
+C -1 ; WX 606 ; N brokenbar ; B 249 -175 357 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 239
+
+KPX A y -33
+KPX A w -25
+KPX A v -10
+KPX A u -15
+KPX A quoteright -95
+KPX A quotedblright -95
+KPX A Y -70
+KPX A W -84
+KPX A V -100
+KPX A U -32
+KPX A T 5
+KPX A Q 5
+KPX A O 5
+KPX A G 5
+KPX A C 5
+
+KPX B period 15
+KPX B comma 15
+KPX B U 15
+KPX B A -11
+
+KPX C A -5
+
+KPX D period -11
+KPX D comma -11
+KPX D Y 6
+KPX D W -11
+KPX D V -18
+
+KPX F r -27
+KPX F period -91
+KPX F o -47
+KPX F i -41
+KPX F e -41
+KPX F comma -91
+KPX F a -47
+KPX F A -79
+
+KPX J u -39
+KPX J period -74
+KPX J o -40
+KPX J e -33
+KPX J comma -74
+KPX J a -40
+KPX J A -30
+
+KPX K y -48
+KPX K u -4
+KPX K o -4
+KPX K e 18
+
+KPX L y -30
+KPX L quoteright -100
+KPX L quotedblright -100
+KPX L Y -55
+KPX L W -69
+KPX L V -97
+KPX L T -75
+
+KPX N period -49
+KPX N comma -49
+
+KPX O period -18
+KPX O comma -18
+KPX O X -18
+KPX O W -15
+KPX O V -24
+KPX O A -5
+
+KPX P period -100
+KPX P o -40
+KPX P e -33
+KPX P comma -100
+KPX P a -40
+KPX P A -80
+
+KPX R W -14
+KPX R V -24
+
+KPX S period -18
+KPX S comma -18
+
+KPX T y -30
+KPX T w -30
+KPX T u -22
+KPX T r -9
+KPX T period -55
+KPX T o -40
+KPX T i -22
+KPX T hyphen -75
+KPX T h -9
+KPX T e -33
+KPX T comma -55
+KPX T a -40
+KPX T O 11
+KPX T A -60
+
+KPX U period -25
+KPX U comma -25
+KPX U A -42
+
+KPX V u -70
+KPX V semicolon 6
+KPX V period -94
+KPX V o -71
+KPX V i -35
+KPX V hyphen -94
+KPX V e -66
+KPX V comma -94
+KPX V colon -49
+KPX V a -55
+KPX V O -19
+KPX V G -12
+KPX V A -100
+
+KPX W y -41
+KPX W u -25
+KPX W semicolon -22
+KPX W period -86
+KPX W o -33
+KPX W i -27
+KPX W hyphen -61
+KPX W h 5
+KPX W e -39
+KPX W comma -86
+KPX W colon -22
+KPX W a -33
+KPX W O -11
+KPX W A -66
+
+KPX Y u -58
+KPX Y semicolon -55
+KPX Y period -91
+KPX Y o -77
+KPX Y i -22
+KPX Y hyphen -91
+KPX Y e -71
+KPX Y comma -91
+KPX Y colon -55
+KPX Y a -77
+KPX Y A -79
+
+KPX a y -8
+KPX a w -8
+KPX a v 6
+
+KPX b y -6
+KPX b v 8
+KPX b period 6
+KPX b comma 6
+
+KPX c y -20
+KPX c period -8
+KPX c l -13
+KPX c k -8
+KPX c h -18
+KPX c comma -8
+
+KPX colon space -18
+
+KPX comma space -18
+KPX comma quoteright -18
+KPX comma quotedblright -18
+
+KPX d y -15
+KPX d w -15
+
+KPX e y -15
+KPX e x -5
+KPX e w -15
+KPX e p -11
+KPX e g -4
+KPX e b -8
+
+KPX f quoteright 105
+KPX f quotedblright 105
+KPX f period -28
+KPX f o 7
+KPX f l 7
+KPX f i 7
+KPX f e 14
+KPX f dotlessi 7
+KPX f comma -28
+KPX f a 8
+
+KPX g y -11
+KPX g r 11
+KPX g period -5
+KPX g comma -5
+
+KPX h y -20
+
+KPX i v 7
+
+KPX k y -15
+KPX k o -22
+KPX k e -16
+
+KPX l y -7
+KPX l w -7
+
+KPX m y -20
+KPX m u -11
+
+KPX n y -20
+KPX n v -7
+KPX n u -11
+
+KPX o y -11
+KPX o w -8
+KPX o v 6
+
+KPX p y -4
+KPX p period 8
+KPX p comma 8
+
+KPX period space -18
+KPX period quoteright -18
+KPX period quotedblright -18
+
+KPX quotedblleft quoteleft 20
+KPX quotedblleft A -60
+
+KPX quotedblright space -18
+
+KPX quoteleft A -80
+
+KPX quoteright v -16
+KPX quoteright t -22
+KPX quoteright s -46
+KPX quoteright r -9
+KPX quoteright l -22
+KPX quoteright d -41
+
+KPX r y -20
+KPX r v -7
+KPX r u -11
+KPX r t -11
+KPX r semicolon 9
+KPX r s -20
+KPX r quoteright 9
+KPX r period -90
+KPX r p -17
+KPX r o -11
+KPX r l -14
+KPX r k 9
+KPX r i -14
+KPX r hyphen -16
+KPX r g -11
+KPX r e -7
+KPX r d -7
+KPX r comma -90
+KPX r colon 9
+KPX r a -11
+
+KPX s period 11
+KPX s comma 11
+
+KPX semicolon space -18
+
+KPX space quotedblleft -18
+KPX space Y -18
+KPX space W -33
+KPX space V -24
+KPX space T -18
+KPX space A -22
+
+KPX v period -11
+KPX v o -6
+KPX v comma -11
+KPX v a -6
+
+KPX w period -17
+KPX w o -14
+KPX w e -8
+KPX w comma -17
+KPX w a -14
+
+KPX x e 5
+
+KPX y period -25
+KPX y o 8
+KPX y e 15
+KPX y comma -25
+KPX y a 8
+
+KPX z e 4
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 259 225 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 259 225 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 259 225 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 259 225 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 229 245 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 259 225 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 296 225 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 296 225 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 296 225 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 296 225 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 116 225 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 116 225 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 116 225 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 116 225 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 326 225 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 315 225 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 315 225 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 315 225 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 315 225 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 315 225 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 206 225 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 340 225 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 340 225 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 340 225 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 340 225 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 246 225 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 236 225 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 226 225 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 167 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 167 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 167 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 167 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 167 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 167 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 93 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 93 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 93 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 93 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -2 -7 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -2 -7 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -2 -7 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -2 -7 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 176 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 121 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 121 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 121 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 121 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 121 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 74 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 176 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 176 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 176 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 176 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 93 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 93 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 63 -10 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/NewCenturySchlbk-Italic.afm b/tlt3.0/library/afm/NewCenturySchlbk-Italic.afm
new file mode 100644
index 0000000..09d2bff
--- /dev/null
+++ b/tlt3.0/library/afm/NewCenturySchlbk-Italic.afm
@@ -0,0 +1,537 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue May 28 16:40:04 1991
+Comment UniqueID 35028
+Comment VMusage 31423 38315
+FontName NewCenturySchlbk-Italic
+FullName New Century Schoolbook Italic
+FamilyName New Century Schoolbook
+Weight Medium
+ItalicAngle -16
+IsFixedPitch false
+FontBBox -166 -250 994 958
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.006
+Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 722
+XHeight 466
+Ascender 737
+Descender -205
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 17 -15 303 737 ;
+C 34 ; WX 400 ; N quotedbl ; B 127 463 363 737 ;
+C 35 ; WX 556 ; N numbersign ; B 28 0 528 690 ;
+C 36 ; WX 556 ; N dollar ; B 4 -142 536 808 ;
+C 37 ; WX 833 ; N percent ; B 43 -15 790 705 ;
+C 38 ; WX 852 ; N ampersand ; B 24 -15 773 737 ;
+C 39 ; WX 204 ; N quoteright ; B 39 463 229 737 ;
+C 40 ; WX 333 ; N parenleft ; B 53 -117 411 745 ;
+C 41 ; WX 333 ; N parenright ; B -93 -117 265 745 ;
+C 42 ; WX 500 ; N asterisk ; B 80 318 500 737 ;
+C 43 ; WX 606 ; N plus ; B 50 0 556 506 ;
+C 44 ; WX 278 ; N comma ; B -39 -165 151 109 ;
+C 45 ; WX 333 ; N hyphen ; B 32 202 259 274 ;
+C 46 ; WX 278 ; N period ; B 17 -15 141 109 ;
+C 47 ; WX 606 ; N slash ; B 132 -15 474 737 ;
+C 48 ; WX 556 ; N zero ; B 30 -15 526 705 ;
+C 49 ; WX 556 ; N one ; B 50 0 459 705 ;
+C 50 ; WX 556 ; N two ; B -37 0 506 705 ;
+C 51 ; WX 556 ; N three ; B -2 -15 506 705 ;
+C 52 ; WX 556 ; N four ; B -8 0 512 705 ;
+C 53 ; WX 556 ; N five ; B 4 -15 540 705 ;
+C 54 ; WX 556 ; N six ; B 36 -15 548 705 ;
+C 55 ; WX 556 ; N seven ; B 69 -15 561 705 ;
+C 56 ; WX 556 ; N eight ; B 6 -15 526 705 ;
+C 57 ; WX 556 ; N nine ; B 8 -15 520 705 ;
+C 58 ; WX 278 ; N colon ; B 17 -15 229 466 ;
+C 59 ; WX 278 ; N semicolon ; B -39 -165 229 466 ;
+C 60 ; WX 606 ; N less ; B 36 -8 542 514 ;
+C 61 ; WX 606 ; N equal ; B 50 117 556 389 ;
+C 62 ; WX 606 ; N greater ; B 64 -8 570 514 ;
+C 63 ; WX 444 ; N question ; B 102 -15 417 737 ;
+C 64 ; WX 747 ; N at ; B -2 -15 750 737 ;
+C 65 ; WX 704 ; N A ; B -87 0 668 737 ;
+C 66 ; WX 722 ; N B ; B -33 0 670 722 ;
+C 67 ; WX 722 ; N C ; B 40 -15 712 737 ;
+C 68 ; WX 778 ; N D ; B -33 0 738 722 ;
+C 69 ; WX 722 ; N E ; B -33 0 700 722 ;
+C 70 ; WX 667 ; N F ; B -33 0 700 722 ;
+C 71 ; WX 778 ; N G ; B 40 -15 763 737 ;
+C 72 ; WX 833 ; N H ; B -33 0 866 722 ;
+C 73 ; WX 407 ; N I ; B -33 0 435 722 ;
+C 74 ; WX 611 ; N J ; B -14 -15 651 722 ;
+C 75 ; WX 741 ; N K ; B -33 0 816 722 ;
+C 76 ; WX 667 ; N L ; B -33 0 627 722 ;
+C 77 ; WX 944 ; N M ; B -33 0 977 722 ;
+C 78 ; WX 815 ; N N ; B -51 -15 866 722 ;
+C 79 ; WX 778 ; N O ; B 40 -15 738 737 ;
+C 80 ; WX 667 ; N P ; B -33 0 667 722 ;
+C 81 ; WX 778 ; N Q ; B 40 -190 738 737 ;
+C 82 ; WX 741 ; N R ; B -45 -15 692 722 ;
+C 83 ; WX 667 ; N S ; B -6 -15 638 737 ;
+C 84 ; WX 685 ; N T ; B 40 0 725 722 ;
+C 85 ; WX 815 ; N U ; B 93 -15 867 722 ;
+C 86 ; WX 704 ; N V ; B 36 -10 779 722 ;
+C 87 ; WX 926 ; N W ; B 53 -10 978 722 ;
+C 88 ; WX 704 ; N X ; B -75 0 779 722 ;
+C 89 ; WX 685 ; N Y ; B 31 0 760 722 ;
+C 90 ; WX 667 ; N Z ; B -25 0 667 722 ;
+C 91 ; WX 333 ; N bracketleft ; B -55 -109 388 737 ;
+C 92 ; WX 606 ; N backslash ; B 132 -15 474 737 ;
+C 93 ; WX 333 ; N bracketright ; B -77 -109 366 737 ;
+C 94 ; WX 606 ; N asciicircum ; B 89 325 517 690 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 204 ; N quoteleft ; B 39 463 229 737 ;
+C 97 ; WX 574 ; N a ; B 2 -15 524 466 ;
+C 98 ; WX 556 ; N b ; B 32 -15 488 737 ;
+C 99 ; WX 444 ; N c ; B 2 -15 394 466 ;
+C 100 ; WX 611 ; N d ; B 2 -15 585 737 ;
+C 101 ; WX 444 ; N e ; B -6 -15 388 466 ;
+C 102 ; WX 333 ; N f ; B -68 -205 470 737 ; L i fi ; L l fl ;
+C 103 ; WX 537 ; N g ; B -79 -205 523 497 ;
+C 104 ; WX 611 ; N h ; B 14 -15 562 737 ;
+C 105 ; WX 333 ; N i ; B 29 -15 282 715 ;
+C 106 ; WX 315 ; N j ; B -166 -205 318 715 ;
+C 107 ; WX 556 ; N k ; B 0 -15 497 737 ;
+C 108 ; WX 333 ; N l ; B 14 -15 292 737 ;
+C 109 ; WX 889 ; N m ; B 14 -15 840 466 ;
+C 110 ; WX 611 ; N n ; B 14 -15 562 466 ;
+C 111 ; WX 500 ; N o ; B 2 -15 450 466 ;
+C 112 ; WX 574 ; N p ; B -101 -205 506 466 ;
+C 113 ; WX 556 ; N q ; B 2 -205 500 466 ;
+C 114 ; WX 444 ; N r ; B 10 0 434 466 ;
+C 115 ; WX 444 ; N s ; B 2 -15 394 466 ;
+C 116 ; WX 352 ; N t ; B 24 -15 328 619 ;
+C 117 ; WX 611 ; N u ; B 44 -15 556 466 ;
+C 118 ; WX 519 ; N v ; B 31 -15 447 466 ;
+C 119 ; WX 778 ; N w ; B 31 -15 706 466 ;
+C 120 ; WX 500 ; N x ; B -33 -15 471 466 ;
+C 121 ; WX 500 ; N y ; B -83 -205 450 466 ;
+C 122 ; WX 463 ; N z ; B -33 -15 416 466 ;
+C 123 ; WX 333 ; N braceleft ; B 38 -109 394 737 ;
+C 124 ; WX 606 ; N bar ; B 267 -250 339 750 ;
+C 125 ; WX 333 ; N braceright ; B -87 -109 269 737 ;
+C 126 ; WX 606 ; N asciitilde ; B 72 184 534 322 ;
+C 161 ; WX 333 ; N exclamdown ; B -22 -205 264 547 ;
+C 162 ; WX 556 ; N cent ; B 62 -144 486 580 ;
+C 163 ; WX 556 ; N sterling ; B -13 -15 544 705 ;
+C 164 ; WX 167 ; N fraction ; B -134 -15 301 705 ;
+C 165 ; WX 556 ; N yen ; B 40 0 624 690 ;
+C 166 ; WX 556 ; N florin ; B -58 -205 569 737 ;
+C 167 ; WX 500 ; N section ; B -10 -147 480 737 ;
+C 168 ; WX 556 ; N currency ; B 26 93 530 597 ;
+C 169 ; WX 278 ; N quotesingle ; B 151 463 237 737 ;
+C 170 ; WX 389 ; N quotedblleft ; B 39 463 406 737 ;
+C 171 ; WX 426 ; N guillemotleft ; B -15 74 402 402 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 40 74 259 402 ;
+C 173 ; WX 333 ; N guilsinglright ; B 40 74 259 402 ;
+C 174 ; WX 611 ; N fi ; B -68 -205 555 737 ;
+C 175 ; WX 611 ; N fl ; B -68 -205 587 737 ;
+C 177 ; WX 500 ; N endash ; B -27 208 487 268 ;
+C 178 ; WX 500 ; N dagger ; B 51 -147 506 737 ;
+C 179 ; WX 500 ; N daggerdbl ; B -54 -147 506 737 ;
+C 180 ; WX 278 ; N periodcentered ; B 71 238 207 374 ;
+C 182 ; WX 650 ; N paragraph ; B 48 -132 665 722 ;
+C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ;
+C 184 ; WX 204 ; N quotesinglbase ; B -78 -165 112 109 ;
+C 185 ; WX 389 ; N quotedblbase ; B -78 -165 289 109 ;
+C 186 ; WX 389 ; N quotedblright ; B 39 463 406 737 ;
+C 187 ; WX 426 ; N guillemotright ; B -15 74 402 402 ;
+C 188 ; WX 1000 ; N ellipsis ; B 59 -15 849 109 ;
+C 189 ; WX 1000 ; N perthousand ; B 6 -15 994 705 ;
+C 191 ; WX 444 ; N questiondown ; B -3 -205 312 547 ;
+C 193 ; WX 333 ; N grave ; B 71 518 262 690 ;
+C 194 ; WX 333 ; N acute ; B 132 518 355 690 ;
+C 195 ; WX 333 ; N circumflex ; B 37 518 331 690 ;
+C 196 ; WX 333 ; N tilde ; B 52 547 383 649 ;
+C 197 ; WX 333 ; N macron ; B 52 560 363 610 ;
+C 198 ; WX 333 ; N breve ; B 69 518 370 677 ;
+C 199 ; WX 333 ; N dotaccent ; B 146 544 248 646 ;
+C 200 ; WX 333 ; N dieresis ; B 59 544 359 646 ;
+C 202 ; WX 333 ; N ring ; B 114 512 314 712 ;
+C 203 ; WX 333 ; N cedilla ; B 3 -215 215 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 32 518 455 690 ;
+C 206 ; WX 333 ; N ogonek ; B 68 -215 254 0 ;
+C 207 ; WX 333 ; N caron ; B 73 518 378 690 ;
+C 208 ; WX 1000 ; N emdash ; B -27 208 987 268 ;
+C 225 ; WX 870 ; N AE ; B -87 0 888 722 ;
+C 227 ; WX 422 ; N ordfeminine ; B 72 416 420 705 ;
+C 232 ; WX 667 ; N Lslash ; B -33 0 627 722 ;
+C 233 ; WX 778 ; N Oslash ; B 16 -68 748 780 ;
+C 234 ; WX 981 ; N OE ; B 40 0 975 722 ;
+C 235 ; WX 372 ; N ordmasculine ; B 66 416 370 705 ;
+C 241 ; WX 722 ; N ae ; B -18 -15 666 466 ;
+C 245 ; WX 333 ; N dotlessi ; B 29 -15 282 466 ;
+C 248 ; WX 333 ; N lslash ; B -25 -15 340 737 ;
+C 249 ; WX 500 ; N oslash ; B 2 -121 450 549 ;
+C 250 ; WX 778 ; N oe ; B 2 -15 722 466 ;
+C 251 ; WX 556 ; N germandbls ; B -76 -205 525 737 ;
+C -1 ; WX 444 ; N ecircumflex ; B -6 -15 388 690 ;
+C -1 ; WX 444 ; N edieresis ; B -6 -15 415 646 ;
+C -1 ; WX 574 ; N aacute ; B 2 -15 524 690 ;
+C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ;
+C -1 ; WX 333 ; N icircumflex ; B 29 -15 331 690 ;
+C -1 ; WX 611 ; N udieresis ; B 44 -15 556 646 ;
+C -1 ; WX 500 ; N ograve ; B 2 -15 450 690 ;
+C -1 ; WX 611 ; N uacute ; B 44 -15 556 690 ;
+C -1 ; WX 611 ; N ucircumflex ; B 44 -15 556 690 ;
+C -1 ; WX 704 ; N Aacute ; B -87 0 668 946 ;
+C -1 ; WX 333 ; N igrave ; B 29 -15 282 690 ;
+C -1 ; WX 407 ; N Icircumflex ; B -33 0 435 946 ;
+C -1 ; WX 444 ; N ccedilla ; B 2 -215 394 466 ;
+C -1 ; WX 574 ; N adieresis ; B 2 -15 524 646 ;
+C -1 ; WX 722 ; N Ecircumflex ; B -33 0 700 946 ;
+C -1 ; WX 444 ; N scaron ; B 2 -15 434 690 ;
+C -1 ; WX 574 ; N thorn ; B -101 -205 506 737 ;
+C -1 ; WX 950 ; N trademark ; B 32 318 968 722 ;
+C -1 ; WX 444 ; N egrave ; B -6 -15 388 690 ;
+C -1 ; WX 333 ; N threesuperior ; B 22 273 359 705 ;
+C -1 ; WX 463 ; N zcaron ; B -33 -15 443 690 ;
+C -1 ; WX 574 ; N atilde ; B 2 -15 524 649 ;
+C -1 ; WX 574 ; N aring ; B 2 -15 524 712 ;
+C -1 ; WX 500 ; N ocircumflex ; B 2 -15 450 690 ;
+C -1 ; WX 722 ; N Edieresis ; B -33 0 700 902 ;
+C -1 ; WX 834 ; N threequarters ; B 22 -15 782 705 ;
+C -1 ; WX 500 ; N ydieresis ; B -83 -205 450 646 ;
+C -1 ; WX 500 ; N yacute ; B -83 -205 450 690 ;
+C -1 ; WX 333 ; N iacute ; B 29 -15 355 690 ;
+C -1 ; WX 704 ; N Acircumflex ; B -87 0 668 946 ;
+C -1 ; WX 815 ; N Uacute ; B 93 -15 867 946 ;
+C -1 ; WX 444 ; N eacute ; B -6 -15 411 690 ;
+C -1 ; WX 778 ; N Ograve ; B 40 -15 738 946 ;
+C -1 ; WX 574 ; N agrave ; B 2 -15 524 690 ;
+C -1 ; WX 815 ; N Udieresis ; B 93 -15 867 902 ;
+C -1 ; WX 574 ; N acircumflex ; B 2 -15 524 690 ;
+C -1 ; WX 407 ; N Igrave ; B -33 0 435 946 ;
+C -1 ; WX 333 ; N twosuperior ; B 0 282 359 705 ;
+C -1 ; WX 815 ; N Ugrave ; B 93 -15 867 946 ;
+C -1 ; WX 834 ; N onequarter ; B 34 -15 782 705 ;
+C -1 ; WX 815 ; N Ucircumflex ; B 93 -15 867 946 ;
+C -1 ; WX 667 ; N Scaron ; B -6 -15 638 946 ;
+C -1 ; WX 407 ; N Idieresis ; B -33 0 456 902 ;
+C -1 ; WX 333 ; N idieresis ; B 29 -15 359 646 ;
+C -1 ; WX 722 ; N Egrave ; B -33 0 700 946 ;
+C -1 ; WX 778 ; N Oacute ; B 40 -15 738 946 ;
+C -1 ; WX 606 ; N divide ; B 50 -22 556 528 ;
+C -1 ; WX 704 ; N Atilde ; B -87 0 668 905 ;
+C -1 ; WX 704 ; N Aring ; B -87 0 668 958 ;
+C -1 ; WX 778 ; N Odieresis ; B 40 -15 738 902 ;
+C -1 ; WX 704 ; N Adieresis ; B -87 0 668 902 ;
+C -1 ; WX 815 ; N Ntilde ; B -51 -15 866 905 ;
+C -1 ; WX 667 ; N Zcaron ; B -25 0 667 946 ;
+C -1 ; WX 667 ; N Thorn ; B -33 0 627 722 ;
+C -1 ; WX 407 ; N Iacute ; B -33 0 452 946 ;
+C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ;
+C -1 ; WX 606 ; N multiply ; B 74 24 532 482 ;
+C -1 ; WX 722 ; N Eacute ; B -33 0 700 946 ;
+C -1 ; WX 685 ; N Ydieresis ; B 31 0 760 902 ;
+C -1 ; WX 333 ; N onesuperior ; B 34 282 311 705 ;
+C -1 ; WX 611 ; N ugrave ; B 44 -15 556 690 ;
+C -1 ; WX 606 ; N logicalnot ; B 50 108 556 389 ;
+C -1 ; WX 611 ; N ntilde ; B 14 -15 562 649 ;
+C -1 ; WX 778 ; N Otilde ; B 40 -15 738 905 ;
+C -1 ; WX 500 ; N otilde ; B 2 -15 467 649 ;
+C -1 ; WX 722 ; N Ccedilla ; B 40 -215 712 737 ;
+C -1 ; WX 704 ; N Agrave ; B -87 0 668 946 ;
+C -1 ; WX 834 ; N onehalf ; B 34 -15 776 705 ;
+C -1 ; WX 778 ; N Eth ; B -33 0 738 722 ;
+C -1 ; WX 400 ; N degree ; B 86 419 372 705 ;
+C -1 ; WX 685 ; N Yacute ; B 31 0 760 946 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 40 -15 738 946 ;
+C -1 ; WX 500 ; N oacute ; B 2 -15 450 690 ;
+C -1 ; WX 611 ; N mu ; B -60 -205 556 466 ;
+C -1 ; WX 606 ; N minus ; B 50 217 556 289 ;
+C -1 ; WX 500 ; N eth ; B 2 -15 450 737 ;
+C -1 ; WX 500 ; N odieresis ; B 2 -15 450 646 ;
+C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ;
+C -1 ; WX 606 ; N brokenbar ; B 267 -175 339 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 181
+
+KPX A y -55
+KPX A w -18
+KPX A v -18
+KPX A u -18
+KPX A quoteright -125
+KPX A quotedblright -125
+KPX A Y -55
+KPX A W -74
+KPX A V -74
+KPX A U -37
+KPX A T -30
+KPX A Q -18
+KPX A O -18
+KPX A G -18
+KPX A C -18
+
+KPX B period -50
+KPX B comma -50
+
+KPX C period -50
+KPX C comma -50
+
+KPX D period -50
+KPX D comma -50
+KPX D Y -18
+KPX D W -18
+KPX D V -18
+
+KPX F r -55
+KPX F period -125
+KPX F o -55
+KPX F i -10
+KPX F e -55
+KPX F comma -125
+KPX F a -55
+KPX F A -35
+
+KPX G period -50
+KPX G comma -50
+
+KPX J u -18
+KPX J period -100
+KPX J o -37
+KPX J e -37
+KPX J comma -100
+KPX J a -37
+KPX J A -18
+
+KPX L y -50
+KPX L quoteright -125
+KPX L quotedblright -125
+KPX L Y -100
+KPX L W -100
+KPX L V -100
+KPX L T -100
+
+KPX N period -60
+KPX N comma -60
+
+KPX O period -50
+KPX O comma -50
+KPX O Y -18
+KPX O X -18
+KPX O V -18
+KPX O T 18
+
+KPX P period -125
+KPX P o -55
+KPX P e -55
+KPX P comma -125
+KPX P a -55
+KPX P A -50
+
+KPX Q period -20
+KPX Q comma -20
+
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+KPX R U -18
+
+KPX S period -50
+KPX S comma -50
+
+KPX T y -50
+KPX T w -50
+KPX T u -50
+KPX T semicolon -50
+KPX T r -50
+KPX T period -100
+KPX T o -74
+KPX T i -18
+KPX T hyphen -100
+KPX T h -25
+KPX T e -74
+KPX T comma -100
+KPX T colon -50
+KPX T a -74
+KPX T O 18
+
+KPX U period -100
+KPX U comma -100
+KPX U A -18
+
+KPX V u -75
+KPX V semicolon -75
+KPX V period -100
+KPX V o -75
+KPX V i -50
+KPX V hyphen -100
+KPX V e -75
+KPX V comma -100
+KPX V colon -75
+KPX V a -75
+KPX V A -37
+
+KPX W y -55
+KPX W u -55
+KPX W semicolon -75
+KPX W period -100
+KPX W o -55
+KPX W i -20
+KPX W hyphen -75
+KPX W h -20
+KPX W e -55
+KPX W comma -100
+KPX W colon -75
+KPX W a -55
+KPX W A -55
+
+KPX Y u -100
+KPX Y semicolon -75
+KPX Y period -100
+KPX Y o -100
+KPX Y i -25
+KPX Y hyphen -100
+KPX Y e -100
+KPX Y comma -100
+KPX Y colon -75
+KPX Y a -100
+KPX Y A -55
+
+KPX b period -50
+KPX b comma -50
+KPX b b -10
+
+KPX c period -50
+KPX c k -18
+KPX c h -18
+KPX c comma -50
+
+KPX colon space -37
+
+KPX comma space -37
+KPX comma quoteright -37
+KPX comma quotedblright -37
+
+KPX e period -37
+KPX e comma -37
+
+KPX f quoteright 75
+KPX f quotedblright 75
+KPX f period -75
+KPX f o -10
+KPX f comma -75
+
+KPX g period -50
+KPX g comma -50
+
+KPX l y -10
+
+KPX o period -50
+KPX o comma -50
+
+KPX p period -50
+KPX p comma -50
+
+KPX period space -37
+KPX period quoteright -37
+KPX period quotedblright -37
+
+KPX quotedblleft A -75
+
+KPX quotedblright space -37
+
+KPX quoteleft quoteleft -37
+KPX quoteleft A -75
+
+KPX quoteright s -25
+KPX quoteright quoteright -37
+KPX quoteright d -37
+
+KPX r semicolon -25
+KPX r s -10
+KPX r period -125
+KPX r k -18
+KPX r hyphen -75
+KPX r comma -125
+KPX r colon -25
+
+KPX s period -50
+KPX s comma -50
+
+KPX semicolon space -37
+
+KPX space quoteleft -37
+KPX space quotedblleft -37
+KPX space Y -37
+KPX space W -37
+KPX space V -37
+KPX space T -37
+KPX space A -37
+
+KPX v period -75
+KPX v comma -75
+
+KPX w period -75
+KPX w comma -75
+
+KPX y period -75
+KPX y comma -75
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 246 256 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 246 256 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 231 256 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 246 256 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 216 246 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 231 256 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 255 256 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 255 256 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 255 256 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 255 256 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 97 256 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 97 256 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 97 256 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 97 256 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 301 256 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 283 256 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 283 256 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 283 256 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 283 256 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 283 256 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 227 256 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 301 256 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 301 256 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 301 256 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 301 256 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 256 256 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 236 256 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 227 256 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 121 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 121 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 121 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 121 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 121 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 121 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 56 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 65 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/NewCenturySchlbk-Roman.afm b/tlt3.0/library/afm/NewCenturySchlbk-Roman.afm
new file mode 100644
index 0000000..80e9221
--- /dev/null
+++ b/tlt3.0/library/afm/NewCenturySchlbk-Roman.afm
@@ -0,0 +1,525 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue May 28 16:31:51 1991
+Comment UniqueID 35025
+Comment VMusage 30420 37312
+FontName NewCenturySchlbk-Roman
+FullName New Century Schoolbook Roman
+FamilyName New Century Schoolbook
+Weight Roman
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -195 -250 1000 965
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated.  All Rights Reserved.
+EncodingScheme AdobeStandardEncoding
+CapHeight 722
+XHeight 464
+Ascender 737
+Descender -205
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 296 ; N exclam ; B 86 -15 210 737 ;
+C 34 ; WX 389 ; N quotedbl ; B 61 443 328 737 ;
+C 35 ; WX 556 ; N numbersign ; B 28 0 528 690 ;
+C 36 ; WX 556 ; N dollar ; B 45 -138 511 813 ;
+C 37 ; WX 833 ; N percent ; B 43 -15 790 705 ;
+C 38 ; WX 815 ; N ampersand ; B 51 -15 775 737 ;
+C 39 ; WX 204 ; N quoteright ; B 25 443 179 737 ;
+C 40 ; WX 333 ; N parenleft ; B 40 -117 279 745 ;
+C 41 ; WX 333 ; N parenright ; B 54 -117 293 745 ;
+C 42 ; WX 500 ; N asterisk ; B 57 306 443 737 ;
+C 43 ; WX 606 ; N plus ; B 50 0 556 506 ;
+C 44 ; WX 278 ; N comma ; B 62 -185 216 109 ;
+C 45 ; WX 333 ; N hyphen ; B 42 199 291 277 ;
+C 46 ; WX 278 ; N period ; B 77 -15 201 109 ;
+C 47 ; WX 278 ; N slash ; B -32 -15 310 737 ;
+C 48 ; WX 556 ; N zero ; B 42 -15 514 705 ;
+C 49 ; WX 556 ; N one ; B 100 0 496 705 ;
+C 50 ; WX 556 ; N two ; B 35 0 505 705 ;
+C 51 ; WX 556 ; N three ; B 42 -15 498 705 ;
+C 52 ; WX 556 ; N four ; B 28 0 528 705 ;
+C 53 ; WX 556 ; N five ; B 46 -15 502 705 ;
+C 54 ; WX 556 ; N six ; B 41 -15 515 705 ;
+C 55 ; WX 556 ; N seven ; B 59 -15 508 705 ;
+C 56 ; WX 556 ; N eight ; B 42 -15 514 705 ;
+C 57 ; WX 556 ; N nine ; B 41 -15 515 705 ;
+C 58 ; WX 278 ; N colon ; B 77 -15 201 474 ;
+C 59 ; WX 278 ; N semicolon ; B 62 -185 216 474 ;
+C 60 ; WX 606 ; N less ; B 50 -8 556 514 ;
+C 61 ; WX 606 ; N equal ; B 50 117 556 389 ;
+C 62 ; WX 606 ; N greater ; B 50 -8 556 514 ;
+C 63 ; WX 444 ; N question ; B 29 -15 415 737 ;
+C 64 ; WX 737 ; N at ; B -8 -15 744 737 ;
+C 65 ; WX 722 ; N A ; B -8 0 730 737 ;
+C 66 ; WX 722 ; N B ; B 29 0 669 722 ;
+C 67 ; WX 722 ; N C ; B 45 -15 668 737 ;
+C 68 ; WX 778 ; N D ; B 29 0 733 722 ;
+C 69 ; WX 722 ; N E ; B 29 0 663 722 ;
+C 70 ; WX 667 ; N F ; B 29 0 638 722 ;
+C 71 ; WX 778 ; N G ; B 45 -15 775 737 ;
+C 72 ; WX 833 ; N H ; B 29 0 804 722 ;
+C 73 ; WX 407 ; N I ; B 38 0 369 722 ;
+C 74 ; WX 556 ; N J ; B 5 -15 540 722 ;
+C 75 ; WX 778 ; N K ; B 29 0 803 722 ;
+C 76 ; WX 667 ; N L ; B 29 0 644 722 ;
+C 77 ; WX 944 ; N M ; B 29 0 915 722 ;
+C 78 ; WX 815 ; N N ; B 24 -15 791 722 ;
+C 79 ; WX 778 ; N O ; B 45 -15 733 737 ;
+C 80 ; WX 667 ; N P ; B 29 0 650 722 ;
+C 81 ; WX 778 ; N Q ; B 45 -190 748 737 ;
+C 82 ; WX 722 ; N R ; B 29 -15 713 722 ;
+C 83 ; WX 630 ; N S ; B 47 -15 583 737 ;
+C 84 ; WX 667 ; N T ; B 19 0 648 722 ;
+C 85 ; WX 815 ; N U ; B 16 -15 799 722 ;
+C 86 ; WX 722 ; N V ; B -8 -10 730 722 ;
+C 87 ; WX 981 ; N W ; B 5 -10 976 722 ;
+C 88 ; WX 704 ; N X ; B -8 0 712 722 ;
+C 89 ; WX 704 ; N Y ; B -11 0 715 722 ;
+C 90 ; WX 611 ; N Z ; B 24 0 576 722 ;
+C 91 ; WX 333 ; N bracketleft ; B 126 -109 315 737 ;
+C 92 ; WX 606 ; N backslash ; B 132 -15 474 737 ;
+C 93 ; WX 333 ; N bracketright ; B 18 -109 207 737 ;
+C 94 ; WX 606 ; N asciicircum ; B 89 325 517 690 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 204 ; N quoteleft ; B 25 443 179 737 ;
+C 97 ; WX 556 ; N a ; B 44 -15 542 479 ;
+C 98 ; WX 556 ; N b ; B 10 -15 522 737 ;
+C 99 ; WX 444 ; N c ; B 34 -15 426 479 ;
+C 100 ; WX 574 ; N d ; B 34 -15 552 737 ;
+C 101 ; WX 500 ; N e ; B 34 -15 466 479 ;
+C 102 ; WX 333 ; N f ; B 18 0 437 737 ; L i fi ; L l fl ;
+C 103 ; WX 537 ; N g ; B 23 -205 542 494 ;
+C 104 ; WX 611 ; N h ; B 7 0 592 737 ;
+C 105 ; WX 315 ; N i ; B 18 0 286 722 ;
+C 106 ; WX 296 ; N j ; B -86 -205 216 722 ;
+C 107 ; WX 593 ; N k ; B 10 0 589 737 ;
+C 108 ; WX 315 ; N l ; B 18 0 286 737 ;
+C 109 ; WX 889 ; N m ; B 26 0 863 479 ;
+C 110 ; WX 611 ; N n ; B 22 0 589 479 ;
+C 111 ; WX 500 ; N o ; B 34 -15 466 479 ;
+C 112 ; WX 574 ; N p ; B 22 -205 540 479 ;
+C 113 ; WX 556 ; N q ; B 34 -205 552 479 ;
+C 114 ; WX 444 ; N r ; B 18 0 434 479 ;
+C 115 ; WX 463 ; N s ; B 46 -15 417 479 ;
+C 116 ; WX 389 ; N t ; B 18 -15 371 666 ;
+C 117 ; WX 611 ; N u ; B 22 -15 589 464 ;
+C 118 ; WX 537 ; N v ; B -6 -10 515 464 ;
+C 119 ; WX 778 ; N w ; B 1 -10 749 464 ;
+C 120 ; WX 537 ; N x ; B 8 0 529 464 ;
+C 121 ; WX 537 ; N y ; B 4 -205 533 464 ;
+C 122 ; WX 481 ; N z ; B 42 0 439 464 ;
+C 123 ; WX 333 ; N braceleft ; B 54 -109 279 737 ;
+C 124 ; WX 606 ; N bar ; B 267 -250 339 750 ;
+C 125 ; WX 333 ; N braceright ; B 54 -109 279 737 ;
+C 126 ; WX 606 ; N asciitilde ; B 72 184 534 322 ;
+C 161 ; WX 296 ; N exclamdown ; B 86 -205 210 547 ;
+C 162 ; WX 556 ; N cent ; B 74 -141 482 584 ;
+C 163 ; WX 556 ; N sterling ; B 18 -15 538 705 ;
+C 164 ; WX 167 ; N fraction ; B -195 -15 362 705 ;
+C 165 ; WX 556 ; N yen ; B -1 0 557 690 ;
+C 166 ; WX 556 ; N florin ; B 0 -205 538 737 ;
+C 167 ; WX 500 ; N section ; B 55 -147 445 737 ;
+C 168 ; WX 556 ; N currency ; B 26 93 530 597 ;
+C 169 ; WX 204 ; N quotesingle ; B 59 443 145 737 ;
+C 170 ; WX 389 ; N quotedblleft ; B 25 443 364 737 ;
+C 171 ; WX 426 ; N guillemotleft ; B 39 78 387 398 ;
+C 172 ; WX 259 ; N guilsinglleft ; B 39 78 220 398 ;
+C 173 ; WX 259 ; N guilsinglright ; B 39 78 220 398 ;
+C 174 ; WX 611 ; N fi ; B 18 0 582 737 ;
+C 175 ; WX 611 ; N fl ; B 18 0 582 737 ;
+C 177 ; WX 556 ; N endash ; B 0 208 556 268 ;
+C 178 ; WX 500 ; N dagger ; B 42 -147 458 737 ;
+C 179 ; WX 500 ; N daggerdbl ; B 42 -149 458 737 ;
+C 180 ; WX 278 ; N periodcentered ; B 71 238 207 374 ;
+C 182 ; WX 606 ; N paragraph ; B 60 -132 546 722 ;
+C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ;
+C 184 ; WX 204 ; N quotesinglbase ; B 25 -185 179 109 ;
+C 185 ; WX 389 ; N quotedblbase ; B 25 -185 364 109 ;
+C 186 ; WX 389 ; N quotedblright ; B 25 443 364 737 ;
+C 187 ; WX 426 ; N guillemotright ; B 39 78 387 398 ;
+C 188 ; WX 1000 ; N ellipsis ; B 105 -15 895 109 ;
+C 189 ; WX 1000 ; N perthousand ; B 6 -15 994 705 ;
+C 191 ; WX 444 ; N questiondown ; B 29 -205 415 547 ;
+C 193 ; WX 333 ; N grave ; B 17 528 242 699 ;
+C 194 ; WX 333 ; N acute ; B 91 528 316 699 ;
+C 195 ; WX 333 ; N circumflex ; B 10 528 323 695 ;
+C 196 ; WX 333 ; N tilde ; B 1 553 332 655 ;
+C 197 ; WX 333 ; N macron ; B 10 568 323 623 ;
+C 198 ; WX 333 ; N breve ; B 25 528 308 685 ;
+C 199 ; WX 333 ; N dotaccent ; B 116 543 218 645 ;
+C 200 ; WX 333 ; N dieresis ; B 16 543 317 645 ;
+C 202 ; WX 333 ; N ring ; B 66 522 266 722 ;
+C 203 ; WX 333 ; N cedilla ; B 29 -215 237 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -9 528 416 699 ;
+C 206 ; WX 333 ; N ogonek ; B 68 -215 254 0 ;
+C 207 ; WX 333 ; N caron ; B 10 528 323 695 ;
+C 208 ; WX 1000 ; N emdash ; B 0 208 1000 268 ;
+C 225 ; WX 1000 ; N AE ; B 0 0 962 722 ;
+C 227 ; WX 334 ; N ordfeminine ; B -4 407 338 705 ;
+C 232 ; WX 667 ; N Lslash ; B 29 0 644 722 ;
+C 233 ; WX 778 ; N Oslash ; B 45 -56 733 778 ;
+C 234 ; WX 1000 ; N OE ; B 21 0 979 722 ;
+C 235 ; WX 300 ; N ordmasculine ; B 4 407 296 705 ;
+C 241 ; WX 796 ; N ae ; B 34 -15 762 479 ;
+C 245 ; WX 315 ; N dotlessi ; B 18 0 286 464 ;
+C 248 ; WX 315 ; N lslash ; B 18 0 286 737 ;
+C 249 ; WX 500 ; N oslash ; B 34 -97 466 561 ;
+C 250 ; WX 833 ; N oe ; B 34 -15 799 479 ;
+C 251 ; WX 574 ; N germandbls ; B 30 -15 537 737 ;
+C -1 ; WX 500 ; N ecircumflex ; B 34 -15 466 695 ;
+C -1 ; WX 500 ; N edieresis ; B 34 -15 466 645 ;
+C -1 ; WX 556 ; N aacute ; B 44 -15 542 699 ;
+C -1 ; WX 737 ; N registered ; B -8 -15 744 737 ;
+C -1 ; WX 315 ; N icircumflex ; B 1 0 314 695 ;
+C -1 ; WX 611 ; N udieresis ; B 22 -15 589 645 ;
+C -1 ; WX 500 ; N ograve ; B 34 -15 466 699 ;
+C -1 ; WX 611 ; N uacute ; B 22 -15 589 699 ;
+C -1 ; WX 611 ; N ucircumflex ; B 22 -15 589 695 ;
+C -1 ; WX 722 ; N Aacute ; B -8 0 730 937 ;
+C -1 ; WX 315 ; N igrave ; B 8 0 286 699 ;
+C -1 ; WX 407 ; N Icircumflex ; B 38 0 369 933 ;
+C -1 ; WX 444 ; N ccedilla ; B 34 -215 426 479 ;
+C -1 ; WX 556 ; N adieresis ; B 44 -15 542 645 ;
+C -1 ; WX 722 ; N Ecircumflex ; B 29 0 663 933 ;
+C -1 ; WX 463 ; N scaron ; B 46 -15 417 695 ;
+C -1 ; WX 574 ; N thorn ; B 22 -205 540 737 ;
+C -1 ; WX 1000 ; N trademark ; B 32 318 968 722 ;
+C -1 ; WX 500 ; N egrave ; B 34 -15 466 699 ;
+C -1 ; WX 333 ; N threesuperior ; B 18 273 315 705 ;
+C -1 ; WX 481 ; N zcaron ; B 42 0 439 695 ;
+C -1 ; WX 556 ; N atilde ; B 44 -15 542 655 ;
+C -1 ; WX 556 ; N aring ; B 44 -15 542 732 ;
+C -1 ; WX 500 ; N ocircumflex ; B 34 -15 466 695 ;
+C -1 ; WX 722 ; N Edieresis ; B 29 0 663 883 ;
+C -1 ; WX 834 ; N threequarters ; B 28 -15 795 705 ;
+C -1 ; WX 537 ; N ydieresis ; B 4 -205 533 645 ;
+C -1 ; WX 537 ; N yacute ; B 4 -205 533 699 ;
+C -1 ; WX 315 ; N iacute ; B 18 0 307 699 ;
+C -1 ; WX 722 ; N Acircumflex ; B -8 0 730 933 ;
+C -1 ; WX 815 ; N Uacute ; B 16 -15 799 937 ;
+C -1 ; WX 500 ; N eacute ; B 34 -15 466 699 ;
+C -1 ; WX 778 ; N Ograve ; B 45 -15 733 937 ;
+C -1 ; WX 556 ; N agrave ; B 44 -15 542 699 ;
+C -1 ; WX 815 ; N Udieresis ; B 16 -15 799 883 ;
+C -1 ; WX 556 ; N acircumflex ; B 44 -15 542 695 ;
+C -1 ; WX 407 ; N Igrave ; B 38 0 369 937 ;
+C -1 ; WX 333 ; N twosuperior ; B 14 282 319 705 ;
+C -1 ; WX 815 ; N Ugrave ; B 16 -15 799 937 ;
+C -1 ; WX 834 ; N onequarter ; B 39 -15 795 705 ;
+C -1 ; WX 815 ; N Ucircumflex ; B 16 -15 799 933 ;
+C -1 ; WX 630 ; N Scaron ; B 47 -15 583 933 ;
+C -1 ; WX 407 ; N Idieresis ; B 38 0 369 883 ;
+C -1 ; WX 315 ; N idieresis ; B 7 0 308 645 ;
+C -1 ; WX 722 ; N Egrave ; B 29 0 663 937 ;
+C -1 ; WX 778 ; N Oacute ; B 45 -15 733 937 ;
+C -1 ; WX 606 ; N divide ; B 50 -22 556 528 ;
+C -1 ; WX 722 ; N Atilde ; B -8 0 730 893 ;
+C -1 ; WX 722 ; N Aring ; B -8 0 730 965 ;
+C -1 ; WX 778 ; N Odieresis ; B 45 -15 733 883 ;
+C -1 ; WX 722 ; N Adieresis ; B -8 0 730 883 ;
+C -1 ; WX 815 ; N Ntilde ; B 24 -15 791 893 ;
+C -1 ; WX 611 ; N Zcaron ; B 24 0 576 933 ;
+C -1 ; WX 667 ; N Thorn ; B 29 0 650 722 ;
+C -1 ; WX 407 ; N Iacute ; B 38 0 369 937 ;
+C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ;
+C -1 ; WX 606 ; N multiply ; B 74 24 532 482 ;
+C -1 ; WX 722 ; N Eacute ; B 29 0 663 937 ;
+C -1 ; WX 704 ; N Ydieresis ; B -11 0 715 883 ;
+C -1 ; WX 333 ; N onesuperior ; B 39 282 294 705 ;
+C -1 ; WX 611 ; N ugrave ; B 22 -15 589 699 ;
+C -1 ; WX 606 ; N logicalnot ; B 50 108 556 389 ;
+C -1 ; WX 611 ; N ntilde ; B 22 0 589 655 ;
+C -1 ; WX 778 ; N Otilde ; B 45 -15 733 893 ;
+C -1 ; WX 500 ; N otilde ; B 34 -15 466 655 ;
+C -1 ; WX 722 ; N Ccedilla ; B 45 -215 668 737 ;
+C -1 ; WX 722 ; N Agrave ; B -8 0 730 937 ;
+C -1 ; WX 834 ; N onehalf ; B 39 -15 820 705 ;
+C -1 ; WX 778 ; N Eth ; B 29 0 733 722 ;
+C -1 ; WX 400 ; N degree ; B 57 419 343 705 ;
+C -1 ; WX 704 ; N Yacute ; B -11 0 715 937 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 45 -15 733 933 ;
+C -1 ; WX 500 ; N oacute ; B 34 -15 466 699 ;
+C -1 ; WX 611 ; N mu ; B 22 -205 589 464 ;
+C -1 ; WX 606 ; N minus ; B 50 217 556 289 ;
+C -1 ; WX 500 ; N eth ; B 34 -15 466 752 ;
+C -1 ; WX 500 ; N odieresis ; B 34 -15 466 645 ;
+C -1 ; WX 737 ; N copyright ; B -8 -15 744 737 ;
+C -1 ; WX 606 ; N brokenbar ; B 267 -175 339 675 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 169
+
+KPX A y -37
+KPX A w -25
+KPX A v -37
+KPX A quoteright -74
+KPX A quotedblright -74
+KPX A Y -75
+KPX A W -50
+KPX A V -75
+KPX A U -30
+KPX A T -18
+
+KPX B period -37
+KPX B comma -37
+KPX B A -18
+
+KPX C period -37
+KPX C comma -37
+KPX C A -18
+
+KPX D period -37
+KPX D comma -37
+KPX D Y -18
+KPX D V -18
+
+KPX F r -10
+KPX F period -125
+KPX F o -55
+KPX F i -10
+KPX F e -55
+KPX F comma -125
+KPX F a -65
+KPX F A -50
+
+KPX G period -37
+KPX G comma -37
+
+KPX J u -25
+KPX J period -74
+KPX J o -25
+KPX J e -25
+KPX J comma -74
+KPX J a -25
+KPX J A -18
+
+KPX K y -25
+KPX K o 10
+KPX K e 10
+
+KPX L y -25
+KPX L quoteright -100
+KPX L quotedblright -100
+KPX L Y -74
+KPX L W -74
+KPX L V -91
+KPX L T -75
+
+KPX N period -55
+KPX N comma -55
+
+KPX O period -37
+KPX O comma -37
+KPX O Y -18
+KPX O V -18
+KPX O T 10
+
+KPX P period -125
+KPX P o -37
+KPX P e -37
+KPX P comma -125
+KPX P a -37
+KPX P A -55
+
+KPX Q period -25
+KPX Q comma -25
+
+KPX S period -37
+KPX S comma -37
+
+KPX T semicolon -37
+KPX T period -125
+KPX T o -55
+KPX T hyphen -100
+KPX T e -55
+KPX T comma -125
+KPX T colon -37
+KPX T a -55
+KPX T O 10
+KPX T A -18
+
+KPX U period -100
+KPX U comma -100
+KPX U A -30
+
+KPX V u -75
+KPX V semicolon -75
+KPX V period -125
+KPX V o -75
+KPX V i -18
+KPX V hyphen -100
+KPX V e -75
+KPX V comma -125
+KPX V colon -75
+KPX V a -85
+KPX V O -18
+KPX V A -74
+
+KPX W y -55
+KPX W u -55
+KPX W semicolon -100
+KPX W period -125
+KPX W o -60
+KPX W i -18
+KPX W hyphen -100
+KPX W e -60
+KPX W comma -125
+KPX W colon -100
+KPX W a -75
+KPX W A -50
+
+KPX Y u -91
+KPX Y semicolon -75
+KPX Y period -100
+KPX Y o -100
+KPX Y i -18
+KPX Y hyphen -125
+KPX Y e -100
+KPX Y comma -100
+KPX Y colon -75
+KPX Y a -100
+KPX Y O -18
+KPX Y A -75
+
+KPX a y -10
+KPX a w -10
+KPX a v -10
+
+KPX b period -18
+KPX b comma -18
+
+KPX c period -18
+KPX c l -7
+KPX c k -7
+KPX c h -7
+KPX c comma -18
+
+KPX colon space -37
+
+KPX comma space -37
+KPX comma quoteright -37
+KPX comma quotedblright -37
+
+KPX e period -18
+KPX e comma -18
+
+KPX f quoteright 100
+KPX f quotedblright 100
+KPX f period -37
+KPX f comma -37
+
+KPX g period -25
+KPX g comma -25
+
+KPX o period -18
+KPX o comma -18
+
+KPX p period -18
+KPX p comma -18
+
+KPX period space -37
+KPX period quoteright -37
+KPX period quotedblright -37
+
+KPX quotedblleft A -74
+
+KPX quotedblright space -37
+
+KPX quoteleft quoteleft -25
+KPX quoteleft A -74
+
+KPX quoteright s -25
+KPX quoteright quoteright -25
+KPX quoteright d -37
+
+KPX r period -100
+KPX r hyphen -37
+KPX r comma -100
+
+KPX s period -25
+KPX s comma -25
+
+KPX semicolon space -37
+
+KPX space quoteleft -37
+KPX space quotedblleft -37
+KPX space Y -37
+KPX space W -37
+KPX space V -37
+KPX space T -37
+KPX space A -37
+
+KPX v period -125
+KPX v comma -125
+
+KPX w period -125
+KPX w comma -125
+KPX w a -18
+
+KPX y period -125
+KPX y comma -125
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 238 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 238 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 238 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 238 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 195 243 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 238 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 195 238 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 195 238 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 195 238 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 195 238 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 37 238 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 37 238 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 37 238 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 37 238 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 241 238 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 238 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 238 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 238 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 238 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 238 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 149 238 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 241 238 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 241 238 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 241 238 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 241 238 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 216 238 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 186 238 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 238 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 112 10 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 84 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 84 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 84 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 84 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -9 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -9 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -9 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -9 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 65 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 102 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 102 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 74 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Palatino-Bold.afm b/tlt3.0/library/afm/Palatino-Bold.afm
new file mode 100644
index 0000000..de147f7
--- /dev/null
+++ b/tlt3.0/library/afm/Palatino-Bold.afm
@@ -0,0 +1,435 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Mon Jul  2 22:26:30 1990
+Comment UniqueID 31793
+Comment VMusage 36031 46923
+FontName Palatino-Bold
+FullName Palatino Bold
+FamilyName Palatino
+Weight Bold
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -152 -266 1000 924
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 681
+XHeight 471
+Ascender 720
+Descender -258
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 63 -12 219 688 ;
+C 34 ; WX 402 ; N quotedbl ; B 22 376 380 695 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 496 673 ;
+C 36 ; WX 500 ; N dollar ; B 28 -114 472 721 ;
+C 37 ; WX 889 ; N percent ; B 61 -9 828 714 ;
+C 38 ; WX 833 ; N ampersand ; B 52 -17 813 684 ;
+C 39 ; WX 278 ; N quoteright ; B 29 405 249 695 ;
+C 40 ; WX 333 ; N parenleft ; B 65 -104 305 723 ;
+C 41 ; WX 333 ; N parenright ; B 28 -104 268 723 ;
+C 42 ; WX 444 ; N asterisk ; B 44 332 399 695 ;
+C 43 ; WX 606 ; N plus ; B 51 0 555 505 ;
+C 44 ; WX 250 ; N comma ; B -6 -166 227 141 ;
+C 45 ; WX 333 ; N hyphen ; B 16 195 317 305 ;
+C 46 ; WX 250 ; N period ; B 47 -12 203 144 ;
+C 47 ; WX 296 ; N slash ; B -9 -17 305 720 ;
+C 48 ; WX 500 ; N zero ; B 33 -17 468 660 ;
+C 49 ; WX 500 ; N one ; B 35 -3 455 670 ;
+C 50 ; WX 500 ; N two ; B 25 -3 472 660 ;
+C 51 ; WX 500 ; N three ; B 22 -17 458 660 ;
+C 52 ; WX 500 ; N four ; B 12 -3 473 672 ;
+C 53 ; WX 500 ; N five ; B 42 -17 472 656 ;
+C 54 ; WX 500 ; N six ; B 37 -17 469 660 ;
+C 55 ; WX 500 ; N seven ; B 46 -3 493 656 ;
+C 56 ; WX 500 ; N eight ; B 34 -17 467 660 ;
+C 57 ; WX 500 ; N nine ; B 31 -17 463 660 ;
+C 58 ; WX 250 ; N colon ; B 47 -12 203 454 ;
+C 59 ; WX 250 ; N semicolon ; B -6 -166 227 454 ;
+C 60 ; WX 606 ; N less ; B 49 -15 558 519 ;
+C 61 ; WX 606 ; N equal ; B 51 114 555 396 ;
+C 62 ; WX 606 ; N greater ; B 49 -15 558 519 ;
+C 63 ; WX 444 ; N question ; B 43 -12 411 687 ;
+C 64 ; WX 747 ; N at ; B 42 -12 704 681 ;
+C 65 ; WX 778 ; N A ; B 24 -3 757 686 ;
+C 66 ; WX 667 ; N B ; B 39 -3 611 681 ;
+C 67 ; WX 722 ; N C ; B 44 -17 695 695 ;
+C 68 ; WX 833 ; N D ; B 35 -3 786 681 ;
+C 69 ; WX 611 ; N E ; B 39 -4 577 681 ;
+C 70 ; WX 556 ; N F ; B 28 -3 539 681 ;
+C 71 ; WX 833 ; N G ; B 47 -17 776 695 ;
+C 72 ; WX 833 ; N H ; B 36 -3 796 681 ;
+C 73 ; WX 389 ; N I ; B 39 -3 350 681 ;
+C 74 ; WX 389 ; N J ; B -11 -213 350 681 ;
+C 75 ; WX 778 ; N K ; B 39 -3 763 681 ;
+C 76 ; WX 611 ; N L ; B 39 -4 577 681 ;
+C 77 ; WX 1000 ; N M ; B 32 -10 968 681 ;
+C 78 ; WX 833 ; N N ; B 35 -16 798 681 ;
+C 79 ; WX 833 ; N O ; B 47 -17 787 695 ;
+C 80 ; WX 611 ; N P ; B 39 -3 594 681 ;
+C 81 ; WX 833 ; N Q ; B 47 -184 787 695 ;
+C 82 ; WX 722 ; N R ; B 39 -3 708 681 ;
+C 83 ; WX 611 ; N S ; B 57 -17 559 695 ;
+C 84 ; WX 667 ; N T ; B 17 -3 650 681 ;
+C 85 ; WX 778 ; N U ; B 26 -17 760 681 ;
+C 86 ; WX 778 ; N V ; B 20 -3 763 681 ;
+C 87 ; WX 1000 ; N W ; B 17 -3 988 686 ;
+C 88 ; WX 667 ; N X ; B 17 -3 650 695 ;
+C 89 ; WX 667 ; N Y ; B 15 -3 660 695 ;
+C 90 ; WX 667 ; N Z ; B 24 -3 627 681 ;
+C 91 ; WX 333 ; N bracketleft ; B 73 -104 291 720 ;
+C 92 ; WX 606 ; N backslash ; B 72 0 534 720 ;
+C 93 ; WX 333 ; N bracketright ; B 42 -104 260 720 ;
+C 94 ; WX 606 ; N asciicircum ; B 52 275 554 678 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 29 405 249 695 ;
+C 97 ; WX 500 ; N a ; B 40 -17 478 471 ;
+C 98 ; WX 611 ; N b ; B 10 -17 556 720 ;
+C 99 ; WX 444 ; N c ; B 37 -17 414 471 ;
+C 100 ; WX 611 ; N d ; B 42 -17 577 720 ;
+C 101 ; WX 500 ; N e ; B 42 -17 461 471 ;
+C 102 ; WX 389 ; N f ; B 34 -3 381 720 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 26 -266 535 471 ;
+C 104 ; WX 611 ; N h ; B 24 -3 587 720 ;
+C 105 ; WX 333 ; N i ; B 34 -3 298 706 ;
+C 106 ; WX 333 ; N j ; B 3 -266 241 706 ;
+C 107 ; WX 611 ; N k ; B 21 -3 597 720 ;
+C 108 ; WX 333 ; N l ; B 24 -3 296 720 ;
+C 109 ; WX 889 ; N m ; B 24 -3 864 471 ;
+C 110 ; WX 611 ; N n ; B 24 -3 587 471 ;
+C 111 ; WX 556 ; N o ; B 40 -17 517 471 ;
+C 112 ; WX 611 ; N p ; B 29 -258 567 471 ;
+C 113 ; WX 611 ; N q ; B 52 -258 589 471 ;
+C 114 ; WX 389 ; N r ; B 30 -3 389 471 ;
+C 115 ; WX 444 ; N s ; B 39 -17 405 471 ;
+C 116 ; WX 333 ; N t ; B 22 -17 324 632 ;
+C 117 ; WX 611 ; N u ; B 25 -17 583 471 ;
+C 118 ; WX 556 ; N v ; B 11 -3 545 459 ;
+C 119 ; WX 833 ; N w ; B 13 -3 820 471 ;
+C 120 ; WX 500 ; N x ; B 20 -3 483 471 ;
+C 121 ; WX 556 ; N y ; B 10 -266 546 459 ;
+C 122 ; WX 500 ; N z ; B 16 -3 464 459 ;
+C 123 ; WX 310 ; N braceleft ; B 5 -117 288 725 ;
+C 124 ; WX 606 ; N bar ; B 260 0 346 720 ;
+C 125 ; WX 310 ; N braceright ; B 22 -117 305 725 ;
+C 126 ; WX 606 ; N asciitilde ; B 51 155 555 342 ;
+C 161 ; WX 278 ; N exclamdown ; B 59 -227 215 471 ;
+C 162 ; WX 500 ; N cent ; B 73 -106 450 554 ;
+C 163 ; WX 500 ; N sterling ; B -2 -19 501 676 ;
+C 164 ; WX 167 ; N fraction ; B -152 0 320 660 ;
+C 165 ; WX 500 ; N yen ; B 17 -3 483 695 ;
+C 166 ; WX 500 ; N florin ; B 11 -242 490 703 ;
+C 167 ; WX 500 ; N section ; B 30 -217 471 695 ;
+C 168 ; WX 500 ; N currency ; B 32 96 468 533 ;
+C 169 ; WX 227 ; N quotesingle ; B 45 376 181 695 ;
+C 170 ; WX 500 ; N quotedblleft ; B 34 405 466 695 ;
+C 171 ; WX 500 ; N guillemotleft ; B 36 44 463 438 ;
+C 172 ; WX 389 ; N guilsinglleft ; B 82 44 307 438 ;
+C 173 ; WX 389 ; N guilsinglright ; B 82 44 307 438 ;
+C 174 ; WX 611 ; N fi ; B 10 -3 595 720 ;
+C 175 ; WX 611 ; N fl ; B 17 -3 593 720 ;
+C 177 ; WX 500 ; N endash ; B 0 208 500 291 ;
+C 178 ; WX 500 ; N dagger ; B 29 -6 472 682 ;
+C 179 ; WX 500 ; N daggerdbl ; B 32 -245 468 682 ;
+C 180 ; WX 250 ; N periodcentered ; B 47 179 203 335 ;
+C 182 ; WX 641 ; N paragraph ; B 19 -161 599 683 ;
+C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 56 -160 276 130 ;
+C 185 ; WX 500 ; N quotedblbase ; B 34 -160 466 130 ;
+C 186 ; WX 500 ; N quotedblright ; B 34 405 466 695 ;
+C 187 ; WX 500 ; N guillemotright ; B 37 44 464 438 ;
+C 188 ; WX 1000 ; N ellipsis ; B 89 -12 911 144 ;
+C 189 ; WX 1000 ; N perthousand ; B 33 -9 982 724 ;
+C 191 ; WX 444 ; N questiondown ; B 33 -231 401 471 ;
+C 193 ; WX 333 ; N grave ; B 18 506 256 691 ;
+C 194 ; WX 333 ; N acute ; B 78 506 316 691 ;
+C 195 ; WX 333 ; N circumflex ; B -2 506 335 681 ;
+C 196 ; WX 333 ; N tilde ; B -16 535 349 661 ;
+C 197 ; WX 333 ; N macron ; B 1 538 332 609 ;
+C 198 ; WX 333 ; N breve ; B 15 506 318 669 ;
+C 199 ; WX 333 ; N dotaccent ; B 100 537 234 671 ;
+C 200 ; WX 333 ; N dieresis ; B -8 537 341 671 ;
+C 202 ; WX 333 ; N ring ; B 67 500 267 700 ;
+C 203 ; WX 333 ; N cedilla ; B 73 -225 300 -7 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -56 506 390 691 ;
+C 206 ; WX 333 ; N ogonek ; B 60 -246 274 -17 ;
+C 207 ; WX 333 ; N caron ; B -2 510 335 685 ;
+C 208 ; WX 1000 ; N emdash ; B 0 208 1000 291 ;
+C 225 ; WX 1000 ; N AE ; B 12 -4 954 681 ;
+C 227 ; WX 438 ; N ordfeminine ; B 77 367 361 660 ;
+C 232 ; WX 611 ; N Lslash ; B 16 -4 577 681 ;
+C 233 ; WX 833 ; N Oslash ; B 32 -20 808 698 ;
+C 234 ; WX 1000 ; N OE ; B 43 -17 985 695 ;
+C 235 ; WX 488 ; N ordmasculine ; B 89 367 399 660 ;
+C 241 ; WX 778 ; N ae ; B 46 -17 731 471 ;
+C 245 ; WX 333 ; N dotlessi ; B 34 -3 298 471 ;
+C 248 ; WX 333 ; N lslash ; B -4 -3 334 720 ;
+C 249 ; WX 556 ; N oslash ; B 23 -18 534 471 ;
+C 250 ; WX 833 ; N oe ; B 48 -17 799 471 ;
+C 251 ; WX 611 ; N germandbls ; B 30 -17 565 720 ;
+C -1 ; WX 667 ; N Zcaron ; B 24 -3 627 909 ;
+C -1 ; WX 444 ; N ccedilla ; B 37 -225 414 471 ;
+C -1 ; WX 556 ; N ydieresis ; B 10 -266 546 691 ;
+C -1 ; WX 500 ; N atilde ; B 40 -17 478 673 ;
+C -1 ; WX 333 ; N icircumflex ; B -2 -3 335 701 ;
+C -1 ; WX 300 ; N threesuperior ; B 9 261 292 667 ;
+C -1 ; WX 500 ; N ecircumflex ; B 42 -17 461 701 ;
+C -1 ; WX 611 ; N thorn ; B 17 -258 563 720 ;
+C -1 ; WX 500 ; N egrave ; B 42 -17 461 711 ;
+C -1 ; WX 300 ; N twosuperior ; B 5 261 295 660 ;
+C -1 ; WX 500 ; N eacute ; B 42 -17 461 711 ;
+C -1 ; WX 556 ; N otilde ; B 40 -17 517 673 ;
+C -1 ; WX 778 ; N Aacute ; B 24 -3 757 915 ;
+C -1 ; WX 556 ; N ocircumflex ; B 40 -17 517 701 ;
+C -1 ; WX 556 ; N yacute ; B 10 -266 546 711 ;
+C -1 ; WX 611 ; N udieresis ; B 25 -17 583 691 ;
+C -1 ; WX 750 ; N threequarters ; B 15 -2 735 667 ;
+C -1 ; WX 500 ; N acircumflex ; B 40 -17 478 701 ;
+C -1 ; WX 833 ; N Eth ; B 10 -3 786 681 ;
+C -1 ; WX 500 ; N edieresis ; B 42 -17 461 691 ;
+C -1 ; WX 611 ; N ugrave ; B 25 -17 583 711 ;
+C -1 ; WX 998 ; N trademark ; B 38 274 961 678 ;
+C -1 ; WX 556 ; N ograve ; B 40 -17 517 711 ;
+C -1 ; WX 444 ; N scaron ; B 39 -17 405 693 ;
+C -1 ; WX 389 ; N Idieresis ; B 20 -3 369 895 ;
+C -1 ; WX 611 ; N uacute ; B 25 -17 583 711 ;
+C -1 ; WX 500 ; N agrave ; B 40 -17 478 711 ;
+C -1 ; WX 611 ; N ntilde ; B 24 -3 587 673 ;
+C -1 ; WX 500 ; N aring ; B 40 -17 478 700 ;
+C -1 ; WX 500 ; N zcaron ; B 16 -3 464 693 ;
+C -1 ; WX 389 ; N Icircumflex ; B 26 -3 363 905 ;
+C -1 ; WX 833 ; N Ntilde ; B 35 -16 798 885 ;
+C -1 ; WX 611 ; N ucircumflex ; B 25 -17 583 701 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 39 -4 577 905 ;
+C -1 ; WX 389 ; N Iacute ; B 39 -3 350 915 ;
+C -1 ; WX 722 ; N Ccedilla ; B 44 -225 695 695 ;
+C -1 ; WX 833 ; N Odieresis ; B 47 -17 787 895 ;
+C -1 ; WX 611 ; N Scaron ; B 57 -17 559 909 ;
+C -1 ; WX 611 ; N Edieresis ; B 39 -4 577 895 ;
+C -1 ; WX 389 ; N Igrave ; B 39 -3 350 915 ;
+C -1 ; WX 500 ; N adieresis ; B 40 -17 478 691 ;
+C -1 ; WX 833 ; N Ograve ; B 47 -17 787 915 ;
+C -1 ; WX 611 ; N Egrave ; B 39 -4 577 915 ;
+C -1 ; WX 667 ; N Ydieresis ; B 15 -3 660 895 ;
+C -1 ; WX 747 ; N registered ; B 26 -17 720 695 ;
+C -1 ; WX 833 ; N Otilde ; B 47 -17 787 885 ;
+C -1 ; WX 750 ; N onequarter ; B 19 -2 735 665 ;
+C -1 ; WX 778 ; N Ugrave ; B 26 -17 760 915 ;
+C -1 ; WX 778 ; N Ucircumflex ; B 26 -17 760 905 ;
+C -1 ; WX 611 ; N Thorn ; B 39 -3 574 681 ;
+C -1 ; WX 606 ; N divide ; B 51 0 555 510 ;
+C -1 ; WX 778 ; N Atilde ; B 24 -3 757 885 ;
+C -1 ; WX 778 ; N Uacute ; B 26 -17 760 915 ;
+C -1 ; WX 833 ; N Ocircumflex ; B 47 -17 787 905 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 114 555 396 ;
+C -1 ; WX 778 ; N Aring ; B 24 -3 757 924 ;
+C -1 ; WX 333 ; N idieresis ; B -8 -3 341 691 ;
+C -1 ; WX 333 ; N iacute ; B 34 -3 316 711 ;
+C -1 ; WX 500 ; N aacute ; B 40 -17 478 711 ;
+C -1 ; WX 606 ; N plusminus ; B 51 0 555 505 ;
+C -1 ; WX 606 ; N multiply ; B 72 21 534 483 ;
+C -1 ; WX 778 ; N Udieresis ; B 26 -17 760 895 ;
+C -1 ; WX 606 ; N minus ; B 51 212 555 298 ;
+C -1 ; WX 300 ; N onesuperior ; B 14 261 287 665 ;
+C -1 ; WX 611 ; N Eacute ; B 39 -4 577 915 ;
+C -1 ; WX 778 ; N Acircumflex ; B 24 -3 757 905 ;
+C -1 ; WX 747 ; N copyright ; B 26 -17 720 695 ;
+C -1 ; WX 778 ; N Agrave ; B 24 -3 757 915 ;
+C -1 ; WX 556 ; N odieresis ; B 40 -17 517 691 ;
+C -1 ; WX 556 ; N oacute ; B 40 -17 517 711 ;
+C -1 ; WX 400 ; N degree ; B 50 360 350 660 ;
+C -1 ; WX 333 ; N igrave ; B 18 -3 298 711 ;
+C -1 ; WX 611 ; N mu ; B 25 -225 583 471 ;
+C -1 ; WX 833 ; N Oacute ; B 47 -17 787 915 ;
+C -1 ; WX 556 ; N eth ; B 40 -17 517 720 ;
+C -1 ; WX 778 ; N Adieresis ; B 24 -3 757 895 ;
+C -1 ; WX 667 ; N Yacute ; B 15 -3 660 915 ;
+C -1 ; WX 606 ; N brokenbar ; B 260 0 346 720 ;
+C -1 ; WX 750 ; N onehalf ; B 9 -2 745 665 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 101
+
+KPX A y -70
+KPX A w -70
+KPX A v -70
+KPX A space -18
+KPX A quoteright -92
+KPX A Y -111
+KPX A W -90
+KPX A V -129
+KPX A T -92
+
+KPX F period -111
+KPX F comma -111
+KPX F A -55
+
+KPX L y -74
+KPX L space -18
+KPX L quoteright -74
+KPX L Y -92
+KPX L W -92
+KPX L V -92
+KPX L T -74
+
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R y -30
+KPX R Y -55
+KPX R W -37
+KPX R V -74
+KPX R T -55
+
+KPX T y -90
+KPX T w -90
+KPX T u -129
+KPX T semicolon -74
+KPX T s -111
+KPX T r -111
+KPX T period -92
+KPX T o -111
+KPX T i -55
+KPX T hyphen -92
+KPX T e -111
+KPX T comma -92
+KPX T colon -74
+KPX T c -129
+KPX T a -111
+KPX T A -92
+
+KPX V y -90
+KPX V u -92
+KPX V semicolon -74
+KPX V r -111
+KPX V period -129
+KPX V o -111
+KPX V i -55
+KPX V hyphen -92
+KPX V e -111
+KPX V comma -129
+KPX V colon -74
+KPX V a -111
+KPX V A -129
+
+KPX W y -74
+KPX W u -74
+KPX W semicolon -37
+KPX W r -74
+KPX W period -37
+KPX W o -74
+KPX W i -37
+KPX W hyphen -37
+KPX W e -74
+KPX W comma -92
+KPX W colon -37
+KPX W a -74
+KPX W A -90
+
+KPX Y v -74
+KPX Y u -74
+KPX Y semicolon -55
+KPX Y q -92
+KPX Y period -74
+KPX Y p -74
+KPX Y o -74
+KPX Y i -55
+KPX Y hyphen -74
+KPX Y e -74
+KPX Y comma -74
+KPX Y colon -55
+KPX Y a -74
+KPX Y A -55
+
+KPX f quoteright 37
+KPX f f -18
+
+KPX one one -37
+
+KPX quoteleft quoteleft -55
+
+KPX quoteright t -18
+KPX quoteright space -55
+KPX quoteright s -55
+KPX quoteright quoteright -55
+
+KPX r quoteright 55
+KPX r period -55
+KPX r hyphen -18
+KPX r comma -55
+
+KPX v period -111
+KPX v comma -111
+
+KPX w period -92
+KPX w comma -92
+
+KPX y period -92
+KPX y comma -92
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 223 224 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 211 224 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 223 224 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 215 224 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 223 224 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 223 224 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 224 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 224 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 224 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 224 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 224 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 224 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 224 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 224 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 250 224 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 224 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 224 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 224 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 224 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 224 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 139 224 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 235 224 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 235 224 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 224 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 223 224 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 211 224 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 199 224 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 224 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 84 20 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 20 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 20 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 84 20 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 12 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 84 20 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 96 20 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 20 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 84 20 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 20 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 20 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 20 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 20 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 12 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 112 20 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 20 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 20 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 112 20 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 12 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 56 8 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 151 20 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 20 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 20 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 131 20 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 144 20 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 124 20 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 8 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Palatino-BoldItalic.afm b/tlt3.0/library/afm/Palatino-BoldItalic.afm
new file mode 100644
index 0000000..44c7b2c
--- /dev/null
+++ b/tlt3.0/library/afm/Palatino-BoldItalic.afm
@@ -0,0 +1,442 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Mon Jul  2 22:48:39 1990
+Comment UniqueID 31799
+Comment VMusage 37656 48548
+FontName Palatino-BoldItalic
+FullName Palatino Bold Italic
+FamilyName Palatino
+Weight Bold
+ItalicAngle -10
+IsFixedPitch false
+FontBBox -170 -271 1073 926
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 681
+XHeight 469
+Ascender 726
+Descender -271
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 58 -17 322 695 ;
+C 34 ; WX 500 ; N quotedbl ; B 137 467 493 720 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 496 673 ;
+C 36 ; WX 500 ; N dollar ; B 20 -108 477 737 ;
+C 37 ; WX 889 ; N percent ; B 56 -17 790 697 ;
+C 38 ; WX 833 ; N ampersand ; B 74 -17 811 695 ;
+C 39 ; WX 278 ; N quoteright ; B 76 431 302 720 ;
+C 40 ; WX 333 ; N parenleft ; B 58 -129 368 723 ;
+C 41 ; WX 333 ; N parenright ; B -12 -129 298 723 ;
+C 42 ; WX 444 ; N asterisk ; B 84 332 439 695 ;
+C 43 ; WX 606 ; N plus ; B 50 -5 556 501 ;
+C 44 ; WX 250 ; N comma ; B -33 -164 208 147 ;
+C 45 ; WX 389 ; N hyphen ; B 37 198 362 300 ;
+C 46 ; WX 250 ; N period ; B 48 -17 187 135 ;
+C 47 ; WX 315 ; N slash ; B 1 -17 315 720 ;
+C 48 ; WX 500 ; N zero ; B 42 -17 490 683 ;
+C 49 ; WX 500 ; N one ; B 41 -3 434 678 ;
+C 50 ; WX 500 ; N two ; B 1 -3 454 683 ;
+C 51 ; WX 500 ; N three ; B 8 -17 450 683 ;
+C 52 ; WX 500 ; N four ; B 3 -3 487 683 ;
+C 53 ; WX 500 ; N five ; B 14 -17 481 675 ;
+C 54 ; WX 500 ; N six ; B 39 -17 488 683 ;
+C 55 ; WX 500 ; N seven ; B 69 -3 544 674 ;
+C 56 ; WX 500 ; N eight ; B 26 -17 484 683 ;
+C 57 ; WX 500 ; N nine ; B 27 -17 491 683 ;
+C 58 ; WX 250 ; N colon ; B 38 -17 236 452 ;
+C 59 ; WX 250 ; N semicolon ; B -33 -164 247 452 ;
+C 60 ; WX 606 ; N less ; B 49 -21 558 517 ;
+C 61 ; WX 606 ; N equal ; B 51 106 555 390 ;
+C 62 ; WX 606 ; N greater ; B 48 -21 557 517 ;
+C 63 ; WX 444 ; N question ; B 91 -17 450 695 ;
+C 64 ; WX 833 ; N at ; B 82 -12 744 681 ;
+C 65 ; WX 722 ; N A ; B -35 -3 685 683 ;
+C 66 ; WX 667 ; N B ; B 8 -3 629 681 ;
+C 67 ; WX 685 ; N C ; B 69 -17 695 695 ;
+C 68 ; WX 778 ; N D ; B 0 -3 747 682 ;
+C 69 ; WX 611 ; N E ; B 11 -3 606 681 ;
+C 70 ; WX 556 ; N F ; B -6 -3 593 681 ;
+C 71 ; WX 778 ; N G ; B 72 -17 750 695 ;
+C 72 ; WX 778 ; N H ; B -12 -3 826 681 ;
+C 73 ; WX 389 ; N I ; B -1 -3 412 681 ;
+C 74 ; WX 389 ; N J ; B -29 -207 417 681 ;
+C 75 ; WX 722 ; N K ; B -10 -3 746 681 ;
+C 76 ; WX 611 ; N L ; B 26 -3 578 681 ;
+C 77 ; WX 944 ; N M ; B -23 -17 985 681 ;
+C 78 ; WX 778 ; N N ; B -2 -3 829 681 ;
+C 79 ; WX 833 ; N O ; B 76 -17 794 695 ;
+C 80 ; WX 667 ; N P ; B 11 -3 673 681 ;
+C 81 ; WX 833 ; N Q ; B 76 -222 794 695 ;
+C 82 ; WX 722 ; N R ; B 4 -3 697 681 ;
+C 83 ; WX 556 ; N S ; B 50 -17 517 695 ;
+C 84 ; WX 611 ; N T ; B 56 -3 674 681 ;
+C 85 ; WX 778 ; N U ; B 83 -17 825 681 ;
+C 86 ; WX 667 ; N V ; B 67 -3 745 681 ;
+C 87 ; WX 1000 ; N W ; B 67 -3 1073 689 ;
+C 88 ; WX 722 ; N X ; B -9 -3 772 681 ;
+C 89 ; WX 611 ; N Y ; B 54 -3 675 695 ;
+C 90 ; WX 667 ; N Z ; B 1 -3 676 681 ;
+C 91 ; WX 333 ; N bracketleft ; B 45 -102 381 723 ;
+C 92 ; WX 606 ; N backslash ; B 72 0 534 720 ;
+C 93 ; WX 333 ; N bracketright ; B -21 -102 315 723 ;
+C 94 ; WX 606 ; N asciicircum ; B 63 275 543 678 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 65 431 291 720 ;
+C 97 ; WX 556 ; N a ; B 44 -17 519 470 ;
+C 98 ; WX 537 ; N b ; B 44 -17 494 726 ;
+C 99 ; WX 444 ; N c ; B 32 -17 436 469 ;
+C 100 ; WX 556 ; N d ; B 38 -17 550 726 ;
+C 101 ; WX 444 ; N e ; B 28 -17 418 469 ;
+C 102 ; WX 333 ; N f ; B -130 -271 449 726 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B -50 -271 529 469 ;
+C 104 ; WX 556 ; N h ; B 22 -17 522 726 ;
+C 105 ; WX 333 ; N i ; B 26 -17 312 695 ;
+C 106 ; WX 333 ; N j ; B -64 -271 323 695 ;
+C 107 ; WX 556 ; N k ; B 34 -17 528 726 ;
+C 108 ; WX 333 ; N l ; B 64 -17 318 726 ;
+C 109 ; WX 833 ; N m ; B 19 -17 803 469 ;
+C 110 ; WX 556 ; N n ; B 17 -17 521 469 ;
+C 111 ; WX 556 ; N o ; B 48 -17 502 469 ;
+C 112 ; WX 556 ; N p ; B -21 -271 516 469 ;
+C 113 ; WX 537 ; N q ; B 32 -271 513 469 ;
+C 114 ; WX 389 ; N r ; B 20 -17 411 469 ;
+C 115 ; WX 444 ; N s ; B 25 -17 406 469 ;
+C 116 ; WX 389 ; N t ; B 42 -17 409 636 ;
+C 117 ; WX 556 ; N u ; B 22 -17 521 469 ;
+C 118 ; WX 556 ; N v ; B 19 -17 513 469 ;
+C 119 ; WX 833 ; N w ; B 27 -17 802 469 ;
+C 120 ; WX 500 ; N x ; B -8 -17 500 469 ;
+C 121 ; WX 556 ; N y ; B 13 -271 541 469 ;
+C 122 ; WX 500 ; N z ; B 31 -17 470 469 ;
+C 123 ; WX 333 ; N braceleft ; B 18 -105 334 720 ;
+C 124 ; WX 606 ; N bar ; B 259 0 347 720 ;
+C 125 ; WX 333 ; N braceright ; B -1 -105 315 720 ;
+C 126 ; WX 606 ; N asciitilde ; B 51 151 555 346 ;
+C 161 ; WX 333 ; N exclamdown ; B 2 -225 259 479 ;
+C 162 ; WX 500 ; N cent ; B 52 -105 456 547 ;
+C 163 ; WX 500 ; N sterling ; B 21 -5 501 683 ;
+C 164 ; WX 167 ; N fraction ; B -170 0 338 683 ;
+C 165 ; WX 500 ; N yen ; B 11 -3 538 695 ;
+C 166 ; WX 500 ; N florin ; B 8 -242 479 690 ;
+C 167 ; WX 556 ; N section ; B 47 -151 497 695 ;
+C 168 ; WX 500 ; N currency ; B 32 96 468 533 ;
+C 169 ; WX 250 ; N quotesingle ; B 127 467 293 720 ;
+C 170 ; WX 500 ; N quotedblleft ; B 65 431 511 720 ;
+C 171 ; WX 500 ; N guillemotleft ; B 35 43 458 446 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 60 43 292 446 ;
+C 173 ; WX 333 ; N guilsinglright ; B 35 40 267 443 ;
+C 174 ; WX 611 ; N fi ; B -130 -271 588 726 ;
+C 175 ; WX 611 ; N fl ; B -130 -271 631 726 ;
+C 177 ; WX 500 ; N endash ; B -12 214 512 282 ;
+C 178 ; WX 556 ; N dagger ; B 67 -3 499 685 ;
+C 179 ; WX 556 ; N daggerdbl ; B 33 -153 537 693 ;
+C 180 ; WX 250 ; N periodcentered ; B 67 172 206 324 ;
+C 182 ; WX 556 ; N paragraph ; B 14 -204 629 681 ;
+C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ;
+C 184 ; WX 250 ; N quotesinglbase ; B -3 -144 220 145 ;
+C 185 ; WX 500 ; N quotedblbase ; B -18 -144 424 145 ;
+C 186 ; WX 500 ; N quotedblright ; B 73 431 519 720 ;
+C 187 ; WX 500 ; N guillemotright ; B 35 40 458 443 ;
+C 188 ; WX 1000 ; N ellipsis ; B 91 -17 896 135 ;
+C 189 ; WX 1000 ; N perthousand ; B 65 -17 912 691 ;
+C 191 ; WX 444 ; N questiondown ; B -12 -226 347 479 ;
+C 193 ; WX 333 ; N grave ; B 110 518 322 699 ;
+C 194 ; WX 333 ; N acute ; B 153 518 392 699 ;
+C 195 ; WX 333 ; N circumflex ; B 88 510 415 684 ;
+C 196 ; WX 333 ; N tilde ; B 82 535 441 654 ;
+C 197 ; WX 333 ; N macron ; B 76 538 418 608 ;
+C 198 ; WX 333 ; N breve ; B 96 518 412 680 ;
+C 199 ; WX 333 ; N dotaccent ; B 202 537 325 668 ;
+C 200 ; WX 333 ; N dieresis ; B 90 537 426 668 ;
+C 202 ; WX 556 ; N ring ; B 277 514 477 714 ;
+C 203 ; WX 333 ; N cedilla ; B 12 -218 248 5 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -28 518 409 699 ;
+C 206 ; WX 333 ; N ogonek ; B 32 -206 238 -17 ;
+C 207 ; WX 333 ; N caron ; B 113 510 445 684 ;
+C 208 ; WX 1000 ; N emdash ; B -12 214 1012 282 ;
+C 225 ; WX 944 ; N AE ; B -29 -3 927 681 ;
+C 227 ; WX 333 ; N ordfeminine ; B 47 391 355 684 ;
+C 232 ; WX 611 ; N Lslash ; B 6 -3 578 681 ;
+C 233 ; WX 833 ; N Oslash ; B 57 -54 797 730 ;
+C 234 ; WX 944 ; N OE ; B 39 -17 961 695 ;
+C 235 ; WX 333 ; N ordmasculine ; B 51 391 346 683 ;
+C 241 ; WX 738 ; N ae ; B 44 -17 711 469 ;
+C 245 ; WX 333 ; N dotlessi ; B 26 -17 293 469 ;
+C 248 ; WX 333 ; N lslash ; B 13 -17 365 726 ;
+C 249 ; WX 556 ; N oslash ; B 14 -50 522 506 ;
+C 250 ; WX 778 ; N oe ; B 48 -17 755 469 ;
+C 251 ; WX 556 ; N germandbls ; B -131 -271 549 726 ;
+C -1 ; WX 667 ; N Zcaron ; B 1 -3 676 896 ;
+C -1 ; WX 444 ; N ccedilla ; B 32 -218 436 469 ;
+C -1 ; WX 556 ; N ydieresis ; B 13 -271 541 688 ;
+C -1 ; WX 556 ; N atilde ; B 44 -17 553 666 ;
+C -1 ; WX 333 ; N icircumflex ; B 26 -17 403 704 ;
+C -1 ; WX 300 ; N threesuperior ; B 23 263 310 683 ;
+C -1 ; WX 444 ; N ecircumflex ; B 28 -17 471 704 ;
+C -1 ; WX 556 ; N thorn ; B -21 -271 516 726 ;
+C -1 ; WX 444 ; N egrave ; B 28 -17 418 719 ;
+C -1 ; WX 300 ; N twosuperior ; B 26 271 321 683 ;
+C -1 ; WX 444 ; N eacute ; B 28 -17 448 719 ;
+C -1 ; WX 556 ; N otilde ; B 48 -17 553 666 ;
+C -1 ; WX 722 ; N Aacute ; B -35 -3 685 911 ;
+C -1 ; WX 556 ; N ocircumflex ; B 48 -17 515 704 ;
+C -1 ; WX 556 ; N yacute ; B 13 -271 541 719 ;
+C -1 ; WX 556 ; N udieresis ; B 22 -17 538 688 ;
+C -1 ; WX 750 ; N threequarters ; B 18 -2 732 683 ;
+C -1 ; WX 556 ; N acircumflex ; B 44 -17 527 704 ;
+C -1 ; WX 778 ; N Eth ; B 0 -3 747 682 ;
+C -1 ; WX 444 ; N edieresis ; B 28 -17 482 688 ;
+C -1 ; WX 556 ; N ugrave ; B 22 -17 521 719 ;
+C -1 ; WX 1000 ; N trademark ; B 38 274 961 678 ;
+C -1 ; WX 556 ; N ograve ; B 48 -17 502 719 ;
+C -1 ; WX 444 ; N scaron ; B 25 -17 489 692 ;
+C -1 ; WX 389 ; N Idieresis ; B -1 -3 454 880 ;
+C -1 ; WX 556 ; N uacute ; B 22 -17 521 719 ;
+C -1 ; WX 556 ; N agrave ; B 44 -17 519 719 ;
+C -1 ; WX 556 ; N ntilde ; B 17 -17 553 666 ;
+C -1 ; WX 556 ; N aring ; B 44 -17 519 714 ;
+C -1 ; WX 500 ; N zcaron ; B 31 -17 517 692 ;
+C -1 ; WX 389 ; N Icircumflex ; B -1 -3 443 896 ;
+C -1 ; WX 778 ; N Ntilde ; B -2 -3 829 866 ;
+C -1 ; WX 556 ; N ucircumflex ; B 22 -17 521 704 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 11 -3 606 896 ;
+C -1 ; WX 389 ; N Iacute ; B -1 -3 420 911 ;
+C -1 ; WX 685 ; N Ccedilla ; B 69 -218 695 695 ;
+C -1 ; WX 833 ; N Odieresis ; B 76 -17 794 880 ;
+C -1 ; WX 556 ; N Scaron ; B 50 -17 557 896 ;
+C -1 ; WX 611 ; N Edieresis ; B 11 -3 606 880 ;
+C -1 ; WX 389 ; N Igrave ; B -1 -3 412 911 ;
+C -1 ; WX 556 ; N adieresis ; B 44 -17 538 688 ;
+C -1 ; WX 833 ; N Ograve ; B 76 -17 794 911 ;
+C -1 ; WX 611 ; N Egrave ; B 11 -3 606 911 ;
+C -1 ; WX 611 ; N Ydieresis ; B 54 -3 675 880 ;
+C -1 ; WX 747 ; N registered ; B 26 -17 720 695 ;
+C -1 ; WX 833 ; N Otilde ; B 76 -17 794 866 ;
+C -1 ; WX 750 ; N onequarter ; B 18 -2 732 683 ;
+C -1 ; WX 778 ; N Ugrave ; B 83 -17 825 911 ;
+C -1 ; WX 778 ; N Ucircumflex ; B 83 -17 825 896 ;
+C -1 ; WX 667 ; N Thorn ; B 11 -3 644 681 ;
+C -1 ; WX 606 ; N divide ; B 50 -5 556 501 ;
+C -1 ; WX 722 ; N Atilde ; B -35 -3 685 866 ;
+C -1 ; WX 778 ; N Uacute ; B 83 -17 825 911 ;
+C -1 ; WX 833 ; N Ocircumflex ; B 76 -17 794 896 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 107 555 390 ;
+C -1 ; WX 722 ; N Aring ; B -35 -3 685 926 ;
+C -1 ; WX 333 ; N idieresis ; B 26 -17 426 688 ;
+C -1 ; WX 333 ; N iacute ; B 26 -17 392 719 ;
+C -1 ; WX 556 ; N aacute ; B 44 -17 519 719 ;
+C -1 ; WX 606 ; N plusminus ; B 50 0 556 501 ;
+C -1 ; WX 606 ; N multiply ; B 72 17 534 479 ;
+C -1 ; WX 778 ; N Udieresis ; B 83 -17 825 880 ;
+C -1 ; WX 606 ; N minus ; B 51 204 555 292 ;
+C -1 ; WX 300 ; N onesuperior ; B 41 271 298 680 ;
+C -1 ; WX 611 ; N Eacute ; B 11 -3 606 911 ;
+C -1 ; WX 722 ; N Acircumflex ; B -35 -3 685 896 ;
+C -1 ; WX 747 ; N copyright ; B 26 -17 720 695 ;
+C -1 ; WX 722 ; N Agrave ; B -35 -3 685 911 ;
+C -1 ; WX 556 ; N odieresis ; B 48 -17 538 688 ;
+C -1 ; WX 556 ; N oacute ; B 48 -17 504 719 ;
+C -1 ; WX 400 ; N degree ; B 50 383 350 683 ;
+C -1 ; WX 333 ; N igrave ; B 26 -17 322 719 ;
+C -1 ; WX 556 ; N mu ; B -15 -232 521 469 ;
+C -1 ; WX 833 ; N Oacute ; B 76 -17 794 911 ;
+C -1 ; WX 556 ; N eth ; B 48 -17 546 726 ;
+C -1 ; WX 722 ; N Adieresis ; B -35 -3 685 880 ;
+C -1 ; WX 611 ; N Yacute ; B 54 -3 675 911 ;
+C -1 ; WX 606 ; N brokenbar ; B 259 0 347 720 ;
+C -1 ; WX 750 ; N onehalf ; B 14 -2 736 683 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 108
+
+KPX A y -55
+KPX A w -37
+KPX A v -55
+KPX A space -55
+KPX A quoteright -55
+KPX A Y -74
+KPX A W -74
+KPX A V -74
+KPX A T -55
+
+KPX F space -18
+KPX F period -111
+KPX F comma -111
+KPX F A -74
+
+KPX L y -37
+KPX L space -18
+KPX L quoteright -55
+KPX L Y -74
+KPX L W -74
+KPX L V -74
+KPX L T -74
+
+KPX P space -55
+KPX P period -129
+KPX P comma -129
+KPX P A -92
+
+KPX R y -20
+KPX R Y -37
+KPX R W -55
+KPX R V -55
+KPX R T -37
+
+KPX T y -80
+KPX T w -50
+KPX T u -92
+KPX T semicolon -55
+KPX T s -92
+KPX T r -92
+KPX T period -55
+KPX T o -111
+KPX T i -74
+KPX T hyphen -92
+KPX T e -111
+KPX T comma -55
+KPX T colon -55
+KPX T c -92
+KPX T a -111
+KPX T O -18
+KPX T A -55
+
+KPX V y -50
+KPX V u -50
+KPX V semicolon -37
+KPX V r -74
+KPX V period -111
+KPX V o -74
+KPX V i -50
+KPX V hyphen -37
+KPX V e -74
+KPX V comma -111
+KPX V colon -37
+KPX V a -92
+KPX V A -74
+
+KPX W y -30
+KPX W u -30
+KPX W semicolon -18
+KPX W r -30
+KPX W period -55
+KPX W o -55
+KPX W i -30
+KPX W e -55
+KPX W comma -55
+KPX W colon -28
+KPX W a -74
+KPX W A -74
+
+KPX Y v -30
+KPX Y u -50
+KPX Y semicolon -55
+KPX Y q -92
+KPX Y period -55
+KPX Y p -74
+KPX Y o -111
+KPX Y i -54
+KPX Y hyphen -55
+KPX Y e -92
+KPX Y comma -55
+KPX Y colon -55
+KPX Y a -111
+KPX Y A -55
+
+KPX f quoteright 37
+KPX f f -37
+
+KPX one one -55
+
+KPX quoteleft quoteleft -55
+
+KPX quoteright t -18
+KPX quoteright space -37
+KPX quoteright s -37
+KPX quoteright quoteright -55
+
+KPX r quoteright 55
+KPX r q -18
+KPX r period -55
+KPX r o -18
+KPX r h -18
+KPX r g -18
+KPX r e -18
+KPX r comma -55
+KPX r c -18
+
+KPX v period -55
+KPX v comma -55
+
+KPX w period -55
+KPX w comma -55
+
+KPX y period -37
+KPX y comma -37
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 212 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 212 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 212 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 212 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 83 212 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 212 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 212 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 212 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 212 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 212 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 212 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 212 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 212 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 212 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 223 212 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 212 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 212 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 212 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 212 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 212 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 212 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 223 212 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 223 212 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 223 212 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 211 212 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 151 212 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 139 212 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 212 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 112 20 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 20 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 20 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 112 20 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 12 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 56 20 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 20 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 20 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 56 20 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 20 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -12 20 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 20 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 20 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 12 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 112 20 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 100 20 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 20 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 112 20 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 12 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 44 8 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 112 20 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 100 20 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 20 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 20 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 112 20 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 20 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 72 8 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Palatino-Italic.afm b/tlt3.0/library/afm/Palatino-Italic.afm
new file mode 100644
index 0000000..46c2eb5
--- /dev/null
+++ b/tlt3.0/library/afm/Palatino-Italic.afm
@@ -0,0 +1,440 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Mon Jul  2 22:37:33 1990
+Comment UniqueID 31796
+Comment VMusage 37415 48307
+FontName Palatino-Italic
+FullName Palatino Italic
+FamilyName Palatino
+Weight Medium
+ItalicAngle -10
+IsFixedPitch false
+FontBBox -170 -276 1010 918
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 692
+XHeight 482
+Ascender 733
+Descender -276
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 76 -8 292 733 ;
+C 34 ; WX 500 ; N quotedbl ; B 140 508 455 733 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 495 692 ;
+C 36 ; WX 500 ; N dollar ; B 15 -113 452 733 ;
+C 37 ; WX 889 ; N percent ; B 74 -7 809 710 ;
+C 38 ; WX 778 ; N ampersand ; B 47 -18 766 692 ;
+C 39 ; WX 278 ; N quoteright ; B 78 488 258 733 ;
+C 40 ; WX 333 ; N parenleft ; B 54 -106 331 733 ;
+C 41 ; WX 333 ; N parenright ; B 2 -106 279 733 ;
+C 42 ; WX 389 ; N asterisk ; B 76 368 400 706 ;
+C 43 ; WX 606 ; N plus ; B 51 0 555 504 ;
+C 44 ; WX 250 ; N comma ; B 8 -143 203 123 ;
+C 45 ; WX 333 ; N hyphen ; B 19 223 304 281 ;
+C 46 ; WX 250 ; N period ; B 53 -5 158 112 ;
+C 47 ; WX 296 ; N slash ; B -40 -119 392 733 ;
+C 48 ; WX 500 ; N zero ; B 36 -11 480 699 ;
+C 49 ; WX 500 ; N one ; B 54 -3 398 699 ;
+C 50 ; WX 500 ; N two ; B 12 -3 437 699 ;
+C 51 ; WX 500 ; N three ; B 22 -11 447 699 ;
+C 52 ; WX 500 ; N four ; B 15 -3 478 699 ;
+C 53 ; WX 500 ; N five ; B 14 -11 491 693 ;
+C 54 ; WX 500 ; N six ; B 49 -11 469 699 ;
+C 55 ; WX 500 ; N seven ; B 53 -3 502 692 ;
+C 56 ; WX 500 ; N eight ; B 36 -11 469 699 ;
+C 57 ; WX 500 ; N nine ; B 32 -11 468 699 ;
+C 58 ; WX 250 ; N colon ; B 44 -5 207 458 ;
+C 59 ; WX 250 ; N semicolon ; B -9 -146 219 456 ;
+C 60 ; WX 606 ; N less ; B 53 -6 554 516 ;
+C 61 ; WX 606 ; N equal ; B 51 126 555 378 ;
+C 62 ; WX 606 ; N greater ; B 53 -6 554 516 ;
+C 63 ; WX 500 ; N question ; B 114 -8 427 706 ;
+C 64 ; WX 747 ; N at ; B 27 -18 718 706 ;
+C 65 ; WX 722 ; N A ; B -19 -3 677 705 ;
+C 66 ; WX 611 ; N B ; B 26 -6 559 692 ;
+C 67 ; WX 667 ; N C ; B 45 -18 651 706 ;
+C 68 ; WX 778 ; N D ; B 28 -3 741 692 ;
+C 69 ; WX 611 ; N E ; B 30 -3 570 692 ;
+C 70 ; WX 556 ; N F ; B 0 -3 548 692 ;
+C 71 ; WX 722 ; N G ; B 50 -18 694 706 ;
+C 72 ; WX 778 ; N H ; B -3 -3 800 692 ;
+C 73 ; WX 333 ; N I ; B 7 -3 354 692 ;
+C 74 ; WX 333 ; N J ; B -35 -206 358 692 ;
+C 75 ; WX 667 ; N K ; B 13 -3 683 692 ;
+C 76 ; WX 556 ; N L ; B 16 -3 523 692 ;
+C 77 ; WX 944 ; N M ; B -19 -18 940 692 ;
+C 78 ; WX 778 ; N N ; B 2 -11 804 692 ;
+C 79 ; WX 778 ; N O ; B 53 -18 748 706 ;
+C 80 ; WX 611 ; N P ; B 9 -3 594 692 ;
+C 81 ; WX 778 ; N Q ; B 53 -201 748 706 ;
+C 82 ; WX 667 ; N R ; B 9 -3 639 692 ;
+C 83 ; WX 556 ; N S ; B 42 -18 506 706 ;
+C 84 ; WX 611 ; N T ; B 53 -3 635 692 ;
+C 85 ; WX 778 ; N U ; B 88 -18 798 692 ;
+C 86 ; WX 722 ; N V ; B 75 -8 754 692 ;
+C 87 ; WX 944 ; N W ; B 71 -8 980 700 ;
+C 88 ; WX 722 ; N X ; B 20 -3 734 692 ;
+C 89 ; WX 667 ; N Y ; B 52 -3 675 705 ;
+C 90 ; WX 667 ; N Z ; B 20 -3 637 692 ;
+C 91 ; WX 333 ; N bracketleft ; B 18 -100 326 733 ;
+C 92 ; WX 606 ; N backslash ; B 81 0 513 733 ;
+C 93 ; WX 333 ; N bracketright ; B 7 -100 315 733 ;
+C 94 ; WX 606 ; N asciicircum ; B 51 283 554 689 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 78 488 258 733 ;
+C 97 ; WX 444 ; N a ; B 4 -11 406 482 ;
+C 98 ; WX 463 ; N b ; B 37 -11 433 733 ;
+C 99 ; WX 407 ; N c ; B 25 -11 389 482 ;
+C 100 ; WX 500 ; N d ; B 17 -11 483 733 ;
+C 101 ; WX 389 ; N e ; B 15 -11 374 482 ;
+C 102 ; WX 278 ; N f ; B -162 -276 413 733 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B -37 -276 498 482 ;
+C 104 ; WX 500 ; N h ; B 10 -9 471 733 ;
+C 105 ; WX 278 ; N i ; B 34 -9 264 712 ;
+C 106 ; WX 278 ; N j ; B -70 -276 265 712 ;
+C 107 ; WX 444 ; N k ; B 8 -9 449 733 ;
+C 108 ; WX 278 ; N l ; B 36 -9 251 733 ;
+C 109 ; WX 778 ; N m ; B 24 -9 740 482 ;
+C 110 ; WX 556 ; N n ; B 24 -9 514 482 ;
+C 111 ; WX 444 ; N o ; B 17 -11 411 482 ;
+C 112 ; WX 500 ; N p ; B -7 -276 465 482 ;
+C 113 ; WX 463 ; N q ; B 24 -276 432 482 ;
+C 114 ; WX 389 ; N r ; B 26 -9 384 482 ;
+C 115 ; WX 389 ; N s ; B 9 -11 345 482 ;
+C 116 ; WX 333 ; N t ; B 41 -9 310 646 ;
+C 117 ; WX 556 ; N u ; B 32 -11 512 482 ;
+C 118 ; WX 500 ; N v ; B 21 -11 477 482 ;
+C 119 ; WX 722 ; N w ; B 21 -11 699 482 ;
+C 120 ; WX 500 ; N x ; B 9 -11 484 482 ;
+C 121 ; WX 500 ; N y ; B -8 -276 490 482 ;
+C 122 ; WX 444 ; N z ; B -1 -11 416 482 ;
+C 123 ; WX 333 ; N braceleft ; B 15 -100 319 733 ;
+C 124 ; WX 606 ; N bar ; B 275 0 331 733 ;
+C 125 ; WX 333 ; N braceright ; B 14 -100 318 733 ;
+C 126 ; WX 606 ; N asciitilde ; B 51 168 555 339 ;
+C 161 ; WX 333 ; N exclamdown ; B 15 -276 233 467 ;
+C 162 ; WX 500 ; N cent ; B 56 -96 418 551 ;
+C 163 ; WX 500 ; N sterling ; B 2 -18 479 708 ;
+C 164 ; WX 167 ; N fraction ; B -170 0 337 699 ;
+C 165 ; WX 500 ; N yen ; B 35 -3 512 699 ;
+C 166 ; WX 500 ; N florin ; B 5 -276 470 708 ;
+C 167 ; WX 500 ; N section ; B 14 -220 463 706 ;
+C 168 ; WX 500 ; N currency ; B 14 115 486 577 ;
+C 169 ; WX 333 ; N quotesingle ; B 140 508 288 733 ;
+C 170 ; WX 500 ; N quotedblleft ; B 98 488 475 733 ;
+C 171 ; WX 500 ; N guillemotleft ; B 57 70 437 440 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 57 70 270 440 ;
+C 173 ; WX 333 ; N guilsinglright ; B 63 70 276 440 ;
+C 174 ; WX 528 ; N fi ; B -162 -276 502 733 ;
+C 175 ; WX 545 ; N fl ; B -162 -276 520 733 ;
+C 177 ; WX 500 ; N endash ; B -10 228 510 278 ;
+C 178 ; WX 500 ; N dagger ; B 48 0 469 692 ;
+C 179 ; WX 500 ; N daggerdbl ; B 10 -162 494 692 ;
+C 180 ; WX 250 ; N periodcentered ; B 53 195 158 312 ;
+C 182 ; WX 500 ; N paragraph ; B 33 -224 611 692 ;
+C 183 ; WX 500 ; N bullet ; B 86 182 430 526 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 27 -122 211 120 ;
+C 185 ; WX 500 ; N quotedblbase ; B 43 -122 424 120 ;
+C 186 ; WX 500 ; N quotedblright ; B 98 488 475 733 ;
+C 187 ; WX 500 ; N guillemotright ; B 63 70 443 440 ;
+C 188 ; WX 1000 ; N ellipsis ; B 102 -5 873 112 ;
+C 189 ; WX 1000 ; N perthousand ; B 72 -6 929 717 ;
+C 191 ; WX 500 ; N questiondown ; B 57 -246 370 467 ;
+C 193 ; WX 333 ; N grave ; B 86 518 310 687 ;
+C 194 ; WX 333 ; N acute ; B 122 518 346 687 ;
+C 195 ; WX 333 ; N circumflex ; B 56 510 350 679 ;
+C 196 ; WX 333 ; N tilde ; B 63 535 390 638 ;
+C 197 ; WX 333 ; N macron ; B 74 538 386 589 ;
+C 198 ; WX 333 ; N breve ; B 92 518 393 677 ;
+C 199 ; WX 333 ; N dotaccent ; B 175 537 283 645 ;
+C 200 ; WX 333 ; N dieresis ; B 78 537 378 637 ;
+C 202 ; WX 333 ; N ring ; B 159 508 359 708 ;
+C 203 ; WX 333 ; N cedilla ; B -9 -216 202 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 46 518 385 730 ;
+C 206 ; WX 333 ; N ogonek ; B 38 -207 196 -18 ;
+C 207 ; WX 333 ; N caron ; B 104 510 409 679 ;
+C 208 ; WX 1000 ; N emdash ; B -10 228 1010 278 ;
+C 225 ; WX 941 ; N AE ; B -4 -3 902 692 ;
+C 227 ; WX 333 ; N ordfeminine ; B 60 404 321 699 ;
+C 232 ; WX 556 ; N Lslash ; B -16 -3 523 692 ;
+C 233 ; WX 778 ; N Oslash ; B 32 -39 762 721 ;
+C 234 ; WX 1028 ; N OE ; B 56 -18 989 706 ;
+C 235 ; WX 333 ; N ordmasculine ; B 66 404 322 699 ;
+C 241 ; WX 638 ; N ae ; B 1 -11 623 482 ;
+C 245 ; WX 278 ; N dotlessi ; B 34 -9 241 482 ;
+C 248 ; WX 278 ; N lslash ; B -10 -9 302 733 ;
+C 249 ; WX 444 ; N oslash ; B -18 -24 460 510 ;
+C 250 ; WX 669 ; N oe ; B 17 -11 654 482 ;
+C 251 ; WX 500 ; N germandbls ; B -160 -276 488 733 ;
+C -1 ; WX 667 ; N Zcaron ; B 20 -3 637 907 ;
+C -1 ; WX 407 ; N ccedilla ; B 25 -216 389 482 ;
+C -1 ; WX 500 ; N ydieresis ; B -8 -276 490 657 ;
+C -1 ; WX 444 ; N atilde ; B 4 -11 446 650 ;
+C -1 ; WX 278 ; N icircumflex ; B 29 -9 323 699 ;
+C -1 ; WX 300 ; N threesuperior ; B 28 273 304 699 ;
+C -1 ; WX 389 ; N ecircumflex ; B 15 -11 398 699 ;
+C -1 ; WX 500 ; N thorn ; B -39 -276 433 733 ;
+C -1 ; WX 389 ; N egrave ; B 15 -11 374 707 ;
+C -1 ; WX 300 ; N twosuperior ; B 13 278 290 699 ;
+C -1 ; WX 389 ; N eacute ; B 15 -11 394 707 ;
+C -1 ; WX 444 ; N otilde ; B 17 -11 446 650 ;
+C -1 ; WX 722 ; N Aacute ; B -19 -3 677 897 ;
+C -1 ; WX 444 ; N ocircumflex ; B 17 -11 411 699 ;
+C -1 ; WX 500 ; N yacute ; B -8 -276 490 707 ;
+C -1 ; WX 556 ; N udieresis ; B 32 -11 512 657 ;
+C -1 ; WX 750 ; N threequarters ; B 35 -2 715 699 ;
+C -1 ; WX 444 ; N acircumflex ; B 4 -11 406 699 ;
+C -1 ; WX 778 ; N Eth ; B 19 -3 741 692 ;
+C -1 ; WX 389 ; N edieresis ; B 15 -11 406 657 ;
+C -1 ; WX 556 ; N ugrave ; B 32 -11 512 707 ;
+C -1 ; WX 1000 ; N trademark ; B 52 285 951 689 ;
+C -1 ; WX 444 ; N ograve ; B 17 -11 411 707 ;
+C -1 ; WX 389 ; N scaron ; B 9 -11 419 687 ;
+C -1 ; WX 333 ; N Idieresis ; B 7 -3 418 847 ;
+C -1 ; WX 556 ; N uacute ; B 32 -11 512 707 ;
+C -1 ; WX 444 ; N agrave ; B 4 -11 406 707 ;
+C -1 ; WX 556 ; N ntilde ; B 24 -9 514 650 ;
+C -1 ; WX 444 ; N aring ; B 4 -11 406 728 ;
+C -1 ; WX 444 ; N zcaron ; B -1 -11 447 687 ;
+C -1 ; WX 333 ; N Icircumflex ; B 7 -3 390 889 ;
+C -1 ; WX 778 ; N Ntilde ; B 2 -11 804 866 ;
+C -1 ; WX 556 ; N ucircumflex ; B 32 -11 512 699 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 30 -3 570 889 ;
+C -1 ; WX 333 ; N Iacute ; B 7 -3 406 897 ;
+C -1 ; WX 667 ; N Ccedilla ; B 45 -216 651 706 ;
+C -1 ; WX 778 ; N Odieresis ; B 53 -18 748 847 ;
+C -1 ; WX 556 ; N Scaron ; B 42 -18 539 907 ;
+C -1 ; WX 611 ; N Edieresis ; B 30 -3 570 847 ;
+C -1 ; WX 333 ; N Igrave ; B 7 -3 354 897 ;
+C -1 ; WX 444 ; N adieresis ; B 4 -11 434 657 ;
+C -1 ; WX 778 ; N Ograve ; B 53 -18 748 897 ;
+C -1 ; WX 611 ; N Egrave ; B 30 -3 570 897 ;
+C -1 ; WX 667 ; N Ydieresis ; B 52 -3 675 847 ;
+C -1 ; WX 747 ; N registered ; B 11 -18 736 706 ;
+C -1 ; WX 778 ; N Otilde ; B 53 -18 748 866 ;
+C -1 ; WX 750 ; N onequarter ; B 31 -2 715 699 ;
+C -1 ; WX 778 ; N Ugrave ; B 88 -18 798 897 ;
+C -1 ; WX 778 ; N Ucircumflex ; B 88 -18 798 889 ;
+C -1 ; WX 611 ; N Thorn ; B 9 -3 570 692 ;
+C -1 ; WX 606 ; N divide ; B 51 0 555 504 ;
+C -1 ; WX 722 ; N Atilde ; B -19 -3 677 866 ;
+C -1 ; WX 778 ; N Uacute ; B 88 -18 798 897 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 53 -18 748 889 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 118 555 378 ;
+C -1 ; WX 722 ; N Aring ; B -19 -3 677 918 ;
+C -1 ; WX 278 ; N idieresis ; B 34 -9 351 657 ;
+C -1 ; WX 278 ; N iacute ; B 34 -9 331 707 ;
+C -1 ; WX 444 ; N aacute ; B 4 -11 414 707 ;
+C -1 ; WX 606 ; N plusminus ; B 51 0 555 504 ;
+C -1 ; WX 606 ; N multiply ; B 83 36 523 474 ;
+C -1 ; WX 778 ; N Udieresis ; B 88 -18 798 847 ;
+C -1 ; WX 606 ; N minus ; B 51 224 555 280 ;
+C -1 ; WX 300 ; N onesuperior ; B 61 278 285 699 ;
+C -1 ; WX 611 ; N Eacute ; B 30 -3 570 897 ;
+C -1 ; WX 722 ; N Acircumflex ; B -19 -3 677 889 ;
+C -1 ; WX 747 ; N copyright ; B 11 -18 736 706 ;
+C -1 ; WX 722 ; N Agrave ; B -19 -3 677 897 ;
+C -1 ; WX 444 ; N odieresis ; B 17 -11 434 657 ;
+C -1 ; WX 444 ; N oacute ; B 17 -11 414 707 ;
+C -1 ; WX 400 ; N degree ; B 90 389 390 689 ;
+C -1 ; WX 278 ; N igrave ; B 34 -9 271 707 ;
+C -1 ; WX 556 ; N mu ; B 15 -226 512 482 ;
+C -1 ; WX 778 ; N Oacute ; B 53 -18 748 897 ;
+C -1 ; WX 444 ; N eth ; B 17 -11 478 733 ;
+C -1 ; WX 722 ; N Adieresis ; B -19 -3 677 847 ;
+C -1 ; WX 667 ; N Yacute ; B 52 -3 675 897 ;
+C -1 ; WX 606 ; N brokenbar ; B 275 0 331 733 ;
+C -1 ; WX 750 ; N onehalf ; B 31 -2 721 699 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 106
+
+KPX A y -55
+KPX A w -37
+KPX A v -37
+KPX A space -37
+KPX A quoteright -55
+KPX A Y -55
+KPX A W -55
+KPX A V -74
+KPX A T -55
+
+KPX F period -111
+KPX F comma -111
+KPX F A -111
+
+KPX L y -37
+KPX L space -18
+KPX L quoteright -37
+KPX L Y -74
+KPX L W -74
+KPX L V -74
+KPX L T -74
+
+KPX P period -129
+KPX P comma -129
+KPX P A -129
+
+KPX R y -37
+KPX R Y -55
+KPX R W -55
+KPX R V -74
+KPX R T -55
+
+KPX T y -92
+KPX T w -92
+KPX T u -111
+KPX T semicolon -74
+KPX T s -111
+KPX T r -111
+KPX T period -74
+KPX T o -111
+KPX T i -55
+KPX T hyphen -55
+KPX T e -111
+KPX T comma -74
+KPX T colon -74
+KPX T c -111
+KPX T a -111
+KPX T O -18
+KPX T A -92
+
+KPX V y -74
+KPX V u -74
+KPX V semicolon -37
+KPX V r -92
+KPX V period -129
+KPX V o -74
+KPX V i -74
+KPX V hyphen -55
+KPX V e -92
+KPX V comma -129
+KPX V colon -37
+KPX V a -74
+KPX V A -210
+
+KPX W y -20
+KPX W u -20
+KPX W semicolon -18
+KPX W r -20
+KPX W period -55
+KPX W o -20
+KPX W i -20
+KPX W hyphen -18
+KPX W e -20
+KPX W comma -55
+KPX W colon -18
+KPX W a -20
+KPX W A -92
+
+KPX Y v -74
+KPX Y u -92
+KPX Y semicolon -74
+KPX Y q -92
+KPX Y period -92
+KPX Y p -74
+KPX Y o -111
+KPX Y i -55
+KPX Y hyphen -74
+KPX Y e -111
+KPX Y comma -92
+KPX Y colon -74
+KPX Y a -92
+KPX Y A -92
+
+KPX f quoteright 55
+
+KPX one one -55
+
+KPX quoteleft quoteleft -74
+
+KPX quoteright t -37
+KPX quoteright space -55
+KPX quoteright s -55
+KPX quoteright quoteright -74
+
+KPX r quoteright 37
+KPX r q -18
+KPX r period -74
+KPX r o -18
+KPX r h -18
+KPX r g -18
+KPX r e -18
+KPX r comma -74
+KPX r c -18
+
+KPX v period -55
+KPX v comma -55
+
+KPX w period -55
+KPX w comma -55
+
+KPX y period -37
+KPX y comma -37
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 271 210 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 261 210 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 255 210 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 235 210 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 235 210 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 255 228 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 207 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 199 210 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 179 210 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 179 210 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 210 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 60 210 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 40 210 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 40 210 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 210 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 263 228 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 283 210 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 263 210 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 255 210 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 251 210 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 263 228 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 130 228 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 277 210 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 255 210 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 210 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 235 210 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 227 210 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 187 210 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 228 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 68 20 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 20 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 20 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 44 20 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 36 20 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 12 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 37 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 48 20 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 48 20 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 28 20 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 16 20 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -15 20 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 20 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 20 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -39 20 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 12 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 68 20 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 56 20 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 56 20 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 36 20 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 56 12 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 10 8 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 124 20 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 20 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 20 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 100 20 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 96 20 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 20 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 38 8 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Palatino-Roman.afm b/tlt3.0/library/afm/Palatino-Roman.afm
new file mode 100644
index 0000000..c7b7aff
--- /dev/null
+++ b/tlt3.0/library/afm/Palatino-Roman.afm
@@ -0,0 +1,446 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Mon Jul  2 22:14:17 1990
+Comment UniqueID 31790
+Comment VMusage 36445 47337
+FontName Palatino-Roman
+FullName Palatino Roman
+FamilyName Palatino
+Weight Roman
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -166 -283 1021 927
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 692
+XHeight 469
+Ascender 726
+Descender -281
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 81 -5 197 694 ;
+C 34 ; WX 371 ; N quotedbl ; B 52 469 319 709 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 495 684 ;
+C 36 ; WX 500 ; N dollar ; B 30 -116 471 731 ;
+C 37 ; WX 840 ; N percent ; B 39 -20 802 709 ;
+C 38 ; WX 778 ; N ampersand ; B 43 -20 753 689 ;
+C 39 ; WX 278 ; N quoteright ; B 45 446 233 709 ;
+C 40 ; WX 333 ; N parenleft ; B 60 -215 301 726 ;
+C 41 ; WX 333 ; N parenright ; B 32 -215 273 726 ;
+C 42 ; WX 389 ; N asterisk ; B 32 342 359 689 ;
+C 43 ; WX 606 ; N plus ; B 51 7 555 512 ;
+C 44 ; WX 250 ; N comma ; B 16 -155 218 123 ;
+C 45 ; WX 333 ; N hyphen ; B 17 215 312 287 ;
+C 46 ; WX 250 ; N period ; B 67 -5 183 111 ;
+C 47 ; WX 606 ; N slash ; B 87 -119 519 726 ;
+C 48 ; WX 500 ; N zero ; B 29 -20 465 689 ;
+C 49 ; WX 500 ; N one ; B 60 -3 418 694 ;
+C 50 ; WX 500 ; N two ; B 16 -3 468 689 ;
+C 51 ; WX 500 ; N three ; B 15 -20 462 689 ;
+C 52 ; WX 500 ; N four ; B 2 -3 472 694 ;
+C 53 ; WX 500 ; N five ; B 13 -20 459 689 ;
+C 54 ; WX 500 ; N six ; B 32 -20 468 689 ;
+C 55 ; WX 500 ; N seven ; B 44 -3 497 689 ;
+C 56 ; WX 500 ; N eight ; B 30 -20 464 689 ;
+C 57 ; WX 500 ; N nine ; B 20 -20 457 689 ;
+C 58 ; WX 250 ; N colon ; B 66 -5 182 456 ;
+C 59 ; WX 250 ; N semicolon ; B 16 -153 218 456 ;
+C 60 ; WX 606 ; N less ; B 57 0 558 522 ;
+C 61 ; WX 606 ; N equal ; B 51 136 555 386 ;
+C 62 ; WX 606 ; N greater ; B 48 0 549 522 ;
+C 63 ; WX 444 ; N question ; B 43 -5 395 694 ;
+C 64 ; WX 747 ; N at ; B 24 -20 724 694 ;
+C 65 ; WX 778 ; N A ; B 15 -3 756 700 ;
+C 66 ; WX 611 ; N B ; B 26 -3 576 692 ;
+C 67 ; WX 709 ; N C ; B 22 -20 670 709 ;
+C 68 ; WX 774 ; N D ; B 22 -3 751 692 ;
+C 69 ; WX 611 ; N E ; B 22 -3 572 692 ;
+C 70 ; WX 556 ; N F ; B 22 -3 536 692 ;
+C 71 ; WX 763 ; N G ; B 22 -20 728 709 ;
+C 72 ; WX 832 ; N H ; B 22 -3 810 692 ;
+C 73 ; WX 337 ; N I ; B 22 -3 315 692 ;
+C 74 ; WX 333 ; N J ; B -15 -194 311 692 ;
+C 75 ; WX 726 ; N K ; B 22 -3 719 692 ;
+C 76 ; WX 611 ; N L ; B 22 -3 586 692 ;
+C 77 ; WX 946 ; N M ; B 16 -13 926 692 ;
+C 78 ; WX 831 ; N N ; B 17 -20 813 692 ;
+C 79 ; WX 786 ; N O ; B 22 -20 764 709 ;
+C 80 ; WX 604 ; N P ; B 22 -3 580 692 ;
+C 81 ; WX 786 ; N Q ; B 22 -176 764 709 ;
+C 82 ; WX 668 ; N R ; B 22 -3 669 692 ;
+C 83 ; WX 525 ; N S ; B 24 -20 503 709 ;
+C 84 ; WX 613 ; N T ; B 18 -3 595 692 ;
+C 85 ; WX 778 ; N U ; B 12 -20 759 692 ;
+C 86 ; WX 722 ; N V ; B 8 -9 706 692 ;
+C 87 ; WX 1000 ; N W ; B 8 -9 984 700 ;
+C 88 ; WX 667 ; N X ; B 14 -3 648 700 ;
+C 89 ; WX 667 ; N Y ; B 9 -3 654 704 ;
+C 90 ; WX 667 ; N Z ; B 15 -3 638 692 ;
+C 91 ; WX 333 ; N bracketleft ; B 79 -184 288 726 ;
+C 92 ; WX 606 ; N backslash ; B 81 0 512 726 ;
+C 93 ; WX 333 ; N bracketright ; B 45 -184 254 726 ;
+C 94 ; WX 606 ; N asciicircum ; B 51 283 554 689 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 278 ; N quoteleft ; B 45 446 233 709 ;
+C 97 ; WX 500 ; N a ; B 32 -12 471 469 ;
+C 98 ; WX 553 ; N b ; B -15 -12 508 726 ;
+C 99 ; WX 444 ; N c ; B 26 -20 413 469 ;
+C 100 ; WX 611 ; N d ; B 35 -12 579 726 ;
+C 101 ; WX 479 ; N e ; B 26 -20 448 469 ;
+C 102 ; WX 333 ; N f ; B 23 -3 341 728 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 32 -283 544 469 ;
+C 104 ; WX 582 ; N h ; B 6 -3 572 726 ;
+C 105 ; WX 291 ; N i ; B 21 -3 271 687 ;
+C 106 ; WX 234 ; N j ; B -40 -283 167 688 ;
+C 107 ; WX 556 ; N k ; B 21 -12 549 726 ;
+C 108 ; WX 291 ; N l ; B 21 -3 271 726 ;
+C 109 ; WX 883 ; N m ; B 16 -3 869 469 ;
+C 110 ; WX 582 ; N n ; B 6 -3 572 469 ;
+C 111 ; WX 546 ; N o ; B 32 -20 514 469 ;
+C 112 ; WX 601 ; N p ; B 8 -281 554 469 ;
+C 113 ; WX 560 ; N q ; B 35 -281 560 469 ;
+C 114 ; WX 395 ; N r ; B 21 -3 374 469 ;
+C 115 ; WX 424 ; N s ; B 30 -20 391 469 ;
+C 116 ; WX 326 ; N t ; B 22 -12 319 621 ;
+C 117 ; WX 603 ; N u ; B 18 -12 581 469 ;
+C 118 ; WX 565 ; N v ; B 6 -7 539 459 ;
+C 119 ; WX 834 ; N w ; B 6 -7 808 469 ;
+C 120 ; WX 516 ; N x ; B 20 -3 496 469 ;
+C 121 ; WX 556 ; N y ; B 12 -283 544 459 ;
+C 122 ; WX 500 ; N z ; B 16 -3 466 462 ;
+C 123 ; WX 333 ; N braceleft ; B 58 -175 289 726 ;
+C 124 ; WX 606 ; N bar ; B 275 0 331 726 ;
+C 125 ; WX 333 ; N braceright ; B 44 -175 275 726 ;
+C 126 ; WX 606 ; N asciitilde ; B 51 176 555 347 ;
+C 161 ; WX 278 ; N exclamdown ; B 81 -225 197 469 ;
+C 162 ; WX 500 ; N cent ; B 61 -101 448 562 ;
+C 163 ; WX 500 ; N sterling ; B 12 -13 478 694 ;
+C 164 ; WX 167 ; N fraction ; B -166 0 337 689 ;
+C 165 ; WX 500 ; N yen ; B 5 -3 496 701 ;
+C 166 ; WX 500 ; N florin ; B 0 -262 473 706 ;
+C 167 ; WX 500 ; N section ; B 26 -219 465 709 ;
+C 168 ; WX 500 ; N currency ; B 30 96 470 531 ;
+C 169 ; WX 208 ; N quotesingle ; B 61 469 147 709 ;
+C 170 ; WX 500 ; N quotedblleft ; B 51 446 449 709 ;
+C 171 ; WX 500 ; N guillemotleft ; B 50 71 450 428 ;
+C 172 ; WX 331 ; N guilsinglleft ; B 66 71 265 428 ;
+C 173 ; WX 331 ; N guilsinglright ; B 66 71 265 428 ;
+C 174 ; WX 605 ; N fi ; B 23 -3 587 728 ;
+C 175 ; WX 608 ; N fl ; B 23 -3 590 728 ;
+C 177 ; WX 500 ; N endash ; B 0 219 500 277 ;
+C 178 ; WX 500 ; N dagger ; B 34 -5 466 694 ;
+C 179 ; WX 500 ; N daggerdbl ; B 34 -249 466 694 ;
+C 180 ; WX 250 ; N periodcentered ; B 67 203 183 319 ;
+C 182 ; WX 628 ; N paragraph ; B 39 -150 589 694 ;
+C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 22 -153 210 110 ;
+C 185 ; WX 500 ; N quotedblbase ; B 51 -153 449 110 ;
+C 186 ; WX 500 ; N quotedblright ; B 51 446 449 709 ;
+C 187 ; WX 500 ; N guillemotright ; B 50 71 450 428 ;
+C 188 ; WX 1000 ; N ellipsis ; B 109 -5 891 111 ;
+C 189 ; WX 1144 ; N perthousand ; B 123 -20 1021 709 ;
+C 191 ; WX 444 ; N questiondown ; B 43 -231 395 469 ;
+C 193 ; WX 333 ; N grave ; B 31 506 255 677 ;
+C 194 ; WX 333 ; N acute ; B 78 506 302 677 ;
+C 195 ; WX 333 ; N circumflex ; B 11 510 323 677 ;
+C 196 ; WX 333 ; N tilde ; B 2 535 332 640 ;
+C 197 ; WX 333 ; N macron ; B 11 538 323 591 ;
+C 198 ; WX 333 ; N breve ; B 26 506 308 664 ;
+C 199 ; WX 250 ; N dotaccent ; B 75 537 175 637 ;
+C 200 ; WX 333 ; N dieresis ; B 17 537 316 637 ;
+C 202 ; WX 333 ; N ring ; B 67 496 267 696 ;
+C 203 ; WX 333 ; N cedilla ; B 96 -225 304 -10 ;
+C 205 ; WX 380 ; N hungarumlaut ; B 3 506 377 687 ;
+C 206 ; WX 313 ; N ogonek ; B 68 -165 245 -20 ;
+C 207 ; WX 333 ; N caron ; B 11 510 323 677 ;
+C 208 ; WX 1000 ; N emdash ; B 0 219 1000 277 ;
+C 225 ; WX 944 ; N AE ; B -10 -3 908 692 ;
+C 227 ; WX 333 ; N ordfeminine ; B 24 422 310 709 ;
+C 232 ; WX 611 ; N Lslash ; B 6 -3 586 692 ;
+C 233 ; WX 833 ; N Oslash ; B 30 -20 797 709 ;
+C 234 ; WX 998 ; N OE ; B 22 -20 962 709 ;
+C 235 ; WX 333 ; N ordmasculine ; B 10 416 323 709 ;
+C 241 ; WX 758 ; N ae ; B 30 -20 732 469 ;
+C 245 ; WX 287 ; N dotlessi ; B 21 -3 271 469 ;
+C 248 ; WX 291 ; N lslash ; B -14 -3 306 726 ;
+C 249 ; WX 556 ; N oslash ; B 16 -23 530 474 ;
+C 250 ; WX 827 ; N oe ; B 32 -20 800 469 ;
+C 251 ; WX 556 ; N germandbls ; B 23 -9 519 731 ;
+C -1 ; WX 667 ; N Zcaron ; B 15 -3 638 908 ;
+C -1 ; WX 444 ; N ccedilla ; B 26 -225 413 469 ;
+C -1 ; WX 556 ; N ydieresis ; B 12 -283 544 657 ;
+C -1 ; WX 500 ; N atilde ; B 32 -12 471 652 ;
+C -1 ; WX 287 ; N icircumflex ; B -12 -3 300 697 ;
+C -1 ; WX 300 ; N threesuperior ; B 1 266 299 689 ;
+C -1 ; WX 479 ; N ecircumflex ; B 26 -20 448 697 ;
+C -1 ; WX 601 ; N thorn ; B -2 -281 544 726 ;
+C -1 ; WX 479 ; N egrave ; B 26 -20 448 697 ;
+C -1 ; WX 300 ; N twosuperior ; B 0 273 301 689 ;
+C -1 ; WX 479 ; N eacute ; B 26 -20 448 697 ;
+C -1 ; WX 546 ; N otilde ; B 32 -20 514 652 ;
+C -1 ; WX 778 ; N Aacute ; B 15 -3 756 908 ;
+C -1 ; WX 546 ; N ocircumflex ; B 32 -20 514 697 ;
+C -1 ; WX 556 ; N yacute ; B 12 -283 544 697 ;
+C -1 ; WX 603 ; N udieresis ; B 18 -12 581 657 ;
+C -1 ; WX 750 ; N threequarters ; B 15 -3 735 689 ;
+C -1 ; WX 500 ; N acircumflex ; B 32 -12 471 697 ;
+C -1 ; WX 774 ; N Eth ; B 14 -3 751 692 ;
+C -1 ; WX 479 ; N edieresis ; B 26 -20 448 657 ;
+C -1 ; WX 603 ; N ugrave ; B 18 -12 581 697 ;
+C -1 ; WX 979 ; N trademark ; B 40 285 939 689 ;
+C -1 ; WX 546 ; N ograve ; B 32 -20 514 697 ;
+C -1 ; WX 424 ; N scaron ; B 30 -20 391 685 ;
+C -1 ; WX 337 ; N Idieresis ; B 19 -3 318 868 ;
+C -1 ; WX 603 ; N uacute ; B 18 -12 581 697 ;
+C -1 ; WX 500 ; N agrave ; B 32 -12 471 697 ;
+C -1 ; WX 582 ; N ntilde ; B 6 -3 572 652 ;
+C -1 ; WX 500 ; N aring ; B 32 -12 471 716 ;
+C -1 ; WX 500 ; N zcaron ; B 16 -3 466 685 ;
+C -1 ; WX 337 ; N Icircumflex ; B 13 -3 325 908 ;
+C -1 ; WX 831 ; N Ntilde ; B 17 -20 813 871 ;
+C -1 ; WX 603 ; N ucircumflex ; B 18 -12 581 697 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 22 -3 572 908 ;
+C -1 ; WX 337 ; N Iacute ; B 22 -3 315 908 ;
+C -1 ; WX 709 ; N Ccedilla ; B 22 -225 670 709 ;
+C -1 ; WX 786 ; N Odieresis ; B 22 -20 764 868 ;
+C -1 ; WX 525 ; N Scaron ; B 24 -20 503 908 ;
+C -1 ; WX 611 ; N Edieresis ; B 22 -3 572 868 ;
+C -1 ; WX 337 ; N Igrave ; B 22 -3 315 908 ;
+C -1 ; WX 500 ; N adieresis ; B 32 -12 471 657 ;
+C -1 ; WX 786 ; N Ograve ; B 22 -20 764 908 ;
+C -1 ; WX 611 ; N Egrave ; B 22 -3 572 908 ;
+C -1 ; WX 667 ; N Ydieresis ; B 9 -3 654 868 ;
+C -1 ; WX 747 ; N registered ; B 11 -18 736 706 ;
+C -1 ; WX 786 ; N Otilde ; B 22 -20 764 883 ;
+C -1 ; WX 750 ; N onequarter ; B 30 -3 727 692 ;
+C -1 ; WX 778 ; N Ugrave ; B 12 -20 759 908 ;
+C -1 ; WX 778 ; N Ucircumflex ; B 12 -20 759 908 ;
+C -1 ; WX 604 ; N Thorn ; B 32 -3 574 692 ;
+C -1 ; WX 606 ; N divide ; B 51 10 555 512 ;
+C -1 ; WX 778 ; N Atilde ; B 15 -3 756 871 ;
+C -1 ; WX 778 ; N Uacute ; B 12 -20 759 908 ;
+C -1 ; WX 786 ; N Ocircumflex ; B 22 -20 764 908 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 120 551 386 ;
+C -1 ; WX 778 ; N Aring ; B 15 -3 756 927 ;
+C -1 ; WX 287 ; N idieresis ; B -6 -3 293 657 ;
+C -1 ; WX 287 ; N iacute ; B 21 -3 279 697 ;
+C -1 ; WX 500 ; N aacute ; B 32 -12 471 697 ;
+C -1 ; WX 606 ; N plusminus ; B 51 0 555 512 ;
+C -1 ; WX 606 ; N multiply ; B 83 36 523 474 ;
+C -1 ; WX 778 ; N Udieresis ; B 12 -20 759 868 ;
+C -1 ; WX 606 ; N minus ; B 51 233 555 289 ;
+C -1 ; WX 300 ; N onesuperior ; B 31 273 269 692 ;
+C -1 ; WX 611 ; N Eacute ; B 22 -3 572 908 ;
+C -1 ; WX 778 ; N Acircumflex ; B 15 -3 756 908 ;
+C -1 ; WX 747 ; N copyright ; B 11 -18 736 706 ;
+C -1 ; WX 778 ; N Agrave ; B 15 -3 756 908 ;
+C -1 ; WX 546 ; N odieresis ; B 32 -20 514 657 ;
+C -1 ; WX 546 ; N oacute ; B 32 -20 514 697 ;
+C -1 ; WX 400 ; N degree ; B 50 389 350 689 ;
+C -1 ; WX 287 ; N igrave ; B 8 -3 271 697 ;
+C -1 ; WX 603 ; N mu ; B 18 -236 581 469 ;
+C -1 ; WX 786 ; N Oacute ; B 22 -20 764 908 ;
+C -1 ; WX 546 ; N eth ; B 32 -20 504 728 ;
+C -1 ; WX 778 ; N Adieresis ; B 15 -3 756 868 ;
+C -1 ; WX 667 ; N Yacute ; B 9 -3 654 908 ;
+C -1 ; WX 606 ; N brokenbar ; B 275 0 331 726 ;
+C -1 ; WX 750 ; N onehalf ; B 15 -3 735 692 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 111
+
+KPX A y -74
+KPX A w -74
+KPX A v -92
+KPX A space -55
+KPX A quoteright -74
+KPX A Y -111
+KPX A W -74
+KPX A V -111
+KPX A T -74
+
+KPX F period -92
+KPX F comma -92
+KPX F A -74
+
+KPX L y -55
+KPX L space -37
+KPX L quoteright -74
+KPX L Y -92
+KPX L W -74
+KPX L V -92
+KPX L T -74
+
+KPX P space -18
+KPX P period -129
+KPX P comma -129
+KPX P A -92
+
+KPX R y -37
+KPX R Y -37
+KPX R W -37
+KPX R V -55
+KPX R T -37
+
+KPX T y -90
+KPX T w -90
+KPX T u -90
+KPX T semicolon -55
+KPX T s -90
+KPX T r -90
+KPX T period -74
+KPX T o -92
+KPX T i -55
+KPX T hyphen -55
+KPX T e -92
+KPX T comma -74
+KPX T colon -55
+KPX T c -111
+KPX T a -92
+KPX T O -18
+KPX T A -74
+
+KPX V y -92
+KPX V u -92
+KPX V semicolon -55
+KPX V r -92
+KPX V period -129
+KPX V o -111
+KPX V i -55
+KPX V hyphen -74
+KPX V e -111
+KPX V comma -129
+KPX V colon -55
+KPX V a -92
+KPX V A -111
+
+KPX W y -50
+KPX W u -50
+KPX W semicolon -18
+KPX W r -74
+KPX W period -92
+KPX W o -92
+KPX W i -55
+KPX W hyphen -55
+KPX W e -92
+KPX W comma -92
+KPX W colon -18
+KPX W a -92
+KPX W A -92
+
+KPX Y v -90
+KPX Y u -90
+KPX Y space -18
+KPX Y semicolon -74
+KPX Y q -90
+KPX Y period -111
+KPX Y p -111
+KPX Y o -92
+KPX Y i -55
+KPX Y hyphen -92
+KPX Y e -92
+KPX Y comma -111
+KPX Y colon -74
+KPX Y a -92
+KPX Y A -92
+
+KPX f quoteright 55
+KPX f f -18
+
+KPX one one -55
+
+KPX quoteleft quoteleft -37
+
+KPX quoteright quoteright -37
+
+KPX r u -8
+KPX r quoteright 74
+KPX r q -18
+KPX r period -74
+KPX r o -18
+KPX r hyphen -18
+KPX r h -18
+KPX r g -18
+KPX r e -18
+KPX r d -18
+KPX r comma -74
+KPX r c -18
+
+KPX space Y -18
+KPX space A -37
+
+KPX v period -111
+KPX v comma -111
+
+KPX w period -92
+KPX w comma -92
+
+KPX y period -111
+KPX y comma -111
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 229 231 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 223 231 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 223 231 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 215 231 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 223 231 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 223 231 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 188 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 231 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 231 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 231 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 231 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 2 231 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 2 231 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 2 231 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 2 231 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 249 231 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 227 231 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 227 231 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 227 231 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 227 231 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 227 243 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 96 231 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 255 231 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 247 231 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 223 231 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 223 231 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 203 231 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 191 231 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 231 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 84 20 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 72 20 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 72 20 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 60 20 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 72 20 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 72 12 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 97 20 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 85 20 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 73 20 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 73 20 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -23 20 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -23 20 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -23 20 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -23 20 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 113 12 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 107 20 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 107 20 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 107 20 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 95 20 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 107 12 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 46 8 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 159 20 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 135 20 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 135 20 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 20 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 144 20 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 20 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 8 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Symbol.afm b/tlt3.0/library/afm/Symbol.afm
new file mode 100644
index 0000000..6f07472
--- /dev/null
+++ b/tlt3.0/library/afm/Symbol.afm
@@ -0,0 +1,210 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.
+Comment Creation Date: Wed Jan 17 21:48:26 1990
+Comment UniqueID 27004
+Comment VMusage 28489 37622
+FontName Symbol
+FullName Symbol
+FamilyName Symbol
+Weight Medium
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -180 -293 1090 1010
+UnderlinePosition -98
+UnderlineThickness 54
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All rights reserved.
+EncodingScheme FontSpecific
+StartCharMetrics 189
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 128 -17 240 672 ;
+C 34 ; WX 713 ; N universal ; B 31 0 681 705 ;
+C 35 ; WX 500 ; N numbersign ; B 20 -16 481 673 ;
+C 36 ; WX 549 ; N existential ; B 25 0 478 707 ;
+C 37 ; WX 833 ; N percent ; B 63 -36 771 655 ;
+C 38 ; WX 778 ; N ampersand ; B 41 -18 750 661 ;
+C 39 ; WX 439 ; N suchthat ; B 48 -17 414 500 ;
+C 40 ; WX 333 ; N parenleft ; B 53 -191 300 673 ;
+C 41 ; WX 333 ; N parenright ; B 30 -191 277 673 ;
+C 42 ; WX 500 ; N asteriskmath ; B 65 134 427 551 ;
+C 43 ; WX 549 ; N plus ; B 10 0 539 533 ;
+C 44 ; WX 250 ; N comma ; B 56 -152 194 104 ;
+C 45 ; WX 549 ; N minus ; B 11 233 535 288 ;
+C 46 ; WX 250 ; N period ; B 69 -17 181 95 ;
+C 47 ; WX 278 ; N slash ; B 0 -18 254 646 ;
+C 48 ; WX 500 ; N zero ; B 23 -17 471 685 ;
+C 49 ; WX 500 ; N one ; B 117 0 390 673 ;
+C 50 ; WX 500 ; N two ; B 25 0 475 686 ;
+C 51 ; WX 500 ; N three ; B 39 -17 435 685 ;
+C 52 ; WX 500 ; N four ; B 16 0 469 685 ;
+C 53 ; WX 500 ; N five ; B 29 -17 443 685 ;
+C 54 ; WX 500 ; N six ; B 36 -17 467 685 ;
+C 55 ; WX 500 ; N seven ; B 24 -16 448 673 ;
+C 56 ; WX 500 ; N eight ; B 54 -18 440 685 ;
+C 57 ; WX 500 ; N nine ; B 31 -18 460 685 ;
+C 58 ; WX 278 ; N colon ; B 81 -17 193 460 ;
+C 59 ; WX 278 ; N semicolon ; B 83 -152 221 460 ;
+C 60 ; WX 549 ; N less ; B 26 0 523 522 ;
+C 61 ; WX 549 ; N equal ; B 11 141 537 390 ;
+C 62 ; WX 549 ; N greater ; B 26 0 523 522 ;
+C 63 ; WX 444 ; N question ; B 70 -17 412 686 ;
+C 64 ; WX 549 ; N congruent ; B 11 0 537 475 ;
+C 65 ; WX 722 ; N Alpha ; B 4 0 684 673 ;
+C 66 ; WX 667 ; N Beta ; B 29 0 592 673 ;
+C 67 ; WX 722 ; N Chi ; B -9 0 704 673 ;
+C 68 ; WX 612 ; N Delta ; B 6 0 608 688 ;
+C 69 ; WX 611 ; N Epsilon ; B 32 0 617 673 ;
+C 70 ; WX 763 ; N Phi ; B 26 0 741 673 ;
+C 71 ; WX 603 ; N Gamma ; B 24 0 609 673 ;
+C 72 ; WX 722 ; N Eta ; B 39 0 729 673 ;
+C 73 ; WX 333 ; N Iota ; B 32 0 316 673 ;
+C 74 ; WX 631 ; N theta1 ; B 18 -18 623 689 ;
+C 75 ; WX 722 ; N Kappa ; B 35 0 722 673 ;
+C 76 ; WX 686 ; N Lambda ; B 6 0 680 688 ;
+C 77 ; WX 889 ; N Mu ; B 28 0 887 673 ;
+C 78 ; WX 722 ; N Nu ; B 29 -8 720 673 ;
+C 79 ; WX 722 ; N Omicron ; B 41 -17 715 685 ;
+C 80 ; WX 768 ; N Pi ; B 25 0 745 673 ;
+C 81 ; WX 741 ; N Theta ; B 41 -17 715 685 ;
+C 82 ; WX 556 ; N Rho ; B 28 0 563 673 ;
+C 83 ; WX 592 ; N Sigma ; B 5 0 589 673 ;
+C 84 ; WX 611 ; N Tau ; B 33 0 607 673 ;
+C 85 ; WX 690 ; N Upsilon ; B -8 0 694 673 ;
+C 86 ; WX 439 ; N sigma1 ; B 40 -233 436 500 ;
+C 87 ; WX 768 ; N Omega ; B 34 0 736 688 ;
+C 88 ; WX 645 ; N Xi ; B 40 0 599 673 ;
+C 89 ; WX 795 ; N Psi ; B 15 0 781 684 ;
+C 90 ; WX 611 ; N Zeta ; B 44 0 636 673 ;
+C 91 ; WX 333 ; N bracketleft ; B 86 -155 299 674 ;
+C 92 ; WX 863 ; N therefore ; B 163 0 701 478 ;
+C 93 ; WX 333 ; N bracketright ; B 33 -155 246 674 ;
+C 94 ; WX 658 ; N perpendicular ; B 15 0 652 674 ;
+C 95 ; WX 500 ; N underscore ; B -2 -252 502 -206 ;
+C 96 ; WX 500 ; N radicalex ; B 480 881 1090 917 ;
+C 97 ; WX 631 ; N alpha ; B 41 -18 622 500 ;
+C 98 ; WX 549 ; N beta ; B 61 -223 515 741 ;
+C 99 ; WX 549 ; N chi ; B 12 -231 522 499 ;
+C 100 ; WX 494 ; N delta ; B 40 -19 481 740 ;
+C 101 ; WX 439 ; N epsilon ; B 22 -19 427 502 ;
+C 102 ; WX 521 ; N phi ; B 27 -224 490 671 ;
+C 103 ; WX 411 ; N gamma ; B 5 -225 484 499 ;
+C 104 ; WX 603 ; N eta ; B 0 -202 527 514 ;
+C 105 ; WX 329 ; N iota ; B 0 -17 301 503 ;
+C 106 ; WX 603 ; N phi1 ; B 36 -224 587 499 ;
+C 107 ; WX 549 ; N kappa ; B 33 0 558 501 ;
+C 108 ; WX 549 ; N lambda ; B 24 -17 548 739 ;
+C 109 ; WX 576 ; N mu ; B 33 -223 567 500 ;
+C 110 ; WX 521 ; N nu ; B -9 -16 475 507 ;
+C 111 ; WX 549 ; N omicron ; B 35 -19 501 499 ;
+C 112 ; WX 549 ; N pi ; B 10 -19 530 487 ;
+C 113 ; WX 521 ; N theta ; B 43 -17 485 690 ;
+C 114 ; WX 549 ; N rho ; B 50 -230 490 499 ;
+C 115 ; WX 603 ; N sigma ; B 30 -21 588 500 ;
+C 116 ; WX 439 ; N tau ; B 10 -19 418 500 ;
+C 117 ; WX 576 ; N upsilon ; B 7 -18 535 507 ;
+C 118 ; WX 713 ; N omega1 ; B 12 -18 671 583 ;
+C 119 ; WX 686 ; N omega ; B 42 -17 684 500 ;
+C 120 ; WX 493 ; N xi ; B 27 -224 469 766 ;
+C 121 ; WX 686 ; N psi ; B 12 -228 701 500 ;
+C 122 ; WX 494 ; N zeta ; B 60 -225 467 756 ;
+C 123 ; WX 480 ; N braceleft ; B 58 -183 397 673 ;
+C 124 ; WX 200 ; N bar ; B 65 -177 135 673 ;
+C 125 ; WX 480 ; N braceright ; B 79 -183 418 673 ;
+C 126 ; WX 549 ; N similar ; B 17 203 529 307 ;
+C 161 ; WX 620 ; N Upsilon1 ; B -2 0 610 685 ;
+C 162 ; WX 247 ; N minute ; B 27 459 228 735 ;
+C 163 ; WX 549 ; N lessequal ; B 29 0 526 639 ;
+C 164 ; WX 167 ; N fraction ; B -180 -12 340 677 ;
+C 165 ; WX 713 ; N infinity ; B 26 124 688 404 ;
+C 166 ; WX 500 ; N florin ; B 2 -193 494 686 ;
+C 167 ; WX 753 ; N club ; B 86 -26 660 533 ;
+C 168 ; WX 753 ; N diamond ; B 142 -36 600 550 ;
+C 169 ; WX 753 ; N heart ; B 117 -33 631 532 ;
+C 170 ; WX 753 ; N spade ; B 113 -36 629 548 ;
+C 171 ; WX 1042 ; N arrowboth ; B 24 -15 1024 511 ;
+C 172 ; WX 987 ; N arrowleft ; B 32 -15 942 511 ;
+C 173 ; WX 603 ; N arrowup ; B 45 0 571 910 ;
+C 174 ; WX 987 ; N arrowright ; B 49 -15 959 511 ;
+C 175 ; WX 603 ; N arrowdown ; B 45 -22 571 888 ;
+C 176 ; WX 400 ; N degree ; B 50 385 350 685 ;
+C 177 ; WX 549 ; N plusminus ; B 10 0 539 645 ;
+C 178 ; WX 411 ; N second ; B 20 459 413 737 ;
+C 179 ; WX 549 ; N greaterequal ; B 29 0 526 639 ;
+C 180 ; WX 549 ; N multiply ; B 17 8 533 524 ;
+C 181 ; WX 713 ; N proportional ; B 27 123 639 404 ;
+C 182 ; WX 494 ; N partialdiff ; B 26 -20 462 746 ;
+C 183 ; WX 460 ; N bullet ; B 50 113 410 473 ;
+C 184 ; WX 549 ; N divide ; B 10 71 536 456 ;
+C 185 ; WX 549 ; N notequal ; B 15 -25 540 549 ;
+C 186 ; WX 549 ; N equivalence ; B 14 82 538 443 ;
+C 187 ; WX 549 ; N approxequal ; B 14 135 527 394 ;
+C 188 ; WX 1000 ; N ellipsis ; B 111 -17 889 95 ;
+C 189 ; WX 603 ; N arrowvertex ; B 280 -120 336 1010 ;
+C 190 ; WX 1000 ; N arrowhorizex ; B -60 220 1050 276 ;
+C 191 ; WX 658 ; N carriagereturn ; B 15 -16 602 629 ;
+C 192 ; WX 823 ; N aleph ; B 175 -18 661 658 ;
+C 193 ; WX 686 ; N Ifraktur ; B 10 -53 578 740 ;
+C 194 ; WX 795 ; N Rfraktur ; B 26 -15 759 734 ;
+C 195 ; WX 987 ; N weierstrass ; B 159 -211 870 573 ;
+C 196 ; WX 768 ; N circlemultiply ; B 43 -17 733 673 ;
+C 197 ; WX 768 ; N circleplus ; B 43 -15 733 675 ;
+C 198 ; WX 823 ; N emptyset ; B 39 -24 781 719 ;
+C 199 ; WX 768 ; N intersection ; B 40 0 732 509 ;
+C 200 ; WX 768 ; N union ; B 40 -17 732 492 ;
+C 201 ; WX 713 ; N propersuperset ; B 20 0 673 470 ;
+C 202 ; WX 713 ; N reflexsuperset ; B 20 -125 673 470 ;
+C 203 ; WX 713 ; N notsubset ; B 36 -70 690 540 ;
+C 204 ; WX 713 ; N propersubset ; B 37 0 690 470 ;
+C 205 ; WX 713 ; N reflexsubset ; B 37 -125 690 470 ;
+C 206 ; WX 713 ; N element ; B 45 0 505 468 ;
+C 207 ; WX 713 ; N notelement ; B 45 -58 505 555 ;
+C 208 ; WX 768 ; N angle ; B 26 0 738 673 ;
+C 209 ; WX 713 ; N gradient ; B 36 -19 681 718 ;
+C 210 ; WX 790 ; N registerserif ; B 50 -17 740 673 ;
+C 211 ; WX 790 ; N copyrightserif ; B 51 -15 741 675 ;
+C 212 ; WX 890 ; N trademarkserif ; B 18 293 855 673 ;
+C 213 ; WX 823 ; N product ; B 25 -101 803 751 ;
+C 214 ; WX 549 ; N radical ; B 10 -38 515 917 ;
+C 215 ; WX 250 ; N dotmath ; B 69 210 169 310 ;
+C 216 ; WX 713 ; N logicalnot ; B 15 0 680 288 ;
+C 217 ; WX 603 ; N logicaland ; B 23 0 583 454 ;
+C 218 ; WX 603 ; N logicalor ; B 30 0 578 477 ;
+C 219 ; WX 1042 ; N arrowdblboth ; B 27 -20 1023 510 ;
+C 220 ; WX 987 ; N arrowdblleft ; B 30 -15 939 513 ;
+C 221 ; WX 603 ; N arrowdblup ; B 39 2 567 911 ;
+C 222 ; WX 987 ; N arrowdblright ; B 45 -20 954 508 ;
+C 223 ; WX 603 ; N arrowdbldown ; B 44 -19 572 890 ;
+C 224 ; WX 494 ; N lozenge ; B 18 0 466 745 ;
+C 225 ; WX 329 ; N angleleft ; B 25 -198 306 746 ;
+C 226 ; WX 790 ; N registersans ; B 50 -20 740 670 ;
+C 227 ; WX 790 ; N copyrightsans ; B 49 -15 739 675 ;
+C 228 ; WX 786 ; N trademarksans ; B 5 293 725 673 ;
+C 229 ; WX 713 ; N summation ; B 14 -108 695 752 ;
+C 230 ; WX 384 ; N parenlefttp ; B 40 -293 436 926 ;
+C 231 ; WX 384 ; N parenleftex ; B 40 -85 92 925 ;
+C 232 ; WX 384 ; N parenleftbt ; B 40 -293 436 926 ;
+C 233 ; WX 384 ; N bracketlefttp ; B 0 -80 341 926 ;
+C 234 ; WX 384 ; N bracketleftex ; B 0 -79 55 925 ;
+C 235 ; WX 384 ; N bracketleftbt ; B 0 -80 340 926 ;
+C 236 ; WX 494 ; N bracelefttp ; B 201 -75 439 926 ;
+C 237 ; WX 494 ; N braceleftmid ; B 14 -85 255 935 ;
+C 238 ; WX 494 ; N braceleftbt ; B 201 -70 439 926 ;
+C 239 ; WX 494 ; N braceex ; B 201 -80 255 935 ;
+C 241 ; WX 329 ; N angleright ; B 21 -198 302 746 ;
+C 242 ; WX 274 ; N integral ; B 2 -107 291 916 ;
+C 243 ; WX 686 ; N integraltp ; B 332 -83 715 921 ;
+C 244 ; WX 686 ; N integralex ; B 332 -88 415 975 ;
+C 245 ; WX 686 ; N integralbt ; B 39 -81 415 921 ;
+C 246 ; WX 384 ; N parenrighttp ; B 54 -293 450 926 ;
+C 247 ; WX 384 ; N parenrightex ; B 398 -85 450 925 ;
+C 248 ; WX 384 ; N parenrightbt ; B 54 -293 450 926 ;
+C 249 ; WX 384 ; N bracketrighttp ; B 22 -80 360 926 ;
+C 250 ; WX 384 ; N bracketrightex ; B 305 -79 360 925 ;
+C 251 ; WX 384 ; N bracketrightbt ; B 20 -80 360 926 ;
+C 252 ; WX 494 ; N bracerighttp ; B 17 -75 255 926 ;
+C 253 ; WX 494 ; N bracerightmid ; B 201 -85 442 935 ;
+C 254 ; WX 494 ; N bracerightbt ; B 17 -70 255 926 ;
+C -1 ; WX 790 ; N apple ; B 56 -3 733 808 ;
+EndCharMetrics
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Times-Bold.afm b/tlt3.0/library/afm/Times-Bold.afm
new file mode 100644
index 0000000..6ee7ef6
--- /dev/null
+++ b/tlt3.0/library/afm/Times-Bold.afm
@@ -0,0 +1,649 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Mar 20 12:17:14 1990
+Comment UniqueID 28417
+Comment VMusage 30458 37350
+FontName Times-Bold
+FullName Times Bold
+FamilyName Times
+Weight Bold
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -168 -218 1000 935
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 676
+XHeight 461
+Ascender 676
+Descender -205
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ;
+C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ;
+C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ;
+C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ;
+C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ;
+C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ;
+C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ;
+C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ;
+C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ;
+C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
+C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ;
+C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ;
+C 46 ; WX 250 ; N period ; B 41 -13 210 156 ;
+C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ;
+C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ;
+C 49 ; WX 500 ; N one ; B 65 0 442 688 ;
+C 50 ; WX 500 ; N two ; B 17 0 478 688 ;
+C 51 ; WX 500 ; N three ; B 16 -14 468 688 ;
+C 52 ; WX 500 ; N four ; B 19 0 475 688 ;
+C 53 ; WX 500 ; N five ; B 22 -8 470 676 ;
+C 54 ; WX 500 ; N six ; B 28 -13 475 688 ;
+C 55 ; WX 500 ; N seven ; B 17 0 477 676 ;
+C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ;
+C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ;
+C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ;
+C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ;
+C 60 ; WX 570 ; N less ; B 31 -8 539 514 ;
+C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
+C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ;
+C 63 ; WX 500 ; N question ; B 57 -13 445 689 ;
+C 64 ; WX 930 ; N at ; B 108 -19 822 691 ;
+C 65 ; WX 722 ; N A ; B 9 0 689 690 ;
+C 66 ; WX 667 ; N B ; B 16 0 619 676 ;
+C 67 ; WX 722 ; N C ; B 49 -19 687 691 ;
+C 68 ; WX 722 ; N D ; B 14 0 690 676 ;
+C 69 ; WX 667 ; N E ; B 16 0 641 676 ;
+C 70 ; WX 611 ; N F ; B 16 0 583 676 ;
+C 71 ; WX 778 ; N G ; B 37 -19 755 691 ;
+C 72 ; WX 778 ; N H ; B 21 0 759 676 ;
+C 73 ; WX 389 ; N I ; B 20 0 370 676 ;
+C 74 ; WX 500 ; N J ; B 3 -96 479 676 ;
+C 75 ; WX 778 ; N K ; B 30 0 769 676 ;
+C 76 ; WX 667 ; N L ; B 19 0 638 676 ;
+C 77 ; WX 944 ; N M ; B 14 0 921 676 ;
+C 78 ; WX 722 ; N N ; B 16 -18 701 676 ;
+C 79 ; WX 778 ; N O ; B 35 -19 743 691 ;
+C 80 ; WX 611 ; N P ; B 16 0 600 676 ;
+C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ;
+C 82 ; WX 722 ; N R ; B 26 0 715 676 ;
+C 83 ; WX 556 ; N S ; B 35 -19 513 692 ;
+C 84 ; WX 667 ; N T ; B 31 0 636 676 ;
+C 85 ; WX 722 ; N U ; B 16 -19 701 676 ;
+C 86 ; WX 722 ; N V ; B 16 -18 701 676 ;
+C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ;
+C 88 ; WX 722 ; N X ; B 16 0 699 676 ;
+C 89 ; WX 722 ; N Y ; B 15 0 699 676 ;
+C 90 ; WX 667 ; N Z ; B 28 0 634 676 ;
+C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ;
+C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ;
+C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ;
+C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ;
+C 97 ; WX 500 ; N a ; B 25 -14 488 473 ;
+C 98 ; WX 556 ; N b ; B 17 -14 521 676 ;
+C 99 ; WX 444 ; N c ; B 25 -14 430 473 ;
+C 100 ; WX 556 ; N d ; B 25 -14 534 676 ;
+C 101 ; WX 444 ; N e ; B 25 -14 426 473 ;
+C 102 ; WX 333 ; N f ; B 14 0 389 691 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 28 -206 483 473 ;
+C 104 ; WX 556 ; N h ; B 16 0 534 676 ;
+C 105 ; WX 278 ; N i ; B 16 0 255 691 ;
+C 106 ; WX 333 ; N j ; B -57 -203 263 691 ;
+C 107 ; WX 556 ; N k ; B 22 0 543 676 ;
+C 108 ; WX 278 ; N l ; B 16 0 255 676 ;
+C 109 ; WX 833 ; N m ; B 16 0 814 473 ;
+C 110 ; WX 556 ; N n ; B 21 0 539 473 ;
+C 111 ; WX 500 ; N o ; B 25 -14 476 473 ;
+C 112 ; WX 556 ; N p ; B 19 -205 524 473 ;
+C 113 ; WX 556 ; N q ; B 34 -205 536 473 ;
+C 114 ; WX 444 ; N r ; B 29 0 434 473 ;
+C 115 ; WX 389 ; N s ; B 25 -14 361 473 ;
+C 116 ; WX 333 ; N t ; B 20 -12 332 630 ;
+C 117 ; WX 556 ; N u ; B 16 -14 537 461 ;
+C 118 ; WX 500 ; N v ; B 21 -14 485 461 ;
+C 119 ; WX 722 ; N w ; B 23 -14 707 461 ;
+C 120 ; WX 500 ; N x ; B 12 0 484 461 ;
+C 121 ; WX 500 ; N y ; B 16 -205 480 461 ;
+C 122 ; WX 444 ; N z ; B 21 0 420 461 ;
+C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ;
+C 124 ; WX 220 ; N bar ; B 66 -19 154 691 ;
+C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ;
+C 126 ; WX 520 ; N asciitilde ; B 29 173 491 333 ;
+C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ;
+C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ;
+C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ;
+C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ;
+C 165 ; WX 500 ; N yen ; B -64 0 547 676 ;
+C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ;
+C 167 ; WX 500 ; N section ; B 57 -132 443 691 ;
+C 168 ; WX 500 ; N currency ; B -26 61 526 613 ;
+C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ;
+C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ;
+C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ;
+C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ;
+C 174 ; WX 556 ; N fi ; B 14 0 536 691 ;
+C 175 ; WX 556 ; N fl ; B 14 0 536 691 ;
+C 177 ; WX 500 ; N endash ; B 0 181 500 271 ;
+C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ;
+C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ;
+C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ;
+C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ;
+C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ;
+C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ;
+C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ;
+C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ;
+C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ;
+C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ;
+C 193 ; WX 333 ; N grave ; B 8 528 246 713 ;
+C 194 ; WX 333 ; N acute ; B 86 528 324 713 ;
+C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ;
+C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ;
+C 197 ; WX 333 ; N macron ; B 1 565 331 637 ;
+C 198 ; WX 333 ; N breve ; B 15 528 318 691 ;
+C 199 ; WX 333 ; N dotaccent ; B 103 537 230 667 ;
+C 200 ; WX 333 ; N dieresis ; B -2 537 335 667 ;
+C 202 ; WX 333 ; N ring ; B 60 527 273 740 ;
+C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ;
+C 206 ; WX 333 ; N ogonek ; B 90 -173 319 44 ;
+C 207 ; WX 333 ; N caron ; B -2 528 335 704 ;
+C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ;
+C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ;
+C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ;
+C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ;
+C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ;
+C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ;
+C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ;
+C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ;
+C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ;
+C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ;
+C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ;
+C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ;
+C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ;
+C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ;
+C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 667 ;
+C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ;
+C -1 ; WX 278 ; N icircumflex ; B -36 0 301 704 ;
+C -1 ; WX 300 ; N threesuperior ; B 3 268 297 688 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ;
+C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ;
+C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ;
+C -1 ; WX 300 ; N twosuperior ; B 0 275 300 688 ;
+C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ;
+C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ;
+C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ;
+C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ;
+C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ;
+C -1 ; WX 556 ; N udieresis ; B 16 -14 537 667 ;
+C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ;
+C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ;
+C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -14 426 667 ;
+C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ;
+C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ;
+C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ;
+C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ;
+C -1 ; WX 389 ; N Idieresis ; B 20 0 370 877 ;
+C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ;
+C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ;
+C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ;
+C -1 ; WX 500 ; N aring ; B 25 -14 488 740 ;
+C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ;
+C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ;
+C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ;
+C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ;
+C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ;
+C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ;
+C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 877 ;
+C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ;
+C -1 ; WX 667 ; N Edieresis ; B 16 0 641 877 ;
+C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ;
+C -1 ; WX 500 ; N adieresis ; B 25 -14 488 667 ;
+C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ;
+C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ;
+C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 877 ;
+C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ;
+C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ;
+C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ;
+C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ;
+C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ;
+C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ;
+C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ;
+C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ;
+C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ;
+C -1 ; WX 722 ; N Aring ; B 9 0 689 935 ;
+C -1 ; WX 278 ; N idieresis ; B -36 0 301 667 ;
+C -1 ; WX 278 ; N iacute ; B 16 0 290 713 ;
+C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ;
+C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ;
+C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
+C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 877 ;
+C -1 ; WX 570 ; N minus ; B 33 209 537 297 ;
+C -1 ; WX 300 ; N onesuperior ; B 28 275 273 688 ;
+C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ;
+C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ;
+C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ;
+C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ;
+C -1 ; WX 500 ; N odieresis ; B 25 -14 476 667 ;
+C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ;
+C -1 ; WX 400 ; N degree ; B 57 402 343 688 ;
+C -1 ; WX 278 ; N igrave ; B -26 0 255 713 ;
+C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ;
+C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ;
+C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ;
+C -1 ; WX 722 ; N Adieresis ; B 9 0 689 877 ;
+C -1 ; WX 722 ; N Yacute ; B 15 0 699 928 ;
+C -1 ; WX 220 ; N brokenbar ; B 66 -19 154 691 ;
+C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 283
+
+KPX A y -74
+KPX A w -90
+KPX A v -100
+KPX A u -50
+KPX A quoteright -74
+KPX A quotedblright 0
+KPX A p -25
+KPX A Y -100
+KPX A W -130
+KPX A V -145
+KPX A U -50
+KPX A T -95
+KPX A Q -45
+KPX A O -45
+KPX A G -55
+KPX A C -55
+
+KPX B period 0
+KPX B comma 0
+KPX B U -10
+KPX B A -30
+
+KPX D period -20
+KPX D comma 0
+KPX D Y -40
+KPX D W -40
+KPX D V -40
+KPX D A -35
+
+KPX F r 0
+KPX F period -110
+KPX F o -25
+KPX F i 0
+KPX F e -25
+KPX F comma -92
+KPX F a -25
+KPX F A -90
+
+KPX G period 0
+KPX G comma 0
+
+KPX J u -15
+KPX J period -20
+KPX J o -15
+KPX J e -15
+KPX J comma 0
+KPX J a -15
+KPX J A -30
+
+KPX K y -45
+KPX K u -15
+KPX K o -25
+KPX K e -25
+KPX K O -30
+
+KPX L y -55
+KPX L quoteright -110
+KPX L quotedblright -20
+KPX L Y -92
+KPX L W -92
+KPX L V -92
+KPX L T -92
+
+KPX N period 0
+KPX N comma 0
+KPX N A -20
+
+KPX O period 0
+KPX O comma 0
+KPX O Y -50
+KPX O X -40
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -40
+
+KPX P period -110
+KPX P o -20
+KPX P e -20
+KPX P comma -92
+KPX P a -10
+KPX P A -74
+
+KPX Q period -20
+KPX Q comma 0
+KPX Q U -10
+
+KPX R Y -35
+KPX R W -35
+KPX R V -55
+KPX R U -30
+KPX R T -40
+KPX R O -30
+
+KPX S period 0
+KPX S comma 0
+
+KPX T y -74
+KPX T w -74
+KPX T u -92
+KPX T semicolon -74
+KPX T r -74
+KPX T period -90
+KPX T o -92
+KPX T i -18
+KPX T hyphen -92
+KPX T h 0
+KPX T e -92
+KPX T comma -74
+KPX T colon -74
+KPX T a -92
+KPX T O -18
+KPX T A -90
+
+KPX U period -50
+KPX U comma -50
+KPX U A -60
+
+KPX V u -92
+KPX V semicolon -92
+KPX V period -145
+KPX V o -100
+KPX V i -37
+KPX V hyphen -74
+KPX V e -100
+KPX V comma -129
+KPX V colon -92
+KPX V a -92
+KPX V O -45
+KPX V G -30
+KPX V A -135
+
+KPX W y -60
+KPX W u -50
+KPX W semicolon -55
+KPX W period -92
+KPX W o -75
+KPX W i -18
+KPX W hyphen -37
+KPX W h 0
+KPX W e -65
+KPX W comma -92
+KPX W colon -55
+KPX W a -65
+KPX W O -10
+KPX W A -120
+
+KPX Y u -92
+KPX Y semicolon -92
+KPX Y period -92
+KPX Y o -111
+KPX Y i -37
+KPX Y hyphen -92
+KPX Y e -111
+KPX Y comma -92
+KPX Y colon -92
+KPX Y a -85
+KPX Y O -35
+KPX Y A -110
+
+KPX a y 0
+KPX a w 0
+KPX a v -25
+KPX a t 0
+KPX a p 0
+KPX a g 0
+KPX a b 0
+
+KPX b y 0
+KPX b v -15
+KPX b u -20
+KPX b period -40
+KPX b l 0
+KPX b comma 0
+KPX b b -10
+
+KPX c y 0
+KPX c period 0
+KPX c l 0
+KPX c k 0
+KPX c h 0
+KPX c comma 0
+
+KPX colon space 0
+
+KPX comma space 0
+KPX comma quoteright -55
+KPX comma quotedblright -45
+
+KPX d y 0
+KPX d w -15
+KPX d v 0
+KPX d period 0
+KPX d d 0
+KPX d comma 0
+
+KPX e y 0
+KPX e x 0
+KPX e w 0
+KPX e v -15
+KPX e period 0
+KPX e p 0
+KPX e g 0
+KPX e comma 0
+KPX e b 0
+
+KPX f quoteright 55
+KPX f quotedblright 50
+KPX f period -15
+KPX f o -25
+KPX f l 0
+KPX f i -25
+KPX f f 0
+KPX f e 0
+KPX f dotlessi -35
+KPX f comma -15
+KPX f a 0
+
+KPX g y 0
+KPX g r 0
+KPX g period -15
+KPX g o 0
+KPX g i 0
+KPX g g 0
+KPX g e 0
+KPX g comma 0
+KPX g a 0
+
+KPX h y -15
+
+KPX i v -10
+
+KPX k y -15
+KPX k o -15
+KPX k e -10
+
+KPX l y 0
+KPX l w 0
+
+KPX m y 0
+KPX m u 0
+
+KPX n y 0
+KPX n v -40
+KPX n u 0
+
+KPX o y 0
+KPX o x 0
+KPX o w -10
+KPX o v -10
+KPX o g 0
+
+KPX p y 0
+
+KPX period quoteright -55
+KPX period quotedblright -55
+
+KPX quotedblleft quoteleft 0
+KPX quotedblleft A -10
+
+KPX quotedblright space 0
+
+KPX quoteleft quoteleft -63
+KPX quoteleft A -10
+
+KPX quoteright v -20
+KPX quoteright t 0
+KPX quoteright space -74
+KPX quoteright s -37
+KPX quoteright r -20
+KPX quoteright quoteright -63
+KPX quoteright quotedblright 0
+KPX quoteright l 0
+KPX quoteright d -20
+
+KPX r y 0
+KPX r v -10
+KPX r u 0
+KPX r t 0
+KPX r s 0
+KPX r r 0
+KPX r q -18
+KPX r period -100
+KPX r p -10
+KPX r o -18
+KPX r n -15
+KPX r m 0
+KPX r l 0
+KPX r k 0
+KPX r i 0
+KPX r hyphen -37
+KPX r g -10
+KPX r e -18
+KPX r d 0
+KPX r comma -92
+KPX r c -18
+KPX r a 0
+
+KPX s w 0
+
+KPX space quoteleft 0
+KPX space quotedblleft 0
+KPX space Y -55
+KPX space W -30
+KPX space V -45
+KPX space T -30
+KPX space A -55
+
+KPX v period -70
+KPX v o -10
+KPX v e -10
+KPX v comma -55
+KPX v a -10
+
+KPX w period -70
+KPX w o -10
+KPX w h 0
+KPX w e 0
+KPX w comma -55
+KPX w a 0
+
+KPX x e 0
+
+KPX y period -70
+KPX y o -25
+KPX y e -10
+KPX y comma -55
+KPX y a 0
+
+KPX z o 0
+KPX z e 0
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 188 210 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 188 210 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 188 210 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 188 210 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 180 195 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 188 210 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 208 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 174 210 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 174 210 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 174 210 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 174 210 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 210 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 210 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 210 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 210 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 210 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 210 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 210 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 210 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 210 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 210 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 210 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 222 210 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 222 210 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 222 210 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 222 210 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 210 215 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 215 210 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 210 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 77 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 77 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 77 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 77 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 77 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 77 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 62 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 62 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 62 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 62 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -34 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -34 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -34 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -34 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 105 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 105 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 105 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 105 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 56 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Times-BoldItalic.afm b/tlt3.0/library/afm/Times-BoldItalic.afm
new file mode 100644
index 0000000..d329ebb
--- /dev/null
+++ b/tlt3.0/library/afm/Times-BoldItalic.afm
@@ -0,0 +1,649 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Mar 20 13:14:55 1990
+Comment UniqueID 28425
+Comment VMusage 32721 39613
+FontName Times-BoldItalic
+FullName Times Bold Italic
+FamilyName Times
+Weight Bold
+ItalicAngle -15
+IsFixedPitch false
+FontBBox -200 -218 996 921
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.009
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 669
+XHeight 462
+Ascender 699
+Descender -205
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ;
+C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ;
+C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ;
+C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ;
+C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ;
+C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ;
+C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ;
+C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ;
+C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ;
+C 42 ; WX 500 ; N asterisk ; B 65 249 456 685 ;
+C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
+C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ;
+C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ;
+C 46 ; WX 250 ; N period ; B -9 -13 139 135 ;
+C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ;
+C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ;
+C 49 ; WX 500 ; N one ; B 5 0 419 683 ;
+C 50 ; WX 500 ; N two ; B -27 0 446 683 ;
+C 51 ; WX 500 ; N three ; B -15 -13 450 683 ;
+C 52 ; WX 500 ; N four ; B -15 0 503 683 ;
+C 53 ; WX 500 ; N five ; B -11 -13 487 669 ;
+C 54 ; WX 500 ; N six ; B 23 -15 509 679 ;
+C 55 ; WX 500 ; N seven ; B 52 0 525 669 ;
+C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ;
+C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ;
+C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ;
+C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ;
+C 60 ; WX 570 ; N less ; B 31 -8 539 514 ;
+C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
+C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ;
+C 63 ; WX 500 ; N question ; B 79 -13 470 684 ;
+C 64 ; WX 832 ; N at ; B 63 -18 770 685 ;
+C 65 ; WX 667 ; N A ; B -67 0 593 683 ;
+C 66 ; WX 667 ; N B ; B -24 0 624 669 ;
+C 67 ; WX 667 ; N C ; B 32 -18 677 685 ;
+C 68 ; WX 722 ; N D ; B -46 0 685 669 ;
+C 69 ; WX 667 ; N E ; B -27 0 653 669 ;
+C 70 ; WX 667 ; N F ; B -13 0 660 669 ;
+C 71 ; WX 722 ; N G ; B 21 -18 706 685 ;
+C 72 ; WX 778 ; N H ; B -24 0 799 669 ;
+C 73 ; WX 389 ; N I ; B -32 0 406 669 ;
+C 74 ; WX 500 ; N J ; B -46 -99 524 669 ;
+C 75 ; WX 667 ; N K ; B -21 0 702 669 ;
+C 76 ; WX 611 ; N L ; B -22 0 590 669 ;
+C 77 ; WX 889 ; N M ; B -29 -12 917 669 ;
+C 78 ; WX 722 ; N N ; B -27 -15 748 669 ;
+C 79 ; WX 722 ; N O ; B 27 -18 691 685 ;
+C 80 ; WX 611 ; N P ; B -27 0 613 669 ;
+C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ;
+C 82 ; WX 667 ; N R ; B -29 0 623 669 ;
+C 83 ; WX 556 ; N S ; B 2 -18 526 685 ;
+C 84 ; WX 611 ; N T ; B 50 0 650 669 ;
+C 85 ; WX 722 ; N U ; B 67 -18 744 669 ;
+C 86 ; WX 667 ; N V ; B 65 -18 715 669 ;
+C 87 ; WX 889 ; N W ; B 65 -18 940 669 ;
+C 88 ; WX 667 ; N X ; B -24 0 694 669 ;
+C 89 ; WX 611 ; N Y ; B 73 0 659 669 ;
+C 90 ; WX 611 ; N Z ; B -11 0 590 669 ;
+C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ;
+C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ;
+C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ;
+C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ;
+C 97 ; WX 500 ; N a ; B -21 -14 455 462 ;
+C 98 ; WX 500 ; N b ; B -14 -13 444 699 ;
+C 99 ; WX 444 ; N c ; B -5 -13 392 462 ;
+C 100 ; WX 500 ; N d ; B -21 -13 517 699 ;
+C 101 ; WX 444 ; N e ; B 5 -13 398 462 ;
+C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B -52 -203 478 462 ;
+C 104 ; WX 556 ; N h ; B -13 -9 498 699 ;
+C 105 ; WX 278 ; N i ; B 2 -9 263 684 ;
+C 106 ; WX 278 ; N j ; B -189 -207 279 684 ;
+C 107 ; WX 500 ; N k ; B -23 -8 483 699 ;
+C 108 ; WX 278 ; N l ; B 2 -9 290 699 ;
+C 109 ; WX 778 ; N m ; B -14 -9 722 462 ;
+C 110 ; WX 556 ; N n ; B -6 -9 493 462 ;
+C 111 ; WX 500 ; N o ; B -3 -13 441 462 ;
+C 112 ; WX 500 ; N p ; B -120 -205 446 462 ;
+C 113 ; WX 500 ; N q ; B 1 -205 471 462 ;
+C 114 ; WX 389 ; N r ; B -21 0 389 462 ;
+C 115 ; WX 389 ; N s ; B -19 -13 333 462 ;
+C 116 ; WX 278 ; N t ; B -11 -9 281 594 ;
+C 117 ; WX 556 ; N u ; B 15 -9 492 462 ;
+C 118 ; WX 444 ; N v ; B 16 -13 401 462 ;
+C 119 ; WX 667 ; N w ; B 16 -13 614 462 ;
+C 120 ; WX 500 ; N x ; B -46 -13 469 462 ;
+C 121 ; WX 444 ; N y ; B -94 -205 392 462 ;
+C 122 ; WX 389 ; N z ; B -43 -78 368 449 ;
+C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ;
+C 124 ; WX 220 ; N bar ; B 66 -18 154 685 ;
+C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ;
+C 126 ; WX 570 ; N asciitilde ; B 54 173 516 333 ;
+C 161 ; WX 389 ; N exclamdown ; B 19 -205 322 492 ;
+C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ;
+C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ;
+C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ;
+C 165 ; WX 500 ; N yen ; B 33 0 628 669 ;
+C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ;
+C 167 ; WX 500 ; N section ; B 36 -143 459 685 ;
+C 168 ; WX 500 ; N currency ; B -26 34 526 586 ;
+C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ;
+C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ;
+C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ;
+C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ;
+C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ;
+C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ;
+C 177 ; WX 500 ; N endash ; B -40 178 477 269 ;
+C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ;
+C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ;
+C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ;
+C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ;
+C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ;
+C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ;
+C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ;
+C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ;
+C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ;
+C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ;
+C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ;
+C 193 ; WX 333 ; N grave ; B 85 516 297 697 ;
+C 194 ; WX 333 ; N acute ; B 139 516 379 697 ;
+C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ;
+C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ;
+C 197 ; WX 333 ; N macron ; B 51 553 393 623 ;
+C 198 ; WX 333 ; N breve ; B 71 516 387 678 ;
+C 199 ; WX 333 ; N dotaccent ; B 163 525 293 655 ;
+C 200 ; WX 333 ; N dieresis ; B 55 525 397 655 ;
+C 202 ; WX 333 ; N ring ; B 127 516 340 729 ;
+C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ;
+C 206 ; WX 333 ; N ogonek ; B -40 -173 189 44 ;
+C 207 ; WX 333 ; N caron ; B 79 516 411 690 ;
+C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ;
+C 225 ; WX 944 ; N AE ; B -64 0 918 669 ;
+C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ;
+C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ;
+C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ;
+C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ;
+C 235 ; WX 300 ; N ordmasculine ; B 56 400 347 685 ;
+C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ;
+C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ;
+C 248 ; WX 278 ; N lslash ; B -13 -9 301 699 ;
+C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ;
+C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ;
+C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ;
+C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ;
+C -1 ; WX 444 ; N ccedilla ; B -24 -218 392 462 ;
+C -1 ; WX 444 ; N ydieresis ; B -94 -205 438 655 ;
+C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ;
+C -1 ; WX 278 ; N icircumflex ; B -2 -9 325 690 ;
+C -1 ; WX 300 ; N threesuperior ; B 17 265 321 683 ;
+C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ;
+C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ;
+C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ;
+C -1 ; WX 300 ; N twosuperior ; B 2 274 313 683 ;
+C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ;
+C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ;
+C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ;
+C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ;
+C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ;
+C -1 ; WX 556 ; N udieresis ; B 15 -9 494 655 ;
+C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ;
+C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ;
+C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ;
+C -1 ; WX 444 ; N edieresis ; B 5 -13 443 655 ;
+C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ;
+C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ;
+C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ;
+C -1 ; WX 389 ; N scaron ; B -19 -13 439 690 ;
+C -1 ; WX 389 ; N Idieresis ; B -32 0 445 862 ;
+C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ;
+C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ;
+C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ;
+C -1 ; WX 500 ; N aring ; B -21 -14 455 729 ;
+C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ;
+C -1 ; WX 389 ; N Icircumflex ; B -32 0 420 897 ;
+C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ;
+C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ;
+C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ;
+C -1 ; WX 389 ; N Iacute ; B -32 0 412 904 ;
+C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ;
+C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ;
+C -1 ; WX 556 ; N Scaron ; B 2 -18 526 897 ;
+C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ;
+C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ;
+C -1 ; WX 500 ; N adieresis ; B -21 -14 471 655 ;
+C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ;
+C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ;
+C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ;
+C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ;
+C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ;
+C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ;
+C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ;
+C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ;
+C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ;
+C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ;
+C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ;
+C -1 ; WX 667 ; N Aring ; B -67 0 593 921 ;
+C -1 ; WX 278 ; N idieresis ; B 2 -9 360 655 ;
+C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ;
+C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ;
+C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ;
+C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
+C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ;
+C -1 ; WX 606 ; N minus ; B 51 209 555 297 ;
+C -1 ; WX 300 ; N onesuperior ; B 30 274 301 683 ;
+C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ;
+C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ;
+C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ;
+C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ;
+C -1 ; WX 500 ; N odieresis ; B -3 -13 466 655 ;
+C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ;
+C -1 ; WX 400 ; N degree ; B 83 397 369 683 ;
+C -1 ; WX 278 ; N igrave ; B 2 -9 260 697 ;
+C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ;
+C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ;
+C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ;
+C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ;
+C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ;
+C -1 ; WX 220 ; N brokenbar ; B 66 -18 154 685 ;
+C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 283
+
+KPX A y -74
+KPX A w -74
+KPX A v -74
+KPX A u -30
+KPX A quoteright -74
+KPX A quotedblright 0
+KPX A p 0
+KPX A Y -70
+KPX A W -100
+KPX A V -95
+KPX A U -50
+KPX A T -55
+KPX A Q -55
+KPX A O -50
+KPX A G -60
+KPX A C -65
+
+KPX B period 0
+KPX B comma 0
+KPX B U -10
+KPX B A -25
+
+KPX D period 0
+KPX D comma 0
+KPX D Y -50
+KPX D W -40
+KPX D V -50
+KPX D A -25
+
+KPX F r -50
+KPX F period -129
+KPX F o -70
+KPX F i -40
+KPX F e -100
+KPX F comma -129
+KPX F a -95
+KPX F A -100
+
+KPX G period 0
+KPX G comma 0
+
+KPX J u -40
+KPX J period -10
+KPX J o -40
+KPX J e -40
+KPX J comma -10
+KPX J a -40
+KPX J A -25
+
+KPX K y -20
+KPX K u -20
+KPX K o -25
+KPX K e -25
+KPX K O -30
+
+KPX L y -37
+KPX L quoteright -55
+KPX L quotedblright 0
+KPX L Y -37
+KPX L W -37
+KPX L V -37
+KPX L T -18
+
+KPX N period 0
+KPX N comma 0
+KPX N A -30
+
+KPX O period 0
+KPX O comma 0
+KPX O Y -50
+KPX O X -40
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -40
+
+KPX P period -129
+KPX P o -55
+KPX P e -50
+KPX P comma -129
+KPX P a -40
+KPX P A -85
+
+KPX Q period 0
+KPX Q comma 0
+KPX Q U -10
+
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+KPX R U -40
+KPX R T -30
+KPX R O -40
+
+KPX S period 0
+KPX S comma 0
+
+KPX T y -37
+KPX T w -37
+KPX T u -37
+KPX T semicolon -74
+KPX T r -37
+KPX T period -92
+KPX T o -95
+KPX T i -37
+KPX T hyphen -92
+KPX T h 0
+KPX T e -92
+KPX T comma -92
+KPX T colon -74
+KPX T a -92
+KPX T O -18
+KPX T A -55
+
+KPX U period 0
+KPX U comma 0
+KPX U A -45
+
+KPX V u -55
+KPX V semicolon -74
+KPX V period -129
+KPX V o -111
+KPX V i -55
+KPX V hyphen -70
+KPX V e -111
+KPX V comma -129
+KPX V colon -74
+KPX V a -111
+KPX V O -30
+KPX V G -10
+KPX V A -85
+
+KPX W y -55
+KPX W u -55
+KPX W semicolon -55
+KPX W period -74
+KPX W o -80
+KPX W i -37
+KPX W hyphen -50
+KPX W h 0
+KPX W e -90
+KPX W comma -74
+KPX W colon -55
+KPX W a -85
+KPX W O -15
+KPX W A -74
+
+KPX Y u -92
+KPX Y semicolon -92
+KPX Y period -74
+KPX Y o -111
+KPX Y i -55
+KPX Y hyphen -92
+KPX Y e -111
+KPX Y comma -92
+KPX Y colon -92
+KPX Y a -92
+KPX Y O -25
+KPX Y A -74
+
+KPX a y 0
+KPX a w 0
+KPX a v 0
+KPX a t 0
+KPX a p 0
+KPX a g 0
+KPX a b 0
+
+KPX b y 0
+KPX b v 0
+KPX b u -20
+KPX b period -40
+KPX b l 0
+KPX b comma 0
+KPX b b -10
+
+KPX c y 0
+KPX c period 0
+KPX c l 0
+KPX c k -10
+KPX c h -10
+KPX c comma 0
+
+KPX colon space 0
+
+KPX comma space 0
+KPX comma quoteright -95
+KPX comma quotedblright -95
+
+KPX d y 0
+KPX d w 0
+KPX d v 0
+KPX d period 0
+KPX d d 0
+KPX d comma 0
+
+KPX e y 0
+KPX e x 0
+KPX e w 0
+KPX e v 0
+KPX e period 0
+KPX e p 0
+KPX e g 0
+KPX e comma 0
+KPX e b -10
+
+KPX f quoteright 55
+KPX f quotedblright 0
+KPX f period -10
+KPX f o -10
+KPX f l 0
+KPX f i 0
+KPX f f -18
+KPX f e -10
+KPX f dotlessi -30
+KPX f comma -10
+KPX f a 0
+
+KPX g y 0
+KPX g r 0
+KPX g period 0
+KPX g o 0
+KPX g i 0
+KPX g g 0
+KPX g e 0
+KPX g comma 0
+KPX g a 0
+
+KPX h y 0
+
+KPX i v 0
+
+KPX k y 0
+KPX k o -10
+KPX k e -30
+
+KPX l y 0
+KPX l w 0
+
+KPX m y 0
+KPX m u 0
+
+KPX n y 0
+KPX n v -40
+KPX n u 0
+
+KPX o y -10
+KPX o x -10
+KPX o w -25
+KPX o v -15
+KPX o g 0
+
+KPX p y 0
+
+KPX period quoteright -95
+KPX period quotedblright -95
+
+KPX quotedblleft quoteleft 0
+KPX quotedblleft A 0
+
+KPX quotedblright space 0
+
+KPX quoteleft quoteleft -74
+KPX quoteleft A 0
+
+KPX quoteright v -15
+KPX quoteright t -37
+KPX quoteright space -74
+KPX quoteright s -74
+KPX quoteright r -15
+KPX quoteright quoteright -74
+KPX quoteright quotedblright 0
+KPX quoteright l 0
+KPX quoteright d -15
+
+KPX r y 0
+KPX r v 0
+KPX r u 0
+KPX r t 0
+KPX r s 0
+KPX r r 0
+KPX r q 0
+KPX r period -65
+KPX r p 0
+KPX r o 0
+KPX r n 0
+KPX r m 0
+KPX r l 0
+KPX r k 0
+KPX r i 0
+KPX r hyphen 0
+KPX r g 0
+KPX r e 0
+KPX r d 0
+KPX r comma -65
+KPX r c 0
+KPX r a 0
+
+KPX s w 0
+
+KPX space quoteleft 0
+KPX space quotedblleft 0
+KPX space Y -70
+KPX space W -70
+KPX space V -70
+KPX space T 0
+KPX space A -37
+
+KPX v period -37
+KPX v o -15
+KPX v e -15
+KPX v comma -37
+KPX v a 0
+
+KPX w period -37
+KPX w o -15
+KPX w h 0
+KPX w e -10
+KPX w comma -37
+KPX w a -10
+
+KPX x e -10
+
+KPX y period -37
+KPX y o 0
+KPX y e 0
+KPX y comma -37
+KPX y a 0
+
+KPX z o 0
+KPX z e 0
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 172 207 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 187 207 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 207 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 172 207 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 157 192 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 207 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 172 207 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 187 207 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 187 207 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 172 207 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 33 207 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 53 207 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 48 207 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 33 207 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 210 207 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 200 207 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 230 207 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 215 207 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 207 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 207 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 207 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 210 207 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 230 207 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 230 207 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 200 207 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 154 207 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 169 207 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 207 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 74 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 74 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 46 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 46 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -42 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -37 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -37 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 97 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 69 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 74 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 97 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 102 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 41 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 13 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Times-Italic.afm b/tlt3.0/library/afm/Times-Italic.afm
new file mode 100644
index 0000000..1db2cff
--- /dev/null
+++ b/tlt3.0/library/afm/Times-Italic.afm
@@ -0,0 +1,649 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Mar 20 13:14:56 1990
+Comment UniqueID 28427
+Comment VMusage 32912 39804
+FontName Times-Italic
+FullName Times Italic
+FamilyName Times
+Weight Medium
+ItalicAngle -15.5
+IsFixedPitch false
+FontBBox -169 -217 1010 883
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 653
+XHeight 441
+Ascender 683
+Descender -205
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ;
+C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ;
+C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ;
+C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ;
+C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ;
+C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ;
+C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ;
+C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ;
+C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ;
+C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ;
+C 43 ; WX 675 ; N plus ; B 86 0 590 506 ;
+C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ;
+C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ;
+C 46 ; WX 250 ; N period ; B 27 -11 138 100 ;
+C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ;
+C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ;
+C 49 ; WX 500 ; N one ; B 49 0 409 676 ;
+C 50 ; WX 500 ; N two ; B 12 0 452 676 ;
+C 51 ; WX 500 ; N three ; B 15 -7 465 676 ;
+C 52 ; WX 500 ; N four ; B 1 0 479 676 ;
+C 53 ; WX 500 ; N five ; B 15 -7 491 666 ;
+C 54 ; WX 500 ; N six ; B 30 -7 521 686 ;
+C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ;
+C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ;
+C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ;
+C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ;
+C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ;
+C 60 ; WX 675 ; N less ; B 84 -8 592 514 ;
+C 61 ; WX 675 ; N equal ; B 86 120 590 386 ;
+C 62 ; WX 675 ; N greater ; B 84 -8 592 514 ;
+C 63 ; WX 500 ; N question ; B 132 -12 472 664 ;
+C 64 ; WX 920 ; N at ; B 118 -18 806 666 ;
+C 65 ; WX 611 ; N A ; B -51 0 564 668 ;
+C 66 ; WX 611 ; N B ; B -8 0 588 653 ;
+C 67 ; WX 667 ; N C ; B 66 -18 689 666 ;
+C 68 ; WX 722 ; N D ; B -8 0 700 653 ;
+C 69 ; WX 611 ; N E ; B -1 0 634 653 ;
+C 70 ; WX 611 ; N F ; B 8 0 645 653 ;
+C 71 ; WX 722 ; N G ; B 52 -18 722 666 ;
+C 72 ; WX 722 ; N H ; B -8 0 767 653 ;
+C 73 ; WX 333 ; N I ; B -8 0 384 653 ;
+C 74 ; WX 444 ; N J ; B -6 -18 491 653 ;
+C 75 ; WX 667 ; N K ; B 7 0 722 653 ;
+C 76 ; WX 556 ; N L ; B -8 0 559 653 ;
+C 77 ; WX 833 ; N M ; B -18 0 873 653 ;
+C 78 ; WX 667 ; N N ; B -20 -15 727 653 ;
+C 79 ; WX 722 ; N O ; B 60 -18 699 666 ;
+C 80 ; WX 611 ; N P ; B 0 0 605 653 ;
+C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ;
+C 82 ; WX 611 ; N R ; B -13 0 588 653 ;
+C 83 ; WX 500 ; N S ; B 17 -18 508 667 ;
+C 84 ; WX 556 ; N T ; B 59 0 633 653 ;
+C 85 ; WX 722 ; N U ; B 102 -18 765 653 ;
+C 86 ; WX 611 ; N V ; B 76 -18 688 653 ;
+C 87 ; WX 833 ; N W ; B 71 -18 906 653 ;
+C 88 ; WX 611 ; N X ; B -29 0 655 653 ;
+C 89 ; WX 556 ; N Y ; B 78 0 633 653 ;
+C 90 ; WX 556 ; N Z ; B -6 0 606 653 ;
+C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ;
+C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ;
+C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ;
+C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ;
+C 97 ; WX 500 ; N a ; B 17 -11 476 441 ;
+C 98 ; WX 500 ; N b ; B 23 -11 473 683 ;
+C 99 ; WX 444 ; N c ; B 30 -11 425 441 ;
+C 100 ; WX 500 ; N d ; B 15 -13 527 683 ;
+C 101 ; WX 444 ; N e ; B 31 -11 412 441 ;
+C 102 ; WX 278 ; N f ; B -147 -207 424 678 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 8 -206 472 441 ;
+C 104 ; WX 500 ; N h ; B 19 -9 478 683 ;
+C 105 ; WX 278 ; N i ; B 49 -11 264 654 ;
+C 106 ; WX 278 ; N j ; B -124 -207 276 654 ;
+C 107 ; WX 444 ; N k ; B 14 -11 461 683 ;
+C 108 ; WX 278 ; N l ; B 41 -11 279 683 ;
+C 109 ; WX 722 ; N m ; B 12 -9 704 441 ;
+C 110 ; WX 500 ; N n ; B 14 -9 474 441 ;
+C 111 ; WX 500 ; N o ; B 27 -11 468 441 ;
+C 112 ; WX 500 ; N p ; B -75 -205 469 441 ;
+C 113 ; WX 500 ; N q ; B 25 -209 483 441 ;
+C 114 ; WX 389 ; N r ; B 45 0 412 441 ;
+C 115 ; WX 389 ; N s ; B 16 -13 366 442 ;
+C 116 ; WX 278 ; N t ; B 37 -11 296 546 ;
+C 117 ; WX 500 ; N u ; B 42 -11 475 441 ;
+C 118 ; WX 444 ; N v ; B 21 -18 426 441 ;
+C 119 ; WX 667 ; N w ; B 16 -18 648 441 ;
+C 120 ; WX 444 ; N x ; B -27 -11 447 441 ;
+C 121 ; WX 444 ; N y ; B -24 -206 426 441 ;
+C 122 ; WX 389 ; N z ; B -2 -81 380 428 ;
+C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ;
+C 124 ; WX 275 ; N bar ; B 105 -18 171 666 ;
+C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ;
+C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ;
+C 161 ; WX 389 ; N exclamdown ; B 59 -205 322 473 ;
+C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ;
+C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ;
+C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ;
+C 165 ; WX 500 ; N yen ; B 27 0 603 653 ;
+C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ;
+C 167 ; WX 500 ; N section ; B 53 -162 461 666 ;
+C 168 ; WX 500 ; N currency ; B -22 53 522 597 ;
+C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ;
+C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ;
+C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ;
+C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ;
+C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ;
+C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ;
+C 177 ; WX 500 ; N endash ; B -6 197 505 243 ;
+C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ;
+C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ;
+C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
+C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ;
+C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ;
+C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ;
+C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ;
+C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ;
+C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ;
+C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ;
+C 191 ; WX 500 ; N questiondown ; B 28 -205 368 471 ;
+C 193 ; WX 333 ; N grave ; B 121 492 311 664 ;
+C 194 ; WX 333 ; N acute ; B 180 494 403 664 ;
+C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ;
+C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ;
+C 197 ; WX 333 ; N macron ; B 99 532 411 583 ;
+C 198 ; WX 333 ; N breve ; B 117 492 418 650 ;
+C 199 ; WX 333 ; N dotaccent ; B 207 508 305 606 ;
+C 200 ; WX 333 ; N dieresis ; B 107 508 405 606 ;
+C 202 ; WX 333 ; N ring ; B 155 492 355 691 ;
+C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ;
+C 206 ; WX 333 ; N ogonek ; B -20 -169 200 40 ;
+C 207 ; WX 333 ; N caron ; B 121 492 426 661 ;
+C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ;
+C 225 ; WX 889 ; N AE ; B -27 0 911 653 ;
+C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ;
+C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ;
+C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ;
+C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ;
+C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ;
+C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ;
+C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ;
+C 248 ; WX 278 ; N lslash ; B 37 -11 307 683 ;
+C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ;
+C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ;
+C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ;
+C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ;
+C -1 ; WX 444 ; N ccedilla ; B 26 -217 425 441 ;
+C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ;
+C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ;
+C -1 ; WX 278 ; N icircumflex ; B 34 -11 328 661 ;
+C -1 ; WX 300 ; N threesuperior ; B 43 268 339 676 ;
+C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ;
+C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ;
+C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ;
+C -1 ; WX 300 ; N twosuperior ; B 33 271 324 676 ;
+C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ;
+C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ;
+C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ;
+C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ;
+C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ;
+C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ;
+C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ;
+C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ;
+C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ;
+C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ;
+C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ;
+C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ;
+C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ;
+C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ;
+C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ;
+C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ;
+C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ;
+C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ;
+C -1 ; WX 500 ; N aring ; B 17 -11 476 691 ;
+C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ;
+C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ;
+C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ;
+C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ;
+C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ;
+C -1 ; WX 333 ; N Iacute ; B -8 0 413 876 ;
+C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ;
+C -1 ; WX 722 ; N Odieresis ; B 60 -18 699 818 ;
+C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ;
+C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ;
+C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ;
+C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ;
+C -1 ; WX 722 ; N Ograve ; B 60 -18 699 876 ;
+C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ;
+C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ;
+C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ;
+C -1 ; WX 722 ; N Otilde ; B 60 -18 699 836 ;
+C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ;
+C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ;
+C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ;
+C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ;
+C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ;
+C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 699 873 ;
+C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ;
+C -1 ; WX 611 ; N Aring ; B -51 0 564 883 ;
+C -1 ; WX 278 ; N idieresis ; B 49 -11 353 606 ;
+C -1 ; WX 278 ; N iacute ; B 49 -11 356 664 ;
+C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ;
+C -1 ; WX 675 ; N plusminus ; B 86 0 590 506 ;
+C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ;
+C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ;
+C -1 ; WX 675 ; N minus ; B 86 220 590 286 ;
+C -1 ; WX 300 ; N onesuperior ; B 43 271 284 676 ;
+C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ;
+C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ;
+C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ;
+C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ;
+C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ;
+C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ;
+C -1 ; WX 400 ; N degree ; B 101 390 387 676 ;
+C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ;
+C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ;
+C -1 ; WX 722 ; N Oacute ; B 60 -18 699 876 ;
+C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ;
+C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ;
+C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ;
+C -1 ; WX 275 ; N brokenbar ; B 105 -18 171 666 ;
+C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 283
+
+KPX A y -55
+KPX A w -55
+KPX A v -55
+KPX A u -20
+KPX A quoteright -37
+KPX A quotedblright 0
+KPX A p 0
+KPX A Y -55
+KPX A W -95
+KPX A V -105
+KPX A U -50
+KPX A T -37
+KPX A Q -40
+KPX A O -40
+KPX A G -35
+KPX A C -30
+
+KPX B period 0
+KPX B comma 0
+KPX B U -10
+KPX B A -25
+
+KPX D period 0
+KPX D comma 0
+KPX D Y -40
+KPX D W -40
+KPX D V -40
+KPX D A -35
+
+KPX F r -55
+KPX F period -135
+KPX F o -105
+KPX F i -45
+KPX F e -75
+KPX F comma -135
+KPX F a -75
+KPX F A -115
+
+KPX G period 0
+KPX G comma 0
+
+KPX J u -35
+KPX J period -25
+KPX J o -25
+KPX J e -25
+KPX J comma -25
+KPX J a -35
+KPX J A -40
+
+KPX K y -40
+KPX K u -40
+KPX K o -40
+KPX K e -35
+KPX K O -50
+
+KPX L y -30
+KPX L quoteright -37
+KPX L quotedblright 0
+KPX L Y -20
+KPX L W -55
+KPX L V -55
+KPX L T -20
+
+KPX N period 0
+KPX N comma 0
+KPX N A -27
+
+KPX O period 0
+KPX O comma 0
+KPX O Y -50
+KPX O X -40
+KPX O W -50
+KPX O V -50
+KPX O T -40
+KPX O A -55
+
+KPX P period -135
+KPX P o -80
+KPX P e -80
+KPX P comma -135
+KPX P a -80
+KPX P A -90
+
+KPX Q period 0
+KPX Q comma 0
+KPX Q U -10
+
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+KPX R U -40
+KPX R T 0
+KPX R O -40
+
+KPX S period 0
+KPX S comma 0
+
+KPX T y -74
+KPX T w -74
+KPX T u -55
+KPX T semicolon -65
+KPX T r -55
+KPX T period -74
+KPX T o -92
+KPX T i -55
+KPX T hyphen -74
+KPX T h 0
+KPX T e -92
+KPX T comma -74
+KPX T colon -55
+KPX T a -92
+KPX T O -18
+KPX T A -50
+
+KPX U period -25
+KPX U comma -25
+KPX U A -40
+
+KPX V u -74
+KPX V semicolon -74
+KPX V period -129
+KPX V o -111
+KPX V i -74
+KPX V hyphen -55
+KPX V e -111
+KPX V comma -129
+KPX V colon -65
+KPX V a -111
+KPX V O -30
+KPX V G 0
+KPX V A -60
+
+KPX W y -70
+KPX W u -55
+KPX W semicolon -65
+KPX W period -92
+KPX W o -92
+KPX W i -55
+KPX W hyphen -37
+KPX W h 0
+KPX W e -92
+KPX W comma -92
+KPX W colon -65
+KPX W a -92
+KPX W O -25
+KPX W A -60
+
+KPX Y u -92
+KPX Y semicolon -65
+KPX Y period -92
+KPX Y o -92
+KPX Y i -74
+KPX Y hyphen -74
+KPX Y e -92
+KPX Y comma -92
+KPX Y colon -65
+KPX Y a -92
+KPX Y O -15
+KPX Y A -50
+
+KPX a y 0
+KPX a w 0
+KPX a v 0
+KPX a t 0
+KPX a p 0
+KPX a g -10
+KPX a b 0
+
+KPX b y 0
+KPX b v 0
+KPX b u -20
+KPX b period -40
+KPX b l 0
+KPX b comma 0
+KPX b b 0
+
+KPX c y 0
+KPX c period 0
+KPX c l 0
+KPX c k -20
+KPX c h -15
+KPX c comma 0
+
+KPX colon space 0
+
+KPX comma space 0
+KPX comma quoteright -140
+KPX comma quotedblright -140
+
+KPX d y 0
+KPX d w 0
+KPX d v 0
+KPX d period 0
+KPX d d 0
+KPX d comma 0
+
+KPX e y -30
+KPX e x -20
+KPX e w -15
+KPX e v -15
+KPX e period -15
+KPX e p 0
+KPX e g -40
+KPX e comma -10
+KPX e b 0
+
+KPX f quoteright 92
+KPX f quotedblright 0
+KPX f period -15
+KPX f o 0
+KPX f l 0
+KPX f i -20
+KPX f f -18
+KPX f e 0
+KPX f dotlessi -60
+KPX f comma -10
+KPX f a 0
+
+KPX g y 0
+KPX g r 0
+KPX g period -15
+KPX g o 0
+KPX g i 0
+KPX g g -10
+KPX g e -10
+KPX g comma -10
+KPX g a 0
+
+KPX h y 0
+
+KPX i v 0
+
+KPX k y -10
+KPX k o -10
+KPX k e -10
+
+KPX l y 0
+KPX l w 0
+
+KPX m y 0
+KPX m u 0
+
+KPX n y 0
+KPX n v -40
+KPX n u 0
+
+KPX o y 0
+KPX o x 0
+KPX o w 0
+KPX o v -10
+KPX o g -10
+
+KPX p y 0
+
+KPX period quoteright -140
+KPX period quotedblright -140
+
+KPX quotedblleft quoteleft 0
+KPX quotedblleft A 0
+
+KPX quotedblright space 0
+
+KPX quoteleft quoteleft -111
+KPX quoteleft A 0
+
+KPX quoteright v -10
+KPX quoteright t -30
+KPX quoteright space -111
+KPX quoteright s -40
+KPX quoteright r -25
+KPX quoteright quoteright -111
+KPX quoteright quotedblright 0
+KPX quoteright l 0
+KPX quoteright d -25
+
+KPX r y 0
+KPX r v 0
+KPX r u 0
+KPX r t 0
+KPX r s -10
+KPX r r 0
+KPX r q -37
+KPX r period -111
+KPX r p 0
+KPX r o -45
+KPX r n 0
+KPX r m 0
+KPX r l 0
+KPX r k 0
+KPX r i 0
+KPX r hyphen -20
+KPX r g -37
+KPX r e -37
+KPX r d -37
+KPX r comma -111
+KPX r c -37
+KPX r a -15
+
+KPX s w 0
+
+KPX space quoteleft 0
+KPX space quotedblleft 0
+KPX space Y -75
+KPX space W -40
+KPX space V -35
+KPX space T -18
+KPX space A -18
+
+KPX v period -74
+KPX v o 0
+KPX v e 0
+KPX v comma -74
+KPX v a 0
+
+KPX w period -74
+KPX w o 0
+KPX w h 0
+KPX w e 0
+KPX w comma -74
+KPX w a 0
+
+KPX x e 0
+
+KPX y period -55
+KPX y o 0
+KPX y e 0
+KPX y comma -55
+KPX y a 0
+
+KPX z o 0
+KPX z e 0
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 139 212 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 144 212 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 139 212 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 149 212 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 129 192 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 139 212 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 149 212 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 169 212 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 159 212 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 149 212 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 10 212 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 40 212 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 30 212 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 10 212 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 177 212 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 195 212 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 230 212 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 230 212 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 205 212 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 212 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 94 212 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 212 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 215 212 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 225 212 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 215 212 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 132 212 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 142 212 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 112 212 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 84 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 46 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -57 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -52 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 49 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 74 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 69 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 74 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 74 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 74 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 36 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 8 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/Times-Roman.afm b/tlt3.0/library/afm/Times-Roman.afm
new file mode 100644
index 0000000..58de46e
--- /dev/null
+++ b/tlt3.0/library/afm/Times-Roman.afm
@@ -0,0 +1,649 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Tue Mar 20 12:15:44 1990
+Comment UniqueID 28416
+Comment VMusage 30487 37379
+FontName Times-Roman
+FullName Times Roman
+FamilyName Times
+Weight Roman
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -168 -218 1000 898
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
+EncodingScheme AdobeStandardEncoding
+CapHeight 662
+XHeight 450
+Ascender 683
+Descender -217
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 130 -9 238 676 ;
+C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ;
+C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ;
+C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ;
+C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ;
+C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ;
+C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ;
+C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ;
+C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ;
+C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ;
+C 43 ; WX 564 ; N plus ; B 30 0 534 506 ;
+C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ;
+C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ;
+C 46 ; WX 250 ; N period ; B 70 -11 181 100 ;
+C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ;
+C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ;
+C 49 ; WX 500 ; N one ; B 111 0 394 676 ;
+C 50 ; WX 500 ; N two ; B 30 0 475 676 ;
+C 51 ; WX 500 ; N three ; B 43 -14 431 676 ;
+C 52 ; WX 500 ; N four ; B 12 0 472 676 ;
+C 53 ; WX 500 ; N five ; B 32 -14 438 688 ;
+C 54 ; WX 500 ; N six ; B 34 -14 468 684 ;
+C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ;
+C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ;
+C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ;
+C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ;
+C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ;
+C 60 ; WX 564 ; N less ; B 28 -8 536 514 ;
+C 61 ; WX 564 ; N equal ; B 30 120 534 386 ;
+C 62 ; WX 564 ; N greater ; B 28 -8 536 514 ;
+C 63 ; WX 444 ; N question ; B 68 -8 414 676 ;
+C 64 ; WX 921 ; N at ; B 116 -14 809 676 ;
+C 65 ; WX 722 ; N A ; B 15 0 706 674 ;
+C 66 ; WX 667 ; N B ; B 17 0 593 662 ;
+C 67 ; WX 667 ; N C ; B 28 -14 633 676 ;
+C 68 ; WX 722 ; N D ; B 16 0 685 662 ;
+C 69 ; WX 611 ; N E ; B 12 0 597 662 ;
+C 70 ; WX 556 ; N F ; B 12 0 546 662 ;
+C 71 ; WX 722 ; N G ; B 32 -14 709 676 ;
+C 72 ; WX 722 ; N H ; B 19 0 702 662 ;
+C 73 ; WX 333 ; N I ; B 18 0 315 662 ;
+C 74 ; WX 389 ; N J ; B 10 -14 370 662 ;
+C 75 ; WX 722 ; N K ; B 34 0 723 662 ;
+C 76 ; WX 611 ; N L ; B 12 0 598 662 ;
+C 77 ; WX 889 ; N M ; B 12 0 863 662 ;
+C 78 ; WX 722 ; N N ; B 12 -11 707 662 ;
+C 79 ; WX 722 ; N O ; B 34 -14 688 676 ;
+C 80 ; WX 556 ; N P ; B 16 0 542 662 ;
+C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ;
+C 82 ; WX 667 ; N R ; B 17 0 659 662 ;
+C 83 ; WX 556 ; N S ; B 42 -14 491 676 ;
+C 84 ; WX 611 ; N T ; B 17 0 593 662 ;
+C 85 ; WX 722 ; N U ; B 14 -14 705 662 ;
+C 86 ; WX 722 ; N V ; B 16 -11 697 662 ;
+C 87 ; WX 944 ; N W ; B 5 -11 932 662 ;
+C 88 ; WX 722 ; N X ; B 10 0 704 662 ;
+C 89 ; WX 722 ; N Y ; B 22 0 703 662 ;
+C 90 ; WX 611 ; N Z ; B 9 0 597 662 ;
+C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ;
+C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ;
+C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ;
+C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ;
+C 97 ; WX 444 ; N a ; B 37 -10 442 460 ;
+C 98 ; WX 500 ; N b ; B 3 -10 468 683 ;
+C 99 ; WX 444 ; N c ; B 25 -10 412 460 ;
+C 100 ; WX 500 ; N d ; B 27 -10 491 683 ;
+C 101 ; WX 444 ; N e ; B 25 -10 424 460 ;
+C 102 ; WX 333 ; N f ; B 20 0 383 683 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 28 -218 470 460 ;
+C 104 ; WX 500 ; N h ; B 9 0 487 683 ;
+C 105 ; WX 278 ; N i ; B 16 0 253 683 ;
+C 106 ; WX 278 ; N j ; B -70 -218 194 683 ;
+C 107 ; WX 500 ; N k ; B 7 0 505 683 ;
+C 108 ; WX 278 ; N l ; B 19 0 257 683 ;
+C 109 ; WX 778 ; N m ; B 16 0 775 460 ;
+C 110 ; WX 500 ; N n ; B 16 0 485 460 ;
+C 111 ; WX 500 ; N o ; B 29 -10 470 460 ;
+C 112 ; WX 500 ; N p ; B 5 -217 470 460 ;
+C 113 ; WX 500 ; N q ; B 24 -217 488 460 ;
+C 114 ; WX 333 ; N r ; B 5 0 335 460 ;
+C 115 ; WX 389 ; N s ; B 51 -10 348 460 ;
+C 116 ; WX 278 ; N t ; B 13 -10 279 579 ;
+C 117 ; WX 500 ; N u ; B 9 -10 479 450 ;
+C 118 ; WX 500 ; N v ; B 19 -14 477 450 ;
+C 119 ; WX 722 ; N w ; B 21 -14 694 450 ;
+C 120 ; WX 500 ; N x ; B 17 0 479 450 ;
+C 121 ; WX 500 ; N y ; B 14 -218 475 450 ;
+C 122 ; WX 444 ; N z ; B 27 0 418 450 ;
+C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ;
+C 124 ; WX 200 ; N bar ; B 67 -14 133 676 ;
+C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ;
+C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ;
+C 161 ; WX 333 ; N exclamdown ; B 97 -218 205 467 ;
+C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ;
+C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ;
+C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ;
+C 165 ; WX 500 ; N yen ; B -53 0 512 662 ;
+C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ;
+C 167 ; WX 500 ; N section ; B 70 -148 426 676 ;
+C 168 ; WX 500 ; N currency ; B -22 58 522 602 ;
+C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ;
+C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ;
+C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ;
+C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ;
+C 174 ; WX 556 ; N fi ; B 31 0 521 683 ;
+C 175 ; WX 556 ; N fl ; B 32 0 521 683 ;
+C 177 ; WX 500 ; N endash ; B 0 201 500 250 ;
+C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ;
+C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ;
+C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
+C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ;
+C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ;
+C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ;
+C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ;
+C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ;
+C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ;
+C 191 ; WX 444 ; N questiondown ; B 30 -218 376 466 ;
+C 193 ; WX 333 ; N grave ; B 19 507 242 678 ;
+C 194 ; WX 333 ; N acute ; B 93 507 317 678 ;
+C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ;
+C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ;
+C 197 ; WX 333 ; N macron ; B 11 547 322 601 ;
+C 198 ; WX 333 ; N breve ; B 26 507 307 664 ;
+C 199 ; WX 333 ; N dotaccent ; B 118 523 216 623 ;
+C 200 ; WX 333 ; N dieresis ; B 18 523 315 623 ;
+C 202 ; WX 333 ; N ring ; B 67 512 266 711 ;
+C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ;
+C 206 ; WX 333 ; N ogonek ; B 64 -165 249 0 ;
+C 207 ; WX 333 ; N caron ; B 11 507 322 674 ;
+C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ;
+C 225 ; WX 889 ; N AE ; B 0 0 863 662 ;
+C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ;
+C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ;
+C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ;
+C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ;
+C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ;
+C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ;
+C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ;
+C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ;
+C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ;
+C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ;
+C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ;
+C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ;
+C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 623 ;
+C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ;
+C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ;
+C -1 ; WX 300 ; N threesuperior ; B 15 262 291 676 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ;
+C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ;
+C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ;
+C -1 ; WX 300 ; N twosuperior ; B 1 270 296 676 ;
+C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ;
+C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ;
+C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ;
+C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ;
+C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ;
+C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ;
+C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ;
+C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ;
+C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -10 424 623 ;
+C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ;
+C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ;
+C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ;
+C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ;
+C -1 ; WX 333 ; N Idieresis ; B 18 0 315 835 ;
+C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ;
+C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ;
+C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ;
+C -1 ; WX 444 ; N aring ; B 37 -10 442 711 ;
+C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ;
+C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ;
+C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ;
+C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ;
+C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ;
+C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ;
+C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 835 ;
+C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ;
+C -1 ; WX 611 ; N Edieresis ; B 12 0 597 835 ;
+C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ;
+C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ;
+C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ;
+C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ;
+C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 835 ;
+C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ;
+C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ;
+C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ;
+C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ;
+C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ;
+C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ;
+C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ;
+C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ;
+C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ;
+C -1 ; WX 722 ; N Aring ; B 15 0 706 898 ;
+C -1 ; WX 278 ; N idieresis ; B -9 0 288 623 ;
+C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ;
+C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ;
+C -1 ; WX 564 ; N plusminus ; B 30 0 534 506 ;
+C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ;
+C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 835 ;
+C -1 ; WX 564 ; N minus ; B 30 220 534 286 ;
+C -1 ; WX 300 ; N onesuperior ; B 57 270 248 676 ;
+C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ;
+C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ;
+C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ;
+C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ;
+C -1 ; WX 500 ; N odieresis ; B 29 -10 470 623 ;
+C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ;
+C -1 ; WX 400 ; N degree ; B 57 390 343 676 ;
+C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ;
+C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ;
+C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ;
+C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ;
+C -1 ; WX 722 ; N Adieresis ; B 15 0 706 835 ;
+C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ;
+C -1 ; WX 200 ; N brokenbar ; B 67 -14 133 676 ;
+C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 283
+
+KPX A y -92
+KPX A w -92
+KPX A v -74
+KPX A u 0
+KPX A quoteright -111
+KPX A quotedblright 0
+KPX A p 0
+KPX A Y -105
+KPX A W -90
+KPX A V -135
+KPX A U -55
+KPX A T -111
+KPX A Q -55
+KPX A O -55
+KPX A G -40
+KPX A C -40
+
+KPX B period 0
+KPX B comma 0
+KPX B U -10
+KPX B A -35
+
+KPX D period 0
+KPX D comma 0
+KPX D Y -55
+KPX D W -30
+KPX D V -40
+KPX D A -40
+
+KPX F r 0
+KPX F period -80
+KPX F o -15
+KPX F i 0
+KPX F e 0
+KPX F comma -80
+KPX F a -15
+KPX F A -74
+
+KPX G period 0
+KPX G comma 0
+
+KPX J u 0
+KPX J period 0
+KPX J o 0
+KPX J e 0
+KPX J comma 0
+KPX J a 0
+KPX J A -60
+
+KPX K y -25
+KPX K u -15
+KPX K o -35
+KPX K e -25
+KPX K O -30
+
+KPX L y -55
+KPX L quoteright -92
+KPX L quotedblright 0
+KPX L Y -100
+KPX L W -74
+KPX L V -100
+KPX L T -92
+
+KPX N period 0
+KPX N comma 0
+KPX N A -35
+
+KPX O period 0
+KPX O comma 0
+KPX O Y -50
+KPX O X -40
+KPX O W -35
+KPX O V -50
+KPX O T -40
+KPX O A -35
+
+KPX P period -111
+KPX P o 0
+KPX P e 0
+KPX P comma -111
+KPX P a -15
+KPX P A -92
+
+KPX Q period 0
+KPX Q comma 0
+KPX Q U -10
+
+KPX R Y -65
+KPX R W -55
+KPX R V -80
+KPX R U -40
+KPX R T -60
+KPX R O -40
+
+KPX S period 0
+KPX S comma 0
+
+KPX T y -80
+KPX T w -80
+KPX T u -45
+KPX T semicolon -55
+KPX T r -35
+KPX T period -74
+KPX T o -80
+KPX T i -35
+KPX T hyphen -92
+KPX T h 0
+KPX T e -70
+KPX T comma -74
+KPX T colon -50
+KPX T a -80
+KPX T O -18
+KPX T A -93
+
+KPX U period 0
+KPX U comma 0
+KPX U A -40
+
+KPX V u -75
+KPX V semicolon -74
+KPX V period -129
+KPX V o -129
+KPX V i -60
+KPX V hyphen -100
+KPX V e -111
+KPX V comma -129
+KPX V colon -74
+KPX V a -111
+KPX V O -40
+KPX V G -15
+KPX V A -135
+
+KPX W y -73
+KPX W u -50
+KPX W semicolon -37
+KPX W period -92
+KPX W o -80
+KPX W i -40
+KPX W hyphen -65
+KPX W h 0
+KPX W e -80
+KPX W comma -92
+KPX W colon -37
+KPX W a -80
+KPX W O -10
+KPX W A -120
+
+KPX Y u -111
+KPX Y semicolon -92
+KPX Y period -129
+KPX Y o -110
+KPX Y i -55
+KPX Y hyphen -111
+KPX Y e -100
+KPX Y comma -129
+KPX Y colon -92
+KPX Y a -100
+KPX Y O -30
+KPX Y A -120
+
+KPX a y 0
+KPX a w -15
+KPX a v -20
+KPX a t 0
+KPX a p 0
+KPX a g 0
+KPX a b 0
+
+KPX b y 0
+KPX b v -15
+KPX b u -20
+KPX b period -40
+KPX b l 0
+KPX b comma 0
+KPX b b 0
+
+KPX c y -15
+KPX c period 0
+KPX c l 0
+KPX c k 0
+KPX c h 0
+KPX c comma 0
+
+KPX colon space 0
+
+KPX comma space 0
+KPX comma quoteright -70
+KPX comma quotedblright -70
+
+KPX d y 0
+KPX d w 0
+KPX d v 0
+KPX d period 0
+KPX d d 0
+KPX d comma 0
+
+KPX e y -15
+KPX e x -15
+KPX e w -25
+KPX e v -25
+KPX e period 0
+KPX e p 0
+KPX e g -15
+KPX e comma 0
+KPX e b 0
+
+KPX f quoteright 55
+KPX f quotedblright 0
+KPX f period 0
+KPX f o 0
+KPX f l 0
+KPX f i -20
+KPX f f -25
+KPX f e 0
+KPX f dotlessi -50
+KPX f comma 0
+KPX f a -10
+
+KPX g y 0
+KPX g r 0
+KPX g period 0
+KPX g o 0
+KPX g i 0
+KPX g g 0
+KPX g e 0
+KPX g comma 0
+KPX g a -5
+
+KPX h y -5
+
+KPX i v -25
+
+KPX k y -15
+KPX k o -10
+KPX k e -10
+
+KPX l y 0
+KPX l w -10
+
+KPX m y 0
+KPX m u 0
+
+KPX n y -15
+KPX n v -40
+KPX n u 0
+
+KPX o y -10
+KPX o x 0
+KPX o w -25
+KPX o v -15
+KPX o g 0
+
+KPX p y -10
+
+KPX period quoteright -70
+KPX period quotedblright -70
+
+KPX quotedblleft quoteleft 0
+KPX quotedblleft A -80
+
+KPX quotedblright space 0
+
+KPX quoteleft quoteleft -74
+KPX quoteleft A -80
+
+KPX quoteright v -50
+KPX quoteright t -18
+KPX quoteright space -74
+KPX quoteright s -55
+KPX quoteright r -50
+KPX quoteright quoteright -74
+KPX quoteright quotedblright 0
+KPX quoteright l -10
+KPX quoteright d -50
+
+KPX r y 0
+KPX r v 0
+KPX r u 0
+KPX r t 0
+KPX r s 0
+KPX r r 0
+KPX r q 0
+KPX r period -55
+KPX r p 0
+KPX r o 0
+KPX r n 0
+KPX r m 0
+KPX r l 0
+KPX r k 0
+KPX r i 0
+KPX r hyphen -20
+KPX r g -18
+KPX r e 0
+KPX r d 0
+KPX r comma -40
+KPX r c 0
+KPX r a 0
+
+KPX s w 0
+
+KPX space quoteleft 0
+KPX space quotedblleft 0
+KPX space Y -90
+KPX space W -30
+KPX space V -50
+KPX space T -18
+KPX space A -55
+
+KPX v period -65
+KPX v o -20
+KPX v e -15
+KPX v comma -65
+KPX v a -25
+
+KPX w period -65
+KPX w o -10
+KPX w h 0
+KPX w e 0
+KPX w comma -65
+KPX w a -10
+
+KPX x e -15
+
+KPX y period -65
+KPX y o 0
+KPX y e 0
+KPX y comma -65
+KPX y a 0
+
+KPX z o 0
+KPX z e 0
+EndKernPairs
+EndKernData
+StartComposites 58
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 212 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 212 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 212 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 212 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 185 187 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 212 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 212 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 212 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 212 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 212 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 212 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 212 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 212 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 212 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 212 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 195 212 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 195 212 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 195 212 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 195 212 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 195 212 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 212 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 212 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 212 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 212 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 212 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 195 212 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 195 212 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 212 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 56 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 56 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 56 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 56 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/ZapfChancery-MediumItalic.afm b/tlt3.0/library/afm/ZapfChancery-MediumItalic.afm
new file mode 100644
index 0000000..7a8df29
--- /dev/null
+++ b/tlt3.0/library/afm/ZapfChancery-MediumItalic.afm
@@ -0,0 +1,481 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.
+Comment Creation Date: Fri Dec 28 16:35:46 1990
+Comment UniqueID 33936
+Comment VMusage 34559 41451
+FontName ZapfChancery-MediumItalic
+FullName ITC Zapf Chancery Medium Italic
+FamilyName ITC Zapf Chancery
+Weight Medium
+ItalicAngle -14
+IsFixedPitch false
+FontBBox -181 -314 1065 831
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.007
+Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated.  All Rights Reserved.ITC Zapf Chancery is a registered trademark of International Typeface Corporation.
+EncodingScheme AdobeStandardEncoding
+CapHeight 708
+XHeight 438
+Ascender 714
+Descender -314
+StartCharMetrics 228
+C 32 ; WX 220 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 280 ; N exclam ; B 119 -14 353 610 ;
+C 34 ; WX 220 ; N quotedbl ; B 120 343 333 610 ;
+C 35 ; WX 440 ; N numbersign ; B 83 0 521 594 ;
+C 36 ; WX 440 ; N dollar ; B 60 -144 508 709 ;
+C 37 ; WX 680 ; N percent ; B 132 -160 710 700 ;
+C 38 ; WX 780 ; N ampersand ; B 126 -16 915 610 ;
+C 39 ; WX 240 ; N quoteright ; B 168 343 338 610 ;
+C 40 ; WX 260 ; N parenleft ; B 96 -216 411 664 ;
+C 41 ; WX 220 ; N parenright ; B -13 -216 302 664 ;
+C 42 ; WX 420 ; N asterisk ; B 139 263 479 610 ;
+C 43 ; WX 520 ; N plus ; B 117 0 543 426 ;
+C 44 ; WX 220 ; N comma ; B 25 -140 213 148 ;
+C 45 ; WX 280 ; N hyphen ; B 69 190 334 248 ;
+C 46 ; WX 220 ; N period ; B 102 -14 228 128 ;
+C 47 ; WX 340 ; N slash ; B 74 -16 458 610 ;
+C 48 ; WX 440 ; N zero ; B 79 -16 538 610 ;
+C 49 ; WX 440 ; N one ; B 41 0 428 610 ;
+C 50 ; WX 440 ; N two ; B 17 -16 485 610 ;
+C 51 ; WX 440 ; N three ; B 1 -16 485 610 ;
+C 52 ; WX 440 ; N four ; B 77 -35 499 610 ;
+C 53 ; WX 440 ; N five ; B 60 -16 595 679 ;
+C 54 ; WX 440 ; N six ; B 90 -16 556 610 ;
+C 55 ; WX 440 ; N seven ; B 157 -33 561 645 ;
+C 56 ; WX 440 ; N eight ; B 65 -16 529 610 ;
+C 57 ; WX 440 ; N nine ; B 32 -16 517 610 ;
+C 58 ; WX 260 ; N colon ; B 98 -14 296 438 ;
+C 59 ; WX 240 ; N semicolon ; B 29 -140 299 438 ;
+C 60 ; WX 520 ; N less ; B 139 0 527 468 ;
+C 61 ; WX 520 ; N equal ; B 117 86 543 340 ;
+C 62 ; WX 520 ; N greater ; B 139 0 527 468 ;
+C 63 ; WX 380 ; N question ; B 150 -14 455 610 ;
+C 64 ; WX 700 ; N at ; B 127 -16 753 610 ;
+C 65 ; WX 620 ; N A ; B 13 -16 697 632 ;
+C 66 ; WX 600 ; N B ; B 85 -6 674 640 ;
+C 67 ; WX 520 ; N C ; B 93 -16 631 610 ;
+C 68 ; WX 700 ; N D ; B 86 -6 768 640 ;
+C 69 ; WX 620 ; N E ; B 91 -12 709 618 ;
+C 70 ; WX 580 ; N F ; B 120 -118 793 629 ;
+C 71 ; WX 620 ; N G ; B 148 -242 709 610 ;
+C 72 ; WX 680 ; N H ; B 18 -16 878 708 ;
+C 73 ; WX 380 ; N I ; B 99 0 504 594 ;
+C 74 ; WX 400 ; N J ; B -14 -147 538 594 ;
+C 75 ; WX 660 ; N K ; B 53 -153 844 610 ;
+C 76 ; WX 580 ; N L ; B 53 -16 657 610 ;
+C 77 ; WX 840 ; N M ; B 58 -16 1020 722 ;
+C 78 ; WX 700 ; N N ; B 85 -168 915 708 ;
+C 79 ; WX 600 ; N O ; B 94 -16 660 610 ;
+C 80 ; WX 540 ; N P ; B 42 0 658 628 ;
+C 81 ; WX 600 ; N Q ; B 84 -177 775 610 ;
+C 82 ; WX 600 ; N R ; B 58 -168 805 640 ;
+C 83 ; WX 460 ; N S ; B 45 -81 558 610 ;
+C 84 ; WX 500 ; N T ; B 63 0 744 667 ;
+C 85 ; WX 740 ; N U ; B 126 -16 792 617 ;
+C 86 ; WX 640 ; N V ; B 124 -16 810 714 ;
+C 87 ; WX 880 ; N W ; B 94 -16 1046 723 ;
+C 88 ; WX 560 ; N X ; B -30 -16 699 610 ;
+C 89 ; WX 560 ; N Y ; B 41 -168 774 647 ;
+C 90 ; WX 620 ; N Z ; B 42 -19 669 624 ;
+C 91 ; WX 240 ; N bracketleft ; B -13 -207 405 655 ;
+C 92 ; WX 480 ; N backslash ; B 140 -16 524 610 ;
+C 93 ; WX 320 ; N bracketright ; B -27 -207 391 655 ;
+C 94 ; WX 520 ; N asciicircum ; B 132 239 532 594 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 240 ; N quoteleft ; B 169 343 339 610 ;
+C 97 ; WX 420 ; N a ; B 92 -15 485 438 ;
+C 98 ; WX 420 ; N b ; B 82 -23 492 714 ;
+C 99 ; WX 340 ; N c ; B 87 -14 406 438 ;
+C 100 ; WX 440 ; N d ; B 102 -14 651 714 ;
+C 101 ; WX 340 ; N e ; B 87 -14 403 438 ;
+C 102 ; WX 320 ; N f ; B -119 -314 547 714 ; L i fi ; L l fl ;
+C 103 ; WX 400 ; N g ; B -108 -314 503 438 ;
+C 104 ; WX 440 ; N h ; B 55 -14 524 714 ;
+C 105 ; WX 240 ; N i ; B 100 -14 341 635 ;
+C 106 ; WX 220 ; N j ; B -112 -314 332 635 ;
+C 107 ; WX 440 ; N k ; B 87 -184 628 714 ;
+C 108 ; WX 240 ; N l ; B 102 -14 480 714 ;
+C 109 ; WX 620 ; N m ; B 86 -14 704 438 ;
+C 110 ; WX 460 ; N n ; B 101 -14 544 438 ;
+C 111 ; WX 400 ; N o ; B 87 -14 449 438 ;
+C 112 ; WX 440 ; N p ; B -23 -314 484 432 ;
+C 113 ; WX 400 ; N q ; B 87 -300 490 510 ;
+C 114 ; WX 300 ; N r ; B 101 -14 424 438 ;
+C 115 ; WX 320 ; N s ; B 46 -14 403 438 ;
+C 116 ; WX 320 ; N t ; B 106 -14 426 539 ;
+C 117 ; WX 460 ; N u ; B 102 -14 528 438 ;
+C 118 ; WX 440 ; N v ; B 87 -14 533 488 ;
+C 119 ; WX 680 ; N w ; B 87 -14 782 488 ;
+C 120 ; WX 420 ; N x ; B 70 -195 589 438 ;
+C 121 ; WX 400 ; N y ; B -24 -314 483 438 ;
+C 122 ; WX 440 ; N z ; B 26 -14 508 445 ;
+C 123 ; WX 240 ; N braceleft ; B 55 -207 383 655 ;
+C 124 ; WX 520 ; N bar ; B 320 -16 378 714 ;
+C 125 ; WX 240 ; N braceright ; B -10 -207 318 655 ;
+C 126 ; WX 520 ; N asciitilde ; B 123 186 539 320 ;
+C 161 ; WX 280 ; N exclamdown ; B 72 -186 306 438 ;
+C 162 ; WX 440 ; N cent ; B 122 -134 476 543 ;
+C 163 ; WX 440 ; N sterling ; B -16 -52 506 610 ;
+C 164 ; WX 60 ; N fraction ; B -181 -16 320 610 ;
+C 165 ; WX 440 ; N yen ; B -1 -168 613 647 ;
+C 166 ; WX 440 ; N florin ; B -64 -314 582 610 ;
+C 167 ; WX 420 ; N section ; B 53 -215 514 610 ;
+C 168 ; WX 440 ; N currency ; B 50 85 474 509 ;
+C 169 ; WX 160 ; N quotesingle ; B 145 343 215 610 ;
+C 170 ; WX 340 ; N quotedblleft ; B 169 343 464 610 ;
+C 171 ; WX 340 ; N guillemotleft ; B 98 24 356 414 ;
+C 172 ; WX 240 ; N guilsinglleft ; B 98 24 258 414 ;
+C 173 ; WX 260 ; N guilsinglright ; B 106 24 266 414 ;
+C 174 ; WX 520 ; N fi ; B -124 -314 605 714 ;
+C 175 ; WX 520 ; N fl ; B -124 -314 670 714 ;
+C 177 ; WX 500 ; N endash ; B 51 199 565 239 ;
+C 178 ; WX 460 ; N dagger ; B 138 -37 568 610 ;
+C 179 ; WX 480 ; N daggerdbl ; B 138 -59 533 610 ;
+C 180 ; WX 220 ; N periodcentered ; B 139 208 241 310 ;
+C 182 ; WX 500 ; N paragraph ; B 105 -199 638 594 ;
+C 183 ; WX 600 ; N bullet ; B 228 149 524 445 ;
+C 184 ; WX 180 ; N quotesinglbase ; B 21 -121 191 146 ;
+C 185 ; WX 280 ; N quotedblbase ; B -14 -121 281 146 ;
+C 186 ; WX 360 ; N quotedblright ; B 158 343 453 610 ;
+C 187 ; WX 380 ; N guillemotright ; B 117 24 375 414 ;
+C 188 ; WX 1000 ; N ellipsis ; B 124 -14 916 128 ;
+C 189 ; WX 960 ; N perthousand ; B 112 -160 1005 700 ;
+C 191 ; WX 400 ; N questiondown ; B 82 -186 387 438 ;
+C 193 ; WX 220 ; N grave ; B 193 492 339 659 ;
+C 194 ; WX 300 ; N acute ; B 265 492 422 659 ;
+C 195 ; WX 340 ; N circumflex ; B 223 482 443 649 ;
+C 196 ; WX 440 ; N tilde ; B 243 543 522 619 ;
+C 197 ; WX 440 ; N macron ; B 222 544 465 578 ;
+C 198 ; WX 440 ; N breve ; B 253 522 501 631 ;
+C 199 ; WX 220 ; N dotaccent ; B 236 522 328 610 ;
+C 200 ; WX 360 ; N dieresis ; B 243 522 469 610 ;
+C 202 ; WX 300 ; N ring ; B 240 483 416 659 ;
+C 203 ; WX 300 ; N cedilla ; B 12 -191 184 6 ;
+C 205 ; WX 400 ; N hungarumlaut ; B 208 492 495 659 ;
+C 206 ; WX 280 ; N ogonek ; B 38 -191 233 6 ;
+C 207 ; WX 340 ; N caron ; B 254 492 474 659 ;
+C 208 ; WX 1000 ; N emdash ; B 51 199 1065 239 ;
+C 225 ; WX 740 ; N AE ; B -21 -16 799 594 ;
+C 227 ; WX 260 ; N ordfeminine ; B 111 338 386 610 ;
+C 232 ; WX 580 ; N Lslash ; B 49 -16 657 610 ;
+C 233 ; WX 660 ; N Oslash ; B 83 -78 751 672 ;
+C 234 ; WX 820 ; N OE ; B 63 -16 909 610 ;
+C 235 ; WX 260 ; N ordmasculine ; B 128 339 373 610 ;
+C 241 ; WX 540 ; N ae ; B 67 -14 624 468 ;
+C 245 ; WX 240 ; N dotlessi ; B 100 -14 306 438 ;
+C 248 ; WX 300 ; N lslash ; B 121 -14 515 714 ;
+C 249 ; WX 440 ; N oslash ; B 46 -64 540 488 ;
+C 250 ; WX 560 ; N oe ; B 78 -14 628 438 ;
+C 251 ; WX 420 ; N germandbls ; B -127 -314 542 714 ;
+C -1 ; WX 340 ; N ecircumflex ; B 87 -14 433 649 ;
+C -1 ; WX 340 ; N edieresis ; B 87 -14 449 610 ;
+C -1 ; WX 420 ; N aacute ; B 92 -15 492 659 ;
+C -1 ; WX 740 ; N registered ; B 137 -16 763 610 ;
+C -1 ; WX 240 ; N icircumflex ; B 100 -14 363 649 ;
+C -1 ; WX 460 ; N udieresis ; B 102 -14 528 610 ;
+C -1 ; WX 400 ; N ograve ; B 87 -14 449 659 ;
+C -1 ; WX 460 ; N uacute ; B 102 -14 528 659 ;
+C -1 ; WX 460 ; N ucircumflex ; B 102 -14 528 649 ;
+C -1 ; WX 620 ; N Aacute ; B 13 -16 702 821 ;
+C -1 ; WX 240 ; N igrave ; B 100 -14 306 659 ;
+C -1 ; WX 380 ; N Icircumflex ; B 99 0 504 821 ;
+C -1 ; WX 340 ; N ccedilla ; B 62 -191 406 438 ;
+C -1 ; WX 420 ; N adieresis ; B 92 -15 485 610 ;
+C -1 ; WX 620 ; N Ecircumflex ; B 91 -12 709 821 ;
+C -1 ; WX 320 ; N scaron ; B 46 -14 464 659 ;
+C -1 ; WX 440 ; N thorn ; B -38 -314 505 714 ;
+C -1 ; WX 1000 ; N trademark ; B 127 187 1046 594 ;
+C -1 ; WX 340 ; N egrave ; B 87 -14 403 659 ;
+C -1 ; WX 264 ; N threesuperior ; B 59 234 348 610 ;
+C -1 ; WX 440 ; N zcaron ; B 26 -14 514 659 ;
+C -1 ; WX 420 ; N atilde ; B 92 -15 522 619 ;
+C -1 ; WX 420 ; N aring ; B 92 -15 485 659 ;
+C -1 ; WX 400 ; N ocircumflex ; B 87 -14 453 649 ;
+C -1 ; WX 620 ; N Edieresis ; B 91 -12 709 762 ;
+C -1 ; WX 660 ; N threequarters ; B 39 -16 706 610 ;
+C -1 ; WX 400 ; N ydieresis ; B -24 -314 483 610 ;
+C -1 ; WX 400 ; N yacute ; B -24 -314 483 659 ;
+C -1 ; WX 240 ; N iacute ; B 100 -14 392 659 ;
+C -1 ; WX 620 ; N Acircumflex ; B 13 -16 697 821 ;
+C -1 ; WX 740 ; N Uacute ; B 126 -16 792 821 ;
+C -1 ; WX 340 ; N eacute ; B 87 -14 462 659 ;
+C -1 ; WX 600 ; N Ograve ; B 94 -16 660 821 ;
+C -1 ; WX 420 ; N agrave ; B 92 -15 485 659 ;
+C -1 ; WX 740 ; N Udieresis ; B 126 -16 792 762 ;
+C -1 ; WX 420 ; N acircumflex ; B 92 -15 485 649 ;
+C -1 ; WX 380 ; N Igrave ; B 99 0 504 821 ;
+C -1 ; WX 264 ; N twosuperior ; B 72 234 354 610 ;
+C -1 ; WX 740 ; N Ugrave ; B 126 -16 792 821 ;
+C -1 ; WX 660 ; N onequarter ; B 56 -16 702 610 ;
+C -1 ; WX 740 ; N Ucircumflex ; B 126 -16 792 821 ;
+C -1 ; WX 460 ; N Scaron ; B 45 -81 594 831 ;
+C -1 ; WX 380 ; N Idieresis ; B 99 0 519 762 ;
+C -1 ; WX 240 ; N idieresis ; B 100 -14 369 610 ;
+C -1 ; WX 620 ; N Egrave ; B 91 -12 709 821 ;
+C -1 ; WX 600 ; N Oacute ; B 94 -16 660 821 ;
+C -1 ; WX 520 ; N divide ; B 117 -14 543 440 ;
+C -1 ; WX 620 ; N Atilde ; B 13 -16 702 771 ;
+C -1 ; WX 620 ; N Aring ; B 13 -16 697 831 ;
+C -1 ; WX 600 ; N Odieresis ; B 94 -16 660 762 ;
+C -1 ; WX 620 ; N Adieresis ; B 13 -16 709 762 ;
+C -1 ; WX 700 ; N Ntilde ; B 85 -168 915 761 ;
+C -1 ; WX 620 ; N Zcaron ; B 42 -19 669 831 ;
+C -1 ; WX 540 ; N Thorn ; B 52 0 647 623 ;
+C -1 ; WX 380 ; N Iacute ; B 99 0 532 821 ;
+C -1 ; WX 520 ; N plusminus ; B 117 0 543 436 ;
+C -1 ; WX 520 ; N multiply ; B 133 16 527 410 ;
+C -1 ; WX 620 ; N Eacute ; B 91 -12 709 821 ;
+C -1 ; WX 560 ; N Ydieresis ; B 41 -168 774 762 ;
+C -1 ; WX 264 ; N onesuperior ; B 83 244 311 610 ;
+C -1 ; WX 460 ; N ugrave ; B 102 -14 528 659 ;
+C -1 ; WX 520 ; N logicalnot ; B 117 86 543 340 ;
+C -1 ; WX 460 ; N ntilde ; B 101 -14 544 619 ;
+C -1 ; WX 600 ; N Otilde ; B 94 -16 660 761 ;
+C -1 ; WX 400 ; N otilde ; B 87 -14 502 619 ;
+C -1 ; WX 520 ; N Ccedilla ; B 93 -191 631 610 ;
+C -1 ; WX 620 ; N Agrave ; B 13 -16 697 821 ;
+C -1 ; WX 660 ; N onehalf ; B 56 -16 702 610 ;
+C -1 ; WX 700 ; N Eth ; B 86 -6 768 640 ;
+C -1 ; WX 400 ; N degree ; B 171 324 457 610 ;
+C -1 ; WX 560 ; N Yacute ; B 41 -168 774 821 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 94 -16 660 821 ;
+C -1 ; WX 400 ; N oacute ; B 87 -14 482 659 ;
+C -1 ; WX 460 ; N mu ; B 7 -314 523 438 ;
+C -1 ; WX 520 ; N minus ; B 117 184 543 242 ;
+C -1 ; WX 400 ; N eth ; B 87 -14 522 714 ;
+C -1 ; WX 400 ; N odieresis ; B 87 -14 479 610 ;
+C -1 ; WX 740 ; N copyright ; B 137 -16 763 610 ;
+C -1 ; WX 520 ; N brokenbar ; B 320 -16 378 714 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 131
+
+KPX A quoteright -40
+KPX A quotedblright -40
+KPX A U -10
+KPX A T 10
+KPX A Q 10
+KPX A O 10
+KPX A G -30
+KPX A C 20
+
+KPX D period -30
+KPX D comma -20
+KPX D Y 10
+KPX D A -10
+
+KPX F period -40
+KPX F i 10
+KPX F comma -30
+
+KPX G period -20
+KPX G comma -10
+
+KPX J period -20
+KPX J comma -10
+
+KPX K u -20
+KPX K o -20
+KPX K e -20
+
+KPX L y -10
+KPX L quoteright -25
+KPX L quotedblright -25
+KPX L W -10
+KPX L V -20
+
+KPX O period -20
+KPX O comma -10
+KPX O Y 10
+KPX O T 20
+KPX O A -20
+
+KPX P period -50
+KPX P o -10
+KPX P e -10
+KPX P comma -40
+KPX P a -20
+KPX P A -10
+
+KPX Q U -10
+
+KPX R Y 10
+KPX R W 10
+KPX R T 20
+
+KPX T o -20
+KPX T i 20
+KPX T hyphen -20
+KPX T h 20
+KPX T e -20
+KPX T a -20
+KPX T O 30
+KPX T A 10
+
+KPX V period -100
+KPX V o -20
+KPX V e -20
+KPX V comma -90
+KPX V a -20
+KPX V O 10
+KPX V G -20
+
+KPX W period -50
+KPX W o -20
+KPX W i 10
+KPX W h 10
+KPX W e -20
+KPX W comma -40
+KPX W a -20
+KPX W O 10
+
+KPX Y u -20
+KPX Y period -50
+KPX Y o -50
+KPX Y i 10
+KPX Y e -40
+KPX Y comma -40
+KPX Y a -60
+
+KPX b period -30
+KPX b l -20
+KPX b comma -20
+KPX b b -20
+
+KPX c k -10
+
+KPX comma quoteright -70
+KPX comma quotedblright -70
+
+KPX d w -20
+KPX d v -10
+KPX d d -40
+
+KPX e y 10
+
+KPX f quoteright 30
+KPX f quotedblright 30
+KPX f period -50
+KPX f f -50
+KPX f e -10
+KPX f comma -40
+KPX f a -20
+
+KPX g y 10
+KPX g period -30
+KPX g i 10
+KPX g e 10
+KPX g comma -20
+KPX g a 10
+
+KPX k y 10
+KPX k o -10
+KPX k e -20
+
+KPX m y 10
+KPX m u 10
+
+KPX n y 20
+
+KPX o period -30
+KPX o comma -20
+
+KPX p period -30
+KPX p p -10
+KPX p comma -20
+
+KPX period quoteright -80
+KPX period quotedblright -80
+
+KPX quotedblleft quoteleft 20
+KPX quotedblleft A 10
+
+KPX quoteleft quoteleft -115
+KPX quoteleft A 10
+
+KPX quoteright v 30
+KPX quoteright t 20
+KPX quoteright s -25
+KPX quoteright r 30
+KPX quoteright quoteright -115
+KPX quoteright quotedblright 20
+KPX quoteright l 20
+
+KPX r period -50
+KPX r i 10
+KPX r comma -40
+
+KPX s period -20
+KPX s comma -10
+
+KPX v period -30
+KPX v comma -20
+
+KPX w period -30
+KPX w o 10
+KPX w h 20
+KPX w comma -20
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 280 162 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 240 172 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 240 152 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 250 162 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 260 172 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 180 152 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 230 162 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 180 172 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 170 152 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 220 162 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 110 162 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 60 172 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 50 152 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 100 162 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 210 142 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 160 162 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 130 172 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 120 152 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 150 162 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 90 142 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 120 172 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 310 162 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 260 172 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 260 152 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 270 162 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 220 162 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 170 152 ;
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 130 172 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 70 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 20 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 10 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 80 0 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 60 0 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 40 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex -10 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis -20 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 30 0 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -30 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -80 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -100 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -40 0 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 10 0 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 60 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 10 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 10 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 60 0 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde -20 0 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron -10 0 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 70 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 20 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 50 0 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 60 0 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 40 0 ;
+EndComposites
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/afm/ZapfDingbats.afm b/tlt3.0/library/afm/ZapfDingbats.afm
new file mode 100644
index 0000000..24fd05e
--- /dev/null
+++ b/tlt3.0/library/afm/ZapfDingbats.afm
@@ -0,0 +1,223 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1985, 1987, 1988, 1989 Adobe Systems Incorporated.  All rights reserved.
+Comment Creation Date: Fri Dec  1 12:57:42 1989
+Comment UniqueID 26200
+Comment VMusage 39281 49041
+FontName ZapfDingbats
+FullName ITC Zapf Dingbats
+FamilyName ITC Zapf Dingbats
+Weight Medium
+ItalicAngle 0
+IsFixedPitch false
+FontBBox -1 -143 981 820
+UnderlinePosition -98
+UnderlineThickness 54
+Version 001.004
+Notice Copyright (c) 1985, 1987, 1988, 1989 Adobe Systems Incorporated.  All rights reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation.
+EncodingScheme FontSpecific
+StartCharMetrics 202
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ;
+C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ;
+C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ;
+C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ;
+C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ;
+C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ;
+C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ;
+C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ;
+C 41 ; WX 690 ; N a117 ; B 35 138 655 553 ;
+C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ;
+C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ;
+C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ;
+C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ;
+C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ;
+C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ;
+C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ;
+C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ;
+C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ;
+C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ;
+C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ;
+C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ;
+C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ;
+C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ;
+C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ;
+C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ;
+C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ;
+C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ;
+C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ;
+C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ;
+C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ;
+C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ;
+C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ;
+C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ;
+C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ;
+C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ;
+C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ;
+C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ;
+C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ;
+C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ;
+C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ;
+C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ;
+C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ;
+C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ;
+C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ;
+C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ;
+C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ;
+C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ;
+C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ;
+C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ;
+C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ;
+C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ;
+C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ;
+C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ;
+C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ;
+C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ;
+C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ;
+C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ;
+C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ;
+C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ;
+C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ;
+C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ;
+C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ;
+C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ;
+C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ;
+C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ;
+C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ;
+C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ;
+C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ;
+C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ;
+C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ;
+C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ;
+C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ;
+C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ;
+C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ;
+C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ;
+C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ;
+C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ;
+C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ;
+C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ;
+C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ;
+C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ;
+C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ;
+C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ;
+C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ;
+C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ;
+C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ;
+C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ;
+C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ;
+C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ;
+C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ;
+C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ;
+C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ;
+C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ;
+C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ;
+C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ;
+C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ;
+C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ;
+C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ;
+C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ;
+C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ;
+C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ;
+C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ;
+C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ;
+C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ;
+C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ;
+C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ;
+C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ;
+C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ;
+C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ;
+C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ;
+C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ;
+C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ;
+C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ;
+C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ;
+C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ;
+C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ;
+C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ;
+C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ;
+C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ;
+C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ;
+C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ;
+C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ;
+C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ;
+C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ;
+C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ;
+C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ;
+C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ;
+C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ;
+C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ;
+C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ;
+C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ;
+C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ;
+C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ;
+C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ;
+C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ;
+C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ;
+C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ;
+C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ;
+C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ;
+C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ;
+C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ;
+C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ;
+C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ;
+C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ;
+C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ;
+C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ;
+C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ;
+C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ;
+C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ;
+C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ;
+C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ;
+C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ;
+C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ;
+C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ;
+C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ;
+C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ;
+C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ;
+C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ;
+C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ;
+C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ;
+C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ;
+C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ;
+C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ;
+C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ;
+C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ;
+C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ;
+C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ;
+C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ;
+C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ;
+C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ;
+C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ;
+C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ;
+C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ;
+C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ;
+C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ;
+C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ;
+C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ;
+C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ;
+C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ;
+C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ;
+C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ;
+C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ;
+C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ;
+C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ;
+C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ;
+C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ;
+C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ;
+C -1 ; WX 410 ; N a86 ; B 35 0 375 692 ;
+C -1 ; WX 509 ; N a85 ; B 35 0 475 692 ;
+C -1 ; WX 334 ; N a95 ; B 35 0 299 692 ;
+C -1 ; WX 509 ; N a205 ; B 35 0 475 692 ;
+C -1 ; WX 390 ; N a89 ; B 35 -14 356 705 ;
+C -1 ; WX 234 ; N a87 ; B 35 -14 199 705 ;
+C -1 ; WX 276 ; N a91 ; B 35 0 242 692 ;
+C -1 ; WX 390 ; N a90 ; B 35 -14 355 705 ;
+C -1 ; WX 410 ; N a206 ; B 35 0 375 692 ;
+C -1 ; WX 317 ; N a94 ; B 35 0 283 692 ;
+C -1 ; WX 317 ; N a93 ; B 35 0 283 692 ;
+C -1 ; WX 276 ; N a92 ; B 35 0 242 692 ;
+C -1 ; WX 334 ; N a96 ; B 35 0 299 692 ;
+C -1 ; WX 234 ; N a88 ; B 35 -14 199 705 ;
+EndCharMetrics
+EndFontMetrics
+
\ No newline at end of file
diff --git a/tlt3.0/library/bltGraph.pro b/tlt3.0/library/bltGraph.pro
new file mode 100644
index 0000000..813d92a
--- /dev/null
+++ b/tlt3.0/library/bltGraph.pro
@@ -0,0 +1,472 @@
+
+%%BeginProlog
+%
+% PostScript prolog file of the BLT graph widget.
+%
+% Copyright 1989-1992 Regents of the University of California.
+% Permission to use, copy, modify, and distribute this
+% software and its documentation for any purpose and without
+% fee is hereby granted, provided that the above copyright
+% notice appear in all copies.  The University of California
+% makes no representations about the suitability of this
+% software for any purpose.  It is provided "as is" without
+% express or implied warranty.
+%
+% Copyright 1991-1997 Bell Labs Innovations for Lucent Technologies.
+%
+% Permission to use, copy, modify, and distribute this software and its
+% documentation for any purpose and without fee is hereby granted, provided
+% that the above copyright notice appear in all copies and that both that the
+% copyright notice and warranty disclaimer appear in supporting documentation,
+% and that the names of Lucent Technologies any of their entities not be used
+% in advertising or publicity pertaining to distribution of the software
+% without specific, written prior permission.
+%
+% Lucent Technologies disclaims all warranties with regard to this software,
+% including all implied warranties of merchantability and fitness.  In no event
+% shall Lucent Technologies be liable for any special, indirect or
+% consequential damages or any damages whatsoever resulting from loss of use,
+% data or profits, whether in an action of contract, negligence or other
+% tortuous action, arising out of or in connection with the use or performance
+% of this software.
+%
+
+200 dict begin
+
+/BaseRatio 1.3467736870885982 def	% Ratio triangle base / symbol size
+/BgColorProc 0 def			% Background color routine (symbols)
+/DrawSymbolProc 0 def			% Routine to draw symbol outline/fill
+/StippleProc 0 def			% Stipple routine (bar segments)
+/DashesProc 0 def			% Dashes routine (line segments)
+  
+% Define the array ISOLatin1Encoding (which specifies how characters are 
+% encoded for ISO-8859-1 fonts), if it isn't already present (Postscript 
+% level 2 is supposed to define it, but level 1 doesn't). 
+ 
+systemdict /ISOLatin1Encoding known not { 
+  /ISOLatin1Encoding [ 
+    /space /space /space /space /space /space /space /space 
+    /space /space /space /space /space /space /space /space 
+    /space /space /space /space /space /space /space /space 
+    /space /space /space /space /space /space /space /space 
+    /space /exclam /quotedbl /numbersign /dollar /percent /ampersand 
+    /quoteright 
+    /parenleft /parenright /asterisk /plus /comma /minus /period /slash 
+    /zero /one /two /three /four /five /six /seven 
+    /eight /nine /colon /semicolon /less /equal /greater /question 
+    /at /A /B /C /D /E /F /G 
+    /H /I /J /K /L /M /N /O 
+    /P /Q /R /S /T /U /V /W 
+    /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore 
+    /quoteleft /a /b /c /d /e /f /g 
+    /h /i /j /k /l /m /n /o 
+    /p /q /r /s /t /u /v /w 
+    /x /y /z /braceleft /bar /braceright /asciitilde /space 
+    /space /space /space /space /space /space /space /space 
+    /space /space /space /space /space /space /space /space 
+    /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent 
+    /dieresis /space /ring /cedilla /space /hungarumlaut /ogonek /caron 
+    /space /exclamdown /cent /sterling /currency /yen /brokenbar /section 
+    /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen 
+    /registered /macron 
+    /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph 
+    /periodcentered 
+    /cedillar /onesuperior /ordmasculine /guillemotright /onequarter 
+    /onehalf /threequarters /questiondown 
+    /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla 
+    /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex 
+    /Idieresis 
+    /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply 
+    /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn 
+    /germandbls 
+    /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla 
+    /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex 
+    /idieresis 
+    /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide 
+    /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn 
+    /ydieresis 
+  ] def 
+} if 
+
+% font ISOEncode font 
+% This procedure changes the encoding of a font from the default 
+% Postscript encoding to ISOLatin1.  It is typically invoked just 
+% before invoking "setfont".  The body of this procedure comes from 
+% Section 5.6.1 of the Postscript book. 
+
+/ISOEncode { 
+  dup length dict
+  begin 
+    {1 index /FID ne {def} {pop pop} ifelse} forall 
+    /Encoding ISOLatin1Encoding def 
+    currentdict 
+  end 
+
+  % I'm not sure why it's necessary to use "definefont" on this new 
+  % font, but it seems to be important; just use the name "Temporary" 
+  % for the font. 
+
+  /Temporary exch definefont 
+} bind def 
+
+/Stroke {
+  gsave
+    stroke
+  grestore
+} def
+
+/Fill {
+  gsave
+    fill
+  grestore
+} def
+
+/SetFont { 	
+  % Stack: pointSize fontName
+  findfont exch scalefont ISOEncode setfont
+} def
+
+/Box {
+  % Stack: x y width height
+  newpath
+    exch 4 2 roll moveto
+    dup 0 rlineto
+    exch 0 exch rlineto
+    neg 0 rlineto
+  closepath
+} def
+
+% The next two definitions are taken from "$tk_library/prolog.ps"
+
+% desiredSize EvenPixels closestSize
+%
+% The procedure below is used for stippling.  Given the optimal size
+% of a dot in a stipple pattern in the current user coordinate system,
+% compute the closest size that is an exact multiple of the device's
+% pixel size.  This allows stipple patterns to be displayed without
+% aliasing effects.
+
+/EvenPixels {
+  % Compute exact number of device pixels per stipple dot.
+  dup 0 matrix currentmatrix dtransform
+  dup mul exch dup mul add sqrt
+
+  % Round to an integer, make sure the number is at least 1, and compute
+  % user coord distance corresponding to this.
+  dup round dup 1 lt {pop 1} if
+  exch div mul
+} bind def
+
+% width height string filled StippleFill --
+%
+% Given a path and other graphics information already set up, this
+% procedure will fill the current path in a stippled fashion.  "String"
+% contains a proper image description of the stipple pattern and
+% "width" and "height" give its dimensions.  If "filled" is true then
+% it means that the area to be stippled is gotten by filling the
+% current path (e.g. the interior of a polygon); if it's false, the
+% area is gotten by stroking the current path (e.g. a wide line).
+% Each stipple dot is assumed to be about one unit across in the
+% current user coordinate system.
+
+% width height string StippleFill --
+%
+% Given a path already set up and a clipping region generated from
+% it, this procedure will fill the clipping region with a stipple
+% pattern.  "String" contains a proper image description of the
+% stipple pattern and "width" and "height" give its dimensions.  Each
+% stipple dot is assumed to be about one unit across in the current
+% user coordinate system.  This procedure trashes the graphics state.
+
+/StippleFill {
+    % The following code is needed to work around a NeWSprint bug.
+
+    /tmpstip 1 index def
+
+    % Change the scaling so that one user unit in user coordinates
+    % corresponds to the size of one stipple dot.
+    1 EvenPixels dup scale
+
+    % Compute the bounding box occupied by the path (which is now
+    % the clipping region), and round the lower coordinates down
+    % to the nearest starting point for the stipple pattern.  Be
+    % careful about negative numbers, since the rounding works
+    % differently on them.
+
+    pathbbox
+    4 2 roll
+    5 index div dup 0 lt {1 sub} if cvi 5 index mul 4 1 roll
+    6 index div dup 0 lt {1 sub} if cvi 6 index mul 3 2 roll
+
+    % Stack now: width height string y1 y2 x1 x2
+    % Below is a doubly-nested for loop to iterate across this area
+    % in units of the stipple pattern size, going up columns then
+    % across rows, blasting out a stipple-pattern-sized rectangle at
+    % each position
+
+    6 index exch {
+	2 index 5 index 3 index {
+	    % Stack now: width height string y1 y2 x y
+
+	    gsave
+	    1 index exch translate
+	    5 index 5 index true matrix tmpstip imagemask
+	    grestore
+	} for
+	pop
+    } for
+    pop pop pop pop pop
+} bind def
+
+
+/LS {	% Stack: x1 y1 x2 y2
+  newpath 
+    4 2 roll moveto 
+    lineto 
+  closepath
+  stroke
+} def
+
+/EndText {
+  %Stack :
+  grestore
+} def
+
+/BeginText {
+  %Stack :  w h theta centerX centerY
+  gsave
+    % Translate the origin to the center of bounding box and rotate
+    translate neg rotate
+    % Translate back to the origin of the text region
+    -0.5 mul exch -0.5 mul exch translate
+} def
+
+/DrawAdjText {
+  %Stack : str strWidth x y
+  moveto				% Go to the text position
+  exch dup dup 4 2 roll
+
+  % Adjust character widths to get desired overall string width
+  % adjust X = (desired width - real width)/#chars
+
+  stringwidth pop sub exch
+  length div
+  0 3 -1 roll
+
+  % Flip back the scale so that the string is not drawn in reverse
+
+  gsave
+    1 -1 scale
+    ashow
+  grestore
+} def
+
+/DrawBitmap {
+  % Stack: ?bgColorProc? boolean centerX centerY width height theta imageStr
+  gsave
+    6 -2 roll translate			% Translate to center of bounding box
+    4 1 roll neg rotate			% Rotate by theta
+    
+    % Find upperleft corner of bounding box
+    
+    2 copy -.5 mul exch -.5 mul exch translate
+    2 copy scale			% Make pixel unit scale
+    newpath
+      0 0 moveto 
+      0 1 lineto 
+      1 1 lineto 
+      1 0 lineto
+    closepath
+    
+    % Fill rectangle with background color
+    
+    4 -1 roll { 
+      gsave 
+	4 -1 roll exec fill 
+      grestore 
+    } if
+    
+    % Paint the image string into the unit rectangle
+    
+    2 copy true 3 -1 roll 0 0 5 -1 roll 0 0 6 array astore 5 -1 roll
+    imagemask
+  grestore
+} def
+
+% Symbols:
+
+% Skinny-cross
+/Sc {
+  % Stack: x y symbolSize
+  gsave
+    3 -2 roll translate 45 rotate
+    0 0 3 -1 roll Sp
+  grestore
+} def
+
+% Skinny-plus
+/Sp {
+  % Stack: x y symbolSize
+  gsave
+    3 -2 roll translate
+    2 idiv
+    dup 2 copy
+    newpath 
+      neg 0 
+      moveto 0 
+      lineto
+    DrawSymbolProc
+    newpath 
+      neg 0 
+      exch moveto 0 
+      exch lineto
+    DrawSymbolProc
+  grestore
+} def
+
+% Cross
+/Cr {
+  % Stack: x y symbolSize
+  gsave
+    3 -2 roll translate 45 rotate
+    0 0 3 -1 roll Pl
+  grestore
+} def
+
+% Plus
+/Pl {
+  % Stack: x y symbolSize
+  gsave
+    3 -2 roll translate
+    dup 2 idiv
+    exch 6 idiv
+
+    %
+    %          2   3		The plus/cross symbol is a
+    %				closed polygon of 12 points.
+    %      0   1   4    5	The diagram to the left
+    %           x,y		represents the positions of
+    %     11  10   7    6	the points which are computed
+    %				below.
+    %          9   8
+    %
+
+    newpath
+      2 copy exch neg exch neg moveto 
+      dup neg dup lineto
+      2 copy neg exch neg lineto
+      2 copy exch neg lineto
+      dup dup neg lineto 
+      2 copy neg lineto 2 copy lineto
+      dup dup lineto 
+      2 copy exch lineto 
+      2 copy neg exch lineto
+      dup dup neg exch lineto 
+      exch neg exch lineto
+    closepath
+    DrawSymbolProc
+  grestore
+} def
+
+% Circle
+/Ci {
+  % Stack: x y symbolSize
+  gsave
+    3 copy pop moveto 
+    newpath
+      2 div 0 360 arc
+    closepath 
+    DrawSymbolProc
+  grestore
+} def
+
+% Square
+/Sq {
+  % Stack: x y symbolSize
+  gsave
+    dup dup 2 div dup
+    6 -1 roll exch sub exch
+    5 -1 roll exch sub 4 -2 roll Box
+    DrawSymbolProc
+  grestore
+} def
+
+% Line
+/Li {
+  % Stack: x y symbolSize
+  gsave
+    3 1 roll exch 3 -1 roll 2 div 3 copy
+    newpath
+      sub exch moveto 
+      add exch lineto
+    closepath
+    stroke
+  grestore
+} def
+
+% Diamond
+/Di {
+  % Stack: x y symbolSize
+  gsave
+    3 1 roll translate 45 rotate 0 0 3 -1 roll Sq
+  grestore
+} def
+    
+% Triangle
+/Tr {
+  % Stack: x y symbolSize
+  gsave
+    3 -2 roll translate
+    BaseRatio mul 0.5 mul		% Calculate 1/2 base
+    dup 0 exch 30 cos mul		% h1 = height above center point
+    neg					% b2 0 -h1
+    newpath 
+      moveto				% point 1;  b2
+      dup 30 sin 30 cos div mul		% h2 = height below center point
+      2 copy lineto			% point 2;  b2 h2
+      exch neg exch lineto		% 
+    closepath
+    DrawSymbolProc
+  grestore
+} def
+
+% Arrow
+/Ar {
+  % Stack: x y symbolSize
+  gsave
+    3 -2 roll translate
+    BaseRatio mul 0.5 mul		% Calculate 1/2 base
+    dup 0 exch 30 cos mul		% h1 = height above center point
+					% b2 0 h1
+    newpath moveto			% point 1;  b2
+    dup 30 sin 30 cos div mul		% h2 = height below center point
+    neg					% -h2 b2
+    2 copy lineto			% point 2;  b2 h2
+    exch neg exch lineto		% 
+    closepath
+    DrawSymbolProc
+  grestore
+} def
+
+% Bitmap
+/Bm {
+  % Stack: x y symbolSize
+  gsave
+    3 1 roll translate pop DrawSymbolProc
+  grestore
+} def
+
+%%EndProlog
+
+%%BeginSetup
+gsave					% Save the graphics state
+
+% Default line/text style parameters
+
+1 setlinewidth				% width
+1 setlinejoin				% join
+0 setlinecap				% cap
+[] 0 setdash				% dashes
+
+0 0 0 setrgbcolor			% color
+
diff --git a/tlt3.0/library/graph.tcl b/tlt3.0/library/graph.tcl
new file mode 100644
index 0000000..16c0e14
--- /dev/null
+++ b/tlt3.0/library/graph.tcl
@@ -0,0 +1,840 @@
+
+namespace eval ::blt::legend {
+    variable _private 
+    array set _private {
+	afterId ""
+	scroll 0
+	space off
+	drag 0
+	x 0
+	y 0
+    }
+}
+
+namespace eval ::blt::ZoomStack {
+    variable _private
+    array set _private {
+	afterId ""
+	scroll 0
+	space off
+	drag 0
+	x 0
+	y 0
+    }
+}
+
+option add *zoomOutline.dashes		4	
+option add *zoomOutline.lineWidth	2
+option add *zoomOutline.xor		yes
+option add *zoomTitle.anchor		nw
+option add *zoomTitle.coords		"-Inf Inf"
+option add *zoomTitle.font		"Arial 14"
+option add *zoomTitle.foreground	yellow3
+option add *zoomTitle.shadow		yellow4
+
+# ----------------------------------------------------------------------
+#
+# Initialize --
+#
+#	Invoked by internally by Treeview_Init routine.  Initializes
+#	the default bindings for the treeview widget entries.  These
+#	are local to the widget, so they can't be set through the
+#	widget's class bind tags.
+#
+# ----------------------------------------------------------------------
+proc blt::LegendSelections { w } {
+    if 0 {
+    #
+    # Active entry bindings
+    #
+    $w legend bind all <Enter> { 
+	%W entry highlight current 
+    }
+    $w legend bind all <Leave> { 
+	%W entry highlight "" 
+    }
+    }
+
+    #
+    # ButtonPress-1
+    #
+    #	Performs the following operations:
+    #
+    #	1. Clears the previous selection.
+    #	2. Selects the current entry.
+    #	3. Sets the focus to this entry.
+    #	4. Scrolls the entry into view.
+    #	5. Sets the selection anchor to this entry, just in case
+    #	   this is "multiple" mode.
+    #
+    
+    $w legend bind all <ButtonPress-1> { 	
+	blt::legend::SetSelectionAnchor %W current
+	set blt::legend::_private(scroll) 1
+    }
+
+    #
+    # B1-Motion
+    #
+    #	For "multiple" mode only.  Saves the current location of the
+    #	pointer for auto-scrolling.  Resets the selection mark.  
+    #
+    $w legend bind all <B1-Motion> { 
+	set blt::legend::_private(x) %x
+	set blt::legend::_private(y) %y
+	set elem [%W legend get @%x,%y]
+	if { $elem != "" } {
+	    if { [%W legend cget -selectmode] == "multiple" } {
+		%W legend selection mark $elem
+	    } else {
+		blt::legend::SetSelectionAnchor %W $elem
+	    }
+	}
+    }
+
+    #
+    # ButtonRelease-1
+    #
+    #	For "multiple" mode only.  
+    #
+    $w legend bind all <ButtonRelease-1> { 
+	if { [%W legend cget -selectmode] == "multiple" } {
+	    %W legend selection anchor current
+	}
+	after cancel $blt::legend::_private(afterId)
+	set blt::legend::_private(scroll) 0
+    }
+
+    #
+    # Shift-ButtonPress-1
+    #
+    #	For "multiple" mode only.
+    #
+
+    $w legend bind all <Shift-ButtonPress-1> { 
+	if { [%W legend cget -selectmode] == "multiple" && 
+	     [%W legend selection present] } {
+	    if { [%W legend get anchor] == "" } {
+		%W legend selection anchor current
+	    }
+	    set elem [%W legend get anchor]
+	    %W legend selection clearall
+	    %W legend selection set $elem current
+	} else {
+	    blt::legend::SetSelectionAnchor %W current
+	}
+    }
+    $w legend bind all <Shift-Double-ButtonPress-1> {
+	# do nothing
+    }
+    $w legend bind all <Shift-B1-Motion> { 
+	# do nothing
+    }
+    $w legend bind all <Shift-ButtonRelease-1> { 
+	after cancel $blt::legend::_private(afterId)
+	set blt::legend::_private(scroll) 0
+    }
+
+    #
+    # Control-ButtonPress-1
+    #
+    #	For "multiple" mode only.  
+    #
+    $w legend bind all <Control-ButtonPress-1> { 
+	if { [%W legend cget -selectmode] == "multiple" } {
+	    set elem [%W legend get current]
+	    %W legend selection toggle $elem
+	    %W legend selection anchor $elem
+	} else {
+	    blt::legend::SetSelectionAnchor %W current
+	}
+    }
+    $w legend bind all <Control-Double-ButtonPress-1> {
+	# do nothing
+    }
+    $w legend bind all <Control-B1-Motion> { 
+	# do nothing
+    }
+    $w legend bind all <Control-ButtonRelease-1> { 
+	after cancel $blt::legend::_private(afterId)
+	set blt::legend::_private(scroll) 0
+    }
+
+    $w legend bind all <Control-Shift-ButtonPress-1> { 
+	if { [%W legend cget -selectmode] == "multiple" && 
+	     [%W legend selection present] } {
+	    if { [%W legend get anchor] == "" } {
+		%W selection anchor current
+	    }
+	    if { [%W legend selection includes anchor] } {
+		%W legend selection set anchor current
+	    } else {
+		%W legend selection clear anchor current
+		%W legend selection set current
+	    }
+	} else {
+	    blt::legend::SetSelectionAnchor %W current
+	}
+    }
+    $w legend bind all <Control-Shift-Double-ButtonPress-1> {
+	# do nothing
+    }
+    $w legend bind all <Control-Shift-B1-Motion> { 
+	# do nothing
+    }
+    $w legend bind all <KeyPress-Up> {
+	blt::legend::MoveFocus %W previous.row
+	if { $blt::legend::_private(space) } {
+	    %W legend selection toggle focus
+	}
+    }
+    $w legend bind all <KeyPress-Down> {
+	blt::legend::MoveFocus %W next.row
+	if { $blt::legend::_private(space) } {
+	    %W legend selection toggle focus
+	}
+    }
+    $w legend bind all <KeyPress-Left> {
+	blt::legend::MoveFocus %W previous.column
+	if { $blt::legend::_private(space) } {
+	    %W legend selection toggle focus
+	}
+    }
+    $w legend bind all <KeyPress-Right> {
+	blt::legend::MoveFocus %W next.column
+	if { $blt::legend::_private(space) } {
+	    %W legend selection toggle focus
+	}
+    }
+    $w legend bind all <KeyPress-space> {
+	if { [%W legend cget -selectmode] == "single" } {
+	    if { [%W legend selection includes focus] } {
+		%W legend selection clearall
+	    } else {
+		%W legend selection clearall
+		%W legend selection set focus
+	    }
+	} else {
+	    %W legend selection toggle focus
+	}
+	set blt::legend::_private(space) on
+    }
+
+    $w legend bind all <KeyRelease-space> { 
+	set blt::legend::_private(space) off
+    }
+    $w legend bind all <KeyPress-Return> {
+	blt::legend::MoveFocus %W focus
+	set blt::legend::_private(space) on
+    }
+    $w legend bind all <KeyRelease-Return> { 
+	set blt::legend::_private(space) off
+    }
+    $w legend bind all <KeyPress-Home> {
+	blt::legend::MoveFocus %W first
+    }
+    $w legend bind all <KeyPress-End> {
+	blt::tv::MoveFocus %W last
+    }
+}
+
+proc blt::legend::SetSelectionAnchor { w tagOrId } {
+    set elem [$w legend get $tagOrId]
+    # If the anchor hasn't changed, don't do anything
+    if { $elem != [$w legend get anchor] } {
+	$w legend selection clearall
+	$w legend focus $elem
+	$w legend selection set $elem
+	$w legend selection anchor $elem
+    }
+}
+
+# ----------------------------------------------------------------------
+#
+# MoveFocus --
+#
+#	Invoked by KeyPress bindings.  Moves the active selection to
+#	the entry <where>, which is an index such as "up", "down",
+#	"prevsibling", "nextsibling", etc.
+#
+# ----------------------------------------------------------------------
+proc blt::legend::MoveFocus { w elem } {
+    catch {$w legend focus $elem} result
+    puts stderr "result=$result elem=$elem"
+    if { [$w legend cget -selectmode] == "single" } {
+        $w legend selection clearall
+        $w legend selection set focus
+	$w legend selection anchor focus
+    }
+}
+
+
+proc Blt_ActiveLegend { g } {
+    $g legend bind all <Enter> [list blt::ActivateLegend $g ]
+    $g legend bind all <Leave> [list blt::DeactivateLegend $g]
+    $g legend bind all <ButtonPress-1> [list blt::HighlightLegend $g]
+}
+
+proc Blt_Crosshairs { g } {
+    blt::Crosshairs $g 
+}
+
+proc Blt_ResetCrosshairs { g state } {
+    blt::Crosshairs $g "Any-Motion" $state
+}
+
+proc Blt_ZoomStack { g args } {
+    array set params {
+	-mode click
+    }
+    array set params $args
+    if { $params(-mode) == "click" } {
+	blt::ZoomStack::ClickClick $g
+    } else {
+	blt::ZoomStack::ClickRelease $g
+    }	
+}
+
+proc Blt_PrintKey { g } {
+    blt::PrintKey $g
+}
+
+proc Blt_ClosestPoint { g } {
+    blt::ClosestPoint $g
+}
+
+#
+# The following procedures that reside in the "blt" namespace are
+# supposed to be private.
+#
+
+proc blt::ActivateLegend { g } {
+    set elem [$g legend get current]
+    $g legend activate $elem
+}
+proc blt::DeactivateLegend { g } {
+    set elem [$g legend get current]
+    $g legend deactivate $elem
+}
+
+proc blt::HighlightLegend { g } {
+    set elem [$g legend get current]
+    if { $elem != ""  } {
+      set relief [$g element cget $elem -legendrelief]
+      if { $relief == "flat" } {
+	$g element configure $elem -legendrelief raised
+	$g element activate $elem
+      } else {
+	$g element configure $elem -legendrelief flat
+	$g element deactivate $elem
+      }
+   }
+}
+
+proc blt::Crosshairs { g {event "Any-Motion"} {state "on"}} {
+    $g crosshairs $state
+    bind crosshairs-$g <$event>   {
+	%W crosshairs configure -position @%x,%y 
+    }
+    bind crosshairs-$g <Leave>   {
+	%W crosshairs off
+    }
+    bind crosshairs-$g <Enter>   {
+	%W crosshairs on
+    }
+    $g crosshairs configure -color red
+    if { $state == "on" } {
+	blt::AddBindTag $g crosshairs-$g
+    } elseif { $state == "off" } {
+	blt::RemoveBindTag $g crosshairs-$g
+    }
+}
+
+proc blt::PrintKey { g {event "Shift-ButtonRelease-3"} } {
+    bind print-$g <$event>  { Blt_PostScriptDialog %W }
+    blt::AddBindTag $g print-$g
+}
+
+proc blt::ClosestPoint { g {event "Control-ButtonPress-2"} } {
+    bind closest-point-$g <$event>  {
+	blt::FindElement %W %x %y
+    }
+    blt::AddBindTag $g closest-point-$g
+}
+
+proc blt::AddBindTag { widget tag } {
+    set oldTagList [bindtags $widget]
+    if { [lsearch $oldTagList $tag] < 0 } {
+	bindtags $widget [linsert $oldTagList 0  $tag]
+    }
+}
+
+proc blt::RemoveBindTag { widget tag } {
+    set oldTagList [bindtags $widget]
+    set index [lsearch $oldTagList $tag]
+    if { $index >= 0 } {
+	bindtags $widget [lreplace $oldTagList $index $index]
+    }
+}
+
+proc blt::FindElement { g x y } {
+    array set info [$g element closest $x $y -interpolate yes]
+    if { ![info exists info(name)] } {
+	beep
+	return
+    }
+    # --------------------------------------------------------------
+    # find(name)		- element Id
+    # find(index)		- index of closest point
+    # find(x) find(y)		- coordinates of closest point
+    #				  or closest point on line segment.
+    # find(dist)		- distance from sample coordinate
+    # --------------------------------------------------------------
+    set markerName "bltClosest_$info(name)"
+    catch { $g marker delete $markerName }
+    $g marker create text -coords { $info(x) $info(y) } \
+	-name $markerName \
+	-text "$info(name): $info(dist)\nindex $info(index)" \
+	-font "Arial 6" \
+	-anchor center -justify left \
+	-yoffset 0 -bg {} 
+
+    set coords [$g invtransform $x $y]
+    set nx [lindex $coords 0]
+    set ny [lindex $coords 1]
+
+    $g marker create line -coords "$nx $ny $info(x) $info(y)" \
+	-name line.$markerName 
+
+    blt::FlashPoint $g $info(name) $info(index) 10
+    blt::FlashPoint $g $info(name) [expr $info(index) + 1] 10
+}
+
+proc blt::FlashPoint { g name index count } {
+    if { $count & 1 } {
+        $g element deactivate $name 
+    } else {
+        $g element activate $name $index
+    }
+    incr count -1
+    if { $count > 0 } {
+	after 200 blt::FlashPoint $g $name $index $count
+	update
+    } else {
+	eval $g marker delete [$g marker names "bltClosest_*"]
+    }
+}
+
+
+proc blt::ZoomStack::Init { g } {
+    variable _private
+    set _private($g,interval) 100
+    set _private($g,afterId) 0
+    set _private($g,A,x) {}
+    set _private($g,A,y) {}
+    set _private($g,B,x) {}
+    set _private($g,B,y) {}
+    set _private($g,stack) {}
+    set _private($g,corner) A
+}
+
+proc blt::ZoomStack::ClickClick { g {start "ButtonPress-1"} {reset "ButtonPress-3"} } {
+    variable _private
+    
+    Init $g
+    
+    bind zoom-$g <Enter> "focus %W"
+    bind zoom-$g <KeyPress-Escape> { blt::ZoomStack::Reset %W }
+    bind zoom-$g <${start}> { blt::ZoomStack::SetPoint %W %x %y }
+    bind zoom-$g <${reset}> { 
+	if { [%W inside %x %y] } { 
+	    blt::ZoomStack::Reset %W 
+	}
+    }
+    blt::AddBindTag $g zoom-$g
+}
+
+proc blt::ZoomStack::ClickRelease { g } {
+    variable _private
+    
+    Init $g
+    bind zoom-$g <Enter> "focus %W"
+    bind zoom-$g <KeyPress-Escape> { blt::ZoomStack::Reset %W }
+    bind zoom-$g <ButtonPress-1> { blt::ZoomStack::DragStart %W %x %y }
+    bind zoom-$g <B1-Motion> { blt::ZoomStack::DragMotion %W %x %y }
+    bind zoom-$g <ButtonRelease-1> { blt::ZoomStack::DragFinish %W %x %y }
+    bind zoom-$g <ButtonPress-3> { 
+	if { [%W inside %x %y] } { 
+	    blt::ZoomStack::Reset %W 
+	}
+    }
+    blt::AddBindTag $g zoom-$g
+}
+
+proc blt::ZoomStack::GetCoords { g x y index } {
+    variable _private
+    if { [$g cget -invertxy] } {
+	set _private($g,$index,x) $y
+	set _private($g,$index,y) $x
+    } else {
+	set _private($g,$index,x) $x
+	set _private($g,$index,y) $y
+    }
+}
+
+proc blt::ZoomStack::MarkPoint { g index } {
+    variable _private
+
+    if { [llength [$g xaxis use]] > 0 } {
+	set x [$g xaxis invtransform $_private($g,$index,x)]
+    } else if { [llength [$g x2axis use]] > 0 } {
+	set x [$g x2axis invtransform $_private($g,$index,x)]
+    }
+    if { [llength [$g yaxis use]] > 0 } {
+	set y [$g yaxis invtransform $_private($g,$index,y)]
+    } else if { [llength [$g y2axis use]] > 0 } {
+	set y [$g y2axis invtransform $_private($g,$index,y)]
+    }
+    set marker "zoomText_$index"
+    set text [format "x=%.4g\ny=%.4g" $x $y] 
+
+    if [$g marker exists $marker] {
+     	$g marker configure $marker -coords { $x $y } -text $text 
+    } else {
+    	$g marker create text -coords { $x $y } -name $marker \
+   	    -font "mathmatica1 10" \
+	    -text $text -anchor center -bg {} -justify left
+    }
+}
+
+proc blt::ZoomStack::DestroyTitle { g } {
+    variable _private
+
+    if { $_private($g,corner) == "A" } {
+	catch { $g marker delete "zoomTitle" }
+    }
+}
+
+proc blt::ZoomStack::Pop { g } {
+    variable _private
+
+    set zoomStack $_private($g,stack)
+    if { [llength $zoomStack] > 0 } {
+	set cmd [lindex $zoomStack 0]
+	set _private($g,stack) [lrange $zoomStack 1 end]
+	eval $cmd
+	TitleLast $g
+	update
+	after 2000 [list blt::ZoomStack::DestroyTitle $g]
+    } else {
+	catch { $g marker delete "zoomTitle" }
+    }
+}
+
+# Push the old axis limits on the stack and set the new ones
+
+proc blt::ZoomStack::Push { g } {
+    variable _private
+
+    eval $g marker delete [$g marker names "zoom*"]
+    if { [info exists _private($g,afterId)] } {
+	after cancel $_private($g,afterId)
+    }
+    set x1 $_private($g,A,x)
+    set y1 $_private($g,A,y)
+    set x2 $_private($g,B,x)
+    set y2 $_private($g,B,y)
+
+    if { ($x1 == $x2) || ($y1 == $y2) } { 
+	# No delta, revert to start
+	return
+    }
+    set cmd {}
+    foreach axis [$g axis names] {
+	if { [$g axis cget $axis -hide] } {
+	    continue
+	}
+	set min [$g axis cget $axis -min] 
+	set max [$g axis cget $axis -max]
+	set logscale  [$g axis cget $axis -logscale]
+	# Save the current scale (log or linear) so that we can restore it.
+	# This is for the case where the user changes to logscale while
+	# zooming.  A previously pushed axis limit could be negative.  It
+	# seems better for popping the zoom stack to restore a previous view
+	# (not convert the ranges).
+	set c [list $g axis configure $axis]
+	lappend c -min $min -max $max -logscale $logscale
+	append cmd "$c\n"
+    }
+
+    # This effectively pushes the command to reset the graph to the current
+    # zoom level onto the stack.  This is useful if the new axis ranges are
+    # bad and we need to reset the zoom stack.
+    set _private($g,stack) [linsert $_private($g,stack) 0 $cmd]
+    foreach axis [$g axis names] {
+	if { [$g axis cget $axis -hide] } {
+	    continue;			# Don't set zoom on axes not displayed.
+	}
+	set type [$g axis type $axis]
+	if { $type  == "x" } {
+	    set min [$g axis invtransform $axis $x1]
+	    set max [$g axis invtransform $axis $x2]
+	} elseif { $type == "y" } {
+	    set min [$g axis invtransform $axis $y1]
+	    set max [$g axis invtransform $axis $y2]
+	} else {
+	    continue;			# Axis is not bound to any margin.
+	}
+	if { ![SetAxisRanges $g $axis $min $max] } {
+	    Pop $g
+	    bell
+	    return
+	}
+    }
+#    blt::busy hold $g 
+    update;				# This "update" redraws the graph
+#    blt::busy release $g
+}
+
+proc blt::ZoomStack::SetAxisRanges { g axis min max } {
+    if { $min > $max } { 
+	set tmp $max; set max $min; set min $tmp
+    }
+    if { [catch { $g axis configure $axis -min $min -max $max }] != 0 } {
+	return 0
+    }
+    return 1
+}
+
+#
+# This routine terminates either an existing zoom, or pops back to
+# the previous zoom level (if no zoom is in progress).
+#
+proc blt::ZoomStack::Reset { g } {
+    variable _private
+
+    if { ![info exists _private($g,corner)] } {
+	Init $g 
+    }
+    eval $g marker delete [$g marker names "zoom*"]
+
+    if { $_private($g,corner) == "A" } {
+	# Reset the whole axis
+	Pop $g
+    } else {
+	set _private($g,corner) A
+	blt::RemoveBindTag $g select-region-$g
+    }
+}
+
+proc blt::ZoomStack::TitleNext { g } {
+    variable _private
+
+    set level [expr [llength $_private($g,stack)] + 1]
+    if { [$g cget -invertxy] } {
+	set coords "Inf -Inf"
+    } else {
+	set coords "-Inf Inf"
+    }
+    $g marker create text -name "zoomTitle" -text "Zoom #$level" \
+	-coords $coords -bindtags "" -anchor nw
+}
+
+proc blt::ZoomStack::TitleLast { g } {
+    variable _private
+
+    set level [llength $_private($g,stack)]
+    if { $level > 0 } {
+     	$g marker create text -name "zoomTitle" -anchor nw \
+	    -text "Zoom #$level" 
+    }
+}
+
+
+proc blt::ZoomStack::SetPoint { g x y } {
+    variable _private
+    if { ![info exists _private($g,corner)] } {
+	Init $g
+    }
+    GetCoords $g $x $y $_private($g,corner)
+    bind select-region-$g <Motion> { 
+	blt::ZoomStack::GetCoords %W %x %y B
+	#blt::ZoomStack::MarkPoint $g B
+	blt::ZoomStack::Box %W
+    }
+    if { $_private($g,corner) == "A" } {
+	if { ![$g inside $x $y] } {
+	    return
+	}
+	# First corner selected, start watching motion events
+
+	#MarkPoint $g A
+	TitleNext $g 
+
+	blt::AddBindTag $g select-region-$g
+	set _private($g,corner) B
+    } else {
+	# Delete the modal binding
+	blt::RemoveBindTag $g select-region-$g
+	Push $g 
+	set _private($g,corner) A
+    }
+}
+
+proc blt::ZoomStack::DragStart { g x y } {
+    variable _private
+    if { ![info exists _private($g,corner)] } {
+	Init $g
+    }
+    GetCoords $g $x $y A
+    if { ![$g inside $x $y] } {
+	return
+    }
+    set _private(drag) 1
+    TitleNext $g 
+}
+
+proc blt::ZoomStack::DragMotion { g x y } {
+    variable _private 
+
+    if { $_private(drag) } {
+	GetCoords $g $x $y B
+	set dx [expr abs($_private($g,B,x) - $_private($g,A,x))]
+	set dy [expr abs($_private($g,B,y) - $_private($g,A,y))]
+	Box $g
+	if { $dy > 10 && $dx > 10 } {
+	    return 1
+	}	
+    }
+    return 0
+}
+
+proc blt::ZoomStack::DragFinish { g x y } {
+    variable _private 
+    if { [DragMotion $g $x $y] } {
+	Push $g 
+    } else {
+	eval $g marker delete [$g marker names "zoom*"]
+	if { [info exists _private($g,afterId)] } {
+	    after cancel $_private($g,afterId)
+	}
+    }
+    set _private(drag) 0
+}
+
+
+proc blt::ZoomStack::MarchingAnts { g offset } {
+    variable _private
+
+    incr offset
+    # wrap the counter after 2^16
+    set offset [expr $offset & 0xFFFF]
+    if { [$g marker exists zoomOutline] } {
+	$g marker configure zoomOutline -dashoffset $offset 
+	set interval $_private($g,interval)
+	set id [after $interval [list blt::ZoomStack::MarchingAnts $g $offset]]
+	set _private($g,afterId) $id
+    }
+}
+
+proc blt::ZoomStack::Box { g } {
+    variable _private
+
+    if { $_private($g,A,x) > $_private($g,B,x) } { 
+	set x1 [$g xaxis invtransform $_private($g,B,x)]
+	set y1 [$g yaxis invtransform $_private($g,B,y)]
+	set x2 [$g xaxis invtransform $_private($g,A,x)]
+	set y2 [$g yaxis invtransform $_private($g,A,y)]
+    } else {
+	set x1 [$g xaxis invtransform $_private($g,A,x)]
+	set y1 [$g yaxis invtransform $_private($g,A,y)]
+	set x2 [$g xaxis invtransform $_private($g,B,x)]
+	set y2 [$g yaxis invtransform $_private($g,B,y)]
+    }
+    set coords { $x1 $y1 $x2 $y1 $x2 $y2 $x1 $y2 $x1 $y1 }
+    if { [$g marker exists "zoomOutline"] } {
+	$g marker configure "zoomOutline" -coords $coords 
+    } else {
+	set X [lindex [$g xaxis use] 0]
+	set Y [lindex [$g yaxis use] 0]
+	$g marker create line -coords $coords -name "zoomOutline" \
+	    -mapx $X -mapy $Y
+	set interval $_private($g,interval)
+	set id [after $interval [list blt::ZoomStack::MarchingAnts $g 0]]
+	set _private($g,afterId) $id
+    }
+}
+
+
+proc Blt_PostScriptDialog { g } {
+    set top $g.top
+    toplevel $top
+
+    foreach var { center landscape maxpect preview decorations padx 
+	pady paperwidth paperheight width height colormode } {
+	global $g.$var
+	set $g.$var [$g postscript cget -$var]
+    }
+    set row 1
+    set col 0
+    label $top.title -text "PostScript Options"
+    blt::table $top $top.title -cspan 7
+    foreach bool { center landscape maxpect preview decorations } {
+	set w $top.$bool-label
+	label $w -text "-$bool" -font "courier 12"
+	blt::table $top $row,$col $w -anchor e -pady { 2 0 } -padx { 0 4 }
+	set w $top.$bool-yes
+	global $g.$bool
+	radiobutton $w -text "yes" -variable $g.$bool -value 1
+	blt::table $top $row,$col+1 $w -anchor w
+	set w $top.$bool-no
+	radiobutton $w -text "no" -variable $g.$bool -value 0
+	blt::table $top $row,$col+2 $w -anchor w
+	incr row
+    }
+    label $top.modes -text "-colormode" -font "courier 12"
+    blt::table $top $row,0 $top.modes -anchor e  -pady { 2 0 } -padx { 0 4 }
+    set col 1
+    foreach m { color greyscale } {
+	set w $top.$m
+	radiobutton $w -text $m -variable $g.colormode -value $m
+	blt::table $top $row,$col $w -anchor w
+	incr col
+    }
+    set row 1
+    frame $top.sep -width 2 -bd 1 -relief sunken
+    blt::table $top $row,3 $top.sep -fill y -rspan 6
+    set col 4
+    foreach value { padx pady paperwidth paperheight width height } {
+	set w $top.$value-label
+	label $w -text "-$value" -font "courier 12"
+	blt::table $top $row,$col $w -anchor e  -pady { 2 0 } -padx { 0 4 }
+	set w $top.$value-entry
+	global $g.$value
+	entry $w -textvariable $g.$value -width 8
+	blt::table $top $row,$col+1 $w -cspan 2 -anchor w -padx 8
+	incr row
+    }
+    blt::table configure $top c3 -width .125i
+    button $top.cancel -text "Cancel" -command "destroy $top"
+    blt::table $top $row,0 $top.cancel  -width 1i -pady 2 -cspan 3
+    button $top.reset -text "Reset" -command "destroy $top"
+    #blt::table $top $row,1 $top.reset  -width 1i
+    button $top.print -text "Print" -command "blt::ResetPostScript $g"
+    blt::table $top $row,4 $top.print  -width 1i -pady 2 -cspan 2
+}
+
+proc blt::ResetPostScript { g } {
+    foreach var { center landscape maxpect preview decorations padx 
+	pady paperwidth paperheight width height colormode } {
+	global $g.$var
+	set old [$g postscript cget -$var]
+	if { [catch {$g postscript configure -$var [set $g.$var]}] != 0 } {
+	    $g postscript configure -$var $old
+	    set $g.$var $old
+	}
+    }
+    $g postscript output "out.ps"
+    puts stdout "wrote file \"out.ps\"."
+    flush stdout
+}
diff --git a/tlt3.0/pkgIndex.tcl.in b/tlt3.0/pkgIndex.tcl.in
new file mode 100755
index 0000000..d7566b4
--- /dev/null
+++ b/tlt3.0/pkgIndex.tcl.in
@@ -0,0 +1,5 @@
+#
+# Tcl package index file
+#
+package ifneeded @PACKAGE_NAME@ @PACKAGE_VERSION@ \
+    [list load [file join $dir @PKG_LIB_FILE@] @PACKAGE_NAME@]
diff --git a/tlt3.0/tclconfig/ChangeLog b/tlt3.0/tclconfig/ChangeLog
new file mode 100644
index 0000000..ffda2bb
--- /dev/null
+++ b/tlt3.0/tclconfig/ChangeLog
@@ -0,0 +1,980 @@
+2013-07-04  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* unix/tcl.m4:  Bug [3324676]: AC_PROG_INSTALL incompat,
+	Bug [3606445]: Unneeded -DHAVE_NO_SEH=1 when not building on Windows
+
+2013-07-02  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* unix/tcl.m4:  Bug [32afa6e256]: dirent64 check is incorrect in tcl.m4
+	(thanks to Brian Griffin)
+
+2013-06-20  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* unix/tcl.m4:  Use X11/Xlib.h for checking where X11 can be found
+	in stead of X11/XIntrinsic.h. Suggested by Pietro Cerutti.
+
+2013-06-04  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* unix/tcl.m4: Eliminate NO_VIZ macro as current
+	zlib uses HAVE_HIDDEN in stead. One more last-moment
+	fix for FreeBSD by Pietro Cerutti
+
+2013-05-19  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* unix/tcl.m4: Fix for FreeBSD, and remove support for old
+	FreeBSD versions. Patch by Pietro Cerutti 
+
+2013-03-12  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* unix/tcl.m4: Patch by Andrew Shadura, providing better support for
+	* three architectures they have in Debian.
+
+2012-08-07  Stuart Cassoff  <stwo at users.sourceforge.net>
+
+	* tcl.m4: Added "-DNDEBUG" to CFLAGS_DEFAULT
+	when building with --disable-symbols.
+
+2012-08-07  Stuart Cassoff  <stwo at users.sourceforge.net>
+
+	* tcl.m4: [Bug 3555058]: Checkin [30736d63f0] broke
+	CFLAGS_DEFAULT, LDFLAGS_DEFAULT
+
+2012-08-07  Stuart Cassoff  <stwo at users.sourceforge.net>
+
+	* tcl.m4: [Bug 3511806]: Checkin [30736d63f0] broke CFLAGS
+
+2012-08-07  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: [Bug 3511806]: Checkin [30736d63f0] broke CFLAGS
+
+2012-07-25  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: My previous commit (2012-04-03) broke the ActiveTcl
+	build for AMD64, because of the quotes in "C:/<path>/AMD64/cl.exe".
+	It turns out that the AC_TRY_COMPILE macro cannot handle that.
+
+2012-07-22  Stuart Cassoff  <stwo at users.sourceforge.net>
+
+	* tcl.m4: Tidy: consistency, spelling, phrasing, whitespace.
+	No functional change.
+
+2012-04-03  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: [Bug 3511806] Compiler checks too early
+	This change allows to build the cygwin and mingw32 ports of
+	Tcl/Tk extensions to build out-of-the-box using a native or
+	cross-compiler, e.g. on Cygwin, Linux or Darwin.
+
+2011-04-02  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* install-sh: Fix issue with library stripping in install-sh
+	 (backported from kevin_walzer's patch from Tcl 8.6 trunk)
+
+2011-04-05  Andreas Kupries  <andreask at activestate.com>
+
+	* tcl.m4: Applied patch by Jeff Lawson. Nicer error message when
+	  tclConfig.sh was not found.
+
+2010-12-15  Stuart Cassoff  <stwo at users.sourceforge.net>
+
+	* install-sh: Upgrade to newer install-sh and use it.
+	* tcl.m4:
+
+2010-12-14  Stuart Cassoff  <stwo at users.sourceforge.net>
+
+	* tcl.m4: Better building on OpenBSD.
+
+2010-12-14  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: when using gcc, don't try to determine Win64 SDK
+
+2010-12-12  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: Determine correctly a cross-compiler-windres
+
+2010-11-23  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: add some cross-compile support, borrowed from Tcl 8.6
+
+2010-09-16  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: correct HP-UX LDFLAGS (only used when building big shell)
+
+2010-09-14  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: add extra if check for .manifest file generation
+	Add notice about package name and version being built.
+
+2010-09-09  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: [FREQ #3058486] TEA_LOAD_CONFIG doesn't set all BUILD_ vars
+	Slightly related: defining BUILD_$1 on all platforms - not only win -
+	allows the -fvisibility feature to be used in extensions as well, at
+	least if you compile against tcl >= 8.5.
+
+2010-08-26  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: ensure safe quoting for autoheader usage
+
+2010-08-19  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: add TEA_ADD_CLEANFILES macro to make adding cleanfiles
+	easier, and add *.exp to CLEANFILES Windows default.
+	(TEA_MAKE_LIB): Enhanced to check for MSVC that requires manifests
+	and auto-embed it into proj DLL via MAKE_SHARED_LIB.  Also define
+	VC_MANIFEST_EMBED_DLL and VC_MANIFEST_EMBED_EXE that do the same
+	magic in case it is needed for extended TEA projects.
+
+2010-08-16  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	*** Bump to TEA_VERSION 3.9 ***
+	If upgrading from TEA_VERSION 3.8, copy over tcl.m4, change
+	TEA_INIT to use 3.9 and reconfigure (ac-2.59+).
+	BUILD_${PACKAGE_NAME} will be auto-defined on Windows for
+	correct setting of TCL_STORAGE_CLASS.
+	TEA_LOAD_CONFIG users should remove the SHLIB_LD_LIBS setting done
+	in configure.in (LIBS will be automagically populated by
+	TEA_LOAD_CONFIG).
+	TEA_EXPORT_CONFIG has been added for ${pkg}Config.sh creators
+	SHLIB_LD_FLAGS was deprecated a while ago, remove it if it is
+	still in your Makefile.in.
+
+	* tcl.m4: add /usr/lib64 to set of auto-search dirs. [Bug 1230554]
+	Auto-define BUILD_$PACKAGE_NAME so users don't need to.  This
+	needs to correspond with $pkg.h define magic for TCL_STORAGE_CLASS.
+	Auto-define CLEANFILES.  Users can expand it.
+	(SHLIB_LD_LIBS): define to '${LIBS}' default and change it only if
+	necessary.  Platforms not using this may simply not work or have
+	very funky linkers.
+	(TEA_LOAD_CONFIG): When loading config for another extension,
+	auto-add stub libraries found with TEA_ADD_LIBS.  Eases
+	configure.in for modules like itk and img::*.
+	(TEA_EXPORT_CONFIG): Add standardized function for exporting a
+	${pkg}Config.sh.  See use by img::* and itcl.
+
+2010-08-12  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	*** Bump to TEA_VERSION 3.8 ***
+	If upgrading from TEA_VERSION 3.7, copy over tcl.m4, change
+	TEA_INIT to use 3.8 and reconfigure (ac-2.59+).
+	No other changes should be necessary.
+
+	* tcl.m4: remove more vestigial bits from removed platforms.
+	Add back SCO_SV-3.2*.
+	Remove use of DL_LIBS and DL_OBJS and related baggage - these are
+	only needed by the core to support 'load'.
+	Allow for macosx in TEA_ADD_SOURCES.
+	Correct check for found_xincludes=no in TEA_PATH_UNIX_X.
+
+2010-08-11  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: remove the following old platform configurations:
+	UNIX_SV*|UnixWare-5*, SunOS-4.*, SINIX*5.4*, SCO_SV-3.2*<readded>,
+	OSF1-1.*, NEXTSTEP-*, NetBSD-1.*|FreeBSD-[[1-2]].*, MP-RAS-*,
+	IRIX-5.*, HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*, dgux*,
+	BSD/OS-2.1*|BSD/OS-3*
+	(AIX): drop AIX-pre4 support and use of ldAix, use -bexpall/-brtl
+
+2010-07-05  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: [Patch #1055668] removal of exported internals from
+	tclInt.h (EXTERN macro)
+
+2010-04-14  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4    - Backport a lot of quoting fixes from tcl8.6/unix/tcl.m4
+	            - Fix determination of CYGPATH for CYGWIN
+	  With those fixes, itcl and tdbc compile fine with CYGWIN
+
+2010-04-06  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* install-sh         [Bug 2982540] configure and install* script files
+	                     should always have LF
+
+2010-02-19  Stuart Cassoff  <stwo at users.sourceforge.net>
+
+	* tcl.m4: Correct compiler/linker flags for threaded builds on
+	OpenBSD.
+
+2010-01-19  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: Detect CYGWIN variant: win32 or unix
+
+2010-01-03  Donal K. Fellows  <dkf at users.sf.net>
+
+	* unix/tcl.m4 (TEA_CONFIG_CFLAGS): [Tcl Bug 1636685]: Use the
+	configuration for modern FreeBSD suggested by the FreeBSD porter.
+
+2009-10-22  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: [Tcl Patch #2883533] tcl.m4 support for Haiku OS
+
+2009-04-27  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_CONFIG_CFLAGS): harden the check to add _r to CC on
+	AIX with threads.
+
+2009-04-10  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): check for 64-bit TkAqua.
+
+2009-03-26  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tclconfig/tcl.m4: Adapt LDFLAGS and LD_SEARCH_FLAGS
+	together with SHLIB_LD definition to unbreak building on HPUX.
+
+2009-03-20  Andreas Kupries  <andreask at activestate.com>
+
+	* tclconfig/tcl.m4: Changed SHLIB_LD definition to unbreak
+	building on HPUX.
+
+2009-03-16  Joe English  <jenglish at users.sourceforge.net>
+
+	* tcl.m4(TEA_PUBLIC_TK_HEADERS): Look at ${TK_INCLUDE_SPEC}
+	(found in tkConfig.sh) when trying to guess where tk.h might be
+	[Patch 1960628].
+
+2009-03-11  Joe English  <jenglish at users.sourceforge.net>
+
+	* tcl.m4: Allow ${SHLIB_SUFFIX} to be overridden at
+	configure-time [Patch 1960628].  Also fix some comment typos,
+	and an uninitialized variable bug-waiting-to-happen.
+
+2008-12-21  Jan Nijtmans  <nijtmans at users.sf.net>
+
+	* tcl.m4: [Bug 2073255] Tcl_GetString(NULL) doesn't crash on HP-UX
+	          (this bug report was for Tcl, but holds for TEA as well.)
+
+2008-12-20  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4: sync with tdbc tcl.m4 changes
+	(SunOS-5.11): Sun cc SHLIB_LD: use LDFLAGS_DEFAULT instead of LDFLAGS
+
+2008-12-02  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	*** Bump to TEA_VERSION 3.7 ***
+
+	* tcl.m4: in private header check, check for <plat>Port.h instead
+	of Int.h to ensure all private headers are available.
+
+2008-11-04  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): sync TEA_PRIVATE_TK_HEADERS handling of
+	Tk.framework PrivateHeaders with TEA_PRIVATE_TCL_HEADERS.
+
+2008-11-04  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_PATH_TCLCONFIG, TEA_PATH_TKCONFIG): exit with error
+	when tclConfig.sh cannot be found. [Bug #1997760]
+	(TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): allow for
+	finding the headers installed in the public areas, e.g. a result of
+	make install-private-headers. [Bug #1631922]
+
+2008-08-12  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): link shlib with current and compatiblity version
+	flags; look for libX11.dylib when searching for X11 libraries.
+
+2008-06-12  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (SunOS-5.11): fix 64bit amd64 support with gcc & Sun cc.
+
+2008-03-27  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (SunOS-5.1x): fix 64bit support for Sun cc. [Bug 1921166]
+
+2008-02-01  Donal K. Fellows  <donal.k.fellows at man.ac.uk>
+
+	* tcl.m4 (TEA_CONFIG_CFLAGS): Updated to work at least in part with
+	more modern VC versions. Currently just made the linker flags more
+	flexible; more work may be needed.
+
+2007-10-26  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): add support for 64-bit X11.
+
+2007-10-23  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	*** Tagged tea-3-branch to start TEA 4 development on HEAD ***
+
+2007-09-17  Joe English  <jenglish at users.sourceforge.net>
+
+	* tcl.m4: use '${CC} -shared' instead of 'ld -Bshareable'
+	to build shared libraries on current NetBSDs [Bug 1749251].
+
+2007-09-15  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4: 	replace all direct references to compiler by ${CC} to
+			enable CC overriding at configure & make time.
+	(SunOS-5.1x):	replace direct use of '/usr/ccs/bin/ld' in SHLIB_LD by
+			'cc' compiler driver.
+
+2007-08-08  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: check Ttk dir for Tk private headers (8.5).
+	Add some comments to other bits.
+
+2007-06-25  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): move where / is added.
+
+2007-06-13  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: fix --with-tkinclude alignment. [Bug 1506111]
+
+2007-06-06  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): fix 64bit arch removal in fat 32&64bit builds.
+
+2007-05-18  Donal K. Fellows  <donal.k.fellows at man.ac.uk>
+
+	* tcl.m4: Added quoting so that paths with spaces cause fewer
+	problems.
+
+2007-03-07  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in -mmacosx-version-min check.
+
+2007-02-15  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: correct private header check to search in generic subdir
+
+2007-02-09  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	*** Bump to TEA_VERSION 3.6 ***
+
+	* tcl.m4: correct -d to -f
+	(TEA_CONFIG_CFLAGS): SHLIB_SUFFIX is .so on HP ia64 [Bug 1615058]
+
+2007-02-08  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): check
+	that the dirs actually have private headers. [Bug 1631922]
+
+2007-02-04  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4: add caching to -pipe check.
+
+2007-01-25  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4: integrate CPPFLAGS into CFLAGS as late as possible and
+	move (rather than duplicate) -isysroot flags from CFLAGS to CPPFLAGS to
+	avoid errors about multiple -isysroot flags from some older gcc builds.
+
+2006-01-19  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4: ensure CPPFLAGS env var is used when set. [Bug 1586861]
+	(Darwin): add -isysroot and -mmacosx-version-min flags to CPPFLAGS when
+	present in CFLAGS to avoid discrepancies between what headers configure
+	sees during preprocessing tests and compiling tests.
+
+2006-12-19  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): --enable-64bit: verify linking with 64bit -arch flag
+	succeeds before enabling 64bit build.
+
+2006-12-16  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Linux): fix previous change to use makefile variable
+	LDFLAGS_DEFAULT instead of LDFLAGS in SHLIB_LD, to ensure linker
+	flags in sampleextension Makefile are picked up.
+
+2006-11-26  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Linux): --enable-64bit support. [Patch 1597389], [Bug 1230558]
+
+2006-08-18  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
+	universal builds including x86_64 and for use of -mmacosx-version-min
+	instead of MACOSX_DEPLOYMENT_TARGET. For Tk extensions, remove 64-bit
+	arch flags from CFLAGS like in the Tk configure, as neither TkAqua nor
+	TkX11 can be built for 64-bit at present.
+
+2006-03-28  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: []-quote AC_DEFUN functions.
+	(TEA_PATH_TKCONFIG): Fixed Windows-specific check for tkConfig.sh.
+	(TEA_MAKE_LIB): Prepend 'lib' for Windows-gcc configs.
+
+2006-03-07  Joe English  <jenglish at users.sourceforge.net>
+
+	* tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD,
+	as per the other *BSD variants [Bug 1334613].
+
+2006-01-25  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	*** Bump to TEA version 3.5 ***
+
+	* tcl.m4: keep LD_SEARCH_FLAGS and CC_SEARCH_FLAGS synchronous
+	with core tcl.m4 meaning.
+
+2006-01-24  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): use makefile variable LDFLAGS_DEFAULT instead of
+	LDFLAGS in SHLIB_LD, to ensure linker flags in sampleextension Makefile
+	are picked up. [Bug 1403343]
+
+2006-01-23  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: add C:/Tcl/lib and C:/Progra~1/Tcl/lib dirs to check for
+	*Config.sh on Windows. [Bug 1407544]
+
+2006-01-23  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): for Tk extensions, remove -arch ppc64 from CFLAGS
+	like in the Tk configure, as neither TkAqua nor TkX11 can be built for
+	64bit at present (no 64bit GUI libraries).
+
+2006-01-22  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: restore system=windows on Windows.
+	Remove error if 'ar' isn't found (it may not be on Windows).
+	Do not add -lxnet or define _XOPEN_SOURCE on HP-UX by default.
+	Ensure the C|LDFLAGS_DEFAULT gets the fully sub'd value at
+	configure time.
+
+2006-01-10  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4: add caching, use AC_CACHE_CHECK instead of AC_CACHE_VAL
+	where possible, consistent message quoting, sync relevant
+	tcl/unix/tcl.m4 HEAD changes and gratuitous formatting differences
+	(notably sunc removal of support for for ancient BSD's, IRIX 4,
+	RISCos and Ultrix by kennykb), Darwin improvements to
+	TEA_LOAD_*CONFIG to make linking work against Tcl/Tk frameworks
+	installed in arbitrary location, change TEA_PROG_* search order
+	(look in *_BIN_DIR parents before *_PREFIX).
+
+2006-01-05  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: add dkf's system config refactor
+
+2006-01-04  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: remove extraneous ' that causes bash 3.1 to choke
+
+2005-12-19  Joe English  <jenglish at users.sourceforge.net>
+
+	* tcl.m4 (TEA_PATH_TCLCONFIG &c): Look for tclConfig.sh &c
+	in ${libdir}, where they are installed by default [Patch #1377407].
+
+2005-12-05  Don Porter  <dgp at users.sf.net>
+
+	* tcl.m4 (TEA_PUBLIC_*_HEADERS):	Better support for finding
+	header files for uninstalled Tcl and Tk.
+
+2005-12-02  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: correctly bump TEA_VERSION var to 3.4
+
+2005-12-01  Daniel Steffen  <das at users.sourceforge.net>
+
+	* unix/tcl.m4 (Darwin): fixed error when MACOSX_DEPLOYMENT_TARGET unset
+
+2005-11-29  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4:  *** Bump to TEA version 3.4 ***
+	Add Windows x64 build support.
+	Remove TEA_PATH_NOSPACE and handle the problem with ""s where
+	necessary - the macro relied on TCLSH_PROG which didn't work for
+	cross-compiles.
+
+2005-11-27  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): add 64bit support, add CFLAGS to SHLIB_LD to
+	support passing -isysroot in env(CFLAGS) to configure (flag can't
+	be present twice, so can't be in both CFLAGS and LDFLAGS during
+	configure), don't use -prebind when deploying on 10.4.
+	(TEA_ENABLE_LANGINFO, TEA_TIME_HANDLER): add/fix caching.
+
+2005-10-30  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4: fixed two tests for TEA_WINDOWINGSYSTEM = "aqua" that
+	should have been for `uname -s` = "Darwin" instead; added some
+	missing quoting.
+	(TEA_PROG_TCLSH, TEA_PROG_WISH): fix incorrect assumption that
+	install location of tclConfig.sh/tkConfig.sh allows to determine
+	the tclsh/wish install dir via ../bin. Indeed tcl/tk can be
+	configured with arbitrary --libdir and --bindir (independent of
+	prefix) and such a configuration is in fact standard with Darwin
+	framework builds. At least now also check ${TCL_PREFIX}/bin
+	resp. ${TK_PREFIX}/bin for presence of tclsh resp. wish (if tcl/tk
+	have been configured with arbitrary --bindir, this will still not
+	find them, for a general solution *Config.sh would need to contain
+	the values of bindir/libdir/includedir passed to configure).
+
+2005-10-07  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: Fix Solaris 5.10 check and Solaris AMD64 64-bit builds.
+
+2005-10-04  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_PRIVATE_TCL_HEADERS): add / to finish sed macro
+	(TEA_ENABLE_THREADS): don't check for pthread_attr_setstacksize func
+
+2005-09-13  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: *** Update to TEA version 3.3 ***
+	define TEA_WINDOWINGSYSTEM in TEA_LOAD_TKCONFIG.
+	Make --enable-threads the default (users can --disable-threads).
+	Improve AIX ${CC}_r fix to better check existing ${CC} value.
+	Do the appropriate evals to not require the *TOP_DIR_NATIVE vars
+	be set for extensions that use private headers.
+	Make aqua check for Xlib compat headers the same as win32.
+
+2005-07-26  Mo DeJong  <mdejong at users.sourceforge.net>
+
+	* tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH,
+	TEA_PROG_WISH, TEA_BUILD_WISH): Remove
+	TEA_BUILD_TCLSH and TEA_BUILD_WISH because
+	of complaints that it broke the build when
+	only an installed version of Tcl was available
+	at extension build time. The TEA_PROG_TCLSH and
+	TEA_PROG_WISH macros will no longer search the
+	path at all. The build tclsh or installed
+	tclsh shell will now be found by TEA_PROG_TCLSH.
+
+2005-07-24  Mo DeJong  <mdejong at users.sourceforge.net>
+
+	* tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH,
+	TEA_PROG_WISH, TEA_BUILD_WISH):
+	Split confused search for tclsh on PATH and
+	build and install locations into two macros.
+	TEA_PROG_TCLSH and TEA_PROG_WISH search the
+	system PATH for an installed tclsh or wish.
+	The TEA_BUILD_TCLSH and TEA_BUILD_WISH
+	macros determine the name of tclsh or
+	wish in the Tcl or Tk build directory even
+	if tclsh or wish has not yet been built.
+	[Tcl bug 1160114]
+	[Tcl patch 1244153]
+
+2005-06-23  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (TEA_PRIVATE_TK_HEADERS): add ${TK_SRC_DIR}/macosx to
+	TK_INCLUDES when building against TkAqua.
+
+	* tcl.m4 (TEA_PATH_X): fixed missing comma in AC_DEFINE
+
+	* tcl.m4: changes to better support framework builds of Tcl and Tk out
+	of the box: search framework install locations for *Config.sh, and if in
+	presence of a framework build, use the framework's Headers and
+	PrivateHeaders directories for public and private includes. [FR 947735]
+
+2005-06-18  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to
+	ensure we can always relocate binaries with install_name_tool.
+
+2005-06-04  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (TEA_PATH_X): for TEA_WINDOWINGSYSTEM == aqua, check if xlib
+	compat headers are available in tkheaders location, otherwise add xlib
+	sourcedir to TK_XINCLUDES.
+
+2005-04-25  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4: added AC_DEFINE* descriptions (from core tcl.m4) to allow
+	use with autoheader.
+	(Darwin): added configure checks for recently added linker flags
+	-single_module and -search_paths_first to allow building with older
+	tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD.
+	(TEA_MISSING_POSIX_HEADERS): added caching of dirent.h check.
+	(TEA_BUGGY_STRTOD): added caching (sync with core tcl.m4).
+
+2005-03-24  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_TCL_64BIT_FLAGS): use Tcl header defaults for wide
+	int type only on Windows when __int64 is detected as valid.
+
+2005-03-24  Don Porter  <dgp at users.sf.net>
+
+	* README.txt:	Update reference to "SC_* macros" to "TEA_* macros".
+	* tcl.m4:	Incorporated recent improvements in SC_PATH_TCLCONFIG
+	and SC_PATH_TKCONFIG into TEA_PATH_TCLCONFIG and TEA_PATH_TKCONFIG.
+	Corrected search path in TEA_PATH_CONFIG and added
+	AC_SUBST($1_BIN_DIR) to TEA_LOAD_CONFIG so that packages that load
+	the configuration of another package can know where they loaded
+	it from.
+
+2005-03-18  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_CONFIG_CFLAGS): correct 2005-03-17 change to have
+	variant LD_SEARCH_FLAGS for gcc and cc builds.
+
+	* tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): correct x-compile check.
+
+2005-03-17  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: Correct gcc build and HP-UX-11.
+
+2005-02-08  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_ADD_LIBS): don't touch lib args starting with -.
+	(TEA_CONFIG_CFLAGS): only define _DLL for CE in shared build.
+	(TEA_MAKE_LIB): set RANLIB* to : on Windows (it's not needed).
+
+2005-02-01  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: redo of 2005-01-27 changes to correctly handle paths
+	with spaces.  Win/CE and Win/64 builds now require a prebuilt
+	tclsh to handle conversion to short pathnames.  This is done in
+	the new TEA_PATH_NOSPACE macro.  For Win/CE|64, make CC just the
+	compiler and move the necessary includes to CFLAGS.
+	(TEA_CONFIG_CFLAGS): Add Solaris 64-bit gcc build support.
+	(TEA_PROG_TCLSH, TEA_PROG_WISH): Allow TCLSH_PROG and WISH_PROG to
+	be set in the env and prevent resetting.
+	(TEA_ADD_LIBS): On Windows using GCC (mingw), convert foo.lib
+	args to -lfoo, for use with mingw.
+		*** POTENTIAL INCOMPATABILITY ***
+	(TEA_CONFIG_CFLAGS): Fix AIX gcc builds to work out-of-box.
+	Bumped TEA to 3.2.
+
+2005-01-27  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: remove cygpath calls to support msys.
+	Update base CE build assumption to "420,ARMV4,ARM,Pocket PC 2003".
+	Make STLIB_LD use $LINKBIN -lib.
+
+2005-01-25  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (Darwin): fixed bug with static build linking to dynamic
+	library in /usr/lib etc instead of linking to static library earlier
+	in search path. [Tcl Bug 956908]
+	Removed obsolete references to Rhapsody.
+
+2004-12-29  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: Updates for VC7 compatibility, fixing CFLAGS and LDFLAGS
+	options, using better default -O levels. [Bug 1092952, 1091967]
+
+2004-12-29  Joe English  <jenglish at users.sourceforge.net>
+
+	* tcl.m4: Do not use ${DBGX} suffix when building
+	shared libraries [patch #1081595, TIP #34]
+
+2004-09-07  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_CONFIG_CFLAGS): support eVC4 Win/CE builds
+
+2004-08-10  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_INIT, TEA_PREFIX): update handling of exec_prefix to
+	work around subdir configures since autoconf only propagates the
+	prefix (not exec_prefix).
+
+2004-07-23  Daniel Steffen  <das at users.sourceforge.net>
+
+	* tcl.m4 (TEA_CONFIG_CFLAGS): Darwin section: brought inline with
+	Tcl 8.5 HEAD config, removed core specific & obsolete settings.
+
+2004-07-22  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_PATH_X): check in TK_DEFS for MAC_OSX_TK to see if
+	we are compiling on Aqua.  Add TEA_WINDOWINGSYSTEM var that
+	reflects 'tk windowingsystem' value.
+
+2004-07-16  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_ENABLE_THREADS): force a threaded build when
+	building against a threaded core.
+	(CFLAGS_WARNING): Remove -Wconversion for gcc builds
+	(TEA_CONFIG_CFLAGS): Reorder configure.in for better 64-bit build
+	configuration, replacing EXTRA_CFLAGS with CFLAGS.  [Bug #874058]
+	Update to latest Tcl 8.5 head config settings.
+	Call this TEA version 3.1.
+
+2004-04-29  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_TCL_64BIT_FLAGS): replace AC_TRY_RUN test with
+	AC_TRY_COMPILE for the long vs. long long check. (kenny)
+
+2004-04-26  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_TCL_64BIT_FLAGS): update against core tcl.m4 to
+	define TCL_WIDE_INT_IS_LONG if 'using long'.
+
+2004-03-19  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: correct Windows builds getting LDFLAGS info in MAKE_LIB
+
+2004-02-11  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: correct TCL_INCLUDES for private headers on Windows - it
+	doesn't need the eval.
+
+2004-02-10  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: don't require TK_INCLUDES and TCL_INCLUDES to have the
+	DIR_NATIVE vars defined when using private headers on unix.
+	Allow $... to TEA_ADD_SOURCES for constructs like
+	TEA_ADD_SOURCES([\$(WIN_OBJECTS)]), that allow the developer to
+	place more in the Makefile.in.
+	tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
+	CHECK on limits.h
+
+2003-12-10  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* Makefile.in:      added TEA_ADD_LIBS, TEA_ADD_INCLUDES and
+	* configure:        TEA_ADD_CFLAGS to configurable parameters with
+	* configure.in:     PKG_* equivs in the Makefile.  This allows the
+	* tclconfig/tcl.m4: user to worry less about actual magic VAR names.
+	Corrected Makefile.in to note that TEA_ADD_TCL_SOURCES requires
+	exact file names.
+
+2003-12-09  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: updated OpenBSD support based on [Patch #775246] (cassoff)
+
+2003-12-05  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* configure:
+	* configure.in:
+	* Makefile.in (VPATH): readd $(srcdir) to front of VPATH as the
+	first part of VPATH can get chopped off.
+	Change .c.$(OBJEXT) rule to .c. at OBJEXT@ to support more makes.
+	* tclconfig/tcl.m4: add TEA_ADD_STUB_SOURCES to support libstub
+	generation and TEA_ADD_TCL_SOURCES to replace RUNTIME_SOURCES as
+	the way the user specifies library files.
+
+2003-12-03  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* configure:           Update of TEA spec to (hopefully) simplify
+	* configure.in:        some aspects of TEA by making use of more
+	* Makefile.in:         AC 2.5x features.  Use PACKAGE_NAME (instead
+	* generic/tclsample.c: of PACKAGE) and PACKAGE_VERSION (instead of
+	* tclconfig/tcl.m4:    VERSION) arguments to AC_INIT as the TEA
+	package name and version.
+	Provide a version argument to TEA_INIT - starting with 3.0.
+	Drop all use of interior shell substs that older makefiles didn't
+	like.  Use PKG_* naming convention instead.
+	Move specification of source files and public headers into
+	configure.in with TEA_ADD_SOURCES and TEA_ADD_HEADERS.  These will
+	be munged during ./configure into the right obj file names (no
+	$(SOURCES:.c=.obj) needed).
+	There is almost nothing that should be touched in Makefile.in now
+	for the developer.  May want to add a TEA_ADD_TCL_SOURCES for the
+	RUNTIME_SOURCES that remains.
+	Use SHLID_LD_FLAGS (instead of SHLID_LDFLAGS) as Tcl does.
+	Only specify the user requested LDFLAGS/CFLAGS in the Makefile,
+	don't mention the _OPTIMIZE/_DEBUG variants.
+
+2003-10-15  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: create a TEA_SETUP_COMPILER_CC the precedes the
+	TEA_SETUP_COMPILER macro.  They are split so the check for CC
+	occurs before any use of CC.  Also add AC_PROG_CPP to the compiler
+	checks.
+
+2003-10-06  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: Updated for autoconf 2.5x prereq.
+	Where TCL_WIDE_INT_TYPE would be __int64, defer to the code checks
+	in tcl.h, which also handles TCL_LL_MODIFIER* properly.
+
+2003-04-22  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: correct default setting of ARCH for WinCE builds.
+	Correct \ escaping for CE sed macros.
+
+2003-04-10  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: replace $(syscal) construct with older `syscall` for
+	systems where sh != bash.
+
+2003-04-09  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_WITH_CELIB): add --enable-wince and --with-celib
+	options for Windows/CE compilation support.  Requires the
+	Microsoft eMbedded SDK and Keuchel's celib emulation layer.
+
+2003-02-18  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_ENABLE_THREADS): Make sure -lpthread gets passed on
+	the link line when checking for the pthread_attr_setstacksize
+	symbol. (dejong)
+
+	* tcl.m4 (TEA_SETUP_COMPILER): added default calls to
+	TEA_TCL_EARLY_FLAGS, TEA_TCL_64BIT_FLAGS,
+	TEA_MISSING_POSIX_HEADERS and TEA_BUGGY_STRTOD.
+
+2003-02-14  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: correct HP-UX ia64 --enable-64bit build flags
+
+2003-01-29  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: check $prefix/lib as well as $exec_prefix/lib when
+	looking for tcl|tkConfig.sh, as this check is done before we would
+	set exec_prefix when the user does not define it.
+
+2003-01-21  Mo DeJong  <mdejong at users.sourceforge.net>
+
+	* tcl.m4 (TEA_CONFIG_CFLAGS): Fix build support
+	for mingw, the previous implementation would
+	use VC++ when compiling with mingw gcc. Don't
+	pass -fPIC since gcc always compiles pic code
+	under win32. Change some hard coded cases
+	of gcc to ${CC}.
+
+2002-10-15  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: move the CFLAGS definition from TEA_ENABLE_SHARED to
+	TEA_MAKE_LIB because setting too early confuses other AC_* macros.
+	Correct the HP-11 SHLIB_LD_LIBS setting.
+
+	* tcl.m4: add the CFLAGS definition into TEA_ENABLE_SHARED and
+	make it pick up the env CFLAGS at configure time.
+
+2002-10-09  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: add --enable-symbols=mem option to enable TCL_MEM_DEBUG.
+	Improved AIX 64-bit build support, allow it on AIX-4 as well.
+	Enable 64-bit HP-11 compilation with gcc.
+	Enable 64-bit IRIX64-6 cc build support.
+	Correct FreeBSD thread library linkage.
+	Add OSF1 static build support.
+	Improve SunOS-5 shared build SHLIB_LD macro.
+
+2002-07-20  Zoran Vasiljevic  <zoran at archiware.com>
+
+	* tcl.m4: Added MINGW32 to list of systems checked for Windows build.
+	Also, fixes some indentation issues with "--with-XXX" options.
+
+2002-04-23  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_ENABLE_THREADS): added USE_THREAD_ALLOC define to
+	use new threaded allocatory by default on Unix for Tcl 8.4.
+	(TEA_CONFIG_CFLAGS): corrected LD_SEARCH_FLAGS for FreeBSD-3+.
+
+2002-04-22  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4 (TEA_SETUP_COMPILER): removed call to AC_CYGWIN so that
+	we can use autoconf 2.5x as well as 2.13.  This prevents us from
+	being able to warn against the use of cygwin gcc at configure
+	time, but allows autoconf 2.5x, which is what is shipped with most
+	newer systems.
+
+2002-04-11  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: Enabled COFF as well as CV style debug info with
+	--enable-symbols to allow Dr. Watson users to see function info.
+	More info on debugging levels can be obtained at:
+	http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+
+2002-04-03  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: change all SC_* macros to TEA_*.  The SC_ was for
+	Scriptics, which is no more.  TEA represents a better, independent
+	prefix that won't need changing.
+	Added preliminary mingw gcc support. [Patch #538772]
+	Added TEA_PREFIX macro that handles defaulting the prefix and
+	exec_prefix vars to those used by Tcl if none were specified.
+	Added TEA_SETUP_COMPILER macro that encompasses the AC_PROG_CC
+	check and several other basic AC_PROG checks needed for making
+	executables.  This greatly simplifies user's configure.in files.
+	Collapsed AIX-5 defines into AIX-* with extra checks for doing the
+	ELF stuff on AIX-5-ia64.
+	Updated TEA_ENABLE_THREADS to take an optional arg to allow
+	switching it on by default (for Thread) and add sanity checking to
+	warn the user if configuring threads incompatibly.
+
+2002-03-29  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: made sure that SHLIB_LDFLAGS was set to LDFLAGS_DEFAULT.
+	Removed --enable-64bit support for AIX-4 because it wasn't correct.
+	Added -MT or -MD Windows linker switches to properly support
+	symbols-enabled builds.
+
+2002-03-28  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: called AC_MSG_ERROR when SC_TEA_INIT wasn't called first
+	instead of calling it as that inlines it each time in shell code.
+	Changed Windows CFLAGS_OPTIMIZE to use -O2 instead of -Oti.
+	Noted TCL_LIB_VERSIONS_OK=nodots for Windows builds.
+	A few changes to support itcl (and perhaps others):
+	Added support for making your own stub libraries to SC_MAKE_LIB.
+	New SC_PATH_CONFIG and SC_LOAD_CONFIG that take a package name arg
+	and find that ${pkg}Config.sh file.  itk uses this for itcl.
+
+2002-03-27  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: made SC_LOAD_TKCONFIG recognize when working with a Tk
+	build dir setup.
+	Added EXTRA_CFLAGS and SHLIB_LD_LIBS substs to SC_CONFIG_CFLAGS.
+	Added XLIBSW onto LIBS when it is defined.
+	Remove TCL_LIBS from MAKE_LIB and correctly use SHLIB_LD_LIBS
+	instead to not rely as much on tclConfig.sh cached info.
+	Add TK_BIN_DIR to paths to find wish in SC_PROG_WISH.
+	These move towards making TEA much more independent of *Config.sh.
+
+2002-03-19  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: corrected forgotten (UN)SHARED_LIB_SUFFIX and
+	SHLIB_SUFFIX defines for Win.
+	(SC_PATH_X): made this only do the check on unix platforms.
+
+2002-03-12  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* README.txt: updated to reflect fewer files
+
+2002-03-06  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* config.guess (removed):
+	* config.sub (removed): removed unnecessary files
+
+	* installFile.tcl (removed):
+	* mkinstalldirs (removed): these aren't really necessary for
+	making TEA work
+
+	* tcl.m4 (SC_PUBLIC_TCL_HEADERS, SC_PUBLIC_TK_HEADERS): don't
+	check /usr(/local)/include for includes on Windows when not using
+	gcc
+
+2002-03-05  Jeff Hobbs  <jeffh at ActiveState.com>
+
+	* tcl.m4: added warnings on Windows, removed RELPATH define and
+	added TCL_LIBS to MAKE_LIB macro.
+
+	This import represents 2.0.0, or a new start at attempting to
+	make TEA much easier for C extension developers.
+
+	**** moved from tclpro project to core tcl project, ****
+	**** renamed to 'tclconfig'                         ****
+
+2001-03-15    Karl Lehenbauer <karl at procplace.com>
+
+	* installFile.tcl: Added updating of the modification time of
+	  the target file whether we overwrote it or decided that it
+	  hadn't changed.  This was necessary for us to be able to
+	  determine whether or not a module install touched the file.
+
+2001-03-08    Karl Lehenbauer <karl at procplace.com>
+
+	* installFile.tcl: Added support for converting new-style (1.1+)
+	  Cygnus drive paths to Tcl-style.
+
+2001-01-15    <brent.welch at interwoven.com>
+
+	* tcl.m4: Added FreeBSD clause.
+
+2001-01-03    <brent.welch at interwoven.com>
+
+	* tcl.m4: Fixed typo in SC_LIB_SPEC where it is checking
+	for exec-prefix.
+
+2000-12-01    <brent.welch at interwoven.com>
+
+	* tcl.m4: Concatenated most of the Ajuba acsite.m4 file
+	so we don't need to modify the autoconf installation.
+	* config.guess:
+	* config.sub:
+	* installFile.tcl:
+	Added files from the itcl config subdirectory,
+	which should go away.
+
+2000-7-29    <welch at ajubasolutions.com>
+
+	* Fixed the use of TCL_SRC_DIR and TK_SRC_DIR within
+	TCL_PRIVATE_INCLUDES and TK_PRIVATE_INCLUDES to match their recent
+	change from $(srcdir) to $(srcdir)/..
diff --git a/tlt3.0/tclconfig/README.txt b/tlt3.0/tclconfig/README.txt
new file mode 100644
index 0000000..59b5a3e
--- /dev/null
+++ b/tlt3.0/tclconfig/README.txt
@@ -0,0 +1,26 @@
+These files comprise the basic building blocks for a Tcl Extension
+Architecture (TEA) extension.  For more information on TEA see:
+
+	http://www.tcl.tk/doc/tea/
+
+This package is part of the Tcl project at SourceForge, and latest
+sources should be available there:
+
+	http://tcl.sourceforge.net/
+
+This package is a freely available open source package.  You can do
+virtually anything you like with it, such as modifying it, redistributing
+it, and selling it either in whole or in part.
+
+CONTENTS
+========
+The following is a short description of the files you will find in
+the sample extension.
+
+README.txt	This file
+
+install-sh	Program used for copying binaries and script files
+		to their install locations.
+
+tcl.m4		Collection of Tcl autoconf macros.  Included by a package's
+		aclocal.m4 to define TEA_* macros.
diff --git a/tlt3.0/tclconfig/install-sh b/tlt3.0/tclconfig/install-sh
new file mode 100755
index 0000000..7c34c3f
--- /dev/null
+++ b/tlt3.0/tclconfig/install-sh
@@ -0,0 +1,528 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-04-20.01; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -S            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -S) stripcmd="$stripprog $2"
+	shift;;
+
+    -t) dst_arg=$2
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/tlt3.0/tclconfig/tcl.m4 b/tlt3.0/tclconfig/tcl.m4
new file mode 100644
index 0000000..8bc9c83
--- /dev/null
+++ b/tlt3.0/tclconfig/tcl.m4
@@ -0,0 +1,4150 @@
+# tcl.m4 --
+#
+#	This file provides a set of autoconf macros to help TEA-enable
+#	a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+AC_PREREQ(2.57)
+
+dnl TEA extensions pass us the version of TEA they think they
+dnl are compatible with (must be set in TEA_INIT below)
+dnl TEA_VERSION="3.9"
+
+# Possible values for key variables defined:
+#
+# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
+# TEA_PLATFORM        - windows unix
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+#	Locate the tclConfig.sh file and perform a sanity check on
+#	the Tcl compile flags
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Adds the following arguments to configure:
+#		--with-tcl=...
+#
+#	Defines the following vars:
+#		TCL_BIN_DIR	Full path to the directory containing
+#				the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+    dnl TEA specific: Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+	# we reset no_tcl in case something fails here
+	no_tcl=true
+	AC_ARG_WITH(tcl,
+	    AC_HELP_STRING([--with-tcl],
+		[directory containing tcl configuration (tclConfig.sh)]),
+	    with_tclconfig="${withval}")
+	AC_MSG_CHECKING([for Tcl configuration])
+	AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+	    # First check to see if --with-tcl was specified.
+	    if test x"${with_tclconfig}" != x ; then
+		case "${with_tclconfig}" in
+		    */tclConfig.sh )
+			if test -f "${with_tclconfig}"; then
+			    AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
+			fi ;;
+		esac
+		if test -f "${with_tclconfig}/tclConfig.sh" ; then
+		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
+		else
+		    AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+		fi
+	    fi
+
+	    # then check for a private Tcl installation
+	    if test x"${ac_cv_c_tclconfig}" = x ; then
+		for i in \
+			../tcl \
+			`ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+			`ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+			../../tcl \
+			`ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+			`ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+			../../../tcl \
+			`ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+			`ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+		    if test "${TEA_PLATFORM}" = "windows" \
+			    -a -f "$i/win/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+			break
+		    fi
+		    if test -f "$i/unix/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # on Darwin, check in Framework installation locations
+	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+			`ls -d /Library/Frameworks 2>/dev/null` \
+			`ls -d /Network/Library/Frameworks 2>/dev/null` \
+			`ls -d /System/Library/Frameworks 2>/dev/null` \
+			; do
+		    if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # TEA specific: on Windows, check in common installation locations
+	    if test "${TEA_PLATFORM}" = "windows" \
+		-a x"${ac_cv_c_tclconfig}" = x ; then
+		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+			; do
+		    if test -f "$i/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # check in a few common install locations
+	    if test x"${ac_cv_c_tclconfig}" = x ; then
+		for i in `ls -d ${libdir} 2>/dev/null` \
+			`ls -d ${exec_prefix}/lib 2>/dev/null` \
+			`ls -d ${prefix}/lib 2>/dev/null` \
+			`ls -d /usr/local/lib 2>/dev/null` \
+			`ls -d /usr/contrib/lib 2>/dev/null` \
+			`ls -d /usr/lib 2>/dev/null` \
+			`ls -d /usr/lib64 2>/dev/null` \
+			; do
+		    if test -f "$i/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # check in a few other private locations
+	    if test x"${ac_cv_c_tclconfig}" = x ; then
+		for i in \
+			${srcdir}/../tcl \
+			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+		    if test "${TEA_PLATFORM}" = "windows" \
+			    -a -f "$i/win/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+			break
+		    fi
+		    if test -f "$i/unix/tclConfig.sh" ; then
+			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+			break
+		    fi
+		done
+	    fi
+	])
+
+	if test x"${ac_cv_c_tclconfig}" = x ; then
+	    TCL_BIN_DIR="# no Tcl configs found"
+	    AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
+	else
+	    no_tcl=
+	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
+	    AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+	fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+#	Locate the tkConfig.sh file
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Adds the following arguments to configure:
+#		--with-tk=...
+#
+#	Defines the following vars:
+#		TK_BIN_DIR	Full path to the directory containing
+#				the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+    #
+    # Ok, lets find the tk configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tk
+    #
+
+    if test x"${no_tk}" = x ; then
+	# we reset no_tk in case something fails here
+	no_tk=true
+	AC_ARG_WITH(tk,
+	    AC_HELP_STRING([--with-tk],
+		[directory containing tk configuration (tkConfig.sh)]),
+	    with_tkconfig="${withval}")
+	AC_MSG_CHECKING([for Tk configuration])
+	AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+	    # First check to see if --with-tkconfig was specified.
+	    if test x"${with_tkconfig}" != x ; then
+		case "${with_tkconfig}" in
+		    */tkConfig.sh )
+			if test -f "${with_tkconfig}"; then
+			    AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+			    with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
+			fi ;;
+		esac
+		if test -f "${with_tkconfig}/tkConfig.sh" ; then
+		    ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
+		else
+		    AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+		fi
+	    fi
+
+	    # then check for a private Tk library
+	    if test x"${ac_cv_c_tkconfig}" = x ; then
+		for i in \
+			../tk \
+			`ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+			`ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+			../../tk \
+			`ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+			`ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+			../../../tk \
+			`ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+			`ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+		    if test "${TEA_PLATFORM}" = "windows" \
+			    -a -f "$i/win/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+			break
+		    fi
+		    if test -f "$i/unix/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # on Darwin, check in Framework installation locations
+	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+			`ls -d /Library/Frameworks 2>/dev/null` \
+			`ls -d /Network/Library/Frameworks 2>/dev/null` \
+			`ls -d /System/Library/Frameworks 2>/dev/null` \
+			; do
+		    if test -f "$i/Tk.framework/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # check in a few common install locations
+	    if test x"${ac_cv_c_tkconfig}" = x ; then
+		for i in `ls -d ${libdir} 2>/dev/null` \
+			`ls -d ${exec_prefix}/lib 2>/dev/null` \
+			`ls -d ${prefix}/lib 2>/dev/null` \
+			`ls -d /usr/local/lib 2>/dev/null` \
+			`ls -d /usr/contrib/lib 2>/dev/null` \
+			`ls -d /usr/lib 2>/dev/null` \
+			`ls -d /usr/lib64 2>/dev/null` \
+			; do
+		    if test -f "$i/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # TEA specific: on Windows, check in common installation locations
+	    if test "${TEA_PLATFORM}" = "windows" \
+		-a x"${ac_cv_c_tkconfig}" = x ; then
+		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+			; do
+		    if test -f "$i/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i; pwd)`"
+			break
+		    fi
+		done
+	    fi
+
+	    # check in a few other private locations
+	    if test x"${ac_cv_c_tkconfig}" = x ; then
+		for i in \
+			${srcdir}/../tk \
+			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+		    if test "${TEA_PLATFORM}" = "windows" \
+			    -a -f "$i/win/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+			break
+		    fi
+		    if test -f "$i/unix/tkConfig.sh" ; then
+			ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+			break
+		    fi
+		done
+	    fi
+	])
+
+	if test x"${ac_cv_c_tkconfig}" = x ; then
+	    TK_BIN_DIR="# no Tk configs found"
+	    AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
+	else
+	    no_tk=
+	    TK_BIN_DIR="${ac_cv_c_tkconfig}"
+	    AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+	fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+#	Load the tclConfig.sh file
+#
+# Arguments:
+#
+#	Requires the following vars to be set:
+#		TCL_BIN_DIR
+#
+# Results:
+#
+#	Substitutes the following vars:
+#		TCL_BIN_DIR
+#		TCL_SRC_DIR
+#		TCL_LIB_FILE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+	. "${TCL_BIN_DIR}/tclConfig.sh"
+    else
+        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
+        TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
+        TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
+    elif test "`uname -s`" = "Darwin"; then
+	# If Tcl was built as a framework, attempt to use the libraries
+	# from the framework at the given location so that linking works
+	# against Tcl.framework installed in an arbitrary location.
+	case ${TCL_DEFS} in
+	    *TCL_FRAMEWORK*)
+		if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+		    for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
+			     "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
+			if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+			    TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
+			    break
+			fi
+		    done
+		fi
+		if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+		    TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
+		    TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+		fi
+		;;
+	esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+    AC_SUBST(TCL_VERSION)
+    AC_SUBST(TCL_PATCH_LEVEL)
+    AC_SUBST(TCL_BIN_DIR)
+    AC_SUBST(TCL_SRC_DIR)
+
+    AC_SUBST(TCL_LIB_FILE)
+    AC_SUBST(TCL_LIB_FLAG)
+    AC_SUBST(TCL_LIB_SPEC)
+
+    AC_SUBST(TCL_STUB_LIB_FILE)
+    AC_SUBST(TCL_STUB_LIB_FLAG)
+    AC_SUBST(TCL_STUB_LIB_SPEC)
+
+    AC_MSG_CHECKING([platform])
+    hold_cc=$CC; CC="$TCL_CC"
+    AC_TRY_COMPILE(,[
+	    #ifdef _WIN32
+		#error win32
+	    #endif
+    ], TEA_PLATFORM="unix",
+	    TEA_PLATFORM="windows"
+    )
+    CC=$hold_cc
+    AC_MSG_RESULT($TEA_PLATFORM)
+
+    # The BUILD_$pkg is to define the correct extern storage class
+    # handling when making this package
+    AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
+	    [Building extension source?])
+    # Do this here as we have fully defined TEA_PLATFORM now
+    if test "${TEA_PLATFORM}" = "windows" ; then
+	EXEEXT=".exe"
+	CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
+    fi
+
+    # TEA specific:
+    AC_SUBST(CLEANFILES)
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(TCL_DEFS)
+    AC_SUBST(TCL_EXTRA_CFLAGS)
+    AC_SUBST(TCL_LD_FLAGS)
+    AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+#	Load the tkConfig.sh file
+#
+# Arguments:
+#
+#	Requires the following vars to be set:
+#		TK_BIN_DIR
+#
+# Results:
+#
+#	Sets the following vars that should be in tkConfig.sh:
+#		TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+	. "${TK_BIN_DIR}/tkConfig.sh"
+    else
+        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+    eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+    # If the TK_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TK_LIB_SPEC will be set to the value
+    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+    # instead of TK_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
+        TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
+        TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
+    elif test "`uname -s`" = "Darwin"; then
+	# If Tk was built as a framework, attempt to use the libraries
+	# from the framework at the given location so that linking works
+	# against Tk.framework installed in an arbitrary location.
+	case ${TK_DEFS} in
+	    *TK_FRAMEWORK*)
+		if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+		    for i in "`cd "${TK_BIN_DIR}"; pwd`" \
+			     "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
+			if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+			    TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
+			    break
+			fi
+		    done
+		fi
+		if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+		    TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
+		    TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+		fi
+		;;
+	esac
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+    # TEA specific: Ensure windowingsystem is defined
+    if test "${TEA_PLATFORM}" = "unix" ; then
+	case ${TK_DEFS} in
+	    *MAC_OSX_TK*)
+		AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+		TEA_WINDOWINGSYSTEM="aqua"
+		;;
+	    *)
+		TEA_WINDOWINGSYSTEM="x11"
+		;;
+	esac
+    elif test "${TEA_PLATFORM}" = "windows" ; then
+	TEA_WINDOWINGSYSTEM="win32"
+    fi
+
+    AC_SUBST(TK_VERSION)
+    AC_SUBST(TK_BIN_DIR)
+    AC_SUBST(TK_SRC_DIR)
+
+    AC_SUBST(TK_LIB_FILE)
+    AC_SUBST(TK_LIB_FLAG)
+    AC_SUBST(TK_LIB_SPEC)
+
+    AC_SUBST(TK_STUB_LIB_FILE)
+    AC_SUBST(TK_STUB_LIB_FLAG)
+    AC_SUBST(TK_STUB_LIB_SPEC)
+
+    # TEA specific:
+    AC_SUBST(TK_LIBS)
+    AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+#	Determine the fully qualified path name of the tclsh executable
+#	in the Tcl build directory or the tclsh installed in a bin
+#	directory. This macro will correctly determine the name
+#	of the tclsh executable even if tclsh has not yet been
+#	built in the build directory. The tclsh found is always
+#	associated with a tclConfig.sh file. This tclsh should be used
+#	only for running extension test cases. It should never be
+#	or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+#	none
+#
+# Results:
+#	Substitutes the following vars:
+#		TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+    AC_MSG_CHECKING([for tclsh])
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+    fi
+    AC_MSG_RESULT([${TCLSH_PROG}])
+    AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+#	Determine the fully qualified path name of the wish executable
+#	in the Tk build directory or the wish installed in a bin
+#	directory. This macro will correctly determine the name
+#	of the wish executable even if wish has not yet been
+#	built in the build directory. The wish found is always
+#	associated with a tkConfig.sh file. This wish should be used
+#	only for running extension test cases. It should never be
+#	or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+#	none
+#
+# Results:
+#	Substitutes the following vars:
+#		WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+    AC_MSG_CHECKING([for wish])
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        # tkConfig.sh is in Tk build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="${TK_BIN_DIR}/wish"
+        fi
+    else
+        # tkConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+        fi
+        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${WISH_PROG}" ; then
+                REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+    fi
+    AC_MSG_RESULT([${WISH_PROG}])
+    AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+#	Allows the building of shared libraries
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Adds the following arguments to configure:
+#		--enable-shared=yes|no
+#
+#	Defines the following vars:
+#		STATIC_BUILD	Used for building import/export libraries
+#				on Windows.
+#
+#	Sets the following vars:
+#		SHARED_BUILD	Value of 1 or 0
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SHARED], [
+    AC_MSG_CHECKING([how to build libraries])
+    AC_ARG_ENABLE(shared,
+	AC_HELP_STRING([--enable-shared],
+	    [build and link with shared libraries (default: on)]),
+	[tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_shared+set}" = set; then
+	enableval="$enable_shared"
+	tcl_ok=$enableval
+    else
+	tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+	AC_MSG_RESULT([shared])
+	SHARED_BUILD=1
+    else
+	AC_MSG_RESULT([static])
+	SHARED_BUILD=0
+	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
+    fi
+    AC_SUBST(SHARED_BUILD)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+#	Specify if thread support should be enabled.  If "yes" is specified
+#	as an arg (optional), threads are enabled by default, "no" means
+#	threads are disabled.  "yes" is the default.
+#
+#	TCL_THREADS is checked so that if you are compiling an extension
+#	against a threaded core, your extension must be compiled threaded
+#	as well.
+#
+#	Note that it is legal to have a thread enabled extension run in a
+#	threaded or non-threaded Tcl core, but a non-threaded extension may
+#	only run in a non-threaded Tcl core.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Adds the following arguments to configure:
+#		--enable-threads
+#
+#	Sets the following vars:
+#		THREADS_LIBS	Thread library(s)
+#
+#	Defines the following vars:
+#		TCL_THREADS
+#		_REENTRANT
+#		_THREAD_SAFE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+    AC_ARG_ENABLE(threads,
+	AC_HELP_STRING([--enable-threads],
+	    [build with threads]),
+	[tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_threads+set}" = set; then
+	enableval="$enable_threads"
+	tcl_ok=$enableval
+    else
+	tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+	TCL_THREADS=1
+
+	if test "${TEA_PLATFORM}" != "windows" ; then
+	    # We are always OK on Windows, so check what this platform wants:
+
+	    # USE_THREAD_ALLOC tells us to try the special thread-based
+	    # allocator that significantly reduces lock contention
+	    AC_DEFINE(USE_THREAD_ALLOC, 1,
+		[Do we want to use the threaded memory allocator?])
+	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+	    if test "`uname -s`" = "SunOS" ; then
+		AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+			[Do we really want to follow the standard? Yes we do!])
+	    fi
+	    AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+	    AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+	    if test "$tcl_ok" = "no"; then
+		# Check a little harder for __pthread_mutex_init in the same
+		# library, as some systems hide it there until pthread.h is
+		# defined.  We could alternatively do an AC_TRY_COMPILE with
+		# pthread.h, but that will work with libpthread really doesn't
+		# exist, like AIX 4.2.  [Bug: 4359]
+		AC_CHECK_LIB(pthread, __pthread_mutex_init,
+		    tcl_ok=yes, tcl_ok=no)
+	    fi
+
+	    if test "$tcl_ok" = "yes"; then
+		# The space is needed
+		THREADS_LIBS=" -lpthread"
+	    else
+		AC_CHECK_LIB(pthreads, pthread_mutex_init,
+		    tcl_ok=yes, tcl_ok=no)
+		if test "$tcl_ok" = "yes"; then
+		    # The space is needed
+		    THREADS_LIBS=" -lpthreads"
+		else
+		    AC_CHECK_LIB(c, pthread_mutex_init,
+			tcl_ok=yes, tcl_ok=no)
+		    if test "$tcl_ok" = "no"; then
+			AC_CHECK_LIB(c_r, pthread_mutex_init,
+			    tcl_ok=yes, tcl_ok=no)
+			if test "$tcl_ok" = "yes"; then
+			    # The space is needed
+			    THREADS_LIBS=" -pthread"
+			else
+			    TCL_THREADS=0
+			    AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+			fi
+		    fi
+		fi
+	    fi
+	fi
+    else
+	TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    AC_MSG_CHECKING([for building with threads])
+    if test "${TCL_THREADS}" = 1; then
+	AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+	AC_MSG_RESULT([yes (default)])
+    else
+	AC_MSG_RESULT([no])
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+	*THREADS=1*)
+	    if test "${TCL_THREADS}" = "0"; then
+		AC_MSG_WARN([
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads.])
+	    fi
+	    ;;
+	*)
+	    if test "${TCL_THREADS}" = "1"; then
+		AC_MSG_WARN([
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core.])
+	    fi
+	    ;;
+    esac
+    AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+#	Specify if debugging symbols should be used.
+#	Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+#	none
+#
+#	TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+#	the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+#	Requires the following vars to be set in the Makefile:
+#		CFLAGS_DEFAULT
+#		LDFLAGS_DEFAULT
+#
+# Results:
+#
+#	Adds the following arguments to configure:
+#		--enable-symbols
+#
+#	Defines the following vars:
+#		CFLAGS_DEFAULT	Sets to $(CFLAGS_DEBUG) if true
+#				Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
+#		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
+#				Sets to $(LDFLAGS_OPTIMIZE) if false
+#		DBGX		Formerly used as debug library extension;
+#				always blank now.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+    dnl TEA specific: Make sure we are initialized
+    AC_REQUIRE([TEA_CONFIG_CFLAGS])
+    AC_MSG_CHECKING([for build with symbols])
+    AC_ARG_ENABLE(symbols,
+	AC_HELP_STRING([--enable-symbols],
+	    [build with debugging symbols (default: off)]),
+	[tcl_ok=$enableval], [tcl_ok=no])
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+	CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
+	LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+	AC_MSG_RESULT([no])
+    else
+	CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+	LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+	if test "$tcl_ok" = "yes"; then
+	    AC_MSG_RESULT([yes (standard debugging)])
+	fi
+    fi
+    # TEA specific:
+    if test "${TEA_PLATFORM}" != "windows" ; then
+	LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+    AC_SUBST(CFLAGS_DEFAULT)
+    AC_SUBST(LDFLAGS_DEFAULT)
+    AC_SUBST(TCL_DBGX)
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+	AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+	if test "$tcl_ok" = "all"; then
+	    AC_MSG_RESULT([enabled symbols mem debugging])
+	else
+	    AC_MSG_RESULT([enabled $tcl_ok debugging])
+	fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+#	Allows use of modern nl_langinfo check for better l10n.
+#	This is only relevant for Unix.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Adds the following arguments to configure:
+#		--enable-langinfo=yes|no (default is yes)
+#
+#	Defines the following vars:
+#		HAVE_LANGINFO	Triggers use of nl_langinfo if defined.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+    AC_ARG_ENABLE(langinfo,
+	AC_HELP_STRING([--enable-langinfo],
+	    [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+	[langinfo_ok=$enableval], [langinfo_ok=yes])
+
+    HAVE_LANGINFO=0
+    if test "$langinfo_ok" = "yes"; then
+	AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+    fi
+    AC_MSG_CHECKING([whether to use nl_langinfo])
+    if test "$langinfo_ok" = "yes"; then
+	AC_CACHE_VAL(tcl_cv_langinfo_h, [
+	    AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+		    [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+	AC_MSG_RESULT([$tcl_cv_langinfo_h])
+	if test $tcl_cv_langinfo_h = yes; then
+	    AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+	fi
+    else
+	AC_MSG_RESULT([$langinfo_ok])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+#	Determine what the system is (some things cannot be easily checked
+#	on a feature-driven basis, alas). This can usually be done via the
+#	"uname" command.
+#
+# Arguments:
+#	none
+#
+# Results:
+#	Defines the following var:
+#
+#	system -	System/platform/version identification code.
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+	# TEA specific:
+	if test "${TEA_PLATFORM}" = "windows" ; then
+	    tcl_cv_sys_version=windows
+	else
+	    tcl_cv_sys_version=`uname -s`-`uname -r`
+	    if test "$?" -ne 0 ; then
+		AC_MSG_WARN([can't find uname command])
+		tcl_cv_sys_version=unknown
+	    else
+		if test "`uname -s`" = "AIX" ; then
+		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+		fi
+	    fi
+	fi
+    ])
+    system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+#	Try to determine the proper flags to pass to the compiler
+#	for building shared libraries and other such nonsense.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Defines and substitutes the following vars:
+#
+#	DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
+#       LDFLAGS -      Flags to pass to the compiler when linking object
+#                       files into an executable application binary such
+#                       as tclsh.
+#       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile. Could
+#                       be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+#       CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile.
+#       SHLIB_CFLAGS -  Flags to pass to cc when compiling the components
+#                       of a shared library (may request position-independent
+#                       code, among other things).
+#       SHLIB_LD -      Base command to use for combining object files
+#                       into a shared library.
+#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+#                       creating shared libraries.  This symbol typically
+#                       goes at the end of the "ld" commands that build
+#                       shared libraries. The value of the symbol defaults to
+#                       "${LIBS}" if all of the dependent libraries should
+#                       be specified when creating a shared library.  If
+#                       dependent libraries should not be specified (as on
+#                       SunOS 4.x, where they cause the link to fail, or in
+#                       general if Tcl and Tk aren't themselves shared
+#                       libraries), then this symbol has an empty string
+#                       as its value.
+#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
+#                       extensions.  An empty string means we don't know how
+#                       to use shared libraries on this platform.
+#       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
+#                       in a static or shared library name, using the $PACKAGE_VERSION variable
+#                       to put the version in the right place.  This is used
+#                       by platforms that need non-standard library names.
+#                       Examples:  ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
+#                       to have a version after the .so, and ${PACKAGE_VERSION}.a
+#                       on AIX, since a shared library needs to have
+#                       a .a extension whereas shared objects for loadable
+#                       extensions have a .so extension.  Defaults to
+#                       ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
+#	CFLAGS_DEBUG -
+#			Flags used when running the compiler in debug mode
+#	CFLAGS_OPTIMIZE -
+#			Flags used when running the compiler in optimize mode
+#	CFLAGS -	Additional CFLAGS added as necessary (usually 64-bit)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+    dnl TEA specific: Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+
+    # Step 0.a: Enable 64 bit support?
+
+    AC_MSG_CHECKING([if 64bit support is requested])
+    AC_ARG_ENABLE(64bit,
+	AC_HELP_STRING([--enable-64bit],
+	    [enable 64bit support (default: off)]),
+	[do64bit=$enableval], [do64bit=no])
+    AC_MSG_RESULT([$do64bit])
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+    AC_ARG_ENABLE(64bit-vis,
+	AC_HELP_STRING([--enable-64bit-vis],
+	    [enable 64bit Sparc VIS support (default: off)]),
+	[do64bitVIS=$enableval], [do64bitVIS=no])
+    AC_MSG_RESULT([$do64bitVIS])
+    # Force 64bit on with VIS
+    AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
+
+    # Step 0.c: Check if visibility support is available. Do this here so
+    # that platform specific alternatives can be used below if this fails.
+
+    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
+	tcl_cv_cc_visibility_hidden, [
+	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+	AC_TRY_LINK([
+	    extern __attribute__((__visibility__("hidden"))) void f(void);
+	    void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
+	    tcl_cv_cc_visibility_hidden=no)
+	CFLAGS=$hold_cflags])
+    AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
+	AC_DEFINE(MODULE_SCOPE,
+	    [extern __attribute__((__visibility__("hidden")))],
+	    [Compiler support for module scope symbols])
+	AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
+    ])
+
+    # Step 0.d: Disable -rpath support?
+
+    AC_MSG_CHECKING([if rpath support is requested])
+    AC_ARG_ENABLE(rpath,
+	AC_HELP_STRING([--disable-rpath],
+	    [disable rpath support (default: on)]),
+	[doRpath=$enableval], [doRpath=yes])
+    AC_MSG_RESULT([$doRpath])
+
+    # TEA specific: Cross-compiling options for Windows/CE builds?
+
+    AS_IF([test "${TEA_PLATFORM}" = windows], [
+	AC_MSG_CHECKING([if Windows/CE build is requested])
+	AC_ARG_ENABLE(wince,
+	    AC_HELP_STRING([--enable-wince],
+		[enable Win/CE support (where applicable)]),
+	    [doWince=$enableval], [doWince=no])
+	AC_MSG_RESULT([$doWince])
+    ])
+
+    # Set the variable "system" to hold the name and version number
+    # for the system.
+
+    TEA_CONFIG_SYSTEM
+
+    # Require ranlib early so we can override it in special cases below.
+
+    AC_REQUIRE([AC_PROG_RANLIB])
+
+    # Set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case and removed some core-only vars.
+
+    do64bit_ok=no
+    # default to '{$LIBS}' and set to "" on per-platform necessary basis
+    SHLIB_LD_LIBS='${LIBS}'
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    UNSHARED_LIB_SUFFIX=""
+    # TEA specific: use PACKAGE_VERSION instead of VERSION
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    AS_IF([test "$GCC" = yes], [
+	CFLAGS_OPTIMIZE=-O2
+	CFLAGS_WARNING="-Wall"
+    ], [
+	CFLAGS_OPTIMIZE=-O
+	CFLAGS_WARNING=""
+    ])
+    AC_CHECK_TOOL(AR, ar)
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION="1.0"])
+    case $system in
+	# TEA specific:
+	windows)
+	    # This is a 2-stage check to make sure we have the 64-bit SDK
+	    # We have to know where the SDK is installed.
+	    # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+	    # MACHINE is IX86 for LINK, but this is used by the manifest,
+	    # which requires x86|amd64|ia64.
+	    MACHINE="X86"
+	    if test "$do64bit" != "no" ; then
+		if test "x${MSSDK}x" = "xx" ; then
+		    MSSDK="C:/Progra~1/Microsoft Platform SDK"
+		fi
+		MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+		PATH64=""
+		case "$do64bit" in
+		    amd64|x64|yes)
+			MACHINE="AMD64" ; # default to AMD64 64-bit build
+			PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+			;;
+		    ia64)
+			MACHINE="IA64"
+			PATH64="${MSSDK}/Bin/Win64"
+			;;
+		esac
+		if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then
+		    AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+		    AC_MSG_WARN([Ensure latest Platform SDK is installed])
+		    do64bit="no"
+		else
+		    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
+		    do64bit_ok="yes"
+		fi
+	    fi
+
+	    if test "$doWince" != "no" ; then
+		if test "$do64bit" != "no" ; then
+		    AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+		fi
+		if test "$GCC" = "yes" ; then
+		    AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+		fi
+		TEA_PATH_CELIB
+		# Set defaults for common evc4/PPC2003 setup
+		# Currently Tcl requires 300+, possibly 420+ for sockets
+		CEVERSION=420; 		# could be 211 300 301 400 420 ...
+		TARGETCPU=ARMV4;	# could be ARMV4 ARM MIPS SH3 X86 ...
+		ARCH=ARM;		# could be ARM MIPS X86EM ...
+		PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+		if test "$doWince" != "yes"; then
+		    # If !yes then the user specified something
+		    # Reset ARCH to allow user to skip specifying it
+		    ARCH=
+		    eval `echo $doWince | awk -F, '{ \
+	    if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+	    if ([$]1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+	    if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+	    if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+	    if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+		    }'`
+		    if test "x${ARCH}" = "x" ; then
+			ARCH=$TARGETCPU;
+		    fi
+		fi
+		OSVERSION=WCE$CEVERSION;
+	    	if test "x${WCEROOT}" = "x" ; then
+			WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+		    if test ! -d "${WCEROOT}" ; then
+			WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+		    fi
+		fi
+		if test "x${SDKROOT}" = "x" ; then
+		    SDKROOT="C:/Program Files/Windows CE Tools"
+		    if test ! -d "${SDKROOT}" ; then
+			SDKROOT="C:/Windows CE Tools"
+		    fi
+		fi
+		WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+		SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+		if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+		    -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+		    AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+		    doWince="no"
+		else
+		    # We could PATH_NOSPACE these, but that's not important,
+		    # as long as we quote them when used.
+		    CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+		    if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+			CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+		    fi
+		    CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+    		fi
+	    fi
+
+	    if test "$GCC" != "yes" ; then
+	        if test "${SHARED_BUILD}" = "0" ; then
+		    runtime=-MT
+	        else
+		    runtime=-MD
+	        fi
+
+                if test "$do64bit" != "no" ; then
+		    # All this magic is necessary for the Win64 SDK RC1 - hobbs
+		    CC="\"${PATH64}/cl.exe\""
+		    CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+		    RC="\"${MSSDK}/bin/rc.exe\""
+		    lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+		    LINKBIN="\"${PATH64}/link.exe\""
+		    CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+		    # Avoid 'unresolved external symbol __security_cookie'
+		    # errors, c.f. http://support.microsoft.com/?id=894573
+		    TEA_ADD_LIBS([bufferoverflowU.lib])
+		elif test "$doWince" != "no" ; then
+		    CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+		    if test "${TARGETCPU}" = "X86"; then
+			CC="\"${CEBINROOT}/cl.exe\""
+		    else
+			CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+		    fi
+		    CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+		    RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+		    arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+		    defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+		    if test "${SHARED_BUILD}" = "1" ; then
+			# Static CE builds require static celib as well
+		    	defs="${defs} _DLL"
+		    fi
+		    for i in $defs ; do
+			AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+		    done
+		    AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+		    AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+		    CFLAGS_DEBUG="-nologo -Zi -Od"
+		    CFLAGS_OPTIMIZE="-nologo -Ox"
+		    lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+		    lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+		    LINKBIN="\"${CEBINROOT}/link.exe\""
+		    AC_SUBST(CELIB_DIR)
+		else
+		    RC="rc"
+		    lflags="-nologo"
+    		    LINKBIN="link"
+		    CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+		fi
+	    fi
+
+	    if test "$GCC" = "yes"; then
+		# mingw gcc mode
+		AC_CHECK_TOOL(RC, windres)
+		CFLAGS_DEBUG="-g"
+		CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+		SHLIB_LD='${CC} -shared'
+		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+		LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+		LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+
+		AC_CACHE_CHECK(for cross-compile version of gcc,
+			ac_cv_cross,
+			AC_TRY_COMPILE([
+			    #ifdef __WIN32__
+				#error cross-compiler
+			    #endif
+			], [],
+			ac_cv_cross=yes,
+			ac_cv_cross=no)
+		      )
+		      if test "$ac_cv_cross" = "yes"; then
+			case "$do64bit" in
+			    amd64|x64|yes)
+				CC="x86_64-w64-mingw32-gcc"
+				LD="x86_64-w64-mingw32-ld"
+				AR="x86_64-w64-mingw32-ar"
+				RANLIB="x86_64-w64-mingw32-ranlib"
+				RC="x86_64-w64-mingw32-windres"
+			    ;;
+			    *)
+				CC="i686-w64-mingw32-gcc"
+				LD="i686-w64-mingw32-ld"
+				AR="i686-w64-mingw32-ar"
+				RANLIB="i686-w64-mingw32-ranlib"
+				RC="i686-w64-mingw32-windres"
+			    ;;
+			esac
+		fi
+
+	    else
+		SHLIB_LD="${LINKBIN} -dll ${lflags}"
+		# link -lib only works when -lib is the first arg
+		STLIB_LD="${LINKBIN} -lib ${lflags}"
+		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+		PATHTYPE=-w
+		# For information on what debugtype is most useful, see:
+		# http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+		# and also
+		# http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
+		# This essentially turns it all on.
+		LDFLAGS_DEBUG="-debug -debugtype:cv"
+		LDFLAGS_OPTIMIZE="-release"
+		if test "$doWince" != "no" ; then
+		    LDFLAGS_CONSOLE="-link ${lflags}"
+		    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+		else
+		    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+		    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+		fi
+	    fi
+
+	    SHLIB_SUFFIX=".dll"
+	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+	    TCL_LIB_VERSIONS_OK=nodots
+    	    ;;
+	AIX-*)
+	    AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
+		# AIX requires the _r compiler when gcc isn't being used
+		case "${CC}" in
+		    *_r|*_r\ *)
+			# ok ...
+			;;
+		    *)
+			# Make sure only first arg gets _r
+		    	CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
+			;;
+		esac
+		AC_MSG_RESULT([Using $CC for compiling with threads])
+	    ])
+	    LIBS="$LIBS -lc"
+	    SHLIB_CFLAGS=""
+	    SHLIB_SUFFIX=".so"
+
+	    LD_LIBRARY_PATH_VAR="LIBPATH"
+
+	    # Check to enable 64-bit flags for compiler/linker
+	    AS_IF([test "$do64bit" = yes], [
+		AS_IF([test "$GCC" = yes], [
+		    AC_MSG_WARN([64bit mode not supported with GCC on $system])
+		], [
+		    do64bit_ok=yes
+		    CFLAGS="$CFLAGS -q64"
+		    LDFLAGS_ARCH="-q64"
+		    RANLIB="${RANLIB} -X64"
+		    AR="${AR} -X64"
+		    SHLIB_LD_FLAGS="-b64"
+		])
+	    ])
+
+	    AS_IF([test "`uname -m`" = ia64], [
+		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+		AS_IF([test "$GCC" = yes], [
+		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+		], [
+		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+		])
+		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+	    ], [
+		AS_IF([test "$GCC" = yes], [
+		    SHLIB_LD='${CC} -shared -Wl,-bexpall'
+		], [
+		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
+		    LDFLAGS="$LDFLAGS -brtl"
+		])
+		SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+		CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+	    ])
+	    ;;
+	BeOS*)
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_LD='${CC} -nostart'
+	    SHLIB_SUFFIX=".so"
+
+	    #-----------------------------------------------------------
+	    # Check for inet_ntoa in -lbind, for BeOS (which also needs
+	    # -lsocket, even if the network functions are in -lnet which
+	    # is always linked to, for compatibility.
+	    #-----------------------------------------------------------
+	    AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+	    ;;
+	BSD/OS-4.*)
+	    SHLIB_CFLAGS="-export-dynamic -fPIC"
+	    SHLIB_LD='${CC} -shared'
+	    SHLIB_SUFFIX=".so"
+	    LDFLAGS="$LDFLAGS -export-dynamic"
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    ;;
+	CYGWIN_*)
+	    SHLIB_CFLAGS=""
+	    SHLIB_LD='${CC} -shared'
+	    SHLIB_SUFFIX=".dll"
+	    EXEEXT=".exe"
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    ;;
+	Haiku*)
+	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_SUFFIX=".so"
+	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
+	    AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
+	    ;;
+	HP-UX-*.11.*)
+	    # Use updated header definitions where possible
+	    AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+	    # TEA specific: Needed by Tcl, but not most extensions
+	    #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+	    #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+	    AS_IF([test "`uname -m`" = ia64], [
+		SHLIB_SUFFIX=".so"
+		# Use newer C++ library for C++ extensions
+		#if test "$GCC" != "yes" ; then
+		#   CPPFLAGS="-AA"
+		#fi
+	    ], [
+		SHLIB_SUFFIX=".sl"
+	    ])
+	    AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+	    AS_IF([test "$tcl_ok" = yes], [
+		LDFLAGS="$LDFLAGS -Wl,-E"
+		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+	    ])
+	    AS_IF([test "$GCC" = yes], [
+		SHLIB_LD='${CC} -shared'
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+	    ], [
+		CFLAGS="$CFLAGS -z"
+		# Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+		#CFLAGS="$CFLAGS +DAportable"
+		SHLIB_CFLAGS="+z"
+		SHLIB_LD="ld -b"
+	    ])
+
+	    # Check to enable 64-bit flags for compiler/linker
+	    AS_IF([test "$do64bit" = "yes"], [
+		AS_IF([test "$GCC" = yes], [
+		    case `${CC} -dumpmachine` in
+			hppa64*)
+			    # 64-bit gcc in use.  Fix flags for GNU ld.
+			    do64bit_ok=yes
+			    SHLIB_LD='${CC} -shared'
+			    AS_IF([test $doRpath = yes], [
+				CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+			    ;;
+			*)
+			    AC_MSG_WARN([64bit mode not supported with GCC on $system])
+			    ;;
+		    esac
+		], [
+		    do64bit_ok=yes
+		    CFLAGS="$CFLAGS +DD64"
+		    LDFLAGS_ARCH="+DD64"
+		])
+	    ]) ;;
+	IRIX-6.*)
+	    SHLIB_CFLAGS=""
+	    SHLIB_LD="ld -n32 -shared -rdata_shared"
+	    SHLIB_SUFFIX=".so"
+	    AS_IF([test $doRpath = yes], [
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+	    AS_IF([test "$GCC" = yes], [
+		CFLAGS="$CFLAGS -mabi=n32"
+		LDFLAGS="$LDFLAGS -mabi=n32"
+	    ], [
+		case $system in
+		    IRIX-6.3)
+			# Use to build 6.2 compatible binaries on 6.3.
+			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+			;;
+		    *)
+			CFLAGS="$CFLAGS -n32"
+			;;
+		esac
+		LDFLAGS="$LDFLAGS -n32"
+	    ])
+	    ;;
+	IRIX64-6.*)
+	    SHLIB_CFLAGS=""
+	    SHLIB_LD="ld -n32 -shared -rdata_shared"
+	    SHLIB_SUFFIX=".so"
+	    AS_IF([test $doRpath = yes], [
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+
+	    # Check to enable 64-bit flags for compiler/linker
+
+	    AS_IF([test "$do64bit" = yes], [
+	        AS_IF([test "$GCC" = yes], [
+	            AC_MSG_WARN([64bit mode not supported by gcc])
+	        ], [
+	            do64bit_ok=yes
+	            SHLIB_LD="ld -64 -shared -rdata_shared"
+	            CFLAGS="$CFLAGS -64"
+	            LDFLAGS_ARCH="-64"
+	        ])
+	    ])
+	    ;;
+	Linux*|GNU*|NetBSD-Debian)
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_SUFFIX=".so"
+
+	    # TEA specific:
+	    CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+
+	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+	    AS_IF([test $doRpath = yes], [
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+	    AS_IF([test $do64bit = yes], [
+		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+		    hold_cflags=$CFLAGS
+		    CFLAGS="$CFLAGS -m64"
+		    AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+		    CFLAGS=$hold_cflags])
+		AS_IF([test $tcl_cv_cc_m64 = yes], [
+		    CFLAGS="$CFLAGS -m64"
+		    do64bit_ok=yes
+		])
+	   ])
+
+	    # The combo of gcc + glibc has a bug related to inlining of
+	    # functions like strtod(). The -fno-builtin flag should address
+	    # this problem but it does not work. The -fno-inline flag is kind
+	    # of overkill but it works. Disable inlining only when one of the
+	    # files in compat/*.c is being linked in.
+
+	    AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
+	    ;;
+	Lynx*)
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_SUFFIX=".so"
+	    CFLAGS_OPTIMIZE=-02
+	    SHLIB_LD='${CC} -shared'
+	    LD_FLAGS="-Wl,--export-dynamic"
+	    AS_IF([test $doRpath = yes], [
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+	    ;;
+	OpenBSD-*)
+	    arch=`arch -s`
+	    case "$arch" in
+	    vax)
+		SHLIB_SUFFIX=""
+		SHARED_LIB_SUFFIX=""
+		LDFLAGS=""
+		;;
+	    *)
+		SHLIB_CFLAGS="-fPIC"
+		SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+		SHLIB_SUFFIX=".so"
+		AS_IF([test $doRpath = yes], [
+		    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+		LDFLAGS="-Wl,-export-dynamic"
+		;;
+	    esac
+	    case "$arch" in
+	    vax)
+		CFLAGS_OPTIMIZE="-O1"
+		;;
+	    *)
+		CFLAGS_OPTIMIZE="-O2"
+		;;
+	    esac
+	    AS_IF([test "${TCL_THREADS}" = "1"], [
+		# On OpenBSD:	Compile with -pthread
+		#		Don't link with -lpthread
+		LIBS=`echo $LIBS | sed s/-lpthread//`
+		CFLAGS="$CFLAGS -pthread"
+	    ])
+	    # OpenBSD doesn't do version numbers with dots.
+	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+	    TCL_LIB_VERSIONS_OK=nodots
+	    ;;
+	NetBSD-*)
+	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+	    SHLIB_SUFFIX=".so"
+	    LDFLAGS="$LDFLAGS -export-dynamic"
+	    AS_IF([test $doRpath = yes], [
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+	    AS_IF([test "${TCL_THREADS}" = "1"], [
+		# The -pthread needs to go in the CFLAGS, not LIBS
+		LIBS=`echo $LIBS | sed s/-pthread//`
+		CFLAGS="$CFLAGS -pthread"
+	    	LDFLAGS="$LDFLAGS -pthread"
+	    ])
+	    ;;
+	FreeBSD-*)
+	    # This configuration from FreeBSD Ports.
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_LD="${CC} -shared"
+	    TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$[@]"
+	    SHLIB_SUFFIX=".so"
+	    LDFLAGS=""
+	    AS_IF([test $doRpath = yes], [
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+	    AS_IF([test "${TCL_THREADS}" = "1"], [
+		# The -pthread needs to go in the LDFLAGS, not LIBS
+		LIBS=`echo $LIBS | sed s/-pthread//`
+		CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+		LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
+	    # Version numbers are dot-stripped by system policy.
+	    TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .`
+	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
+	    TCL_LIB_VERSIONS_OK=nodots
+	    ;;
+	Darwin-*)
+	    CFLAGS_OPTIMIZE="-Os"
+	    SHLIB_CFLAGS="-fno-common"
+	    # To avoid discrepancies between what headers configure sees during
+	    # preprocessing tests and compiling tests, move any -isysroot and
+	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+		if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
+	    CFLAGS="`echo " ${CFLAGS}" | \
+		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+		if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
+	    AS_IF([test $do64bit = yes], [
+		case `arch` in
+		    ppc)
+			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+				tcl_cv_cc_arch_ppc64, [
+			    hold_cflags=$CFLAGS
+			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+			    AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+				    tcl_cv_cc_arch_ppc64=no)
+			    CFLAGS=$hold_cflags])
+			AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
+			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+			    do64bit_ok=yes
+			]);;
+		    i386)
+			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+				tcl_cv_cc_arch_x86_64, [
+			    hold_cflags=$CFLAGS
+			    CFLAGS="$CFLAGS -arch x86_64"
+			    AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+				    tcl_cv_cc_arch_x86_64=no)
+			    CFLAGS=$hold_cflags])
+			AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
+			    CFLAGS="$CFLAGS -arch x86_64"
+			    do64bit_ok=yes
+			]);;
+		    *)
+			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+		esac
+	    ], [
+		# Check for combined 32-bit and 64-bit fat build
+		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
+		    fat_32_64=yes])
+	    ])
+	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+		hold_ldflags=$LDFLAGS
+		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+		AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+		LDFLAGS=$hold_ldflags])
+	    AS_IF([test $tcl_cv_ld_single_module = yes], [
+		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+	    ])
+	    # TEA specific: link shlib with current and compatibility version flags
+	    vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
+	    SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
+	    SHLIB_SUFFIX=".dylib"
+	    # Don't use -prebind when building for Mac OS X 10.4 or later only:
+	    AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+		"`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
+		LDFLAGS="$LDFLAGS -prebind"])
+	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
+		    tcl_cv_ld_search_paths_first, [
+		hold_ldflags=$LDFLAGS
+		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+		AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
+			tcl_cv_ld_search_paths_first=no)
+		LDFLAGS=$hold_ldflags])
+	    AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
+		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+	    ])
+	    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+		AC_DEFINE(MODULE_SCOPE, [__private_extern__],
+		    [Compiler support for module scope symbols])
+		tcl_cv_cc_visibility_hidden=yes
+	    ])
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+	    # TEA specific: for combined 32 & 64 bit fat builds of Tk
+	    # extensions, verify that 64-bit build is possible.
+	    AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
+		AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
+		    AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
+			for v in CFLAGS CPPFLAGS LDFLAGS; do
+			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+			done
+			CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+			LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+			AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
+			    tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
+			for v in CFLAGS CPPFLAGS LDFLAGS; do
+			    eval $v'="$hold_'$v'"'
+			done])
+		])
+		AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
+		    AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
+			for v in CFLAGS CPPFLAGS LDFLAGS; do
+			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+			done
+			CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
+			LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
+			AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
+			    tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
+			for v in CFLAGS CPPFLAGS LDFLAGS; do
+			    eval $v'="$hold_'$v'"'
+			done])
+		])
+		# remove 64-bit arch flags from CFLAGS et al. if configuration
+		# does not support 64-bit.
+		AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
+		    AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
+		    for v in CFLAGS CPPFLAGS LDFLAGS; do
+			eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+		    done])
+	    ])
+	    ;;
+	OS/390-*)
+	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy
+	    AC_DEFINE(_OE_SOCKETS, 1,	# needed in sys/socket.h
+		[Should OS/390 do the right thing with sockets?])
+	    ;;
+	OSF1-V*)
+	    # Digital OSF/1
+	    SHLIB_CFLAGS=""
+	    AS_IF([test "$SHARED_BUILD" = 1], [
+	        SHLIB_LD='ld -shared -expect_unresolved "*"'
+	    ], [
+	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+	    ])
+	    SHLIB_SUFFIX=".so"
+	    AS_IF([test $doRpath = yes], [
+		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+	    AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
+		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
+	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
+	    AS_IF([test "${TCL_THREADS}" = 1], [
+		CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+		CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+		LIBS=`echo $LIBS | sed s/-lpthreads//`
+		AS_IF([test "$GCC" = yes], [
+		    LIBS="$LIBS -lpthread -lmach -lexc"
+		], [
+		    CFLAGS="$CFLAGS -pthread"
+		    LDFLAGS="$LDFLAGS -pthread"
+		])
+	    ])
+	    ;;
+	QNX-6*)
+	    # QNX RTP
+	    # This may work for all QNX, but it was only reported for v6.
+	    SHLIB_CFLAGS="-fPIC"
+	    SHLIB_LD="ld -Bshareable -x"
+	    SHLIB_LD_LIBS=""
+	    SHLIB_SUFFIX=".so"
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    ;;
+	SCO_SV-3.2*)
+	    AS_IF([test "$GCC" = yes], [
+		SHLIB_CFLAGS="-fPIC -melf"
+		LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+	    ], [
+	       SHLIB_CFLAGS="-Kpic -belf"
+	       LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+	    ])
+	    SHLIB_LD="ld -G"
+	    SHLIB_LD_LIBS=""
+	    SHLIB_SUFFIX=".so"
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    ;;
+	SunOS-5.[[0-6]])
+	    # Careful to not let 5.10+ fall into this case
+
+	    # Note: If _REENTRANT isn't defined, then Solaris
+	    # won't define thread-safe library routines.
+
+	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+		[Do we really want to follow the standard? Yes we do!])
+
+	    SHLIB_CFLAGS="-KPIC"
+	    SHLIB_SUFFIX=".so"
+	    AS_IF([test "$GCC" = yes], [
+		SHLIB_LD='${CC} -shared'
+		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+	    ], [
+		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+		CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+	    ])
+	    ;;
+	SunOS-5*)
+	    # Note: If _REENTRANT isn't defined, then Solaris
+	    # won't define thread-safe library routines.
+
+	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+		[Do we really want to follow the standard? Yes we do!])
+
+	    SHLIB_CFLAGS="-KPIC"
+
+	    # Check to enable 64-bit flags for compiler/linker
+	    AS_IF([test "$do64bit" = yes], [
+		arch=`isainfo`
+		AS_IF([test "$arch" = "sparcv9 sparc"], [
+		    AS_IF([test "$GCC" = yes], [
+			AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
+			    AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+			], [
+			    do64bit_ok=yes
+			    CFLAGS="$CFLAGS -m64 -mcpu=v9"
+			    LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+			    SHLIB_CFLAGS="-fPIC"
+			])
+		    ], [
+			do64bit_ok=yes
+			AS_IF([test "$do64bitVIS" = yes], [
+			    CFLAGS="$CFLAGS -xarch=v9a"
+			    LDFLAGS_ARCH="-xarch=v9a"
+			], [
+			    CFLAGS="$CFLAGS -xarch=v9"
+			    LDFLAGS_ARCH="-xarch=v9"
+			])
+			# Solaris 64 uses this as well
+			#LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+		    ])
+		], [AS_IF([test "$arch" = "amd64 i386"], [
+		    AS_IF([test "$GCC" = yes], [
+			case $system in
+			    SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+				do64bit_ok=yes
+				CFLAGS="$CFLAGS -m64"
+				LDFLAGS="$LDFLAGS -m64";;
+			    *)
+				AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
+			esac
+		    ], [
+			do64bit_ok=yes
+			case $system in
+			    SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+				CFLAGS="$CFLAGS -m64"
+				LDFLAGS="$LDFLAGS -m64";;
+			    *)
+				CFLAGS="$CFLAGS -xarch=amd64"
+				LDFLAGS="$LDFLAGS -xarch=amd64";;
+			esac
+		    ])
+		], [AC_MSG_WARN([64bit mode not supported for $arch])])])
+	    ])
+
+	    SHLIB_SUFFIX=".so"
+	    AS_IF([test "$GCC" = yes], [
+		SHLIB_LD='${CC} -shared'
+		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+		AS_IF([test "$do64bit_ok" = yes], [
+		    AS_IF([test "$arch" = "sparcv9 sparc"], [
+			# We need to specify -static-libgcc or we need to
+			# add the path to the sparv9 libgcc.
+			# JH: static-libgcc is necessary for core Tcl, but may
+			# not be necessary for extensions.
+			SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+			# for finding sparcv9 libgcc, get the regular libgcc
+			# path, remove so name and append 'sparcv9'
+			#v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+			#CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+		    ], [AS_IF([test "$arch" = "amd64 i386"], [
+			# JH: static-libgcc is necessary for core Tcl, but may
+			# not be necessary for extensions.
+			SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+		    ])])
+		])
+	    ], [
+		case $system in
+		    SunOS-5.[[1-9]][[0-9]]*)
+			# TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+			SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
+		    *)
+			SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+		esac
+		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+	    ])
+	    ;;
+	UNIX_SV* | UnixWare-5*)
+	    SHLIB_CFLAGS="-KPIC"
+	    SHLIB_LD='${CC} -G'
+	    SHLIB_LD_LIBS=""
+	    SHLIB_SUFFIX=".so"
+	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+	    # that don't grok the -Bexport option.  Test that it does.
+	    AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+		hold_ldflags=$LDFLAGS
+		LDFLAGS="$LDFLAGS -Wl,-Bexport"
+		AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+	        LDFLAGS=$hold_ldflags])
+	    AS_IF([test $tcl_cv_ld_Bexport = yes], [
+		LDFLAGS="$LDFLAGS -Wl,-Bexport"
+	    ])
+	    CC_SEARCH_FLAGS=""
+	    LD_SEARCH_FLAGS=""
+	    ;;
+    esac
+
+    AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
+	AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+    ])
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+    # Add in the arch flags late to ensure it wasn't removed.
+    # Not necessary in TEA, but this is aligned with core
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    AS_IF([test "$GCC" = yes], [
+	case $system in
+	    AIX-*) ;;
+	    BSD/OS*) ;;
+	    CYGWIN_*|MINGW32_*) ;;
+	    IRIX*) ;;
+	    NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+	    Darwin-*) ;;
+	    SCO_SV-3.2*) ;;
+	    windows) ;;
+	    *) SHLIB_CFLAGS="-fPIC" ;;
+	esac])
+
+    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+	AC_DEFINE(MODULE_SCOPE, [extern],
+	    [No Compiler support for module scope symbols])
+    ])
+
+    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
+    # TEA specific: use PACKAGE_VERSION instead of VERSION
+    SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
+    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
+    # TEA specific: use PACKAGE_VERSION instead of VERSION
+    UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
+
+    if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
+	AC_CACHE_CHECK(for SEH support in compiler,
+	    tcl_cv_seh,
+	AC_TRY_RUN([
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+	    int main(int argc, char** argv) {
+		int a, b = 0;
+		__try {
+		    a = 666 / b;
+		}
+		__except (EXCEPTION_EXECUTE_HANDLER) {
+		    return 0;
+		}
+		return 1;
+	    }
+	],
+	    tcl_cv_seh=yes,
+	    tcl_cv_seh=no,
+	    tcl_cv_seh=no)
+	)
+	if test "$tcl_cv_seh" = "no" ; then
+	    AC_DEFINE(HAVE_NO_SEH, 1,
+		    [Defined when mingw does not support SEH])
+	fi
+
+	#
+	# Check to see if the excpt.h include file provided contains the
+	# definition for EXCEPTION_DISPOSITION; if not, which is the case
+	# with Cygwin's version as of 2002-04-10, define it to be int,
+	# sufficient for getting the current code to work.
+	#
+	AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
+	    tcl_cv_eh_disposition,
+	    AC_TRY_COMPILE([
+#	    define WIN32_LEAN_AND_MEAN
+#	    include <windows.h>
+#	    undef WIN32_LEAN_AND_MEAN
+	    ],[
+		EXCEPTION_DISPOSITION x;
+	    ],
+		tcl_cv_eh_disposition=yes,
+		tcl_cv_eh_disposition=no)
+	)
+	if test "$tcl_cv_eh_disposition" = "no" ; then
+	AC_DEFINE(EXCEPTION_DISPOSITION, int,
+		[Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
+	fi
+
+	# Check to see if winnt.h defines CHAR, SHORT, and LONG
+	# even if VOID has already been #defined. The win32api
+	# used by mingw and cygwin is known to do this.
+
+	AC_CACHE_CHECK(for winnt.h that ignores VOID define,
+	    tcl_cv_winnt_ignore_void,
+	    AC_TRY_COMPILE([
+#define VOID void
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+	    ], [
+		CHAR c;
+		SHORT s;
+		LONG l;
+	    ],
+        tcl_cv_winnt_ignore_void=yes,
+        tcl_cv_winnt_ignore_void=no)
+	)
+	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
+	    AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
+		    [Defined when cygwin/mingw ignores VOID define in winnt.h])
+	fi
+    fi
+
+	# See if the compiler supports casting to a union type.
+	# This is used to stop gcc from printing a compiler
+	# warning when initializing a union member.
+
+	AC_CACHE_CHECK(for cast to union support,
+	    tcl_cv_cast_to_union,
+	    AC_TRY_COMPILE([],
+	    [
+		  union foo { int i; double d; };
+		  union foo f = (union foo) (int) 0;
+	    ],
+	    tcl_cv_cast_to_union=yes,
+	    tcl_cv_cast_to_union=no)
+	)
+	if test "$tcl_cv_cast_to_union" = "yes"; then
+	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
+		    [Defined when compiler supports casting to union type.])
+	fi
+
+    AC_SUBST(CFLAGS_DEBUG)
+    AC_SUBST(CFLAGS_OPTIMIZE)
+    AC_SUBST(CFLAGS_WARNING)
+
+    AC_SUBST(STLIB_LD)
+    AC_SUBST(SHLIB_LD)
+
+    AC_SUBST(SHLIB_LD_LIBS)
+    AC_SUBST(SHLIB_CFLAGS)
+
+    AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+    TEA_TCL_EARLY_FLAGS
+    TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+#	Determine which interface to use to talk to the serial port.
+#	Note that #include lines must begin in leftmost column for
+#	some compilers to recognize them as preprocessor directives,
+#	and some build environments have stdin not pointing at a
+#	pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Defines only one of the following vars:
+#		HAVE_SYS_MODEM_H
+#		USE_TERMIOS
+#		USE_TERMIO
+#		USE_SGTTY
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+    AC_CHECK_HEADERS(sys/modem.h)
+    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+    AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0) {
+	cfsetospeed(&t, 0);
+	t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+	return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    if test $tcl_cv_api_serial = no ; then
+	AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0) {
+	t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+	return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+	AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0) {
+	t.sg_ospeed = 0;
+	t.sg_flags |= ODDP | EVENP | RAW;
+	return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+	AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0
+	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+	cfsetospeed(&t, 0);
+	t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+	return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+	AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0
+	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+	t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+	return 0;
+    }
+    return 1;
+    }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+	AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0
+	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+	t.sg_ospeed = 0;
+	t.sg_flags |= ODDP | EVENP | RAW;
+	return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+    fi])
+    case $tcl_cv_api_serial in
+	termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+	termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+	sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_MISSING_POSIX_HEADERS
+#
+#	Supply substitutes for missing POSIX header files.  Special
+#	notes:
+#	    - stdlib.h doesn't define strtol, strtoul, or
+#	      strtod in some versions of SunOS
+#	    - some versions of string.h don't declare procedures such
+#	      as strstr
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Defines some of the following vars:
+#		NO_DIRENT_H
+#		NO_ERRNO_H
+#		NO_VALUES_H
+#		HAVE_LIMITS_H or NO_LIMITS_H
+#		NO_STDLIB_H
+#		NO_STRING_H
+#		NO_SYS_WAIT_H
+#		NO_DLFCN_H
+#		HAVE_SYS_PARAM_H
+#
+#		HAVE_STRING_H ?
+#
+# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
+# CHECK on limits.h
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
+    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
+    AC_TRY_LINK([#include <sys/types.h>
+#include <dirent.h>], [
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+	/*
+	 * Generate compilation error to make the test fail:  Lynx headers
+	 * are only valid if really in the POSIX environment.
+	 */
+
+	missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
+
+    if test $tcl_cv_dirent_h = no; then
+	AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
+    fi
+
+    # TEA specific:
+    AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
+    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
+    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
+    AC_CHECK_HEADER(limits.h,
+	[AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
+	[AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
+    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
+    if test $tcl_ok = 0; then
+	AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
+    fi
+    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+	AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
+    fi
+
+    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
+    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+    AC_HAVE_HEADERS(sys/param.h)
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+#	Locate the X11 header files and the X11 library archive.  Try
+#	the ac_path_x macro first, but if it doesn't find the X stuff
+#	(e.g. because there's no xmkmf program) then check through
+#	a list of possible directories.  Under some conditions the
+#	autoconf macro will return an include directory that contains
+#	no include files, so double-check its result just to be safe.
+#
+#	This should be called after TEA_CONFIG_CFLAGS as setting the
+#	LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Sets the following vars:
+#		XINCLUDES
+#		XLIBSW
+#		PKG_LIBS (appends to)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+    if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+	TEA_PATH_UNIX_X
+    fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+    AC_PATH_X
+    not_really_there=""
+    if test "$no_x" = ""; then
+	if test "$x_includes" = ""; then
+	    AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
+	else
+	    if test ! -r $x_includes/X11/Xlib.h; then
+		not_really_there="yes"
+	    fi
+	fi
+    fi
+    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+	AC_MSG_CHECKING([for X11 header files])
+	found_xincludes="no"
+	AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
+	if test "$found_xincludes" = "no"; then
+	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+	    for i in $dirs ; do
+		if test -r $i/X11/Xlib.h; then
+		    AC_MSG_RESULT([$i])
+		    XINCLUDES=" -I$i"
+		    found_xincludes="yes"
+		    break
+		fi
+	    done
+	fi
+    else
+	if test "$x_includes" != ""; then
+	    XINCLUDES="-I$x_includes"
+	    found_xincludes="yes"
+	fi
+    fi
+    if test "$found_xincludes" = "no"; then
+	AC_MSG_RESULT([couldn't find any!])
+    fi
+
+    if test "$no_x" = yes; then
+	AC_MSG_CHECKING([for X11 libraries])
+	XLIBSW=nope
+	dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+	for i in $dirs ; do
+	    if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+		AC_MSG_RESULT([$i])
+		XLIBSW="-L$i -lX11"
+		x_libraries="$i"
+		break
+	    fi
+	done
+    else
+	if test "$x_libraries" = ""; then
+	    XLIBSW=-lX11
+	else
+	    XLIBSW="-L$x_libraries -lX11"
+	fi
+    fi
+    if test "$XLIBSW" = nope ; then
+	AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+    fi
+    if test "$XLIBSW" = nope ; then
+	AC_MSG_RESULT([could not find any!  Using -lX11.])
+	XLIBSW=-lX11
+    fi
+    # TEA specific:
+    if test x"${XLIBSW}" != x ; then
+	PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+#	The statements below check for systems where POSIX-style
+#	non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
+#	On these systems (mostly older ones), use the old BSD-style
+#	FIONBIO approach instead.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Defines some of the following vars:
+#		HAVE_SYS_IOCTL_H
+#		HAVE_SYS_FILIO_H
+#		USE_FIONBIO
+#		O_NONBLOCK
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+    AC_CHECK_HEADERS(sys/ioctl.h)
+    AC_CHECK_HEADERS(sys/filio.h)
+    TEA_CONFIG_SYSTEM
+    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+    case $system in
+	OSF*)
+	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+	    AC_MSG_RESULT([FIONBIO])
+	    ;;
+	*)
+	    AC_MSG_RESULT([O_NONBLOCK])
+	    ;;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANDLER
+#
+#	Checks how the system deals with time.h, what time structures
+#	are used on the system, and what fields the structures have.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Defines some of the following vars:
+#		USE_DELTA_FOR_TZ
+#		HAVE_TM_GMTOFF
+#		HAVE_TM_TZADJ
+#		HAVE_TIMEZONE_VAR
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+    AC_CHECK_HEADERS(sys/time.h)
+    AC_HEADER_TIME
+    AC_STRUCT_TIMEZONE
+
+    AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+	AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+	    tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+    if test $tcl_cv_member_tm_tzadj = yes ; then
+	AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+    fi
+
+    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+	AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+	    tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+    if test $tcl_cv_member_tm_gmtoff = yes ; then
+	AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+    fi
+
+    #
+    # Its important to include time.h in this check, as some systems
+    # (like convex) have timezone functions, etc.
+    #
+    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+	AC_TRY_COMPILE([#include <time.h>],
+	    [extern long timezone;
+	    timezone += 1;
+	    exit (0);],
+	    tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+    if test $tcl_cv_timezone_long = yes ; then
+	AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+    else
+	#
+	# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+	#
+	AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+	    AC_TRY_COMPILE([#include <time.h>],
+		[extern time_t timezone;
+		timezone += 1;
+		exit (0);],
+		tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+	if test $tcl_cv_timezone_time = yes ; then
+	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+	fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+#	Under Solaris 2.4, strtod returns the wrong value for the
+#	terminating character under some conditions.  Check for this
+#	and if the problem exists use a substitute procedure
+#	"fixstrtod" (provided by Tcl) that corrects the error.
+#	Also, on Compaq's Tru64 Unix 5.0,
+#	strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Might defines some of the following vars:
+#		strtod (=fixstrtod)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+    if test "$tcl_strtod" = 1; then
+	AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+	    AC_TRY_RUN([
+		extern double strtod();
+		int main() {
+		    char *infString="Inf", *nanString="NaN", *spaceString=" ";
+		    char *term;
+		    double value;
+		    value = strtod(infString, &term);
+		    if ((term != infString) && (term[-1] == 0)) {
+			exit(1);
+		    }
+		    value = strtod(nanString, &term);
+		    if ((term != nanString) && (term[-1] == 0)) {
+			exit(1);
+		    }
+		    value = strtod(spaceString, &term);
+		    if (term == (spaceString+1)) {
+			exit(1);
+		    }
+		    exit(0);
+		}], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+		    tcl_cv_strtod_buggy=buggy)])
+	if test "$tcl_cv_strtod_buggy" = buggy; then
+	    AC_LIBOBJ([fixstrtod])
+	    USE_COMPAT=1
+	    AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+	fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_LINK_LIBS
+#
+#	Search for the libraries needed to link the Tcl shell.
+#	Things like the math library (-lm) and socket stuff (-lsocket vs.
+#	-lnsl) are dealt with here.
+#
+# Arguments:
+#	Requires the following vars to be set in the Makefile:
+#		DL_LIBS (not in TEA, only needed in core)
+#		LIBS
+#		MATH_LIBS
+#
+# Results:
+#
+#	Substitutes the following vars:
+#		TCL_LIBS
+#		MATH_LIBS
+#
+#	Might append to the following vars:
+#		LIBS
+#
+#	Might define the following vars:
+#		HAVE_NET_ERRNO_H
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_LINK_LIBS], [
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
+    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
+    AC_CHECK_HEADER(net/errno.h, [
+	AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
+
+    #--------------------------------------------------------------------
+    #	Check for the existence of the -lsocket and -lnsl libraries.
+    #	The order here is important, so that they end up in the right
+    #	order in the command line generated by make.  Here are some
+    #	special considerations:
+    #	1. Use "connect" and "accept" to check for -lsocket, and
+    #	   "gethostbyname" to check for -lnsl.
+    #	2. Use each function name only once:  can't redo a check because
+    #	   autoconf caches the results of the last check and won't redo it.
+    #	3. Use -lnsl and -lsocket only if they supply procedures that
+    #	   aren't already present in the normal libraries.  This is because
+    #	   IRIX 5.2 has libraries, but they aren't needed and they're
+    #	   bogus:  they goof up name resolution if used.
+    #	4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #	   To get around this problem, check for both libraries together
+    #	   if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
+    if test "$tcl_checkSocket" = 1; then
+	AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
+	    LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
+    fi
+    if test "$tcl_checkBoth" = 1; then
+	tk_oldLibs=$LIBS
+	LIBS="$LIBS -lsocket -lnsl"
+	AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
+    fi
+    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
+	    [LIBS="$LIBS -lnsl"])])
+
+    # TEA specific: Don't perform the eval of the libraries here because
+    # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(MATH_LIBS)
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+#	Check for what flags are needed to be passed so the correct OS
+#	features are available.
+#
+# Arguments:
+#	None
+#
+# Results:
+#
+#	Might define the following vars:
+#		_ISOC99_SOURCE
+#		_LARGEFILE64_SOURCE
+#		_LARGEFILE_SOURCE64
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+	AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+	    AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+	AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+	tcl_flags="$tcl_flags $1"
+    fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+    AC_MSG_CHECKING([for required early compiler flags])
+    tcl_flags=""
+    TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+	[char *p = (char *)strtoll; char *q = (char *)strtoull;])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+	[struct stat64 buf; int i = stat64("/", &buf);])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+	[char *p = (char *)open64;])
+    if test "x${tcl_flags}" = "x" ; then
+	AC_MSG_RESULT([none])
+    else
+	AC_MSG_RESULT([${tcl_flags}])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+#	Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+#	None
+#
+# Results:
+#
+#	Might define the following vars:
+#		TCL_WIDE_INT_IS_LONG
+#		TCL_WIDE_INT_TYPE
+#		HAVE_STRUCT_DIRENT64
+#		HAVE_STRUCT_STAT64
+#		HAVE_TYPE_OFF64_T
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+    AC_MSG_CHECKING([for 64-bit integer type])
+    AC_CACHE_VAL(tcl_cv_type_64bit,[
+	tcl_cv_type_64bit=none
+	# See if the compiler knows natively about __int64
+	AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+	    tcl_type_64bit=__int64, tcl_type_64bit="long long")
+	# See if we should use long anyway  Note that we substitute in the
+	# type that is our current guess for a 64-bit type inside this check
+	# program, so it should be modified only carefully...
+        AC_TRY_COMPILE(,[switch (0) {
+            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
+        }],tcl_cv_type_64bit=${tcl_type_64bit})])
+    if test "${tcl_cv_type_64bit}" = none ; then
+	AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+	AC_MSG_RESULT([using long])
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+		-a "${TEA_PLATFORM}" = "windows" ; then
+	# TEA specific: We actually want to use the default tcl.h checks in
+	# this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+	AC_MSG_RESULT([using Tcl header defaults])
+    else
+	AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+	    [What type should be used to define wide integers?])
+	AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+	# Now check for auxiliary declarations
+	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+	    AC_TRY_COMPILE([#include <sys/types.h>
+#include <dirent.h>],[struct dirent64 p;],
+		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+	fi
+
+	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+	    AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+		tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+	    AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+	fi
+
+	AC_CHECK_FUNCS(open64 lseek64)
+	AC_MSG_CHECKING([for off64_t])
+	AC_CACHE_VAL(tcl_cv_type_off64_t,[
+	    AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+		tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+	dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+	dnl functions lseek64 and open64 are defined.
+	if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+	        test "x${ac_cv_func_lseek64}" = "xyes" && \
+	        test "x${ac_cv_func_open64}" = "xyes" ; then
+	    AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+	    AC_MSG_RESULT([yes])
+	else
+	    AC_MSG_RESULT([no])
+	fi
+    fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+#	Init various Tcl Extension Architecture (TEA) variables.
+#	This should be the first called TEA_* macro.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Defines and substs the following vars:
+#		CYGPATH
+#		EXEEXT
+#	Defines only:
+#		TEA_VERSION
+#		TEA_INITED
+#		TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+#	Select the executable extension based on the host type.  This
+#	is a lightweight replacement for AC_EXEEXT that doesn't require
+#	a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.9"
+
+    AC_MSG_CHECKING([for correct TEA configuration])
+    if test x"${PACKAGE_NAME}" = x ; then
+	AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.in])
+    fi
+    if test x"$1" = x ; then
+	AC_MSG_ERROR([
+TEA version not specified.])
+    elif test "$1" != "${TEA_VERSION}" ; then
+	AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
+    else
+	AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+    fi
+
+    # If the user did not set CFLAGS, set it now to keep macros
+    # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+	CFLAGS=""
+    fi
+
+    case "`uname -s`" in
+	*win32*|*WIN32*|*MINGW32_*)
+	    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
+	    EXEEXT=".exe"
+	    TEA_PLATFORM="windows"
+	    ;;
+	*CYGWIN_*)
+	    CYGPATH=echo
+	    EXEEXT=".exe"
+	    # TEA_PLATFORM is determined later in LOAD_TCLCONFIG
+	    ;;
+	*)
+	    CYGPATH=echo
+	    # Maybe we are cross-compiling....
+	    case ${host_alias} in
+		*mingw32*)
+		EXEEXT=".exe"
+		TEA_PLATFORM="windows"
+		;;
+	    *)
+		EXEEXT=""
+		TEA_PLATFORM="unix"
+		;;
+	    esac
+	    ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+	exec_prefix_default=yes
+	exec_prefix=$prefix
+    fi
+
+    AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
+
+    AC_SUBST(EXEEXT)
+    AC_SUBST(CYGPATH)
+
+    # This package name must be replaced statically for AC_SUBST to work
+    AC_SUBST(PKG_LIB_FILE)
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+    AC_SUBST(PKG_STUB_LIB_FILE)
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+    AC_SUBST(PKG_TCL_SOURCES)
+    AC_SUBST(PKG_HEADERS)
+    AC_SUBST(PKG_INCLUDES)
+    AC_SUBST(PKG_LIBS)
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+#	Specify one or more source files.  Users should check for
+#	the right platform before adding to their list.
+#	It is not important to specify the directory, as long as it is
+#	in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#	one or more file names
+#
+# Results:
+#
+#	Defines and substs the following vars:
+#		PKG_SOURCES
+#		PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+	case $i in
+	    [\$]*)
+		# allow $-var names
+		PKG_SOURCES="$PKG_SOURCES $i"
+		PKG_OBJECTS="$PKG_OBJECTS $i"
+		;;
+	    *)
+		# check for existence - allows for generic/win/unix VPATH
+		# To add more dirs here (like 'src'), you have to update VPATH
+		# in Makefile.in as well
+		if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+		    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+		    -a ! -f "${srcdir}/macosx/$i" \
+		    ; then
+		    AC_MSG_ERROR([could not find source file '$i'])
+		fi
+		PKG_SOURCES="$PKG_SOURCES $i"
+		# this assumes it is in a VPATH dir
+		i=`basename $i`
+		# handle user calling this before or after TEA_SETUP_COMPILER
+		if test x"${OBJEXT}" != x ; then
+		    j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+		else
+		    j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+		fi
+		PKG_OBJECTS="$PKG_OBJECTS $j"
+		;;
+	esac
+    done
+    AC_SUBST(PKG_SOURCES)
+    AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+#	Specify one or more source files.  Users should check for
+#	the right platform before adding to their list.
+#	It is not important to specify the directory, as long as it is
+#	in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#	one or more file names
+#
+# Results:
+#
+#	Defines and substs the following vars:
+#		PKG_STUB_SOURCES
+#		PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+	# check for existence - allows for generic/win/unix VPATH
+	if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+	    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+	    -a ! -f "${srcdir}/macosx/$i" \
+	    ; then
+	    AC_MSG_ERROR([could not find stub source file '$i'])
+	fi
+	PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+	# this assumes it is in a VPATH dir
+	i=`basename $i`
+	# handle user calling this before or after TEA_SETUP_COMPILER
+	if test x"${OBJEXT}" != x ; then
+	    j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+	else
+	    j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+	fi
+	PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+#	Specify one or more Tcl source files.  These should be platform
+#	independent runtime files.
+#
+# Arguments:
+#	one or more file names
+#
+# Results:
+#
+#	Defines and substs the following vars:
+#		PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+	# check for existence, be strict because it is installed
+	if test ! -f "${srcdir}/$i" ; then
+	    AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+	fi
+	PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+    AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+#	Specify one or more source headers.  Users should check for
+#	the right platform before adding to their list.
+#
+# Arguments:
+#	one or more file names
+#
+# Results:
+#
+#	Defines and substs the following vars:
+#		PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+    vars="$@"
+    for i in $vars; do
+	# check for existence, be strict because it is installed
+	if test ! -f "${srcdir}/$i" ; then
+	    AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+	fi
+	PKG_HEADERS="$PKG_HEADERS $i"
+    done
+    AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+#	Specify one or more include dirs.  Users should check for
+#	the right platform before adding to their list.
+#
+# Arguments:
+#	one or more file names
+#
+# Results:
+#
+#	Defines and substs the following vars:
+#		PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+    vars="$@"
+    for i in $vars; do
+	PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+    AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+#	Specify one or more libraries.  Users should check for
+#	the right platform before adding to their list.  For Windows,
+#	libraries provided in "foo.lib" format will be converted to
+#	"-lfoo" when using GCC (mingw).
+#
+# Arguments:
+#	one or more file names
+#
+# Results:
+#
+#	Defines and substs the following vars:
+#		PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+    vars="$@"
+    for i in $vars; do
+	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+	    # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+	    i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+	fi
+	PKG_LIBS="$PKG_LIBS $i"
+    done
+    AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+#	Specify one or more CFLAGS.  Users should check for
+#	the right platform before adding to their list.
+#
+# Arguments:
+#	one or more file names
+#
+# Results:
+#
+#	Defines and substs the following vars:
+#		PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+    PKG_CFLAGS="$PKG_CFLAGS $@"
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CLEANFILES --
+#
+#	Specify one or more CLEANFILES.
+#
+# Arguments:
+#	one or more file names to clean target
+#
+# Results:
+#
+#	Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CLEANFILES], [
+    CLEANFILES="$CLEANFILES $@"
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+#	Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	If --prefix or --exec-prefix was not specified, $prefix and
+#	$exec_prefix will be set to the values given to Tcl when it was
+#	configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+    if test "${prefix}" = "NONE"; then
+	prefix_default=yes
+	if test x"${TCL_PREFIX}" != x; then
+	    AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+	    prefix=${TCL_PREFIX}
+	else
+	    AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+	    prefix=/usr/local
+	fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+	-o x"${exec_prefix_default}" = x"yes" ; then
+	if test x"${TCL_EXEC_PREFIX}" != x; then
+	    AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+	    exec_prefix=${TCL_EXEC_PREFIX}
+	else
+	    AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+	    exec_prefix=$prefix
+	fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+#	Do compiler checks the way we want.  This is just a replacement
+#	for AC_PROG_CC in TEA configure.in files to make them cleaner.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    AC_PROG_CC
+    AC_PROG_CPP
+
+    INSTALL="\$(SHELL) \$(srcdir)/tclconfig/install-sh -c"
+    AC_SUBST(INSTALL)
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    AC_PROG_MAKE_SET
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    AC_CHECK_TOOL(RANLIB, ranlib)
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+    AC_OBJEXT
+    AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+#	Do compiler checks that use the compiler.  This must go after
+#	TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+    AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+	AC_CACHE_CHECK([if the compiler understands -pipe],
+	    tcl_cv_cc_pipe, [
+	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+	    AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
+	    CFLAGS=$hold_cflags])
+	if test $tcl_cv_cc_pipe = yes; then
+	    CFLAGS="$CFLAGS -pipe"
+	fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    AC_C_BIGENDIAN
+    if test "${TEA_PLATFORM}" = "unix" ; then
+	TEA_TCL_LINK_LIBS
+	TEA_MISSING_POSIX_HEADERS
+	# Let the user call this, because if it triggers, they will
+	# need a compat/strtod.c that is correct.  Users can also
+	# use Tcl_GetDouble(FromObj) instead.
+	#TEA_BUGGY_STRTOD
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+#	Generate a line that can be used to build a shared/unshared library
+#	in a platform independent manner.
+#
+# Arguments:
+#	none
+#
+#	Requires:
+#
+# Results:
+#
+#	Defines the following vars:
+#	CFLAGS -	Done late here to note disturb other AC macros
+#       MAKE_LIB -      Command to execute to build the Tcl library;
+#                       differs depending on whether or not Tcl is being
+#                       compiled as a shared library.
+#	MAKE_SHARED_LIB	Makefile rule for building a shared library
+#	MAKE_STATIC_LIB	Makefile rule for building a static library
+#	MAKE_STUB_LIB	Makefile rule for building a stub library
+#	VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
+#	VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+	MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+	MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+	AC_EGREP_CPP([manifest needed], [
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+print("manifest needed")
+#endif
+	], [
+	# Could do a CHECK_PROG for mt, but should always be with MSVC8+
+	VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi"
+	VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi"
+	MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
+	TEA_ADD_CLEANFILES([*.manifest])
+	])
+	MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)"
+    else
+	MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
+	MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+	MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+	MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+	MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+	if test "${SHARED_BUILD}" = "1" ; then
+	    # We force the unresolved linking of symbols that are really in
+	    # the private libraries of Tcl and Tk.
+	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+	    if test x"${TK_BIN_DIR}" != x ; then
+		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+	    fi
+	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+	else
+	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+	fi
+	# Some packages build their own stubs libraries
+	eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+	if test "$GCC" = "yes"; then
+	    PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+	fi
+	# These aren't needed on Windows (either MSVC or gcc)
+	RANLIB=:
+	RANLIB_STUB=:
+    else
+	RANLIB_STUB="${RANLIB}"
+	if test "${SHARED_BUILD}" = "1" ; then
+	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+	    if test x"${TK_BIN_DIR}" != x ; then
+		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+	    fi
+	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+	    RANLIB=:
+	else
+	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+	fi
+	# Some packages build their own stubs libraries
+	eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+	CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+    AC_SUBST(MAKE_LIB)
+    AC_SUBST(MAKE_SHARED_LIB)
+    AC_SUBST(MAKE_STATIC_LIB)
+    AC_SUBST(MAKE_STUB_LIB)
+    AC_SUBST(RANLIB_STUB)
+    AC_SUBST(VC_MANIFEST_EMBED_DLL)
+    AC_SUBST(VC_MANIFEST_EMBED_EXE)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+#	Compute the name of an existing object library located in libdir
+#	from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+#	basename	The base name of the library without version
+#			numbers, extensions, or "lib" prefixes.
+#	extra_dir	Extra directory in which to search for the
+#			library.  This location is used first, then
+#			$prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+#	TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+#	Defines the following vars:
+#		${basename}_LIB_NAME	The computed library name.
+#		${basename}_LIB_SPEC	The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+    AC_MSG_CHECKING([for $1 library])
+
+    # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+    tea_lib_name_dir="${exec_prefix}/lib"
+
+    # Or in a user-specified location.
+
+    if test x"$2" != x ; then
+	tea_extra_lib_dir=$2
+    else
+	tea_extra_lib_dir=NONE
+    fi
+
+    for i in \
+	    `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+	    `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+	    `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+	    `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+	    `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+	    `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+	    `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
+	    `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
+	    `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+	    `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+	if test -f "$i" ; then
+	    tea_lib_name_dir=`dirname $i`
+	    $1_LIB_NAME=`basename $i`
+	    $1_LIB_PATH_NAME=$i
+	    break
+	fi
+    done
+
+    if test "${TEA_PLATFORM}" = "windows"; then
+	$1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+    else
+	# Strip off the leading "lib" and trailing ".a" or ".so"
+
+	tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+	$1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+    fi
+
+    if test "x${$1_LIB_NAME}" = x ; then
+	AC_MSG_ERROR([not found])
+    else
+	AC_MSG_RESULT([${$1_LIB_SPEC}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+#	Locate the private Tcl include files
+#
+# Arguments:
+#
+#	Requires:
+#		TCL_SRC_DIR	Assumes that TEA_LOAD_TCLCONFIG has
+#				already been called.
+#
+# Results:
+#
+#	Substitutes the following vars:
+#		TCL_TOP_DIR_NATIVE
+#		TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+    # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+    AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
+    AC_MSG_CHECKING([for Tcl private include files])
+
+    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+    # Check to see if tcl<Plat>Port.h isn't already with the public headers
+    # Don't look for tclInt.h because that resides with tcl.h in the core
+    # sources, but the <plat>Port headers are in a different directory
+    if test "${TEA_PLATFORM}" = "windows" -a \
+	-f "${ac_cv_c_tclh}/tclWinPort.h"; then
+	result="private headers found with public headers"
+    elif test "${TEA_PLATFORM}" = "unix" -a \
+	-f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+	result="private headers found with public headers"
+    else
+	TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+	if test "${TEA_PLATFORM}" = "windows"; then
+	    TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+	else
+	    TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+	fi
+	# Overwrite the previous TCL_INCLUDES as this should capture both
+	# public and private headers in the same set.
+	# We want to ensure these are substituted so as not to require
+	# any *_NATIVE vars be defined in the Makefile
+	TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+	if test "`uname -s`" = "Darwin"; then
+            # If Tcl was built as a framework, attempt to use
+            # the framework's Headers and PrivateHeaders directories
+            case ${TCL_DEFS} in
+	    	*TCL_FRAMEWORK*)
+		    if test -d "${TCL_BIN_DIR}/Headers" -a \
+			    -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+			TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+		    else
+			TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+		    fi
+	            ;;
+	    esac
+	    result="Using ${TCL_INCLUDES}"
+	else
+	    if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+		AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+	    fi
+	    result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+	fi
+    fi
+
+    AC_SUBST(TCL_TOP_DIR_NATIVE)
+
+    AC_SUBST(TCL_INCLUDES)
+    AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+#	Locate the installed public Tcl header files
+#
+# Arguments:
+#	None.
+#
+# Requires:
+#	CYGPATH must be set
+#
+# Results:
+#
+#	Adds a --with-tclinclude switch to configure.
+#	Result is cached.
+#
+#	Substitutes the following vars:
+#		TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+    AC_MSG_CHECKING([for Tcl public headers])
+
+    AC_ARG_WITH(tclinclude, [  --with-tclinclude       directory containing the public Tcl header files], with_tclinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tclh, [
+	# Use the value from --with-tclinclude, if it was given
+
+	if test x"${with_tclinclude}" != x ; then
+	    if test -f "${with_tclinclude}/tcl.h" ; then
+		ac_cv_c_tclh=${with_tclinclude}
+	    else
+		AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+	    fi
+	else
+	    list=""
+	    if test "`uname -s`" = "Darwin"; then
+		# If Tcl was built as a framework, attempt to use
+		# the framework's Headers directory
+		case ${TCL_DEFS} in
+		    *TCL_FRAMEWORK*)
+			list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+			;;
+		esac
+	    fi
+
+	    # Look in the source dir only if Tcl is not installed,
+	    # and in that situation, look there before installed locations.
+	    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+		list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+	    fi
+
+	    # Check order: pkg --prefix location, Tcl's --prefix location,
+	    # relative to directory of tclConfig.sh.
+
+	    eval "temp_includedir=${includedir}"
+	    list="$list \
+		`ls -d ${temp_includedir}        2>/dev/null` \
+		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+		list="$list /usr/local/include /usr/include"
+		if test x"${TCL_INCLUDE_SPEC}" != x ; then
+		    d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+		    list="$list `ls -d ${d} 2>/dev/null`"
+		fi
+	    fi
+	    for i in $list ; do
+		if test -f "$i/tcl.h" ; then
+		    ac_cv_c_tclh=$i
+		    break
+		fi
+	    done
+	fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+	AC_MSG_ERROR([tcl.h not found.  Please specify its location with --with-tclinclude])
+    else
+	AC_MSG_RESULT([${ac_cv_c_tclh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+#	Locate the private Tk include files
+#
+# Arguments:
+#
+#	Requires:
+#		TK_SRC_DIR	Assumes that TEA_LOAD_TKCONFIG has
+#				 already been called.
+#
+# Results:
+#
+#	Substitutes the following vars:
+#		TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+    # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
+    AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
+    AC_MSG_CHECKING([for Tk private include files])
+
+    TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+    TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+
+    # Check to see if tk<Plat>Port.h isn't already with the public headers
+    # Don't look for tkInt.h because that resides with tk.h in the core
+    # sources, but the <plat>Port headers are in a different directory
+    if test "${TEA_PLATFORM}" = "windows" -a \
+	-f "${ac_cv_c_tkh}/tkWinPort.h"; then
+	result="private headers found with public headers"
+    elif test "${TEA_PLATFORM}" = "unix" -a \
+	-f "${ac_cv_c_tkh}/tkUnixPort.h"; then
+	result="private headers found with public headers"
+    else
+	TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+	TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+	if test "${TEA_PLATFORM}" = "windows"; then
+	    TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+	else
+	    TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+	fi
+	# Overwrite the previous TK_INCLUDES as this should capture both
+	# public and private headers in the same set.
+	# We want to ensure these are substituted so as not to require
+	# any *_NATIVE vars be defined in the Makefile
+	TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+	# Detect and add ttk subdir
+	if test -d "${TK_SRC_DIR}/generic/ttk"; then
+	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
+	fi
+	if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+	fi
+	if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+	fi
+	if test "`uname -s`" = "Darwin"; then
+	    # If Tk was built as a framework, attempt to use
+	    # the framework's Headers and PrivateHeaders directories
+	    case ${TK_DEFS} in
+		*TK_FRAMEWORK*)
+			if test -d "${TK_BIN_DIR}/Headers" -a \
+				-d "${TK_BIN_DIR}/PrivateHeaders"; then
+			    TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
+			else
+			    TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+			fi
+			;;
+	    esac
+	    result="Using ${TK_INCLUDES}"
+	else
+	    if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+	       AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+	    fi
+	    result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
+	fi
+    fi
+
+    AC_SUBST(TK_TOP_DIR_NATIVE)
+    AC_SUBST(TK_XLIB_DIR_NATIVE)
+
+    AC_SUBST(TK_INCLUDES)
+    AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+#	Locate the installed public Tk header files
+#
+# Arguments:
+#	None.
+#
+# Requires:
+#	CYGPATH must be set
+#
+# Results:
+#
+#	Adds a --with-tkinclude switch to configure.
+#	Result is cached.
+#
+#	Substitutes the following vars:
+#		TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+    AC_MSG_CHECKING([for Tk public headers])
+
+    AC_ARG_WITH(tkinclude, [  --with-tkinclude        directory containing the public Tk header files], with_tkinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tkh, [
+	# Use the value from --with-tkinclude, if it was given
+
+	if test x"${with_tkinclude}" != x ; then
+	    if test -f "${with_tkinclude}/tk.h" ; then
+		ac_cv_c_tkh=${with_tkinclude}
+	    else
+		AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+	    fi
+	else
+	    list=""
+	    if test "`uname -s`" = "Darwin"; then
+		# If Tk was built as a framework, attempt to use
+		# the framework's Headers directory.
+		case ${TK_DEFS} in
+		    *TK_FRAMEWORK*)
+			list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+			;;
+		esac
+	    fi
+
+	    # Look in the source dir only if Tk is not installed,
+	    # and in that situation, look there before installed locations.
+	    if test -f "${TK_BIN_DIR}/Makefile" ; then
+		list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+	    fi
+
+	    # Check order: pkg --prefix location, Tk's --prefix location,
+	    # relative to directory of tkConfig.sh, Tcl's --prefix location,
+	    # relative to directory of tclConfig.sh.
+
+	    eval "temp_includedir=${includedir}"
+	    list="$list \
+		`ls -d ${temp_includedir}        2>/dev/null` \
+		`ls -d ${TK_PREFIX}/include      2>/dev/null` \
+		`ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
+		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+		list="$list /usr/local/include /usr/include"
+		if test x"${TK_INCLUDE_SPEC}" != x ; then
+		    d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+		    list="$list `ls -d ${d} 2>/dev/null`"
+		fi
+	    fi
+	    for i in $list ; do
+		if test -f "$i/tk.h" ; then
+		    ac_cv_c_tkh=$i
+		    break
+		fi
+	    done
+	fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tkh}" = x ; then
+	AC_MSG_ERROR([tk.h not found.  Please specify its location with --with-tkinclude])
+    else
+	AC_MSG_RESULT([${ac_cv_c_tkh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+    TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TK_INCLUDES)
+
+    if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+	# On Windows and Aqua, we need the X compat headers
+	AC_MSG_CHECKING([for X11 header files])
+	if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+	    INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+	    TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+	    AC_SUBST(TK_XINCLUDES)
+	fi
+	AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+#	Locate the ${1}Config.sh file and perform a sanity check on
+#	the ${1} compile flags.  These are used by packages like
+#	[incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Adds the following arguments to configure:
+#		--with-$1=...
+#
+#	Defines the following vars:
+#		$1_BIN_DIR	Full path to the directory containing
+#				the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+    #
+    # Ok, lets find the $1 configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-$1
+    #
+
+    if test x"${no_$1}" = x ; then
+	# we reset no_$1 in case something fails here
+	no_$1=true
+	AC_ARG_WITH($1, [  --with-$1              directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+	AC_MSG_CHECKING([for $1 configuration])
+	AC_CACHE_VAL(ac_cv_c_$1config,[
+
+	    # First check to see if --with-$1 was specified.
+	    if test x"${with_$1config}" != x ; then
+		case ${with_$1config} in
+		    */$1Config.sh )
+			if test -f ${with_$1config}; then
+			    AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+			    with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+			fi;;
+		esac
+		if test -f "${with_$1config}/$1Config.sh" ; then
+		    ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+		else
+		    AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+		fi
+	    fi
+
+	    # then check for a private $1 installation
+	    if test x"${ac_cv_c_$1config}" = x ; then
+		for i in \
+			../$1 \
+			`ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+			`ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+			`ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+			../../$1 \
+			`ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+			`ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+			`ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+			../../../$1 \
+			`ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+			`ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+			`ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+			${srcdir}/../$1 \
+			`ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+			`ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+			`ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+			`ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+			; do
+		    if test -f "$i/$1Config.sh" ; then
+			ac_cv_c_$1config=`(cd $i; pwd)`
+			break
+		    fi
+		    if test -f "$i/unix/$1Config.sh" ; then
+			ac_cv_c_$1config=`(cd $i/unix; pwd)`
+			break
+		    fi
+		done
+	    fi
+
+	    # check in a few common install locations
+	    if test x"${ac_cv_c_$1config}" = x ; then
+		for i in `ls -d ${libdir} 2>/dev/null` \
+			`ls -d ${exec_prefix}/lib 2>/dev/null` \
+			`ls -d ${prefix}/lib 2>/dev/null` \
+			`ls -d /usr/local/lib 2>/dev/null` \
+			`ls -d /usr/contrib/lib 2>/dev/null` \
+			`ls -d /usr/lib 2>/dev/null` \
+			`ls -d /usr/lib64 2>/dev/null` \
+			; do
+		    if test -f "$i/$1Config.sh" ; then
+			ac_cv_c_$1config=`(cd $i; pwd)`
+			break
+		    fi
+		done
+	    fi
+	])
+
+	if test x"${ac_cv_c_$1config}" = x ; then
+	    $1_BIN_DIR="# no $1 configs found"
+	    AC_MSG_WARN([Cannot find $1 configuration definitions])
+	    exit 0
+	else
+	    no_$1=
+	    $1_BIN_DIR=${ac_cv_c_$1config}
+	    AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+	fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+#	Load the $1Config.sh file
+#
+# Arguments:
+#
+#	Requires the following vars to be set:
+#		$1_BIN_DIR
+#
+# Results:
+#
+#	Substitutes the following vars:
+#		$1_SRC_DIR
+#		$1_LIB_FILE
+#		$1_LIB_SPEC
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+    AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+    if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+        AC_MSG_RESULT([loading])
+	. "${$1_BIN_DIR}/$1Config.sh"
+    else
+        AC_MSG_RESULT([file not found])
+    fi
+
+    #
+    # If the $1_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable $1_LIB_SPEC will be set to the value
+    # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+    # instead of $1_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    #
+
+    if test -f "${$1_BIN_DIR}/Makefile" ; then
+	AC_MSG_WARN([Found Makefile - using build library specs for $1])
+        $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+        $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+        $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+        $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
+        $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
+    fi
+
+    AC_SUBST($1_VERSION)
+    AC_SUBST($1_BIN_DIR)
+    AC_SUBST($1_SRC_DIR)
+
+    AC_SUBST($1_LIB_FILE)
+    AC_SUBST($1_LIB_SPEC)
+
+    AC_SUBST($1_STUB_LIB_FILE)
+    AC_SUBST($1_STUB_LIB_SPEC)
+    AC_SUBST($1_STUB_LIB_PATH)
+
+    # Allow the caller to prevent this auto-check by specifying any 2nd arg
+    AS_IF([test "x$2" = x], [
+	# Check both upper and lower-case variants
+	# If a dev wanted non-stubs libs, this function could take an option
+	# to not use _STUB in the paths below
+	AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
+	    [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
+	    [TEA_LOAD_CONFIG_LIB($1_STUB)])
+    ])
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG_LIB --
+#
+#	Helper function to load correct library from another extension's
+#	${PACKAGE}Config.sh.
+#
+# Results:
+#	Adds to LIBS the appropriate extension library
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
+    AC_MSG_CHECKING([For $1 library for LIBS])
+    # This simplifies the use of stub libraries by automatically adding
+    # the stub lib to your path.  Normally this would add to SHLIB_LD_LIBS,
+    # but this is called before CONFIG_CFLAGS.  More importantly, this adds
+    # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
+    if test "x${$1_LIB_SPEC}" != "x" ; then
+	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
+	    TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
+	    AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
+	else
+	    TEA_ADD_LIBS([${$1_LIB_SPEC}])
+	    AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
+	fi
+    else
+	AC_MSG_RESULT([file not found])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_EXPORT_CONFIG --
+#
+#	Define the data to insert into the ${PACKAGE}Config.sh file
+#
+# Arguments:
+#
+#	Requires the following vars to be set:
+#		$1
+#
+# Results:
+#	Substitutes the following vars:
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_EXPORT_CONFIG], [
+    #--------------------------------------------------------------------
+    # These are for $1Config.sh
+    #--------------------------------------------------------------------
+
+    # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
+    eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
+    if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+	eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
+	eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
+    else
+	eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+	eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+    fi
+    $1_BUILD_LIB_SPEC="-L`pwd` ${$1_LIB_FLAG}"
+    $1_LIB_SPEC="-L${pkglibdir} ${$1_LIB_FLAG}"
+    $1_BUILD_STUB_LIB_SPEC="-L`pwd` [$]{$1_STUB_LIB_FLAG}"
+    $1_STUB_LIB_SPEC="-L${pkglibdir} [$]{$1_STUB_LIB_FLAG}"
+    $1_BUILD_STUB_LIB_PATH="`pwd`/[$]{PKG_STUB_LIB_FILE}"
+    $1_STUB_LIB_PATH="${pkglibdir}/[$]{PKG_STUB_LIB_FILE}"
+
+    AC_SUBST($1_BUILD_LIB_SPEC)
+    AC_SUBST($1_LIB_SPEC)
+    AC_SUBST($1_BUILD_STUB_LIB_SPEC)
+    AC_SUBST($1_STUB_LIB_SPEC)
+    AC_SUBST($1_BUILD_STUB_LIB_PATH)
+    AC_SUBST($1_STUB_LIB_PATH)
+
+    AC_SUBST(MAJOR_VERSION)
+    AC_SUBST(MINOR_VERSION)
+    AC_SUBST(PATCHLEVEL)
+])
+
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+#	Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+#	none
+#
+# Results:
+#
+#	Adds the following arguments to configure:
+#		--with-celib=...
+#
+#	Defines the following vars:
+#		CELIB_DIR	Full path to the directory containing
+#				the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+	# we reset no_celib in case something fails here
+	no_celib=true
+	AC_ARG_WITH(celib,[  --with-celib=DIR        use Windows/CE support library from DIR], with_celibconfig=${withval})
+	AC_MSG_CHECKING([for Windows/CE celib directory])
+	AC_CACHE_VAL(ac_cv_c_celibconfig,[
+	    # First check to see if --with-celibconfig was specified.
+	    if test x"${with_celibconfig}" != x ; then
+		if test -d "${with_celibconfig}/inc" ; then
+		    ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+		else
+		    AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+		fi
+	    fi
+
+	    # then check for a celib library
+	    if test x"${ac_cv_c_celibconfig}" = x ; then
+		for i in \
+			../celib-palm-3.0 \
+			../celib \
+			../../celib-palm-3.0 \
+			../../celib \
+			`ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+			${srcdir}/../celib-palm-3.0 \
+			${srcdir}/../celib \
+			`ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+			; do
+		    if test -d "$i/inc" ; then
+			ac_cv_c_celibconfig=`(cd $i; pwd)`
+			break
+		    fi
+		done
+	    fi
+	])
+	if test x"${ac_cv_c_celibconfig}" = x ; then
+	    AC_MSG_ERROR([Cannot find celib support library directory])
+	else
+	    no_celib=
+	    CELIB_DIR=${ac_cv_c_celibconfig}
+	    CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+	    AC_MSG_RESULT([found $CELIB_DIR])
+	fi
+    fi
+])
+
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/unix/Makefile b/unix/Makefile
index 321e17c..1c7f263 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -32,12 +32,3 @@ distclean : clean
 	rm -f *.o *.so *.a
 
 FORCE	:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SRC:.C=.d)
-endif
diff --git a/unix/rotstr.C b/unix/rotstr.C
index 8ba3cc0..e1996ee 100644
--- a/unix/rotstr.C
+++ b/unix/rotstr.C
@@ -2,12 +2,12 @@
 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 // For conditions of distribution and use, see copyright notice in "copyright"
 
+#include <X11/Xutil.h>
+
 #include "rotstr.h"
 #include "vector.h"
 #include "widget.h"
 
-#include <tk.h>
-#include <X11/Xutil.h>
 
 void XDrawRotString(Display* display, Drawable drawable, GC gc, 
 		   Vector& v, double angle, const char* text, 
diff --git a/unix/rotstr.h b/unix/rotstr.h
index 5623831..1e44482 100644
--- a/unix/rotstr.h
+++ b/unix/rotstr.h
@@ -10,6 +10,6 @@
 class Widget;
 class Vector;
 extern void XDrawRotString(Display* display, Drawable drawable, GC gc,
-			   Vector&, double angle, const char* text, 
+			   Vector& v, double angle, const char* text, 
 			   Tk_Font font, Widget* parent);
 #endif
diff --git a/win/Makefile b/win/Makefile
index 512febf..aee4c5b 100644
--- a/win/Makefile
+++ b/win/Makefile
@@ -4,8 +4,10 @@ include ../make.pkgs
 # no ./configure
 CXXFLAGS = $(CXXOPT) \
 	-I../include \
-	-I../$(TKDIR)/generic -I../$(TKDIR)/win \
+	-I../$(TCLDIR)/generic \
+	-I../$(TKDIR)/generic \
 	-I../saotk/vector \
+	-I../$(TKDIR)/win \
 	-I$(X11INCLUDE)
 
 SRC	= rotstr.C \
@@ -35,12 +37,3 @@ distclean : clean
 	rm -f *.o *.so *.a
 
 FORCE	:
-
-ifdef DEPENDS
-%.d: %.C
-	set -e; $(CXX) -MM $(CXXFLAGS) $< \
-	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
-	[ -s $@ ] || rm -f $@
-
-include $(SRC:.C=.d)
-endif

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/saods9.git



More information about the debian-science-commits mailing list