summaryrefslogtreecommitdiff
path: root/dviware/catdvi
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/catdvi
Initial commit
Diffstat (limited to 'dviware/catdvi')
-rw-r--r--dviware/catdvi/AUTHORS27
-rw-r--r--dviware/catdvi/COPYING339
-rw-r--r--dviware/catdvi/ChangeLog952
-rw-r--r--dviware/catdvi/GNUmakefile219
-rw-r--r--dviware/catdvi/INSTALL59
-rw-r--r--dviware/catdvi/MD5SUMS129
-rw-r--r--dviware/catdvi/Manifest119
-rw-r--r--dviware/catdvi/NEWS93
-rw-r--r--dviware/catdvi/README90
-rw-r--r--dviware/catdvi/TODO85
-rw-r--r--dviware/catdvi/adobe2h.c201
-rw-r--r--dviware/catdvi/adobe2h.d1
-rw-r--r--dviware/catdvi/adobetbl.h1799
-rw-r--r--dviware/catdvi/build.sh80
-rw-r--r--dviware/catdvi/bytesex.c135
-rw-r--r--dviware/catdvi/bytesex.d1
-rw-r--r--dviware/catdvi/bytesex.h67
-rw-r--r--dviware/catdvi/canvas.c368
-rw-r--r--dviware/catdvi/canvas.d2
-rw-r--r--dviware/catdvi/canvas.h82
-rw-r--r--dviware/catdvi/catdvi.1371
-rw-r--r--dviware/catdvi/catdvi.c245
-rw-r--r--dviware/catdvi/catdvi.d2
-rw-r--r--dviware/catdvi/catdvi.pdfbin0 -> 68703 bytes
-rw-r--r--dviware/catdvi/catdvi.txt258
-rw-r--r--dviware/catdvi/changelog-authors2
-rw-r--r--dviware/catdvi/config.mk.in44
-rw-r--r--dviware/catdvi/configure1188
-rw-r--r--dviware/catdvi/configure.in70
-rwxr-xr-xdviware/catdvi/cvsparser.pl34
-rw-r--r--dviware/catdvi/density.c349
-rw-r--r--dviware/catdvi/density.d1
-rw-r--r--dviware/catdvi/density.h157
-rw-r--r--dviware/catdvi/enc/README89
-rw-r--r--dviware/catdvi/enc/amssymba.enc220
-rw-r--r--dviware/catdvi/enc/amssymbb.enc220
-rw-r--r--dviware/catdvi/enc/blackboard.enc163
-rw-r--r--dviware/catdvi/enc/cork.enc100
-rw-r--r--dviware/catdvi/enc/dummy.enc103
-rw-r--r--dviware/catdvi/enc/euex.enc171
-rw-r--r--dviware/catdvi/enc/eufrak.enc202
-rw-r--r--dviware/catdvi/enc/eurosym.enc100
-rw-r--r--dviware/catdvi/enc/latexsym.enc127
-rw-r--r--dviware/catdvi/enc/marvo00.enc305
-rw-r--r--dviware/catdvi/enc/marvo98.enc256
-rw-r--r--dviware/catdvi/enc/ot1.enc38
-rw-r--r--dviware/catdvi/enc/ot1wofl.enc51
-rw-r--r--dviware/catdvi/enc/texmext.enc184
-rw-r--r--dviware/catdvi/enc/texmital.enc183
-rw-r--r--dviware/catdvi/enc/texmsym.enc183
-rw-r--r--dviware/catdvi/enc/textcomp.enc154
-rw-r--r--dviware/catdvi/enc/textt.enc50
-rw-r--r--dviware/catdvi/findtfm.h34
-rw-r--r--dviware/catdvi/fixword.c45
-rw-r--r--dviware/catdvi/fixword.d1
-rw-r--r--dviware/catdvi/fixword.h54
-rw-r--r--dviware/catdvi/fntenc.c156
-rw-r--r--dviware/catdvi/fntenc.d5
-rw-r--r--dviware/catdvi/fntenc.h28
-rw-r--r--dviware/catdvi/fontinfo.c597
-rw-r--r--dviware/catdvi/fontinfo.d2
-rw-r--r--dviware/catdvi/fontinfo.h58
-rw-r--r--dviware/catdvi/getopt.c1051
-rw-r--r--dviware/catdvi/getopt.d1
-rw-r--r--dviware/catdvi/getopt.h169
-rw-r--r--dviware/catdvi/getopt1.c188
-rw-r--r--dviware/catdvi/getopt1.d1
-rw-r--r--dviware/catdvi/glyphops.c320
-rw-r--r--dviware/catdvi/glyphops.d2
-rw-r--r--dviware/catdvi/glyphops.h65
-rw-r--r--dviware/catdvi/kpathsea.c46
-rw-r--r--dviware/catdvi/kpathsea.d1
-rw-r--r--dviware/catdvi/layout.c1119
-rw-r--r--dviware/catdvi/layout.d2
-rw-r--r--dviware/catdvi/layout.h21
-rw-r--r--dviware/catdvi/linebuf.c137
-rw-r--r--dviware/catdvi/linebuf.d1
-rw-r--r--dviware/catdvi/linebuf.h67
-rw-r--r--dviware/catdvi/manifest-filter.lst8
-rwxr-xr-xdviware/catdvi/manifest-filter.pl37
-rw-r--r--dviware/catdvi/outenc.c1367
-rw-r--r--dviware/catdvi/outenc.d2
-rw-r--r--dviware/catdvi/outenc.h60
-rw-r--r--dviware/catdvi/page.c1038
-rw-r--r--dviware/catdvi/page.d2
-rw-r--r--dviware/catdvi/page.h44
-rw-r--r--dviware/catdvi/page2.h96
-rw-r--r--dviware/catdvi/pageref.c161
-rw-r--r--dviware/catdvi/pageref.d1
-rw-r--r--dviware/catdvi/pageref.h62
-rw-r--r--dviware/catdvi/pse2unic.c428
-rw-r--r--dviware/catdvi/pse2unic.d1
-rw-r--r--dviware/catdvi/readdvi.c444
-rw-r--r--dviware/catdvi/readdvi.d2
-rw-r--r--dviware/catdvi/readdvi.h29
-rw-r--r--dviware/catdvi/regsta.c109
-rw-r--r--dviware/catdvi/regsta.d1
-rw-r--r--dviware/catdvi/regsta.h57
-rw-r--r--dviware/catdvi/sparse.c202
-rw-r--r--dviware/catdvi/sparse.d1
-rw-r--r--dviware/catdvi/sparse.h161
-rw-r--r--dviware/catdvi/test/box.tex7
-rw-r--r--dviware/catdvi/test/finnish.tex12
-rw-r--r--dviware/catdvi/test/ligatures.tex7
-rw-r--r--dviware/catdvi/test/math.tex18
-rw-r--r--dviware/catdvi/test/ot1umlauts.tex12
-rw-r--r--dviware/catdvi/test/private.tex8
-rw-r--r--dviware/catdvi/test/testfont.tex517
-rw-r--r--dviware/catdvi/test/texlogo.tex7
-rw-r--r--dviware/catdvi/test/texmext.tex40
-rw-r--r--dviware/catdvi/tfminfo.c131
-rw-r--r--dviware/catdvi/tfminfo.d1
-rw-r--r--dviware/catdvi/util.c227
-rw-r--r--dviware/catdvi/util.d1
-rw-r--r--dviware/catdvi/util.h121
-rw-r--r--dviware/catdvi/version.h3
-rw-r--r--dviware/catdvi/version.h.in3
-rw-r--r--dviware/catdvi/vlist.c231
-rw-r--r--dviware/catdvi/vlist.d1
-rw-r--r--dviware/catdvi/vlist.h119
120 files changed, 20418 insertions, 0 deletions
diff --git a/dviware/catdvi/AUTHORS b/dviware/catdvi/AUTHORS
new file mode 100644
index 0000000000..11a5be3bd4
--- /dev/null
+++ b/dviware/catdvi/AUTHORS
@@ -0,0 +1,27 @@
+Antti-Juhani Kaijanaho <gaia@iki.fi> (former maintainer)
+ - everything not explicitly mentioned
+
+J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl> (original author)
+ - all of attic/Makefile.JHM (no longer distributed, but in CVS)
+ - original versions of utils.[ch] and catdvi.[ch]
+ - original version of what became readdvi.c
+ - original version of what became bytesex.[ch]
+
+Bjoern Brill <brill@fs.math.uni-frankfurt.de> (current maintainer)
+ - the manual page
+ - adobe2h.c, tfminfo.c, build.sh
+ - {glyphops,linebuf,density,pageref,sparse,vlist,canvas}.[ch]
+ - rewrite of outenc.[ch]
+ - parts of page.c
+ - almost everything in layout.[ch]
+ - enc/{eurosym,marvo00,marvo98,textcomp,textt,latexsym,amssymba,amssymbb,
+ euex,eufrak}.enc
+ - assorted changes elsewhere
+
+The following files are copyrighted by the Free Software Foundation.
+Their authors are not known to us.
+ getopt.c, getopt1.c, getopt.h
+
+The original versions of the following files are copied from
+the DVIPSk distribution.
+ enc/cork.enc enc/ot1.enc
diff --git a/dviware/catdvi/COPYING b/dviware/catdvi/COPYING
new file mode 100644
index 0000000000..e77696ae8d
--- /dev/null
+++ b/dviware/catdvi/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/dviware/catdvi/ChangeLog b/dviware/catdvi/ChangeLog
new file mode 100644
index 0000000000..491a6165cb
--- /dev/null
+++ b/dviware/catdvi/ChangeLog
@@ -0,0 +1,952 @@
+2002-11-24 Sunday 18:29 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobe2h.c, density.c, fntenc.c, linebuf.c: Fix a few compiler
+ warnings.
+
+2002-11-17 Sunday 18:38 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * INSTALL, NEWS, README, configure.in: Prepare for 0.14.
+
+2002-11-17 Sunday 18:37 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * AUTHORS, TODO: Update.
+
+2002-11-17 Sunday 18:36 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * glyphops.c: Hints for the wide hat and wide tilde accents in AMS
+ fonts.
+
+2002-11-17 Sunday 18:35 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * page.c: Add bubble_node() as a wrapper around bubble() and use it
+ everywhere but in insert_list(). This reduces direct manipulation
+ of the global list_latest variable as far as possible.
+
+2002-11-12 Tuesday 00:29 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * pse2unic.c: Fix char signedness in report_line()s prototype,
+ silences harmless compiler warning.
+
+2002-11-12 Tuesday 00:28 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fontinfo.c: - font_def(): be a bit less picky about which fonts
+ define axis_height,
+ some of the AMS fonts are not really "TeX math symbols" encoded
+ but do.
+ - font_def(): substitute missing fonts by cmr10.
+ - read_tfm(): abort if opening the tfm file fails (missing fonts
+ can't be
+ the cause anymore).
+
+2002-11-12 Tuesday 00:26 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * page.c: page_set_glyph(): call glyph_get_hint() only once and
+ save the result.
+
+2002-11-12 Tuesday 00:24 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * outenc.c: New translations for US-ASCII and friends: GLYPH_tilde
+ and GLYPH_similar to GLYPH_asciitilde, GLYPH_lessequal and
+ GLYPH_greaterequal to the usual ASCII art, the mathematical
+ alphabets (script, fraktur, blackboard bold) to the normal
+ alphabet.
+
+2002-11-12 Tuesday 00:23 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * build.sh: Prepare for 0.14.
+
+2002-11-08 Friday 00:36 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fntenc.c: Make TEX MATH ITALIC SUBSET an alias for TEX MATH
+ ITALIC.
+
+2002-11-08 Friday 00:32 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * catdvi.1: Update.
+
+2002-11-08 Friday 00:29 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fntenc.c, pse2unic.c, enc/euex.enc: Add Euler compatible
+ extension font encoding.
+
+2002-11-07 Thursday 00:19 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * outenc.c: Optimize the default path in outenc_get_width(),
+ outenc_write().
+
+2002-11-06 Wednesday 23:39 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * glyphops.c, outenc.c: Use new spars32_t instead of sparp_t
+ holding pointers to ints.
+
+2002-11-06 Wednesday 01:25 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fntenc.c: Add TEX MATH SYMBOLS SUBSET as an alias for TEX MATH
+ SYMBOLS.
+
+2002-11-06 Wednesday 01:24 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * sparse.c: Forgot a null pointer check.
+
+2002-11-05 Tuesday 23:18 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * sparse.c, sparse.h: Added "array of sint32" class (spars32_t).
+ Cleaned up a lot. May be a bit faster now.
+
+2002-10-31 Thursday 00:49 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h, outenc.c, enc/texmext.enc, enc/texmsym.enc: Update to
+ latest Unicode version - use mathematical angle brackets instead
+ of angle brackets where appropriate (Unicode 3.2) - use math
+ script alphabet (Unicode 3.1) - use new bracket pieces (Unicode
+ 3.2) instead of Adobe's private space version
+
+2002-10-23 Wednesday 23:17 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * outenc.c: Add some translations for non-Unicode chars in
+ AMSSymbolsB encoding.
+
+2002-10-15 Tuesday 22:45 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h, enc/amssymba.enc: Regularize some glyph names.
+
+2002-10-15 Tuesday 22:14 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h: Fix typo.
+
+2002-10-15 Tuesday 21:47 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fntenc.c, pse2unic.c, enc/amssymbb.enc: Add AMSSymbolsB encoding.
+
+2002-10-15 Tuesday 21:46 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h: Add new glyphs required for AMSSymbolsB encoding.
+
+2002-10-01 Tuesday 23:21 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * util.c, util.h: Simplify xmalloc().
+
+2002-09-12 Thursday 22:29 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fntenc.c, pse2unic.c, enc/amssymba.enc: Add AMS Symbols A (msam)
+ encoding.
+
+2002-09-12 Thursday 22:27 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h: Add new glyphs for msam. Remove superfluous spaces in
+ circle[A-Z] glyph definitions.
+
+2002-07-30 Tuesday 21:56 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/eufrak.enc, fntenc.c, pse2unic.c: Add eufrak (Euler Fraktur)
+ font encoding.
+
+2002-07-21 Sunday 23:00 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, pse2unic.c, enc/blackboard.enc, enc/blackboard.h:
+ Add a proper .enc file for the blackboard encoding (now that the
+ necessary Unicode chars are there). Thus, enc/blackboard.h is a
+ generated file now.
+
+2002-07-21 Sunday 22:56 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h: Add some of the new math characters in Unicode 3.2,
+ mostly from the mathematic alphanumerical symbols block.
+
+2002-07-09 Tuesday 22:51 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fontinfo.c: Optimize font_w_to_space(), which is called _very_
+ often: - Precompute constant (per font) values int font_def() and
+ store them in struct tfm_t. - The remaining calculations can
+ be switched from double arithmetic to integer arithmetic
+ without loss of precision.
+
+2002-07-09 Tuesday 22:50 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fixword.c: - fw2double(): cast 1 to uint32 before shifting.
+ - fw_prod(): add missing minus signs in return values.
+ - fw_prod(): use shifts instead of multiplication/division by
+ powers of 2.
+
+2002-07-09 Tuesday 22:48 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * layout.c: Allow page_words to have no ceiling. Fixes superfluous
+ empty line at the beginning of every page.
+
+2002-07-05 Friday 21:39 uid44598
+
+ * regsta.c: Optimize dump_regs() for default (no debug output)
+ case.
+
+2002-07-05 Friday 21:34 uid44598
+
+ * bytesex.c: Optimize {u,s}_readbigendiannumber() a bit.
+
+2002-07-01 Monday 23:31 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * page2.h: Fix typo in comment.
+
+2002-07-01 Monday 23:30 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * TODO: updates
+
+2002-07-01 Monday 23:29 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * layout.c: Heavily reworked and improved 2-dimensional layout
+ code.
+
+2002-07-01 Monday 23:28 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * util.h: Get size_t from <stddef.h> instead of <stdlib.h>.
+
+2002-06-09 Sunday 13:42 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, layout.c, layout.h, page.c, page2.h: Split out the
+ page_print_* functions into separate source file layout.c. Export
+ a few page.c internals in page2.h to make this possible.
+
+2002-06-09 Sunday 13:40 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * util.h: Include <stdlib.h> because we use size_t.
+
+2002-06-09 Sunday 13:39 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h, canvas.c: Add box drawing glyphs to adobetbl.h and
+ use their descriptive names in canvas.c
+
+2002-04-23 Tuesday 00:28 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * page.c: The beginnings of a really two-dimensional layout
+ algorithm; currently almost equivalent to, but already a bit better
+ than what we had before. Simplify decide_space_count, we don't
+ need the complicated cases anymore.
+
+2002-04-23 Tuesday 00:27 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * density.c, density.h: Fix bug in scdf_set_curr_to_x when x ==
+ xmax. Add new function sdcf_floor_of_integral(). Update some
+ comments.
+
+2002-04-23 Tuesday 00:26 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile: Integrate canvas.{c,h}.
+
+2002-04-23 Tuesday 00:25 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * canvas.c, canvas.h: Models a two-dimensional array of display
+ cells in which one can draw text and rules.
+
+2002-04-09 Tuesday 22:20 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fontinfo.c: Use xmalloc instead of malloc/enomem -- zero sized
+ allocations are possible here.
+
+2002-04-09 Tuesday 22:19 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * catdvi.c: Add facility to simulate different malloc behaviour on
+ GNU libc.
+
+2002-04-09 Tuesday 22:19 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * util.c, util.h: - Add xmalloc() macro (handles zero sized
+ allocations right).
+ - Don't duplicate enomem() and NOTREACHED message strings in
+ every
+ object file which uses these macros.
+ - Switch debug output functions from "char * format" to "const
+ char * format"
+ - Add facility to simulate different malloc behaviour on GNU
+ libc.
+
+2002-04-01 Monday 22:57 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * README, configure.in: Update for 0.13 final.
+
+2002-03-30 Saturday 01:36 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * page.c: Use SINT32_MIN, SINT32_MAX macros instead of (broken)
+ explicit constants which made problems on alpha.
+
+2002-03-30 Saturday 01:35 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * bytesex.h: Fix SINT32_MIN macro.
+
+2002-03-28 Thursday 23:16 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * density.c, tfminfo.c, vlist.c: Get malloc() declaration from
+ <stdlib.h> (ISO C) instead of obsolete <malloc.h>.
+
+2002-03-24 Sunday 22:37 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * configure.in: Bump version to 0.13.pre2.
+
+2002-03-24 Sunday 22:37 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h, glyphops.c, outenc.c: Add some glyphs. Make polish \L
+ and \l work. Translate /Eng to "Ng" and /eng to "ng" for ascii and
+ friends.
+
+2002-03-24 Sunday 22:35 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fntenc.c, pse2unic.c, enc/dummy.enc, enc/ot1wofl.enc: Encoding
+ selection fixes: - Forgot to uppercase `LATEX SYMBOLS' entry in
+ fontenctbl[]. - Add dummy encoding for some AMS fonts which lie
+ about their encoding. - Move `TeX Text without f-ligatures' to a
+ seperate .enc file since it is not completely a subset of `Tex
+ Text'.
+
+2002-03-24 Sunday 22:32 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/textt.enc: Fix code point 0x20 (/$space -> /$visualspace).
+
+2002-03-24 Sunday 22:31 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/ot1.enc: Code points 0x22 (/quotedblright) and 0x5c
+ (/quotedblleft) were interchanged. Fix code point 0x20 (/$space ->
+ /$polishstroke).
+
+2002-03-24 Sunday 22:30 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/cork.enc: Fix code points 0x17 (/$space -> /$ZWNJ), 0x20
+ (/$spacesymbol -> /$visualspace), 0x8d (/$Ng -> /Eng), 0xad (/$ng
+ -> /eng).
+
+2002-03-13 Wednesday 22:59 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * configure.in: Bump version to 0.13.pre1.
+
+2002-03-13 Wednesday 22:59 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * INSTALL, NEWS, README, build.sh, catdvi.c: Prepare for 0.13.
+
+2002-03-13 Wednesday 22:58 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * AUTHORS: Update.
+
+2002-03-13 Wednesday 22:57 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/texmsym.enc: Correct wrong mapping of code points 0x7d, 0x7e.
+
+2002-03-13 Wednesday 22:56 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h, catdvi.1, fntenc.c, pse2unic.c, enc/latexsym.enc:
+ Added latexsym encoding.
+
+2002-03-13 Wednesday 22:54 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fontinfo.c: Don't compare .tfm checksums if either is zero.
+
+2002-03-09 Saturday 00:34 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/textcomp.enc: fix unavailable glyphs
+
+2002-03-09 Saturday 00:34 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * catdvi.1: manpage update
+
+2002-03-09 Saturday 00:33 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * catdvi.c: change -e option to accept encoding as name too
+
+2002-03-09 Saturday 00:32 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fntenc.c, util.c, util.h: move some small string utilities from
+ fntenc.c to util.c
+
+2002-03-09 Saturday 00:31 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * outenc.c, outenc.h: add ISO-8859-15 output encoding; some related
+ cleanups
+
+2002-02-13 Wednesday 00:01 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * outenc.h: Add multiple inclusion guard.
+
+2002-02-13 Wednesday 00:01 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * outenc.c: Fix behaviour of generic_register_accentings() and
+ generic_accent() when more than one accenting table is registered.
+
+2002-02-13 Wednesday 00:00 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, vlist.c, vlist.h: Add generic list class.
+
+2002-02-07 Thursday 22:51 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * TODO: Updates
+
+2002-02-07 Thursday 22:51 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobe2h.c, adobetbl.h: Add many new Unicode chars, including
+ .notavail (REPLACEMENT CHARACTER) which needs special treatment in
+ adobe2h.c .
+
+2002-02-07 Thursday 22:49 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * pse2unic.c: Check that adobetbl.h is sorted (bsearch won't work
+ otherwise). Add marvosym encodings.
+
+2002-02-07 Thursday 22:46 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/marvo00.enc, enc/marvo98.enc, fntenc.c: Add (old and new)
+ marvosym encodings.
+
+2002-02-07 Thursday 22:44 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile: Stop enumerating all headers in enc/ manually.
+
+2002-01-17 Thursday 23:11 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, adobetbl.h, fntenc.c, fntenc.h, fontinfo.c,
+ fontinfo.h, glyphops.c, outenc.c, pse2unic.c, readdvi.c, tfminfo.c,
+ enc/eurosym.enc, enc/textcomp.enc: Add new font encodings: eurosym,
+ text companion; and related changes elsewhere: - adobetbl.h,
+ glyphops.c: Add new glyphs and glyph hints. - outenc.c: Add new
+ accentings + translations. Also fix a printf() format. -
+ fntenc.c fntenc.h: pattern matching for font family in
+ find_fntenc() (need this for fonts with "U" encoding like
+ eurosym and probably others in future). Changes prototype of
+ find_fntenc(). - fontinfo.c fontinfo.h: New function
+ font_family(). Adapt calls to find_fntenc(). - readdvi.c:
+ Adapt calls to find_fntenc(). - tfminfo.c: Show font family. And
+ remove max, min macro definitions. - pse2unic.c: Allow a command
+ in the preamble of the report (e.g. \usepackage)
+
+2002-01-17 Thursday 23:06 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * page.c, util.h: Define max, min in util.h; remove other
+ definitions.
+
+2001-12-30 Sunday 00:26 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * readdvi.c: Don't ignore rules completely -- we can't output them
+ yet, but a set_rule needs to move the reference point even though.
+
+2001-12-10 Monday 22:26 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * configure.in: Check for getopt_long() in libkpathsea only if not
+ found in libc. Bump version to final.
+
+2001-12-09 Sunday 22:17 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * bytesex.c: Fixed unwanted sign extension in s_readbigendiannumber
+ when sizeof(unsigned long) > sizeof(int). size
+
+2001-12-08 Saturday 23:13 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, NEWS, README, build.sh, catdvi.c, config.mk.in,
+ configure.in: Fixed clashing getopt symbols on systems with
+ static-only libkpathsea. Added --with-kpathsea-prefix option to
+ configure.
+
+2001-11-28 Wednesday 06:01 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * README: fix my name
+
+2001-11-28 Wednesday 00:02 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * TODO: updates
+
+2001-11-28 Wednesday 00:01 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fontinfo.c: font_w_to_space(): handle fonts with quad == 0
+
+2001-11-28 Wednesday 00:00 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * tfminfo.c: print font parameter names
+
+2001-11-28 Wednesday 00:00 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * readdvi.c: fix fnt_def debug output -- font name is "n", not
+ "comment"
+
+2001-11-27 Tuesday 23:59 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * page.c: Use BF_DIACRITIC instead of GH_DIACRITIC in
+ page_adjust_diacritics. Avoid the page_adjust_* loops when there's
+ nothing to adjust.
+
+2001-11-27 Tuesday 23:58 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * manifest-filter.lst: include version.h (for builds without
+ ./configure) and plain text copy of man page in distribution
+
+2001-11-27 Tuesday 23:57 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * NEWS, README, configure.in: prepare for 0.12
+
+2001-11-27 Tuesday 23:56 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * INSTALL: add ISO C compiler to requirements, fix typo
+
+2001-11-27 Tuesday 23:55 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * catdvi.1: add note about output width, small fixes
+
+2001-11-27 Tuesday 23:54 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile: add catdvi.txt and catdvi.html targets, small
+ rearrangements
+
+2001-11-21 Wednesday 00:48 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * catdvi.c: update maintainer address and copyrights
+
+2001-11-21 Wednesday 00:47 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * catdvi.1: update manpage
+
+2001-11-21 Wednesday 00:46 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * build.sh: simple build script for systems without GNU make
+
+2001-11-21 Wednesday 00:24 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * INSTALL: elaborate
+
+2001-11-21 Wednesday 00:22 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobe2h.c, glyphops.c, page.c: portability fixes -- stay ANSI C
+ compliant
+
+2001-11-14 Wednesday 00:18 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobe2h.c, glyphops.c, glyphops.h, outenc.c, outenc.h, page.c,
+ pse2unic.c: small fixes; remove some compiler warnings
+
+2001-11-14 Wednesday 00:15 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * TODO: updates
+
+2001-11-11 Sunday 23:09 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * tfminfo.c: Forgot to include "findtfm.h".
+
+2001-11-11 Sunday 23:08 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, catdvi.1, catdvi.c, page.c, page.h, pageref.c,
+ pageref.h, readdvi.c:
+ Added cmd line option to select page range. And fixed a runaway
+ comment in page_adjust_radicals().
+
+2001-11-11 Sunday 23:01 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * bytesex.h: define SINT32_MAX, SINT32_MIN, UINT32_MAX
+
+2001-10-23 Tuesday 22:52 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, tfminfo.c: tfminfo is a new program to dump some
+ information about a tfm file (not much there yet).
+
+2001-10-23 Tuesday 22:50 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * test/texmext.tex: test for correct positioning of the TeX math
+ extension glyphs
+
+2001-10-23 Tuesday 22:46 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * TODO, adobetbl.h, fontinfo.c, fontinfo.h, glyphops.c, glyphops.h,
+ outenc.c, page.c, page.h, readdvi.c, enc/texmext.enc: Added support
+ for most of `TeX Math Extensions' encoding (all but the extensible
+ recipes). Fixed most of the missing glyphs there. Reposition big
+ operators and radicals so they appear at the right place in
+ printout. This required some changes to other parts of the program:
+ + fontinfo.c page.c page.h readdvi.c: Record depth of glyph in
+ box_t. + fontinfo.c fontinfo.h : Make non-mandatory font
+ parameters accessible. + fontinfo.c fontinfo.h : Added
+ font_axis_height(), renamed scale() to font_scale_fw() and
+ exported both. + readdvi.c : Keep track of the math axis and pass
+ it on to page_set_glyph(). + page.c : struct box_t has a few
+ new members.
+
+2001-04-16 Monday 20:21 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h, glyphops.c, outenc.c, enc/cork.enc, enc/ot1.enc,
+ enc/texmital.enc, enc/texmsym.enc, enc/textt.enc: Mark all
+ duplicate glyph names in adobetbl.h and get rid of all references
+ to them (pse2unic resolves references to duplicates in an arbitrary
+ fashion).
+
+2001-04-14 Saturday 20:05 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * outenc.c: Some new ascii/latin1 translations; (C) and (R) signs
+ as accentings.
+
+2001-04-14 Saturday 20:02 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * glyphops.c: Some new combining diacritics: encircle, slash
+ through, arrow above.
+
+2001-04-14 Saturday 20:01 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/texmital.enc, adobetbl.h: Fixed most of the missing glyphs in
+ texmital.enc .
+
+2001-04-12 Thursday 01:48 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/texmsym.enc: Fixed all but one missing glyph.
+
+2001-04-12 Thursday 01:47 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h: Added a lot of TeX math symbols.
+
+2001-04-12 Thursday 01:46 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * outenc.c: Added ascii translation minus -> hyphen.
+
+2001-04-10 Tuesday 00:11 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * TODO: Removed done items.
+
+2001-04-10 Tuesday 00:10 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * catdvi.c, glyphops.c, glyphops.h, linebuf.c, linebuf.h, outenc.c,
+ outenc.h, page.c, util.c: outenc.c, outenc.h: complete
+ reorganisation. Works string-based now, not character based; can
+ tell how wide strings would be in output. page.c: use new outenc
+ facilities to get ligatures correctly aligned. other files: moved
+ some code to outenc.c.
+
+2001-04-10 Tuesday 00:03 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * util.h: - enomem(): tell where we ran out of memory.
+ - Added "lengthof" macro for arays.
+
+2001-04-10 Tuesday 00:00 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h: Added some glyphs (quotes, ligatures).
+
+2001-03-22 Thursday 02:11 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, pse2unic.c: Collect all available TeX font ->
+ Unicode mapping information in a (LaTeX) report. Makes it much
+ easier to check what's going on.
+
+2001-03-19 Monday 02:10 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/cork.enc: Fixed the missing glyphs.
+
+2001-03-19 Monday 02:09 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, adobe2h.c, glyphops.c: Automatically derive a header
+ with glyph constants from adobetbl.h and use that in glyphops.c
+ instead of home brew definitions.
+
+2001-03-19 Monday 02:05 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * adobetbl.h: Added some glyphs: diacritics, private replacements
+ for ambiguous tcommaaccent, Tcommaaccent.
+
+2001-02-28 Wednesday 02:07 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * fontinfo.c: font_w_to_space(): if the tfm file has param[2]
+ (space) == 0, don't use param[6] (quad) as substitute, but only a
+ fraction of it. Improves math.
+
+2001-02-27 Tuesday 02:16 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * sparse.c: Portability fix: do not assume NULL is represented by a
+ zero bit pattern.
+
+2001-02-23 Friday 02:51 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * TODO: Document some ideas.
+
+2001-02-23 Friday 02:48 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, catdvi.c, glyphops.c, sparse.c, sparse.h: Use
+ "sparse arrays" (a lightweight container class based on trees)
+ instead of linear lists for glyph property lookups.
+
+2001-02-22 Thursday 17:12 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * outenc.c: Some new ASCII exceptions.
+
+2001-02-22 Thursday 07:06 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * test/math.tex: some more advanced maths
+
+2001-02-21 Wednesday 19:55 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, NEWS, README, configure.in, cvsparser.pl,
+ manifest-filter.lst, manifest-filter.pl: merge from 0.11 branch
+
+2001-02-21 Wednesday 19:32 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile (ver_0_11): Fix the dist target.
+
+2001-02-21 Wednesday 19:15 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile (ver_0_11): If NOSIGN is empty, sign. Not the other
+ way around.
+
+2001-02-21 Wednesday 19:14 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile (ver_0_11): Propagate NOSIGN to the child make making
+ MD5SUMS.
+
+2001-02-21 Wednesday 19:12 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile (ver_0_11): Make a useful NOSIGN option.
+
+2001-02-21 Wednesday 19:09 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile (ver_0_11): Don't rebuild ChangeLog after making
+ MD5UMS.
+
+2001-02-21 Wednesday 19:06 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile (ver_0_11): Actually do something useful in rewritten
+ dist target.
+
+2001-02-21 Wednesday 19:00 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile (ver_0_11): Use Manifest from $(grbdir) when building
+ all in Manifest.
+
+2001-02-21 Wednesday 18:55 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile (ver_0_11): Oops, forgot -v from grep.
+
+2001-02-21 Wednesday 18:53 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile (ver_0_11): Make all files in Manifest, to be sure.
+
+2001-02-21 Wednesday 18:50 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * manifest-filter.lst (ver_0_11): Another fix
+
+2001-02-21 Wednesday 18:48 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile (ver_0_11): Fix.
+
+2001-02-21 Wednesday 18:47 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * manifest-filter.lst: file manifest-filter.lst was initially added
+ on branch ver_0_11.
+
+2001-02-21 Wednesday 18:47 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * cvsparser.pl: file cvsparser.pl was initially added on branch
+ ver_0_11.
+
+2001-02-21 Wednesday 18:47 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, cvsparser.pl, manifest-filter.lst,
+ manifest-filter.pl (ver_0_11): an untested new release-building
+ system
+
+2001-02-21 Wednesday 18:47 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * manifest-filter.pl: file manifest-filter.pl was initially added
+ on branch ver_0_11.
+
+2001-02-21 Wednesday 17:05 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * NEWS, README, configure.in (ver_0_11): preparation for 0.11
+ release
+
+2001-02-11 Sunday 23:04 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile: dist target: include ChangeLog in the distribution
+ tarball (seems to be the right thing, revert me if I'm wrong).
+
+2001-02-09 Friday 00:30 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * page.c: small fixes to page_print() : - change one debug message
+ level 10 -> 80 - forgot to free some memory
+
+2001-02-09 Friday 00:23 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, density.c, density.h, page.c: new alignment
+ algorithm (experimental, patch #103454)
+
+2001-02-09 Friday 00:19 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * GNUmakefile, fntenc.c, enc/textt.enc: added "TeX Typewriter Text"
+ input encoding (patch #103455)
+
+2001-02-09 Friday 00:15 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * enc/ot1.enc: correct /periodsuperoir -> /dotaccent in OT1
+ encoding (patch #103456)
+
+2001-02-07 Wednesday 17:02 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, changelog-authors, config.mk.in: add ChangeLog
+ autogeneration
+
+2001-02-07 Wednesday 16:50 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * README: björn again
+
+2001-02-07 Wednesday 16:46 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * AUTHORS: updated Björn's data
+
+2001-02-07 Wednesday 00:07 Björn Brill <bjoernb@users.sourceforge.net>
+
+ * linebuf.c: Added missing brackets in linebuf_output_with_enc() -
+ operator precedence bug, but so far without consequences.
+
+2000-12-02 Saturday 11:45 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, catdvi.1, catdvi.c, glyphops.c, glyphops.h,
+ linebuf.c, linebuf.h, page.c, page.h, test/ot1umlauts.tex: OT1
+ diacritics support and sequential feature from Bjoern Brill
+
+2000-06-16 Friday 15:43 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * NEWS, configure.in, catdvi.1: Release 0.10.
+
+2000-06-16 Friday 15:43 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * README: Release 0.10; note the mailing list
+
+2000-06-16 Friday 15:42 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * TODO: Update for --enable-developer-warnings
+
+2000-06-16 Friday 15:27 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, config.mk.in, configure.in, pse2unic.c, util.c,
+ util.h: Make pse2unic suppress warnings when warnings are not asked
+ for at configure time.
+
+2000-06-14 Wednesday 19:53 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * AUTHORS: Add Bjoern Brill the manpage author.
+
+2000-06-14 Wednesday 19:48 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile: Added an uninstall target.
+
+2000-06-14 Wednesday 19:46 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, config.mk.in: Install and distribute the manpage.
+
+2000-06-14 Wednesday 19:39 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * catdvi.1: Manpage from Bjoern Brill
+
+2000-04-16 Sunday 02:05 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile: Remove .tar.gz too at start of dist.
+
+2000-04-16 Sunday 01:59 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * NEWS, README, configure.in: Bumped version number to 0.9.
+
+2000-04-16 Sunday 01:47 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * config.mk.in: Added exec_prefix.
+
+2000-04-16 Sunday 01:36 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile: Typo.
+
+2000-04-16 Sunday 01:35 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile: Create also gzipped release files in dist target.
+
+2000-04-16 Sunday 01:27 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile: Include the file name in install's target argument
+
+2000-04-10 Monday 14:41 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, config.mk.in: wrote a skeleton install target that
+ probably does not work correctly
+
+2000-02-18 Friday 22:15 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * NEWS: 0.8 preparations
+
+2000-02-18 Friday 22:15 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, config.mk.in: Added dist target
+
+2000-02-18 Friday 18:08 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * enc/blackboard.h: oops, forgot this file
+
+2000-02-18 Friday 18:06 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, INSTALL, config.mk, config.mk.in, configure.in,
+ version.h, version.h.in: Use autoconf.
+
+2000-02-18 Friday 18:04 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * README: Updated.
+
+2000-02-18 Friday 17:09 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * Makefile: Removing cruft
+
+2000-02-17 Thursday 22:46 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * .depend, LICENSE, catdvi.h: Removing more old cruft
+
+2000-02-17 Thursday 22:39 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * README: Updated URLs, preparing for 0.7b
+
+2000-02-17 Thursday 22:15 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * README, version.h: Importing v0.7a
+
+2000-02-17 Thursday 22:08 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * NEWS, README, fixword.c, fixword.h, fontinfo.c, page.c,
+ readdvi.c, readdvi.h, regsta.c, regsta.h, test/box.tex: Importing
+ v0.7
+
+2000-02-17 Thursday 21:59 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, INSTALL, NEWS, README, TODO, adobetbl.h, bytesex.c,
+ bytesex.h, catdvi.c, findtfm.h, fntenc.c, fontinfo.c, fontinfo.h,
+ getopt.c, getopt.h, getopt1.c, kpathsea.c, outenc.c, outenc.h,
+ readdvi.c, regsta.c, regsta.h, version.h, enc/cork.enc, config.mk,
+ fixword.c, fixword.h, page.c, page.h, test/finnish.tex,
+ test/ligatures.tex, test/math.tex, test/private.tex,
+ test/testfont.tex, test/texlogo.tex: Importing v0.6
+
+2000-02-17 Thursday 21:54 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * GNUmakefile, NEWS, README, catdvi.c, outenc.c, version.h:
+ Importing v0.5
+
+2000-02-17 Thursday 21:33 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * AUTHORS, README, TODO, catdvi.c, fntenc.c, fntenc.h, outenc.c,
+ outenc.h, regsta.c, regsta.h, util.c, util.h, GNUmakefile, INSTALL,
+ NEWS, adobetbl.h, bytesex.c, bytesex.h, findtfm.h, fontinfo.c,
+ fontinfo.h, getopt.c, getopt.h, getopt1.c, kpathsea.c, pse2unic.c,
+ readdvi.c, readdvi.h, version.h, enc/README, enc/cork.enc,
+ enc/ot1.enc, enc/texmext.enc, enc/texmital.enc, enc/texmsym.enc:
+ Importing v0.4
+
+2000-02-17 Thursday 21:29 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * AUTHORS, Makefile, README, catdvi.c, TODO, fntenc.c, fntenc.h,
+ outenc.c, outenc.h: Importing v0.3
+
+2000-02-17 Thursday 21:25 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * README, catdvi.c: Importing v0.2
+
+2000-02-17 Thursday 21:21 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * README, catdvi.c, regsta.c, COPYING: Importing v0.1 (the previous
+ was v.0.0, oops)
+
+2000-02-17 Thursday 21:18 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * Makefile, catdvi.h, LICENSE, catdvi.c, .depend, AUTHORS, util.c,
+ util.h, README, regsta.h, regsta.c: Initial revision
+
+2000-02-17 Thursday 21:18 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ * Makefile, catdvi.h, LICENSE, catdvi.c, .depend, AUTHORS, util.c,
+ util.h, README, regsta.h, regsta.c: Version 0.1 import
+
diff --git a/dviware/catdvi/GNUmakefile b/dviware/catdvi/GNUmakefile
new file mode 100644
index 0000000000..c759085b97
--- /dev/null
+++ b/dviware/catdvi/GNUmakefile
@@ -0,0 +1,219 @@
+# catdvi - get text from DVI files
+# Copyright (C) 1999 J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl>
+# Copyright (C) 1999, 2000, 2001 Antti-Juhani Kaijanaho <gaia@iki.fi>
+# Copyright (C) 2000-2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#CC = gcc
+#CFLAGS = -Wall -W -Wshadow -Wpointer-arith -Wbad-function-cast \
+# -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
+# -Wmissing-declarations -ansi -pedantic -g
+
+include config.mk
+
+ifeq ($(CFG_HAS_GETOPT_LONG),yes)
+GETOPT = # nothing
+CPPFLAGS += -DCFG_HAS_GETOPT_LONG
+else
+ifeq ($(CFG_KPATHSEA_HAS_GETOPT_LONG),yes)
+GETOPT = # nothing
+CPPFLAGS += -DCFG_KPATHSEA_HAS_GETOPT_LONG
+else
+GETOPT = getopt.c getopt1.c
+endif
+endif
+
+ifeq ($(CFG_HAS_KPATHSEA),yes)
+FINDTFM = kpathsea.o
+LDLIBS = -lkpathsea
+else
+$(error Sorry) # Implement a replacement for kpathsea.c yourself...
+endif
+
+ifeq ($(CFG_SHOW_PSE2UNIC_WARNINGS),yes)
+PSE2UNICFLAGS = # nothing
+else
+PSE2UNICFLAGS = -w
+endif
+
+programs := catdvi pse2unic adobe2h tfminfo
+tests := $(wildcard test/*.tex)
+sources := $(wildcard *.c)
+encfiles := $(wildcard enc/*.enc)
+
+all1 : $(programs) $(tests:.tex=.dvi)
+
+catdvi : bytesex.o catdvi.o fixword.o fntenc.o fontinfo.o outenc.o \
+ page.o readdvi.o regsta.o util.o glyphops.o linebuf.o\
+ density.o sparse.o pageref.o vlist.o canvas.o layout.o\
+ $(GETOPT) $(FINDTFM)
+
+# fontinfo : fontinfo.o bytesex.o util.o
+tfminfo : tfminfo.o bytesex.o fixword.o fontinfo.o util.o fntenc.o $(FINDTFM)
+
+pse2unic : pse2unic.o util.o
+
+adobe2h : adobe2h.o
+
+fntenc.o fntenc.d : $(encfiles:.enc=.h)
+
+glyphops.o glyphops.d : glyphenm.h
+
+glyphenm.h : adobe2h
+ ./adobe2h > glyphenm.h
+
+config.mk : config.mk.in
+ ./config.status
+
+ChangeLog :
+ CVS_RSH=ssh $(CVS2CL) -U changelog-authors -W 1200 -b --gmt -w --ignore ChangeLog
+
+.PHONY : ChangeLog
+
+clean :
+ $(RM) *.o $(programs) core tags test/*.log test/*.aux
+ $(RM) enc/*.log enc/*.aux
+ find . -name '*~' -or -name '*.bck' | xargs $(RM)
+
+distclean : clean
+ $(RM) *.d test/*.dvi test/*.log test/*.aux 1
+ $(RM) enc/*.dvi enc/*.tex
+ $(RM) glyphenm.h $(encfiles:.enc=.h)
+ $(RM) config.cache config.status config.mk version.h config.log
+ $(RM) -r $(package)-$(version)
+ $(RM) -r test/auto
+
+maintainer-clean : distclean
+ $(RM) test/*.dvi configure ChangeLog
+
+%.d: %.c
+ set -e; $(CC) -MM $(CPPFLAGS) $< | \
+ sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
+ [ -s $@ ] || rm -f $@
+
+test/%.dvi : test/%.tex
+ cd test && latex $(notdir $<)
+
+enc/%.h enc/%.tex : enc/%.enc pse2unic
+ ./pse2unic $(PSE2UNICFLAGS) $< $(<:.enc=.h) $(<:.enc=.tex)
+
+# autogenerated documentation
+#
+enc/%.dvi : enc/%.tex
+ cd enc && latex $(notdir $<)
+
+encreports : $(encfiles:.enc=.dvi)
+
+catdvi.txt : catdvi.1
+ man -l catdvi.1 -Tascii | col -b -x > catdvi.txt
+
+catdvi.html: catdvi.1
+ troff2html -man catdvi.1 > catdvi.html
+
+# release packaging
+#
+dist : distdir=$(package)-$(version)
+dist : $(sources:.c=.d) ChangeLog
+ rm -rf $(distdir)
+ $(RM) $(distdir).tar
+ $(RM) $(distdir).tar.bz2
+ $(RM) $(distdir).tar.gz
+ mkdir $(distdir)
+ set -e ; for d in $(shell cat Manifest | xargs -l1 dirname | sort | uniq) ;\
+ do \
+ echo -n "Making directory $(distdir)/$$d ..." ;\
+ mkdir -p $(distdir)/$$d ;\
+ echo "done." ;\
+ done
+ set -e ; for f in $(shell cat Manifest);\
+ do \
+ echo -n "Copying $$f ..." ;\
+ ln $$f $(distdir)/$$f ;\
+ echo "done." ;\
+ done
+ tar cf $(distdir).tar $(distdir)
+ bzip2 -9k $(distdir).tar
+ gzip -9 $(distdir).tar
+
+install: catdvi
+ $(INSTALL_PROGRAM) catdvi $(bindir)/catdvi
+ $(INSTALL_DATA) catdvi.1 $(man1dir)/catdvi.1
+
+uninstall:
+ $(RM) $(bindir)/catdvi
+ $(RM) $(man1dir)/catdvi.1
+
+# For fun ;-)
+linecount :
+ rmccmt $(filter-out getopt.c getopt.h getopt1.c adobetbl.h, \
+ $(wildcard *.c *.h)) | indent | uniq | wc -l
+
+Manifest:
+ rm -f $@.new $@.edi
+ ./cvsparser.pl | ./manifest-filter.pl > $@.edi
+ sort $@.edi -o $@.new
+ mv $@.new $@
+ rm -f $@.edi
+
+.PHONY: Manifest MD5SUMS
+
+SIGN=gpg --clearsign
+MD5SUMS: Manifest
+ rm -f $@.new
+ set -e; for f in `egrep -v '^$@$$' Manifest `;\
+ do \
+ sum=$$(md5sum $$f | awk '{ print $$1; }'); \
+ size=$$(ls -l $$f | awk '{ print $$5; }'); \
+ printf "%s %5i %s\n" $$sum $$size $$f >> $@.new;\
+ done
+ if [ "$(NOSIGN)" = "" ] ;\
+ then\
+ $(SIGN) $@.new ;\
+ rm -f $@.new ;\
+ mv $@.new.asc $@ ;\
+ else\
+ mv $@.new $@ ;\
+ fi
+
+CVSTAG=none
+official-release : VERSION=$(shell echo $(CVSTAG) \
+ | sed -e 's/^rel_//' -e 's/_/./g')
+official-release : grbdir=catdvi-release-build
+official-release :
+ rm -rf $(grbdir)
+ set -e ;\
+ if $$(echo $(VERSION) \
+ | egrep '^[0-9]+\.[0-9]+(\.(pre)?[0-9]+)?$$' >/dev/null);\
+ then\
+ :; \
+ else \
+ echo "Bad VERSION"; \
+ exit 1; \
+ fi
+ cvs -z3 -d$(shell cat CVS/Root) checkout -r $(CVSTAG) \
+ -d $(grbdir) catdvi
+ cd $(grbdir) && autoconf && ./configure
+ make -C $(grbdir) Manifest
+ make -C $(grbdir) `egrep -v '^(Manifest|MD5SUMS)$$' $(grbdir)/Manifest`
+ make -C $(grbdir) -o Manifest NOSIGN=$(NOSIGN) MD5SUMS
+ make -C $(grbdir) -o ChangeLog dist
+ ln -f $(grbdir)/catdvi-$(VERSION).tar.gz
+ ln -f $(grbdir)/catdvi-$(VERSION).tar.bz2
+ rm -rf $(grbdir)
+
+
+include $(sources:.c=.d)
+
diff --git a/dviware/catdvi/INSTALL b/dviware/catdvi/INSTALL
new file mode 100644
index 0000000000..d6fc581608
--- /dev/null
+++ b/dviware/catdvi/INSTALL
@@ -0,0 +1,59 @@
+ -*- Text -*-
+
+This file describes how to build and install CatDVI version 0.14.
+
+
+REQUIREMENTS:
+
+ * a hosted ISO C (1990) environment
+
+ * the kpathsea library (installed) and accompanying header files
+
+ * only when building from CVS (if you don't know what that means then
+ you aren't): GNU autoconf
+
+Attention:
+ * For GNU/Linux users: with most distributions, it is not enough to have
+ TeX installed; the kpathsea headers are usually contained in an extra
+ package called "libkpathsea-dev" or "tetex-devel" or similar.
+
+ * For teTeX users: there were (are?) some teTeX pre-built binary tarballs
+ with statically linked libkpathsea in existence that did (do?) not include
+ the necessary development files. These will not work.
+
+ * Cross compiling catdvi does not work at the moment.
+
+
+IF YOU HAVE GNU MAKE AND A POSIX SHELL ENVIRONMENT:
+
+This is the easiest way. Note you need _GNU_ make. Really.
+
+ * Only when building from CVS:
+ autoconf
+
+ * On systems where "make" is GNU make (e.g. Linux):
+ ./configure [options]
+ make
+ make install
+
+ * On systems where "make" is not GNU make, but GNU make is available under
+ a different name (e.g. *BSD). The customary name is then "gmake".
+ Assuming this name:
+ MAKE=gmake ./configure [options]
+ gmake
+ gmake install
+
+The options to configure are standard. Type
+ ./configure --help
+for a list.
+
+
+OTHERWISE:
+
+A simple bourne shell script "build.sh" is included in the distribution tarball.
+Edit to your needs and run. Then install the resulting catdvi executable and
+(perhaps) the catdvi.1 man page to appropriate places.
+
+Even if you don't have a bourne shell compatible /bin/sh, it is fairly easy
+to understand what the script does and to adapt it to your environment or
+execute the necessary steps manually.
diff --git a/dviware/catdvi/MD5SUMS b/dviware/catdvi/MD5SUMS
new file mode 100644
index 0000000000..b4c21dbf90
--- /dev/null
+++ b/dviware/catdvi/MD5SUMS
@@ -0,0 +1,129 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+515943a6ccdcab2c5741843752704fe6 5297 ./adobe2h.c
+77b4fd36d2e55948e3e14bea95dc79f6 43 ./adobe2h.d
+ce69caf8d9df109f6a433f43f2964fd1 116823 ./adobetbl.h
+089d09784aa20d2f2dee7d412e0abfee 1040 ./AUTHORS
+c56a39442120687a42cf05cf8c74fa06 1934 ./build.sh
+091e6a030f3bae2145fd164388d19be6 3913 ./bytesex.c
+e8df54e06d699b104d0bfe1b33d55ccb 49 ./bytesex.d
+fba456044fbd7ed3041e35e37b7194e0 2108 ./bytesex.h
+3c1934a968329cab625af360a696b3ce 8679 ./canvas.c
+cfb4b86192efe9a5979c16c4129fa515 105 ./canvas.d
+215b9b7564182d5c18cc766bc2bd6727 2513 ./canvas.h
+ddaa2053e4ce5451cf476426ca8e7ef9 9324 ./catdvi.1
+b07819bd5d0f8f6119417f97a4380475 9934 ./catdvi.c
+5baee9395f3529ee7a2f089954846a7f 126 ./catdvi.d
+f32e9baf57627b5cda32458cda7dbbcf 10830 catdvi.txt
+cad1a88a21b03120c7409281be51b194 32329 ChangeLog
+3216e610116ce9f3621a2de8e7d695d9 97 ./changelog-authors
+49491579096a87d0c63b9631b26b8ab9 1493 ./config.mk.in
+c705210480591c3f34cd1a6156f7cde7 38508 configure
+31c7937671b9d0c091d2e59c54868897 2686 ./configure.in
+18810669f13b87348459e611d31ab760 17976 ./COPYING
+1bc0daee99a43ced545b80d753ac77f2 908 ./cvsparser.pl
+064983d4ced04693df6f4eb37b0fa172 8227 ./density.c
+f204e625fabc43bd3494b3d57cf9a63b 59 ./density.d
+241900eb3e59eb0bf1d7a40c302de942 5120 ./density.h
+d92aaf05ca3b5050a7b9e697ded52dad 3544 ./enc/amssymba.enc
+95a85ecac386d7f9b8d0185beab21543 3797 ./enc/amssymbb.enc
+1f606f51229515dac06111ff355c0161 2769 ./enc/blackboard.enc
+2e701ce338d3596acacaff35b705f11c 3847 ./enc/cork.enc
+1f8883d3981860d74b683ddd2dd380db 2783 ./enc/dummy.enc
+a3cda8472b2651847c7a27d189ce72d6 2992 ./enc/euex.enc
+2587c99ee4d6a8523428dcf1f74f4f14 3059 ./enc/eufrak.enc
+8b809ae35c94078536df5dc901f4b556 2546 ./enc/eurosym.enc
+3514567ffdfe0b198c0fe1b3320264f9 2721 ./enc/latexsym.enc
+25ddccadc43df18cd8b7aa90f6a478ba 4456 ./enc/marvo00.enc
+353c79854ac5aa79b14ebc4109ad4809 3223 ./enc/marvo98.enc
+85f0362b2dd6a30f87044c524804fad0 2017 ./enc/ot1.enc
+e9bc9c7dcf7eef74469cd7790443e508 2227 ./enc/ot1wofl.enc
+845259c859be60b1dbcbf63ea4724552 4365 ./enc/README
+df8ec255ef59dbff3ddacc4dbbdaa917 3689 ./enc/texmext.enc
+d41daf99b1ba7adda2c5249decb02a08 2629 ./enc/texmital.enc
+51252074f6d5ab1a4133aa70ce1e211a 3333 ./enc/texmsym.enc
+bc0aea31f88b1e920c4ea7683aff575a 3617 ./enc/textcomp.enc
+34974e342a0b780e036a9c62bad60640 2222 ./enc/textt.enc
+4ad2a329a875076c5701c6b90f6dc394 1232 ./findtfm.h
+65ebad7b2bd4c2c5c008fce2003f5af3 1367 ./fixword.c
+cdf5c7e9fb2ce9c7553e8e44d122999a 59 ./fixword.d
+1442f05bb958bafe6b0b5acd6cc3de2c 1615 ./fixword.h
+41427f9996338d2f84e6c384cdb5bda2 5472 ./fntenc.c
+8927f57565e1ce90d6fa869eaa606d65 312 ./fntenc.d
+27da724e042ad817d7ec087d52078edb 975 ./fntenc.h
+0138c4be2fcc5523c0e6093a726300fc 17148 ./fontinfo.c
+0adcb1641ea593f948ea569fdb67253b 105 ./fontinfo.d
+de569a16178bb451c2dbd2981643ade7 2003 ./fontinfo.h
+c30c5a02f4395595259724f35c960edc 4522 ./getopt1.c
+2cc8eb5a00b551d05fea6a0999bab028 41 ./getopt1.d
+9efc332d17b4ee818e047f33d248fd67 30035 ./getopt.c
+9c793329bcefbe8eba65f74c3bc10930 29 ./getopt.d
+0637f5374eb844d636f69e8a20ec07da 5833 ./getopt.h
+56df1966a4fa56d0ebebdaef1a775f85 13693 ./glyphops.c
+6ea4801fead0fed7387ae3432d5dd73d 96 ./glyphops.d
+55fe12fb502ea05d723a4bb8d0721c05 2304 ./glyphops.h
+566783e46ef4f76c269a0908eb4954d1 5894 ./GNUmakefile
+f0a3ecfc00c989b9c82987c908bb2bc0 1838 ./INSTALL
+3ad5d52339b0b4de49ae46e76c20156c 1458 ./kpathsea.c
+3f332b66001596dc76ff0941e89e2b45 55 ./kpathsea.d
+8aa5afa0b71c488cac55e21162819c59 29465 ./layout.c
+9d133744657ea73a794908cf442b82f6 150 ./layout.d
+fe9ff15649ed411bdc978aa786cae8de 931 ./layout.h
+641e14d601e592d29f8ce5dba890d265 3500 ./linebuf.c
+139ee69d757e0cda5213777e0c8e7514 76 ./linebuf.d
+0683a24008758196bfded8666763dd8d 2109 ./linebuf.h
+03289b4d70ad7f862b3fd8612ff09fd7 1560 Manifest
+48c2972dc73c675bcdb0a43a06d97518 101 ./manifest-filter.lst
+92ce92c24932bcd7a00f607dbad8a04d 886 ./manifest-filter.pl
+49fc28ed67896aae97a8389c16292582 3244 ./NEWS
+533b76697e8e3d84f07af97cc5c460d1 52612 ./outenc.c
+ef0873e8b4266e90b11fe2275c0e57e4 124 ./outenc.d
+926dce23137c2b73878ad353e2c33803 1853 ./outenc.h
+942b0da008a3042bc3e3b22f1fd2d7c9 2995 ./page2.h
+2ff036ad2495cc3ff75c2f0b87d2ac42 27292 ./page.c
+6d83157c438e25b1be3f5009923c939a 88 ./page.d
+1c91ca32e186c756e677afba8062fc39 1385 ./page.h
+9715b220e45c4ca52d79c1151d8257fd 3991 ./pageref.c
+37baaf721f9570569a6fa44e600190e5 59 ./pageref.d
+59dfaa58e9a854dad8e2ed23c9d1527e 2084 ./pageref.h
+de43677e902c8a5320381fdd9456abb0 11254 ./pse2unic.c
+0437122637a6f0df46fc7a487e4d0a81 53 ./pse2unic.d
+026f6e52ecd5521b132138c56e8c0faa 15096 ./readdvi.c
+7b7db5b64ad1c6dbecd4efc04b08aaf8 137 ./readdvi.d
+9c7c84f721666da24a56fe9d46c551b1 952 ./readdvi.h
+68572ff04d86c4c2669731e33462e64b 3470 ./README
+5b9d68c707e9054a98b869da27585483 2985 ./regsta.c
+2ab55981e89bf9bc3af1f1ccd94a66c3 55 ./regsta.d
+b503ff1f8b1cc8c3e746fdb2adb104a8 1680 ./regsta.h
+31ee6ef401ad250bb9d83f015581354c 5317 ./sparse.c
+f16a56fcc5adf10b856c39936d3169f3 55 ./sparse.d
+57ee58a3505f4b05ae777b57baffdfa9 5333 ./sparse.h
+66fcca4fe909255b1dca252f389d1e2b 73 ./test/box.tex
+a5f793f3dbb9cc65676837900e69b0b2 223 ./test/finnish.tex
+312289e1c1cfd3754ebe3deb8bf4217d 115 ./test/ligatures.tex
+4cf2747e3e3d617263dfec415246eb1d 246 ./test/math.tex
+a0c5ada082790026e4c1496b42eab0fc 223 ./test/ot1umlauts.tex
+0494b14cb2f3d3d67b5b38efb7dea594 136 ./test/private.tex
+8e0ae6ac59e3c2c195895cd33d133990 6522 ./test/testfont.tex
+ab8942c3944a4a03ca3bf5f150af3dae 78 ./test/texlogo.tex
+0d1faa427c8096ab5718700395aafb81 1233 ./test/texmext.tex
+f823e273e6b3395c62e4ad2d2d260e62 2615 ./tfminfo.c
+b172429d189f850c7afd92ffa6179070 80 ./tfminfo.d
+4ccfa6b4eac3392c0201d44dd9a3d8c6 3704 ./TODO
+bf4d4971ab3f1f1588cb0c1d0a7cef0b 5467 ./util.c
+99b6cb19cc8a5e1d68da398087f1201b 30 ./util.d
+56449015af371179567a37384d975314 4029 ./util.h
+9d25ebfca06182eaa1ea96b4793021bc 49 version.h
+b6ae824d7f8c4d9ec9b5bb19bb0a6646 57 ./version.h.in
+4473d22d33e7bc76b3025984ff567683 5222 ./vlist.c
+fbb6a0b78c5939edb4b88d9d2153fcdb 41 ./vlist.d
+5ed658e54699d7682681f3a6e2f4ed33 3495 ./vlist.h
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.6 (GNU/Linux)
+Comment: Weitere Infos: siehe http://www.gnupg.org
+
+iD8DBQE94RvUYRTFWiWYSk8RAoygAKCNhSrfZszmv2+uP8hsw3pyXNt0SACgupNF
+AsrvXwq1Yi0aAkkzqBISapg=
+=CUW1
+-----END PGP SIGNATURE-----
diff --git a/dviware/catdvi/Manifest b/dviware/catdvi/Manifest
new file mode 100644
index 0000000000..875e6d90ec
--- /dev/null
+++ b/dviware/catdvi/Manifest
@@ -0,0 +1,119 @@
+./adobe2h.c
+./adobe2h.d
+./adobetbl.h
+./AUTHORS
+./build.sh
+./bytesex.c
+./bytesex.d
+./bytesex.h
+./canvas.c
+./canvas.d
+./canvas.h
+./catdvi.1
+./catdvi.c
+./catdvi.d
+catdvi.txt
+ChangeLog
+./changelog-authors
+./config.mk.in
+configure
+./configure.in
+./COPYING
+./cvsparser.pl
+./density.c
+./density.d
+./density.h
+./enc/amssymba.enc
+./enc/amssymbb.enc
+./enc/blackboard.enc
+./enc/cork.enc
+./enc/dummy.enc
+./enc/euex.enc
+./enc/eufrak.enc
+./enc/eurosym.enc
+./enc/latexsym.enc
+./enc/marvo00.enc
+./enc/marvo98.enc
+./enc/ot1.enc
+./enc/ot1wofl.enc
+./enc/README
+./enc/texmext.enc
+./enc/texmital.enc
+./enc/texmsym.enc
+./enc/textcomp.enc
+./enc/textt.enc
+./findtfm.h
+./fixword.c
+./fixword.d
+./fixword.h
+./fntenc.c
+./fntenc.d
+./fntenc.h
+./fontinfo.c
+./fontinfo.d
+./fontinfo.h
+./getopt1.c
+./getopt1.d
+./getopt.c
+./getopt.d
+./getopt.h
+./glyphops.c
+./glyphops.d
+./glyphops.h
+./GNUmakefile
+./INSTALL
+./kpathsea.c
+./kpathsea.d
+./layout.c
+./layout.d
+./layout.h
+./linebuf.c
+./linebuf.d
+./linebuf.h
+Manifest
+./manifest-filter.lst
+./manifest-filter.pl
+MD5SUMS
+./NEWS
+./outenc.c
+./outenc.d
+./outenc.h
+./page2.h
+./page.c
+./page.d
+./page.h
+./pageref.c
+./pageref.d
+./pageref.h
+./pse2unic.c
+./pse2unic.d
+./readdvi.c
+./readdvi.d
+./readdvi.h
+./README
+./regsta.c
+./regsta.d
+./regsta.h
+./sparse.c
+./sparse.d
+./sparse.h
+./test/box.tex
+./test/finnish.tex
+./test/ligatures.tex
+./test/math.tex
+./test/ot1umlauts.tex
+./test/private.tex
+./test/testfont.tex
+./test/texlogo.tex
+./test/texmext.tex
+./tfminfo.c
+./tfminfo.d
+./TODO
+./util.c
+./util.d
+./util.h
+version.h
+./version.h.in
+./vlist.c
+./vlist.d
+./vlist.h
diff --git a/dviware/catdvi/NEWS b/dviware/catdvi/NEWS
new file mode 100644
index 0000000000..672020637f
--- /dev/null
+++ b/dviware/catdvi/NEWS
@@ -0,0 +1,93 @@
+ -*- Text -*-
+
+0.14 - More powerful layout algorithm with enhanced vertical positioning
+ capabilities and better handling of sub- and superscripts in
+ mathematical formulae.
+ - New font encodings: all AMS fonts except the cyrillic ones.
+ - Completed Blackboard font encoding.
+ - Brought in line with Unicode 3.2.
+ - Fixed false out of memory errors on some systems (e.g. AIX 4.2).
+ - Several small fixes and improvements.
+
+0.13 - New font encoding `LaTeX symbols'.
+ - Three new font encodings offering the European currency symbol:
+ + Henrik Theilings European currency symbol (`eurosym') font
+ + TS1, the encoding of the TeX text companion fonts
+ + Martin Vogels symbol (`MarVoSym') font
+ - New output encoding ISO-8859-15, which offers the Euro symbol.
+ - The --output-encoding option now accepts descriptive names (but still
+ understands encoding numbers as well).
+ - Some bug fixes.
+
+0.12 - Page range selectable by command line options.
+ - Improved OML, OMS, OMX and Cork input font encodings.
+ - Try to diplay hanging glyphs (e.g. operators and radicals) at the
+ visually correct position. Improves math.
+ - Translate more Unicode glyphs to available equivalents for ASCII and
+ ISO-8859-1 output encodings.
+ - New, more flexible output encoding handler gets width of ligatures
+ right.
+ - Building without GNU make should be easier now.
+ - Some bug fixes and speedups.
+ - Fixed building on FreeBSD (and maybe other systems).
+
+0.11 - Sequential processing option
+ - New font encoding: TeX Typewriter Text
+ - New, much better alignment algorithm
+ - Some bug fixes.
+
+0.10 - Added a manual page.
+ - More build system tweaks (no more missing glyph warnings for
+ regular builds)
+
+0.9 - More build system development. Should now be up for debianization.
+
+0.8 - Improved build system (uses autoconf)
+
+0.7 - Bug fix: dimension scaling was fucked up
+
+0.6 - New option --copyright.
+
+ - Remove option -v; leave --version.
+
+ - Use private space to map characters that are not in Unicode,
+ such as SS, NG and ng.
+
+ - Added the test/ subirectory.
+
+ - Added a partially filled translation table for Blackboard encoding
+
+ - Wrote a lite version of the new layout algorithm.
+
+ - TFM file parsing code is now almost finished
+
+
+0.5 - Bug fixes:
+ * catdvi.c (main): Mention -d in the --help output
+ * outenc.c (oen_tbl): Add the missing comma between
+ the ASCII and Latin-1 entries.
+ * GNUmakefile (distclean, maintainer-clean): Include
+ enc/*.h files in the distribution.
+
+
+0.4 - Output routines for US-ASCII and ISO 8859-1
+
+ - Easy way to generate font encoding translation tables from DVIPS
+ .enc files.
+
+ - Translation tables for the Cork encoding and most of Knuth's font encodings,
+ with occasional unknown glyph.
+
+ - Option parsing. (Current options: -dehv)
+
+ - Font encoding is now found by reading the TFM; the TFM file is
+ found with help from kpathsea.
+
+ - New build system.
+
+
+0.3 - Use Unicode internally
+
+ - output Unicode
+
+ - translate OT1 to Unicode
diff --git a/dviware/catdvi/README b/dviware/catdvi/README
new file mode 100644
index 0000000000..b96fb47ff0
--- /dev/null
+++ b/dviware/catdvi/README
@@ -0,0 +1,90 @@
+CatDVI v. 0.14 -*- Text -*-
+==============
+
+This is a DVI to plain text converter. The current version is a work
+in progress; it may not be robust enough for production work, although
+it does work fine for simple linear-text DVI files, and now even for
+some more complex DVI files.
+
+Please refer to the man page (man -l ./catdvi.1) or its plain text version,
+catdvi.txt, for a discussion of what currently works and what doesn't.
+
+
+Copyright 1999-2001 Antti-Juhani Kaijanaho
+Copyright 1999 J.H.M. Dassen (Ray)
+Copyright 2000-2002 Bjoern Brill
+Copyright 1987-1999 Free Software Foundation, Inc.
+Copyright Karl Berry, Olaf Weber and others (kpathsea library)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+(the file COPYING) along with this program; if not, write to the
+Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+Compiling and Installing CatDVI
+-------------------------------
+
+You need a hosted ISO C (1990) environment (almost every moderately modern
+C compiler + toolchain should do) and the kpathsea library (included
+with e.g. teTeX).
+
+Detailed instructions can be found in INSTALL.
+
+I want CatDVI to be as portable as possible, but can test it only under
+GNU/Linux on x86. If you had to make changes to make it work on your
+platform, please let me know. Code implementing font search without the
+kpathsea library is also welcome.
+
+
+Release Notes
+-------------
+
+New since v. 0.13:
+ - More powerful layout algorithm with enhanced vertical positioning
+ capabilities and better handling of sub- and superscripts in
+ mathematical formulae.
+ - New font encodings: all AMS fonts except the cyrillic ones.
+ - Completed Blackboard font encoding.
+ - Brought in line with Unicode 3.2.
+ - Fixed false out of memory errors on some systems (e.g. AIX 4.2).
+ - Several small fixes and improvements.
+
+A brief summary of differences from older version can be found in NEWS,
+and the full revision history is kept in ChangeLog.
+
+Contact Information
+-------------------
+
+ * The CatDVI project has a mailing list. To subscribe, visit
+ http://lists.sourceforge.net/mailman/listinfo/catdvi-misc
+
+ * PLEASE REPORT ALL BUGS! Use the bug reporting form at
+ https://sourceforge.net/bugs/?group_id=2703
+ or mail me directly, or use the project mailing list.
+
+ * The project web page is at
+ http://catdvi.sourceforge.net/
+
+ * Source can be downloaded at
+ https://sourceforge.net/project/showfiles.php?group_id=2703
+ A reasonably up-to-date version will always be available at CTAN, in
+ directory "dviware".
+ CatDVI is also available in some versions of Debian GNU.
+
+Please contact me if you have any problems with this program. I am also
+interested in general feedback, e.g. platforms on which the program
+works, what exactly you're using it for, or what additional features you
+would like to see.
+
+
+ -- Bjoern Brill <brill@fs.math.uni-frankfurt.de> Sun, 17 Nov 2002 19:32:11 +0100
diff --git a/dviware/catdvi/TODO b/dviware/catdvi/TODO
new file mode 100644
index 0000000000..f753663ff5
--- /dev/null
+++ b/dviware/catdvi/TODO
@@ -0,0 +1,85 @@
+IMPORTANT -*- Text -*-
+
+ * Figure out how font's space params relate to the whitespace between
+ words in DVI.
+ [the current heuristics seem to work quite well however]
+
+ * Go through the current font encoding translation tables and fix the
+ unknown glyphs (do a make enc/*.h after ./configure
+ --enable-developer-warnings to see the problems).
+ [nearly done]
+
+BUGS:
+
+ [None except the known limitations]
+
+SMALL IMPROVEMENTS:
+
+ * Add encodings: TEX extended ASCII.
+ * should ./configure --enable-developer-warnings add
+ -Wall etc. to CFLAGS if we're using gcc?
+
+CLEANUPS
+
+ * page.c :
+ - box_t has grown large. Do we need a constructor?
+ - Put diacritics, texmext, radicals in a list and loop over the list
+ to adjust them, not over the whole page.
+ * fntenc.c: add additional per-encoding info, like "this encoding has the
+ same params array as OMS".
+ * Rethink the *clean targets in the makefile.
+ * Reorganize the glyph tweak tables in outenc.c
+ * Referencing fonts by their number begins to get ugly. Switch to pointers.
+
+PROJECTS
+
+ * Faciliate recovery of lost LaTeX files: introduce a "LATEX" output
+ encoding which spits out LaTeX commands for at least the most common
+ symbols. (Thanks to Giovanni Salme for suggesting this).
+
+ * Supplements to outenc.c :
+ - Add more visual substitutions for ascii and latin1 output encodings:
+ Arrows, angle brackets, lessmuch, greatermuch, ...
+
+ * Extend or mimick the diacritics mechanism to glue "multipart" glyphs
+ (long arrows, mapsto, hookarrow, etc.) together. The same could also
+ work for extended recipies.
+
+ * Math layout improvements -- the word break heuristics we use work well
+ with normal text, but fail miserably with math (no wonder since
+ TeX uses different spacing methods for math and the document author
+ usually adds another, impredictable, bunch of spacing instructions).
+ This sometimes leads to funny spacing in catdvis output.
+
+ One possible approach would be: there are no word breaks in formulae.
+ Position every glyph in a formula based on its DVI coordinates (as we do
+ with word beginnings). Think about how to pick the glyphs that we have to
+ position directly. Possibilities:
+ - based on glyph hints (i.e. per-unicode-char information)
+ - based on per-font information (math chars form extra character sets,
+ at least with TeX). Not really nice.
+
+ * Add rule support. Most important are line-like rules for fractions,
+ tables, etc. A lot of the required infrastructure is now implemented
+ (canvas.c and layout.c). Still to be done:
+ - Reserve sufficient space to print the rules, but allow rules to
+ intersect (for table borders etc.).
+ Most likely, special private space glyphs will be inserted into the page
+ to represent the rules. If so, then
+ - Try to detect fraction slashes and treat them like "on axis" texmext
+ glyphs.
+ - Define some kind of bogus font metrics for these glyphs.
+ - We will need "subclasses" of page_word_t to make this work.
+ - And some special case "break here" test in the word breaking code.
+ Maybe make this generic and combine with better math spacing attempts.
+
+ * What about a Win32/MikTeX port? Current MikTeX seems to include libkpathsea.
+ * Think about the pros and cons of using GNU automake.
+
+WISHLIST
+
+ * Implement TFM file location routine also without kpathsea
+ * Add support for non-latin languages. Cyrillic should be easiest (but
+ will need native speakers to verify the implementation), right-to-left
+ languages a lot harder.
+ * Looking at xdvik and kdvi, it may be time for a catdvi library.
diff --git a/dviware/catdvi/adobe2h.c b/dviware/catdvi/adobe2h.c
new file mode 100644
index 0000000000..f374a11984
--- /dev/null
+++ b/dviware/catdvi/adobe2h.c
@@ -0,0 +1,201 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2001-2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Standalone program - generates a header which enumerates
+ * (in fact #defines, since ISO C restricts enums to int and we don't know
+ * if int is 32 bit wide) constant names for all the glyphs in adobetbl.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+
+typedef unsigned long uint32;
+
+/* FIXME: remove this struct in pse2unic.c and here, move it to adobetbl.h? */
+struct adobe2unicode_t {
+ char const * adobe;
+ uint32 unicode;
+};
+#define A_MAX_LEN 32
+ /* including 0 terminator */
+
+
+#define PROGNAME "adobe2h"
+
+#define ORIGFILE "adobetbl.h"
+#include ORIGFILE
+
+/* #define OUTFILE "glyphenm.h" */
+#define GUARD "GLYPHENM_H"
+
+
+
+int main(void) {
+ FILE * f;
+ int i;
+ int tbl_len;
+ time_t now;
+
+ time(&now);
+
+#ifdef OUTFILE
+ f = fopen(OUTFILE, "w");
+ if(f == NULL) {
+ perror(PROGNAME ": could not open " OUTFILE " for writing");
+ exit(1);
+ }
+#else
+ f = stdout;
+#endif
+
+ fputs(
+ "/* AUTOMATICALLY GENERATED -- DO NOT EDIT ! */\n" \
+ "\n" \
+ "#ifndef " GUARD "\n" \
+ "#define " GUARD "\n" \
+ "\n",
+ f
+ );
+ fprintf(
+ f,
+ "/* created by " PROGNAME " on %s", /* newline from ctime */
+ ctime(&now)
+ );
+ fputs(
+ " * from included glyph name table \"" ORIGFILE "\"\n" \
+ " */\n" \
+ "\n",
+ f
+ );
+
+ /* loop over all entries and output a #define for each */
+ tbl_len = sizeof(adobe2unicode) / sizeof(adobe2unicode[0]);
+ for(i = 0; i < tbl_len; ++i) {
+ uint32 u;
+ const char * a, * prefix;
+ char *p;
+ char s[A_MAX_LEN];
+ int duplicate, is_private, is_catdvi;
+
+ u = adobe2unicode[i].unicode;
+ a = adobe2unicode[i].adobe;
+
+ /* Attention: adobetbl.h used to have duplicate definitions of some
+ * glyphs (removed by brute force).
+ */
+ duplicate = (i > 0) && (strcmp(adobe2unicode[i-1].adobe, a) == 0);
+
+ is_private = (u >= 0xe000 && u <= 0xf8ff) ||
+ (u >= 0xf0000 && u <= 0x10ffff);
+
+ /* our additions in the glyph name table begin with `$' */
+ is_catdvi = (a[0] == '$');
+
+ /* need to rename .notdef and .notavail */
+ if(strcmp(a, ".notdef") == 0) a = "NOTDEF";
+ if(strcmp(a, ".notavail") == 0) a = "NOTAVAIL";
+
+ /* $ is not valid in C identifiers */
+ if(is_catdvi) ++a;
+
+ /* As adobetbl.h is based on the adobe glyph list, we choose a
+ * naming convention that tries to avoid clashes with Adobe's as
+ * defined in
+ * http://partners.adobe.com/asn/developer/type/unicodegn.html
+ * (to retain source level compatibility with future glyph list
+ * extensions and other software using Adobe glyph names, e.g. dvips).
+ * Some things have to be changed, though, since we want to
+ * generate a sane C header file :)
+ */
+ if(is_private) {
+ /* mark Adobes + our private use area */
+ if(is_catdvi) prefix = "GLYPH_CATDVI_";
+ else prefix = "GLYPH_ADOBE_";
+ }
+ else {
+ if(is_catdvi) prefix = "GLYPH_UNI_";
+ /* if our additions are not in the private use area, assume
+ * we have added something that is defined in Unicode but
+ * missing in Adobes glyph list.
+ */
+ else prefix = "GLYPH_";
+ /* Is Adobe and Unicode. No special markers required. */
+ }
+
+ /* Check for non-alphanumeric characters in glyph names. Dot and
+ * underscore may appear. We change dot to underscore as well.
+ */
+ strncpy(s, a, A_MAX_LEN);
+ if(s[A_MAX_LEN - 1] != 0) {
+ fprintf(
+ stderr,
+ PROGNAME ": Warning: glyph name `%s' too long; " \
+ "glyph ignored.\n",
+ a
+ );
+ goto some_error;
+ }
+
+ for(p = s; *p != 0; ++p) {
+ if(!isalnum(*p)) switch(*p) {
+ case '_':
+ break;
+ case '.':
+ *p = '_';
+ break;
+ default:
+ fprintf(
+ stderr,
+ PROGNAME ": Warning: illegal character " \
+ "`%c\' in glyph name `%s'; glyph ignored.\n",
+ *p,
+ a
+ );
+ goto some_error;
+ }
+ }
+
+ if(duplicate) {
+ /* We can't have duplicate definitions in the header; assume the
+ * first one is the best and document the others as comment.
+ */
+ fprintf(f, "/* #define %s%s %#06lxL ;Duplicate */\n", prefix, s, u);
+ fprintf(
+ stderr,
+ PROGNAME ": Warning: duplicate definition for " \
+ "glyph name `%s\'; commented out.\n",
+ s
+ );
+ }
+ else fprintf(f, "#define %s%s %#06lxL\n", prefix, s, u);
+
+ some_error: ;
+
+ } /* for i */
+
+ fputs(
+ "\n" \
+ "#endif /* " GUARD " */\n",
+ f
+ );
+ fclose(f);
+ exit(0);
+}
diff --git a/dviware/catdvi/adobe2h.d b/dviware/catdvi/adobe2h.d
new file mode 100644
index 0000000000..aaaf84c355
--- /dev/null
+++ b/dviware/catdvi/adobe2h.d
@@ -0,0 +1 @@
+adobe2h.o adobe2h.d : adobe2h.c adobetbl.h
diff --git a/dviware/catdvi/adobetbl.h b/dviware/catdvi/adobetbl.h
new file mode 100644
index 0000000000..c66874781a
--- /dev/null
+++ b/dviware/catdvi/adobetbl.h
@@ -0,0 +1,1799 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2001 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef ADOBETBL_H
+#define ADOBETBL_H
+
+/* The following table is based on the Adobe Glyph List v. 1.2,
+ available at
+ http://partners.adobe.com/asn/developer/typeforum/glyphlist.txt The
+ symbol names that begin with '$' are our additions.
+ This table has to be strcmp-sorted by glyph names! */
+
+/* Adobe defines several glyphs in the BMP private use area U+E000..U+F8FF .
+ * Catdvi references some of Adobes definitions and, additionally, uses
+ * a few code points in the "high" (formerly "surrogate pairs") private use
+ * area U+000F0000..U+0010FFFF :
+ * - Single code points are allocated from U+0010FFFF downwards in no
+ * particular order.
+ * - Lowest currently allocated: U+0010FFEF
+ * - The "TeX Math Extension" font encoding is reproduced in its entirety,
+ * shifted to U+0010FF00..U+0010FF7F (with a reserved hole at
+ * U+0010FF30..U+0010FF43 where we would duplicate stuff that Adobe has
+ * already defined elsewhere).
+ */
+
+/* For box drawing glyphs (U+25xx), we use the following abbreviations:
+ * prefix: bdraw
+ * weights: light, heavy, singl, dbl
+ * directions: up, dn, lf, rt, vert, horz
+ */
+
+#ifndef ADOBETBL_SHOULD_HAVE_CRUFTY_DUPLICATES
+
+#define DUP1 ".DUP1"
+#define DUP2 ".DUP2"
+
+#else
+
+#define DUP1
+#define DUP2
+
+#endif
+
+
+static struct adobe2unicode_t adobe2unicode[] = {
+ { "$Amathbb", 0x0001d538 }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL A */
+ { "$Amathfrak", 0x0001d504 }, /* MATHEMATICAL FRAKTUR CAPITAL A */
+ { "$Amathscript", 0x0001d49c }, /* MATHEMATICAL SCRIPT CAPITAL A */
+ { "$Bmathbb", 0x0001d539 }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL B */
+ { "$Bmathfrak", 0x0001d505 }, /* MATHEMATICAL FRAKTUR CAPITAL B */
+ { "$Bscript", 0x212c }, /* SCRIPT CAPITAL B */
+ { "$Cdblstruck", 0x2102 }, /* DOUBLE-STRUCK CAPITAL C */
+ { "$Cfraktur", 0x212d }, /* BLACK-LETTER CAPITAL C */
+ { "$Cmathscript", 0x0001d49e }, /* MATHEMATICAL SCRIPT CAPITAL C */
+ { "$Delta" , 0x0394 }, /* GREEK CAPITAL LETTER DELTA; distinguish Adobe duplicates */
+ { "$Dmathbb", 0x0001d53b }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL D */
+ { "$Dmathfrak", 0x0001d507 }, /* MATHEMATICAL FRAKTUR CAPITAL D */
+ { "$Dmathscript", 0x0001d49f }, /* MATHEMATICAL SCRIPT CAPITAL D */
+ { "$DoubleS", 0x0010fffd }, /* PRIVATE SPACE CAPITAL GERMAN DOUBLE S */
+ { "$Emathbb", 0x0001d53c }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL E */
+ { "$Emathfrak", 0x0001d508 }, /* MATHEMATICAL FRAKTUR CAPITAL E */
+ { "$Escript", 0x2130 }, /* SCRIPT CAPITAL E */
+ { "$Eurodblstroke", 0x0010fffa }, /* PRIVATE SPACE EURO SIGN DOUBLE STROKE */
+ { "$Eurodblstrokecomb", 0x0010fff9 }, /* PRIVATE SPACE COMBINING EURO SIGN DOUBLE STROKE */
+ { "$Finv", 0x2132 }, /* TURNED CAPITAL F */
+ { "$Fmathbb", 0x0001d53d }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL F */
+ { "$Fmathfrak", 0x0001d509 }, /* MATHEMATICAL FRAKTUR CAPITAL F */
+ { "$Fscript", 0x2131 }, /* SCRIPT CAPITAL F */
+ { "$Game", 0x2141 }, /* TURNED SANS-SERIF CAPITAL G */
+ { "$Gmathbb", 0x0001d53e }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL G */
+ { "$Gmathfrak", 0x0001d50a }, /* MATHEMATICAL FRAKTUR CAPITAL G */
+ { "$Gmathscript", 0x0001d4a2 }, /* MATHEMATICAL SCRIPT CAPITAL G */
+ { "$Hdblstruck", 0x210d }, /* DOUBLE-STRUCK CAPITAL H */
+ { "$Hfraktur", 0x210c }, /* BLACK-LETTER CAPITAL H */
+ { "$Hscript", 0x210b }, /* SCRIPT CAPITAL H */
+ { "$Imathbb", 0x0001d540 }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL I */
+ { "$Iscript", 0x2110 }, /* SCRIPT CAPITAL I */
+ { "$Jmathbb", 0x0001d541 }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL J */
+ { "$Jmathfrak", 0x0001d50d }, /* MATHEMATICAL FRAKTUR CAPITAL J */
+ { "$Jmathscript", 0x0001d4a5 }, /* MATHEMATICAL SCRIPT CAPITAL J */
+ { "$Kmathbb", 0x0001d542 }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL K */
+ { "$Kmathfrak", 0x0001d50e }, /* MATHEMATICAL FRAKTUR CAPITAL K */
+ { "$Kmathscript", 0x0001d4a6 }, /* MATHEMATICAL SCRIPT CAPITAL K */
+ { "$Lmathbb", 0x0001d543 }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL L */
+ { "$Lmathfrak", 0x0001d50f }, /* MATHEMATICAL FRAKTUR CAPITAL L */
+ { "$Lscript", 0x2112 }, /* SCRIPT CAPITAL L */
+ { "$Mho" , 0x2127 }, /* INVERTED OHM SIGN */
+ { "$Mmathbb", 0x0001d544 }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL M */
+ { "$Mmathfrak", 0x0001d510 }, /* MATHEMATICAL FRAKTUR CAPITAL M */
+ { "$Mscript", 0x2133 }, /* SCRIPT CAPITAL M */
+ { "$Ndblstruck", 0x2115 }, /* DOUBLE-STRUCK CAPITAL N */
+ { "$Ng", 0x0010ffff }, /* PRIVATE SPACE LIGATURE CAPITAL NG */
+ { "$Nmathfrak", 0x0001d511 }, /* MATHEMATICAL FRAKTUR CAPITAL N */
+ { "$Nmathscript", 0x0001d4a9 }, /* MATHEMATICAL SCRIPT CAPITAL N */
+ { "$Ohm" , 0x2126 }, /* OHM SIGN; distinguish Adobe duplicates */
+ { "$Omathbb", 0x0001d546 }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL O */
+ { "$Omathfrak", 0x0001d512 }, /* MATHEMATICAL FRAKTUR CAPITAL O */
+ { "$Omathscript", 0x0001d4aa }, /* MATHEMATICAL SCRIPT CAPITAL O */
+ { "$Omega" , 0x03A9 }, /* GREEK CAPITAL LETTER OMEGA; distinguish Adobe duplicates */
+ { "$Pdblstruck", 0x2119 }, /* DOUBLE-STRUCK CAPITAL P */
+ { "$Pmathfrak", 0x0001d513 }, /* MATHEMATICAL FRAKTUR CAPITAL P */
+ { "$Pmathscript", 0x0001d4ab }, /* MATHEMATICAL SCRIPT CAPITAL P */
+ { "$Qdblstruck", 0x211a }, /* DOUBLE-STRUCK CAPITAL Q */
+ { "$Qmathfrak", 0x0001d514 }, /* MATHEMATICAL FRAKTUR CAPITAL Q */
+ { "$Qmathscript", 0x0001d4ac }, /* MATHEMATICAL SCRIPT CAPITAL Q */
+ { "$Rdblstruck", 0x211d }, /* DOUBLE-STRUCK CAPITAL R */
+ { "$Rscript", 0x211b }, /* SCRIPT CAPITAL R */
+ { "$Scedilla" , 0x015E }, /* LATIN CAPITAL LETTER S WITH CEDILLA; distinguish Adobe duplicates */
+ { "$Smathbb", 0x0001d54a }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL S */
+ { "$Smathfrak", 0x0001d516 }, /* MATHEMATICAL FRAKTUR CAPITAL S */
+ { "$Smathscript", 0x0001d4ae }, /* MATHEMATICAL SCRIPT CAPITAL S */
+ { "$Tcedilla", 0x0162 }, /* LATIN CAPITAL LETTER T WITH CEDILLA; distinguish Adobe duplicates */
+ { "$Tcommaaccent", 0x021A }, /* LATIN CAPITAL LETTER T WITH COMMA BELOW; distinguish Adobe duplicates */
+ { "$Tmathbb", 0x0001d54b }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL T */
+ { "$Tmathfrak", 0x0001d517 }, /* MATHEMATICAL FRAKTUR CAPITAL T */
+ { "$Tmathscript", 0x0001d4af }, /* MATHEMATICAL SCRIPT CAPITAL T */
+ { "$Umathbb", 0x0001d54c }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL U */
+ { "$Umathfrak", 0x0001d518 }, /* MATHEMATICAL FRAKTUR CAPITAL U */
+ { "$Umathscript", 0x0001d4b0 }, /* MATHEMATICAL SCRIPT CAPITAL U */
+ { "$Vmathbb", 0x0001d54d }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL V */
+ { "$Vmathfrak", 0x0001d519 }, /* MATHEMATICAL FRAKTUR CAPITAL V */
+ { "$Vmathscript", 0x0001d4b1 }, /* MATHEMATICAL SCRIPT CAPITAL V */
+ { "$Wmathbb", 0x0001d54e }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL W */
+ { "$Wmathfrak", 0x0001d51a }, /* MATHEMATICAL FRAKTUR CAPITAL W */
+ { "$Wmathscript", 0x0001d4b2 }, /* MATHEMATICAL SCRIPT CAPITAL W */
+ { "$Xmathbb", 0x0001d54f }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL X */
+ { "$Xmathfrak", 0x0001d51b }, /* MATHEMATICAL FRAKTUR CAPITAL X */
+ { "$Xmathscript", 0x0001d4b3 }, /* MATHEMATICAL SCRIPT CAPITAL X */
+ { "$Ymathbb", 0x0001d550 }, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL Y */
+ { "$Ymathfrak", 0x0001d51c }, /* MATHEMATICAL FRAKTUR CAPITAL Y */
+ { "$Ymathscript", 0x0001d4b4 }, /* MATHEMATICAL SCRIPT CAPITAL Y */
+ { "$ZWNJ" , 0x200c }, /* ZERO WIDTH NON-JOINER */
+ { "$Zdblstruck", 0x2124 }, /* DOUBLE-STRUCK CAPITAL Z */
+ { "$Zfraktur", 0x2128 }, /* BLACK-LETTER CAPITAL Z */
+ { "$Zmathscript", 0x0001d4b5 }, /* MATHEMATICAL SCRIPT CAPITAL Z */
+ { "$acutemodifier", 0x02ca }, /* MODIFIER LETTER ACUTE ACCENT */
+ { "$amathbb", 0x0001d552 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL A */
+ { "$amathfrak", 0x0001d51e }, /* MATHEMATICAL FRAKTUR SMALL A */
+ { "$angbracketleftBig", 0x0010ff44 }, /* PRIVATE SPACE VERY LARGE LEFT-POINTING ANGLE BRACKET */
+ { "$angbracketleftBigg", 0x0010ff2a }, /* PRIVATE SPACE VERY HUGE LEFT-POINTING ANGLE BRACKET */
+ { "$angbracketleftbig", 0x0010ff0a }, /* PRIVATE SPACE LARGE LEFT-POINTING ANGLE BRACKET */
+ { "$angbracketleftbigg", 0x0010ff1c }, /* PRIVATE SPACE HUGE LEFT-POINTING ANGLE BRACKET */
+ { "$angbracketrightBig", 0x0010ff45 }, /* PRIVATE SPACE VERY LARGE RIGHT-POINTING ANGLE BRACKET */
+ { "$angbracketrightBigg", 0x0010ff2b }, /* PRIVATE SPACE VERY HUGE RIGHT-POINTING ANGLE BRACKET */
+ { "$angbracketrightbig", 0x0010ff0b }, /* PRIVATE SPACE LARGE RIGHT-POINTING ANGLE BRACKET */
+ { "$angbracketrightbigg", 0x0010ff1d }, /* PRIVATE SPACE HUGE RIGHT-POINTING ANGLE BRACKET */
+ { "$angleleftmath", 0x27e8 }, /* MATHEMATICAL LEFT ANGLE BRACKET */
+ { "$anglerightmath", 0x27e9 }, /* MATHEMATICAL RIGHT ANGLE BRACKET */
+ { "$ankh", 0x2625 }, /* ANKH */
+ { "$answerphone", 0x2315 }, /* TELEPHONE RECORDER */
+ { "$approxequal1", 0x224a }, /* ALMOST EQUAL OR EQUAL TO */
+ { "$aquarius", 0x2652 }, /* AQUARIUS */
+ { "$aries", 0x2648 }, /* ARIES */
+ { "$arrowanticlockwise", 0x21ba }, /* ANTICLOCKWISE OPEN CIRCLE ARROW */
+ { "$arrowbt", 0x0010ff79 }, /* PRIVATE SPACE ARROW BOTTOM */
+ { "$arrowclockwise", 0x21bb }, /* CLOCKWISE OPEN CIRCLE ARROW */
+ { "$arrowdblbt", 0x0010ff7f }, /* PRIVATE SPACE DOUBLE ARROW BOTTOM */
+ { "$arrowdbltp", 0x0010ff7e }, /* PRIVATE SPACE DOUBLE ARROW TOP */
+ { "$arrowdblupdn", 0x21d5 }, /* UP DOWN DOUBLE ARROW */
+ { "$arrowheaddown", 0x2304 }, /* DOWN ARROWHEAD */
+ { "$arrowheadup", 0x2303 }, /* UP ARROWHEAD */
+ { "$arrownortheast", 0x2197 }, /* NORTH EAST ARROW */
+ { "$arrownorthwest", 0x2196 }, /* NORTH WEST ARROW */
+ { "$arrowsdowndown", 0x21ca }, /* DOWNWARDS PAIRED ARROWS */
+ { "$arrowsleftleft", 0x21c7 }, /* LEFTWARDS PAIRED ARROWS */
+ { "$arrowsleftright", 0x21c6 }, /* LEFTWARDS ARROW OVER RIGHTWARDS ARROW */
+ { "$arrowsoutheast", 0x2198 }, /* SOUTH EAST ARROW */
+ { "$arrowsouthwest", 0x2199 }, /* SOUTH WEST ARROW */
+ { "$arrowsrightleft", 0x21c4 }, /* RIGHTWARDS ARROW OVER LEFTWARDS ARROW */
+ { "$arrowsrightright", 0x21c9 }, /* RIGHTWARDS PAIRED ARROWS */
+ { "$arrowsupup", 0x21c8 }, /* UPWARDS PAIRED ARROWS */
+ { "$arrowtp", 0x0010ff78 }, /* PRIVATE SPACE ARROW TOP */
+ { "$arrowtripleleft", 0x21da }, /* LEFTWARDS TRIPLE ARROW */
+ { "$arrowtripleright", 0x21db }, /* RIGHTWARDS TRIPLE ARROW */
+ { "$arrowuptipleft", 0x21b0 }, /* UPWARDS ARROW WITH TIP LEFTWARDS */
+ { "$arrowuptipright", 0x21b1 }, /* UPWARDS ARROW WITH TIP RIGHTWARDS */
+ { "$arrowvertexdbl", 0x0010ff77 }, /* PRIVATE SPACE DOUBLE ARROW VERTICAL EXTENDER */
+ { "$asterisklow", 0x204e }, /* LOW ASTERISK */
+ { "$backslashBig", 0x0010ff2f }, /* PRIVATE SPACE VERY LARGE REVERSE SOLIDUS */
+ { "$backslashBigg", 0x0010ff2d }, /* PRIVATE SPACE VERY HUGE REVERSE SOLIDUS */
+ { "$backslashbig", 0x0010ff0f }, /* PRIVATE SPACE LARGE REVERSE SOLIDUS */
+ { "$backslashbigg", 0x0010ff1f }, /* PRIVATE SPACE HUGE REVERSE SOLIDUS */
+ { "$baht", 0x0e3f }, /* THAI CURRENCY SYMBOL BAHT */
+ { "$bardbl", 0x2016 }, /* DOUBLE VERTICAL LINE */
+ { "$barwedge", 0x22bc }, /* NAND */
+ { "$bdrawlightdn", 0x2577 }, /* BOX DRAWINGS LIGHT DOWN */
+ { "$bdrawlightdnhorz", 0x252c }, /* BOX DRAWINGS LIGHT DOWN AND HORIZONTAL; Adobe has this as "SF060000" */
+ { "$bdrawlightdnlf", 0x2510 }, /* BOX DRAWINGS LIGHT DOWN AND LEFT; Adobe has this as "SF030000" */
+ { "$bdrawlightdnrt", 0x250c }, /* BOX DRAWINGS LIGHT DOWN AND RIGHT; Adobe has this as "SF010000" */
+ { "$bdrawlighthorz", 0x2500 }, /* BOX DRAWINGS LIGHT HORIZONTAL; Adobe has this as "SF100000" */
+ { "$bdrawlightlf", 0x2574 }, /* BOX DRAWINGS LIGHT LEFT */
+ { "$bdrawlightrt", 0x2576 }, /* BOX DRAWINGS LIGHT RIGHT */
+ { "$bdrawlightup", 0x2575 }, /* BOX DRAWINGS LIGHT UP */
+ { "$bdrawlightuphorz", 0x2534 }, /* BOX DRAWINGS LIGHT UP AND HORIZONTAL; Adobe has this as "SF070000" */
+ { "$bdrawlightuplf", 0x2518 }, /* BOX DRAWINGS LIGHT UP AND LEFT; Adobe has this as "SF040000" */
+ { "$bdrawlightuprt", 0x2514 }, /* BOX DRAWINGS LIGHT UP AND RIGHT; Adobe has this as "SF020000" */
+ { "$bdrawlightvert", 0x2502 }, /* BOX DRAWINGS LIGHT VERTICAL; Adobe has this as "SF110000" */
+ { "$bdrawlightverthorz", 0x253c }, /* BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL; Adobe has this as "SF050000" */
+ { "$bdrawlightvertlf", 0x2524 }, /* BOX DRAWINGS LIGHT VERTICAL AND LEFT; Adobe has this as "SF090000" */
+ { "$bdrawlightvertrt", 0x251c }, /* BOX DRAWINGS LIGHT VERTICAL AND RIGHT; Adobe has this as "SF080000" */
+ { "$because", 0x2235 }, /* BECAUSE */
+ { "$beth", 0x2136 }, /* BET SYMBOL */
+ { "$between", 0x226c }, /* BETWEEN */
+ { "$biohazard", 0x2623 }, /* BIOHAZARD SIGN */
+ { "$blank", 0x2422 }, /* BLANK SYMBOL */
+ { "$bmathbb", 0x0001d553 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL B */
+ { "$bmathfrak", 0x0001d51f }, /* MATHEMATICAL FRAKTUR SMALL B */
+ { "$bowtie", 0x22c8 }, /* BOWTIE */
+ { "$box", 0x25a1 }, /* WHITE SQUARE */
+ { "$boxdot", 0x22a1 }, /* SQUARED DOT OPERATOR */
+ { "$boxminus", 0x229f }, /* SQUARED MINUS */
+ { "$boxmultiply", 0x22a0 }, /* SQUARED TIMES */
+ { "$boxplus", 0x229e }, /* SQUARED PLUS */
+ { "$braceex", 0x23aa }, /* CURLY BRACKET EXTENSION; not Adobe's private space version */
+ { "$bracehtipdownleft", 0x0010ff7a }, /* PRIVATE SPACE UPWARDS-POINTING CURLY BRACKET LEFT TIP */
+ { "$bracehtipdownright", 0x0010ff7b }, /* PRIVATE SPACE UPWARDS-POINTING CURLY BRACKET RIGHT TIP */
+ { "$bracehtipupleft", 0x0010ff7c }, /* PRIVATE SPACE DOWNWARDS-POINTING CURLY BRACKET LEFT TIP */
+ { "$bracehtipupright", 0x0010ff7d }, /* PRIVATE SPACE DOWNWARDS-POINTING CURLY BRACKET RIGHT TIP */
+ { "$braceleftBig", 0x0010ff6e }, /* PRIVATE SPACE VERY LARGE LEFT CURLY BRACKET */
+ { "$braceleftBigg", 0x0010ff28 }, /* PRIVATE SPACE VERY HUGE LEFT CURLY BRACKET */
+ { "$braceleftbig", 0x0010ff08 }, /* PRIVATE SPACE LARGE LEFT CURLY BRACKET */
+ { "$braceleftbigg", 0x0010ff1a }, /* PRIVATE SPACE HUGE LEFT CURLY BRACKET */
+ { "$braceleftbt", 0x23a9 }, /* LEFT CURLY BRACKET LOWER HOOK; not Adobe's private space version */
+ { "$braceleftmid", 0x23a8 }, /* LEFT CURLY BRACKET MIDDLE PIECE; not Adobe's private space version */
+ { "$bracelefttp", 0x23a7 }, /* LEFT CURLY BRACKET UPPER HOOK; not Adobe's private space version */
+ { "$braceleftwhite", 0x2983 }, /* LEFT WHITE CURLY BRACKET */
+ { "$bracerightBig", 0x0010ff6f }, /* PRIVATE SPACE VERY LARGE RIGHT CURLY BRACKET */
+ { "$bracerightBigg", 0x0010ff29 }, /* PRIVATE SPACE VERY HUGE RIGHT CURLY BRACKET */
+ { "$bracerightbig", 0x0010ff09 }, /* PRIVATE SPACE LARGE RIGHT CURLY BRACKET */
+ { "$bracerightbigg", 0x0010ff1b }, /* PRIVATE SPACE HUGE RIGHT CURLY BRACKET */
+ { "$bracerightbt", 0x23ad }, /* RIGHT CURLY BRACKET LOWER HOOK; not Adobe's private space version */
+ { "$bracerightmid", 0x23ac }, /* RIGHT CURLY BRACKET MIDDLE PIECE; not Adobe's private space version */
+ { "$bracerighttp", 0x23ab }, /* RIGHT CURLY BRACKET UPPER HOOK; not Adobe's private space version */
+ { "$bracerightwhite", 0x2984 }, /* RIGHT WHITE CURLY BRACKET */
+ { "$bracketleftBig", 0x0010ff68 }, /* PRIVATE SPACE VERY LARGE LEFT SQUARE BRACKET */
+ { "$bracketleftBigg", 0x0010ff22 }, /* PRIVATE SPACE VERY HUGE LEFT SQUARE BRACKET */
+ { "$bracketleftbig", 0x0010ff02 }, /* PRIVATE SPACE LARGE LEFT SQUARE BRACKET */
+ { "$bracketleftbigg", 0x0010ff14 }, /* PRIVATE SPACE HUGE LEFT SQUARE BRACKET */
+ { "$bracketleftbt", 0x23a3 }, /* LEFT SQUARE BRACKET LOWER CORNER; not Adobe's private space version */
+ { "$bracketleftex", 0x23a2 }, /* LEFT SQUARE BRACKET EXTENSION; not Adobe's private space version */
+ { "$bracketlefttp", 0x23a1 }, /* LEFT SQUARE BRACKET UPPER CORNER; not Adobe's private space version */
+ { "$bracketleftwhite", 0x301a }, /* LEFT WHITE SQUARE BRACKET */
+ { "$bracketleftwhitemath", 0x27e6 }, /* MATHEMATICAL LEFT WHITE SQUARE BRACKET */
+ { "$bracketrightBig", 0x0010ff69 }, /* PRIVATE SPACE VERY LARGE RIGHT SQUARE BRACKET */
+ { "$bracketrightBigg", 0x0010ff23 }, /* PRIVATE SPACE VERY HUGE RIGHT SQUARE BRACKET */
+ { "$bracketrightbig", 0x0010ff03 }, /* PRIVATE SPACE LARGE RIGHT SQUARE BRACKET */
+ { "$bracketrightbigg", 0x0010ff15 }, /* PRIVATE SPACE HUGE RIGHT SQUARE BRACKET */
+ { "$bracketrightbt", 0x23a6 }, /* RIGHT SQUARE BRACKET LOWER CORNER; not Adobe's private space version */
+ { "$bracketrightex", 0x23a5 }, /* RIGHT SQUARE BRACKET EXTENSION; not Adobe's private space version */
+ { "$bracketrighttp", 0x23a4 }, /* RIGHT SQUARE BRACKET UPPER CORNER; not Adobe's private space version */
+ { "$bracketrightwhite", 0x301b }, /* RIGHT WHITE SQUARE BRACKET */
+ { "$bracketrightwhitemath", 0x27e7 }, /* MATHEMATICAL RIGHT WHITE SQUARE BRACKET */
+ { "$brevecomb", 0x0306 }, /* COMBINING BREVE */
+ { "$bulletmath" , 0x2219 }, /* BULLET OPERATOR; distinguish Adobe duplicates */
+ { "$bumpdentequal", 0x224e }, /* GEOMETRICALLY EQUIVALENT TO */
+ { "$bumpequal", 0x224f }, /* DIFFERENCE BETWEEN */
+ { "$cancer", 0x264b }, /* CANCER */
+ { "$capricorn", 0x2651 }, /* CAPRICORN */
+ { "$caroncomb", 0x030c }, /* COMBINING CARON */
+ { "$cedillacomb", 0x0327 }, /* COMBINING CEDILLA */
+ { "$ceilingleft", 0x2308 }, /* LEFT CEILING */
+ { "$ceilingleftBig", 0x0010ff6c }, /* PRIVATE SPACE VERY LARGE LEFT CEILING */
+ { "$ceilingleftBigg", 0x0010ff26 }, /* PRIVATE SPACE VERY HUGE LEFT CEILING */
+ { "$ceilingleftbig", 0x0010ff06 }, /* PRIVATE SPACE LARGE LEFT CEILING */
+ { "$ceilingleftbigg", 0x0010ff18 }, /* PRIVATE SPACE HUGE LEFT CEILING */
+ { "$ceilingright", 0x2309 }, /* RIGHT CEILING */
+ { "$ceilingrightBig", 0x0010ff6d }, /* PRIVATE SPACE VERY LARGE RIGHT CEILING */
+ { "$ceilingrightBigg", 0x0010ff27 }, /* PRIVATE SPACE VERY HUGE RIGHT CEILING */
+ { "$ceilingrightbig", 0x0010ff07 }, /* PRIVATE SPACE LARGE RIGHT CEILING */
+ { "$ceilingrightbigg", 0x0010ff19 }, /* PRIVATE SPACE HUGE RIGHT CEILING */
+ { "$celsius" , 0x2103 }, /* DEGREE CELSIUS */
+ { "$checkedbox", 0x2611 }, /* BALLOT BOX WITH CHECK */
+ { "$checkmark", 0x2713 }, /* CHECK MARK */
+ { "$circleA", 0x24b6 }, /* CIRCLED LATIN CAPITAL LETTER A */
+ { "$circleB", 0x24b7 }, /* CIRCLED LATIN CAPITAL LETTER B */
+ { "$circleC", 0x24b8 }, /* CIRCLED LATIN CAPITAL LETTER C */
+ { "$circleD", 0x24b9 }, /* CIRCLED LATIN CAPITAL LETTER D */
+ { "$circleE", 0x24ba }, /* CIRCLED LATIN CAPITAL LETTER E */
+ { "$circleF", 0x24bb }, /* CIRCLED LATIN CAPITAL LETTER F */
+ { "$circleG", 0x24bc }, /* CIRCLED LATIN CAPITAL LETTER G */
+ { "$circleH", 0x24bd }, /* CIRCLED LATIN CAPITAL LETTER H */
+ { "$circleI", 0x24be }, /* CIRCLED LATIN CAPITAL LETTER I */
+ { "$circleJ", 0x24bf }, /* CIRCLED LATIN CAPITAL LETTER J */
+ { "$circleK", 0x24c0 }, /* CIRCLED LATIN CAPITAL LETTER K */
+ { "$circleL", 0x24c1 }, /* CIRCLED LATIN CAPITAL LETTER L */
+ { "$circleM", 0x24c2 }, /* CIRCLED LATIN CAPITAL LETTER M */
+ { "$circleN", 0x24c3 }, /* CIRCLED LATIN CAPITAL LETTER N */
+ { "$circleO", 0x24c4 }, /* CIRCLED LATIN CAPITAL LETTER O */
+ { "$circleP", 0x24c5 }, /* CIRCLED LATIN CAPITAL LETTER P */
+ { "$circleQ", 0x24c6 }, /* CIRCLED LATIN CAPITAL LETTER Q */
+ { "$circleR", 0x24c7 }, /* CIRCLED LATIN CAPITAL LETTER R */
+ { "$circleS", 0x24c8 }, /* CIRCLED LATIN CAPITAL LETTER S */
+ { "$circleT", 0x24c9 }, /* CIRCLED LATIN CAPITAL LETTER T */
+ { "$circleU", 0x24ca }, /* CIRCLED LATIN CAPITAL LETTER U */
+ { "$circleV", 0x24cb }, /* CIRCLED LATIN CAPITAL LETTER V */
+ { "$circleW", 0x24cc }, /* CIRCLED LATIN CAPITAL LETTER W */
+ { "$circleX", 0x24cd }, /* CIRCLED LATIN CAPITAL LETTER X */
+ { "$circleY", 0x24ce }, /* CIRCLED LATIN CAPITAL LETTER Y */
+ { "$circleZ", 0x24cf }, /* CIRCLED LATIN CAPITAL LETTER Z */
+ { "$circleasterisk", 0x229b }, /* CIRCLED ASTERISK OPERATOR */
+ { "$circlecomb", 0x20dd }, /* COMBINING ENCLOSING CIRCLE */
+ { "$circledash", 0x229d }, /* CIRCLED DASH */
+ { "$circledivide", 0x2298 }, /* CIRCLED DIVISION SLASH */
+ { "$circledot", 0x2299 }, /* CIRCLED DOT OPERATOR */
+ { "$circledotdisplay", 0x0010ff4b }, /* PRIVATE SPACE DISPLAY MATH CIRCLED DOT OPERATOR */
+ { "$circledottext", 0x0010ff4a }, /* PRIVATE SPACE INLINE MATH CIRCLED DOT OPERATOR */
+ { "$circleequal", 0x229c }, /* CIRCLED EQUALS */
+ { "$circlelarge", 0x25ef }, /* LARGE CIRCLE */
+ { "$circleminus", 0x2296 }, /* CIRCLED MINUS */
+ { "$circlemultiplydisplay", 0x0010ff4f }, /* PRIVATE SPACE DISPLAY MATH CIRCLED TIMES */
+ { "$circlemultiplytext", 0x0010ff4e }, /* PRIVATE SPACE INLINE MATH CIRCLED TIMES */
+ { "$circleplusdisplay", 0x0010ff4d }, /* PRIVATE SPACE DISPLAY MATH CIRCLED PLUS */
+ { "$circleplustext", 0x0010ff4c }, /* PRIVATE SPACE INLINE MATH CIRCLED PLUS */
+ { "$circlering", 0x229a }, /* CIRCLED RING OPERATOR */
+ { "$circumflexcomb", 0x0302 }, /* COMBINING CIRCUMFLEX ACCENT */
+ { "$cmathbb", 0x0001d554 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL C */
+ { "$cmathfrak", 0x0001d520 }, /* MATHEMATICAL FRAKTUR SMALL C */
+ { "$complement", 0x2201 }, /* COMPLEMENT */
+ { "$contintegral", 0x222e }, /* CONTOUR INTEGRAL */
+ { "$contintegraldisplay", 0x0010ff49 }, /* PRIVATE SPACE DISPLAY MATH CONTOUR INTEGRAL */
+ { "$contintegraltext", 0x0010ff48 }, /* PRIVATE SPACE INLINE MATH CONTOUR INTEGRAL */
+ { "$coproduct", 0x2210 }, /* N-ARY COPRODUCT */
+ { "$coproductdisplay", 0x0010ff61 }, /* PRIVATE SPACE DISPLAY MATH N-ARY COPRODUCT */
+ { "$coproducttext", 0x0010ff60 }, /* PRIVATE SPACE INLINE MATH N-ARY COPRODUCT */
+ { "$corresponds", 0x2259 }, /* ESTIMATES */
+ { "$crossedbox", 0x2612 }, /* BALLOT BOX WITH X */
+ { "$curlyvee", 0x22ce }, /* CURLY LOGICAl OR */
+ { "$curlywedge", 0x22cf }, /* CURLY LOGICAL AND */
+ { "$curvearrowleft", 0x21b6 }, /* ANTICLOCKWISE TOP SEMICIRCLE ARROW */
+ { "$curvearrowright", 0x21b7 }, /* CLOCKWISE TOP SEMICIRCLE ARROW */
+ { "$daleth", 0x2138 }, /* DALET SYMBOL */
+ { "$deltaequal", 0x225c }, /* DELTA EQUAL TO */
+ { "$diamondmath", 0x22c4 }, /* DIAMOND OPERATOR */
+ { "$diamondshape", 0x25c7 }, /* WHITE DIAMOND */
+ { "$diamondwhite", 0x2662 }, /* WHITE DIAMOND SUIT */
+ { "$dieresiscomb", 0x0308 }, /* COMBINING DIAERESIS */
+ { "$digamma", 0x03dc }, /* GREEK LETTER DIGAMMA */
+ { "$dingbatarrow2794", 0x2794 }, /* HEAVY WIDE-HEADED RIGHTWARDS ARROW */
+ { "$discount", 0x2052 }, /* COMMERCIAL MINUS SIGN */
+ { "$divideontimes", 0x22c7 }, /* DIVISION TIMES */
+ { "$divides", 0x2223 }, /* DIVIDES */
+ { "$dividesnot", 0x2224 }, /* DOES NOT DIVIDE */
+ { "$divisionbackslashbig", 0x29f9 }, /* BIG REVERSE SOLIDUS */
+ { "$divisionslash", 0x2215 }, /* DIVISION SLASH; distinguish Adobe duplicates */
+ { "$divisionslashbig", 0x29f8 }, /* BIG SOLIDUS */
+ { "$dmathbb", 0x0001d555 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL D */
+ { "$dmathfrak", 0x0001d521 }, /* MATHEMATICAL FRAKTUR SMALL D */
+ { "$dotaccentcomb", 0x0307 }, /* COMBINING DOT ABOVE */
+ { "$dotequaldot", 0x2251 }, /* GEOMETRICALLY EQUAL TO */
+ { "$dotplus", 0x2214 }, /* DOT PLUS */
+ { "$doublebarwedge", 0x2a5e }, /* LOGICAL AND WITH DOUBLE OVERBAR */
+ { "$earth", 0x2641 }, /* EARTH */
+ { "$eightmathbb", 0x0001de0 }, /* MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT */
+ { "$emathbb", 0x0001d556 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL E */
+ { "$emathfrak", 0x0001d522 }, /* MATHEMATICAL FRAKTUR SMALL E */
+ { "$envelope", 0x2709 }, /* ENVELOPE */
+ { "$epsilon1", 0x03f5 }, /* GREEK LUNATE EPSILON SYMBOL */
+ { "$epsilon1inv", 0x03f6 }, /* GREEK REVERSED LUNATE EPSILON SYMBOL */
+ { "$equalfollows", 0x22df }, /* EQUAl TO OR SUCCEEDS */
+ { "$equalprecedes", 0x22de }, /* EQUAL TO OR PRECEDES */
+ { "$equalsimilar", 0x2242 }, /* MINUS TILDE */
+ { "$equalslantedgreater", 0x2a96 }, /* SLANTED EQUAl TO OR GREATER-THAN */
+ { "$equalslantedless", 0x2a95 }, /* SLANTED EQUAl TO OR LESS-THAN */
+ { "$equivasymptotic", 0x224d }, /* EQUIVALENT TO */
+ { "$fallingdotsequal", 0x2252 }, /* APPROXIMATELY EQUAL TO OR THE IMAGE OF */
+ { "$filledboxsmall", 0x25aa }, /* BLACK SMALL SQUARE; Adobe has this as "H18543" */
+ { "$filledcircle", 0x25cf }, /* BLACK CIRCLE; Adobe has this as "H18533" */
+ { "$filledlozenge", 0x29eb }, /* BLACK LOZENGE */
+ { "$fist", 0x261e }, /* WHITE RIGHT POINTING INDEX */
+ { "$fivemathbb", 0x0001d7dd }, /* MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE */
+ { "$flat", 0x266d }, /* MUSIC FLAT SIGN */
+ { "$floorleft", 0x230a }, /* LEFT FLOOR */
+ { "$floorleftBig", 0x0010ff6a }, /* PRIVATE SPACE VERY LARGE LEFT FLOOR */
+ { "$floorleftBigg", 0x0010ff24 }, /* PRIVATE SPACE VERY HUGE LEFT FLOOR */
+ { "$floorleftbig", 0x0010ff04 }, /* PRIVATE SPACE LARGE LEFT FLOOR */
+ { "$floorleftbigg", 0x0010ff16 }, /* PRIVATE SPACE HUGE LEFT FLOOR */
+ { "$floorright", 0x230b }, /* RIGHT FLOOR */
+ { "$floorrightBig", 0x0010ff6b }, /* PRIVATE SPACE VERY LARGE RIGHT FLOOR */
+ { "$floorrightBigg", 0x0010ff25 }, /* PRIVATE SPACE VERY HUGE RIGHT FLOOR */
+ { "$floorrightbig", 0x0010ff05 }, /* PRIVATE SPACE LARGE RIGHT FLOOR */
+ { "$floorrightbigg", 0x0010ff17 }, /* PRIVATE SPACE HUGE RIGHT FLOOR */
+ { "$fmathbb", 0x0001d557 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL F */
+ { "$fmathfrak", 0x0001d523 }, /* MATHEMATICAL FRAKTUR SMALL F */
+ { "$follows", 0x227b }, /* SUCCEEDS */
+ { "$followsapprox", 0x2ab8 }, /* SUCCEEDS ABOVE ALMOST EQUAL TO */
+ { "$followsequal", 0x227d }, /* SUCCEEDS OR EQUAL TO */
+ { "$followsnot", 0x2281 }, /* DOES NOT SUCCEED */
+ { "$followsnotapprox", 0x2aba }, /* SUCCEEDS ABOVE NOT ALMOST EQUAL TO */
+ { "$followsnotequal", 0x2ab6 }, /* SUCCEEDS ABOVE NOT EQUAL TO */
+ { "$followsnotsimilar", 0x22e9 }, /* SUCCEEDS BUT NOT EQUIVALENT TO */
+ { "$followssimilar", 0x227f }, /* SUCCEEDS OR EQUIVALENT TO */
+ { "$forces", 0x22a9 }, /* FORCES */
+ { "$forcesnot", 0x22ae }, /* DOES NOT FORCE */
+ { "$forcestriplevbar", 0x22aa }, /* TRIPLE VERTICAL BAR RIGHT TURNSTILE */
+ { "$fourmathbb", 0x0001d7dc }, /* MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR */
+ { "$fractionslash", 0x2044 }, /* FRACTION SLASH; distinguish Adobe duplicates */
+ { "$frown", 0x2322 }, /* FROWN */
+ { "$frownface", 0x2639 }, /* WHITE FROWNING FACE */
+ { "$gemini", 0x264a }, /* GEMINI */
+ { "$gimel", 0x2137 }, /* GIMEL SYMBOL */
+ { "$gmathbb", 0x0001d558 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL G */
+ { "$gmathfrak", 0x0001d524 }, /* MATHEMATICAL FRAKTUR SMALL G */
+ { "$gravemodifier", 0x02cb }, /* MODIFIER LETTER GRAVE ACCENT */
+ { "$greaterapprox", 0x2a86 }, /* GREATER-THAN OR APPROXIMATE */
+ { "$greaterdot", 0x22d7 }, /* GREATER-THAN WITH DOT */
+ { "$greaterequal2", 0x2267 }, /* GREATER-THAN OVER EQUAL TO */
+ { "$greaterequalless", 0x22db }, /* GREATER-THAN EQUAL TO OR LESS-THAN */
+ { "$greaterequallessstacked", 0x2a8c }, /* GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN */
+ { "$greaterequalslanted", 0x2a7e }, /* GREATER-THAN OR SLANTED EQUAL TO */
+ { "$greaterless", 0x2277 }, /* GREATER-THAN OR LESS-THAN */
+ { "$greatermuch", 0x226b }, /* MUCH GREATER-THAN */
+ { "$greaternotapprox", 0x2a8a }, /* GREATER-THAN AND NOT APPROXIMATE */
+ { "$greaternotequal", 0x2269 }, /* GREATER-THAN BUT NOT EQUAL TO */
+ { "$greaternotequal1", 0x2a88 }, /* GREATER-THAN AND SINGLE-LINE NOT EQUAL TO */
+ { "$greaternotsimilar", 0x22e7 }, /* GREATER-THAN BUT NOT EQUIVALENT TO */
+ { "$greatersimilar", 0x2273 }, /* GREATER-THAN OR EQUIVALENT TO */
+ { "$greaterverymuch", 0x22d9 }, /* VERY MUCH GREATER-THAN */
+ { "$harpoondownbarbleft", 0x21c3 }, /* DOWNWARDS HARPOON WITH BARB LEFTWARDS */
+ { "$harpoondownbarbright", 0x21c2 }, /* DOWNWARDS HARPOON WITH BARB RIGHTWARDS */
+ { "$harpoonleftbarbdown", 0x21bd }, /* LEFTWARDS HARPOON WITH BARB DOWNWARDS */
+ { "$harpoonleftbarbup", 0x21bc }, /* LEFTWARDS HARPOON WITH BARB UPWARDS */
+ { "$harpoonrightbarbdown", 0x21c1 }, /* RIGHTWARDS HARPOON WITH BARB DOWNWARDS */
+ { "$harpoonrightbarbup", 0x21c0 }, /* RIGHTWARDS HARPOON WITH BARB UPWARDS */
+ { "$harpoonsleftright", 0x21cb }, /* LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON */
+ { "$harpoonsrightleft", 0x21cc }, /* RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON */
+ { "$harpoonupbarbleft", 0x21bf }, /* UPWARDS HARPOON WITH BARB LEFTWARDS */
+ { "$harpoonupbarbright", 0x21be }, /* UPWARDS HARPOON WITH BARB RIGHTWARDS */
+ { "$hatwide", 0x0010ff62 }, /* PRIVATE SPACE WIDE CIRCUMFLEX MATH ACCENT */
+ { "$hatwider", 0x0010ff63 }, /* PRIVATE SPACE WIDER CIRCUMFLEX MATH ACCENT */
+ { "$hatwidest", 0x0010ff64 }, /* PRIVATE SPACE WIDEST CIRCUMFLEX MATH ACCENT */
+ { "$hatxwide", 0x0010ffef }, /* PRIVATE SPACE EXTREMELY WIDE CIRCUMFLEX MATH ACCENT */
+ { "$heartwhite", 0x2661 }, /* WHITE HEART SUIT */
+ { "$hmathbb", 0x0001d559 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL H */
+ { "$hmathfrak", 0x0001d525 }, /* MATHEMATICAL FRAKTUR SMALL H */
+ { "$hyphen" , 0x002D }, /* HYPHEN-MINUS; distinguish Adobe duplicates */
+ { "$hyphensoft" , 0x00AD }, /* SOFT HYPHEN; distinguish Adobe duplicates */
+ { "$imathbb", 0x0001d55a }, /* MATHEMATICAL DOUBLE-STRUCK SMALL I */
+ { "$imathfrak", 0x0001d526 }, /* MATHEMATICAL FRAKTUR SMALL I */
+ { "$increment" , 0x2206 }, /* INCREMENT; distinguish Adobe duplicates */
+ { "$information" , 0x2139 }, /* INFORMATION SOURCE */
+ { "$integraldisplay", 0x0010ff5a }, /* PRIVATE SPACE DISPLAY MATH INTEGRAL */
+ { "$integraltext", 0x0010ff52 }, /* PRIVATE SPACE INLINE MATH INTEGRAL */
+ { "$intercalate", 0x22ba }, /* INTERCALATE */
+ { "$interrobang", 0x203d }, /* INTERROBANG */
+ { "$intersectiondbl", 0x22d2 }, /* DOUBLE INTERSECTION */
+ { "$intersectiondisplay", 0x0010ff5c }, /* PRIVATE SPACE DISPLAY MATH INTERSECTION */
+ { "$intersectionsq", 0x2293 }, /* SQUARE CAP */
+ { "$intersectiontext", 0x0010ff54 }, /* PRIVATE SPACE INLINE MATH INTERSECTION */
+ { "$jmathbb", 0x0001d55b }, /* MATHEMATICAL DOUBLE-STRUCK SMALL J */
+ { "$jmathfrak", 0x0001d527 }, /* MATHEMATICAL FRAKTUR SMALL J */
+ { "$jupiter", 0x2643 }, /* JUPITER */
+ { "$kappa1", 0x03f0 }, /* GREEK KAPPA SYMBOL */
+ { "$keyboard" , 0x2328 }, /* KEYBOARD */
+ { "$kmathbb", 0x0001d55c }, /* MATHEMATICAL DOUBLE-STRUCK SMALL K */
+ { "$kmathfrak", 0x0001d528 }, /* MATHEMATICAL FRAKTUR SMALL K */
+ { "$latincross", 0x271d }, /* LATIN CROSS */
+ { "$latticetop", 0x22a4 }, /* DOWN TACK */
+ { "$leftthreetimes", 0x22cb }, /* LEFT SEMIDIRECT PRODUCT */
+ { "$lefttimes", 0x22c9 }, /* LEFT NORMAL FACTOR SEMIDIRECT PRODUCT */
+ { "$lefttorque", 0x2939 }, /* LEFT-SIDE ARC ANTICLOCKWISE ARROW */
+ { "$leo", 0x264c }, /* LEO */
+ { "$lessapprox", 0x2a85 }, /* LESS-THAN OR APPROXIMATE */
+ { "$lessdot", 0x22d6 }, /* LESS-THAN WITH DOT */
+ { "$lessequal2", 0x2266 }, /* LESS-THAN OVER EQUAl TO */
+ { "$lessequalgreater", 0x22da }, /* LESS-THAN EQUAL TO OR GREATER-THAN */
+ { "$lessequalgreaterstacked", 0x2a8b }, /* LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN */
+ { "$lessequalslanted", 0x2a7d }, /* LESS-THAN OR SLANTED EQUAL TO */
+ { "$lessgreater", 0x2276 }, /* LESS-THAN OR GREATER-THAN */
+ { "$lessmuch", 0x226a }, /* MUCH LESS-THAN */
+ { "$lessnotapprox", 0x2a89 }, /* LESS-THAN AND NOT APPROXIMATE */
+ { "$lessnotequal", 0x2268 }, /* LESS-THAN BUT NOT EQUAL TO */
+ { "$lessnotequal1", 0x2a87 }, /* LESS-THAN AND SINGLE-LINE NOT EQUAL TO */
+ { "$lessnotsimilar", 0x22e6 }, /* LESS-THAN BUT NOT EQUIVALENT TO */
+ { "$lesssimilar", 0x2272 }, /* LESS-THAN OR EQUIVALENT TO */
+ { "$lessverymuch", 0x22d8 }, /* VERY MUCH LESS-THAN */
+ { "$libra", 0x264e }, /* LIBRA */
+ { "$llcorner", 0x231e }, /* BOTTOM LEFT CORNER */
+ { "$lmathbb", 0x0001d55d }, /* MATHEMATICAL DOUBLE-STRUCK SMALL L */
+ { "$lmathfrak", 0x0001d529 }, /* MATHEMATICAL FRAKTUR SMALL L */
+ { "$logicalanddisplay", 0x0010ff5e }, /* PRIVATE SPACE DISPLAY MATH LOGICAL AND */
+ { "$logicalandtext", 0x0010ff56 }, /* PRIVATE SPACE INLINE MATH LOGICAL AND */
+ { "$logicalordisplay", 0x0010ff5f }, /* PRIVATE SPACE DISPLAY MATH LOGICAL OR */
+ { "$logicalortext", 0x0010ff57 }, /* PRIVATE SPACE INLINE MATH LOGICAL OR */
+ { "$longst", 0xfb05 }, /* LATIN SMALL LIGATURE LONG S T */
+ { "$looparrowleft", 0x21ab }, /* LEFTWARDS ARROW WITH LOOP */
+ { "$looparrowright", 0x21ac }, /* RIGHTWARDS ARROW WITH LOOP */
+ { "$lrcorner", 0x231f }, /* BOTTOM RIGHT CORNER */
+ { "$lscript", 0x2113 }, /* SCRIPT SMALL L; Adobe has this as "afii61289" */
+ { "$macron", 0x00AF }, /* MACRON; distinguish Adobe duplicates */
+ { "$macroncomb", 0x0304 }, /* COMBINING MACRON */
+ { "$macronmodifier", 0x02c9 }, /* MODIFIER LETTER MACRON */
+ { "$maltesecross", 0x2720 }, /* MALTESE CROSS */
+ { "$measuredangle", 0x2221 }, /* MEASURED ANGLE */
+ { "$mercury", 0x263f }, /* MERCURY */
+ { "$micro", 0x00B5 }, /* MICRO SIGN; distinguish Adobe duplicates */
+ { "$minusplus", 0x2213 }, /* MINUS-OR-PLUS SIGN */
+ { "$minutereversed", 0x2035 }, /* REVERSED PRIME */
+ { "$mmathbb", 0x0001d55e }, /* MATHEMATICAL DOUBLE-STRUCK SMALL M */
+ { "$mmathfrak", 0x0001d52a }, /* MATHEMATICAL FRAKTUR SMALL M */
+ { "$moonfirstquarter", 0x263d }, /* FIRST QUARTER MOON */
+ { "$mu", 0x03BC }, /* GREEK SMALL LETTER MU; distinguish Adobe duplicates */
+ { "$multimap", 0x22b8 }, /* MULTIMAP */
+ { "$naira", 0x20a6 }, /* NAIRA SIGN */
+ { "$natural", 0x266e }, /* MUSIC NATURAL SIGN */
+ { "$negationslash", 0x0010fffc }, /* PRIVATE SPACE NEGATION SLASH */
+ { "$neptune", 0x2646 }, /* NEPTUNE */
+ { "$ng", 0x0010fffe }, /* PRIVATE SPACE LIGATURE SMALL NG */
+ { "$ninemathbb", 0x0001de1 }, /* MATHEMATICAL DOUBLE-STRUCK DIGIT NINE */
+ { "$nmathbb", 0x0001d55f }, /* MATHEMATICAL DOUBLE-STRUCK SMALL N */
+ { "$nmathfrak", 0x0001d52b }, /* MATHEMATICAL FRAKTUR SMALL N */
+ { "$normalin", 0x22b2 }, /* NORMAL SUBGROUP OF */
+ { "$normalizes", 0x22b3 }, /* CONTAINS AS NORMAL SUBGROUP */
+ { "$notarrowboth", 0x21ae }, /* LEFT RIGHT ARROW WITH STROKE */
+ { "$notarrowdblboth", 0x21ce }, /* LEFT RIGHT DOUBLE ARROW WITH STROKE */
+ { "$notarrowdblleft", 0x21cd }, /* LEFTWARDS DOUBLE ARROW WITH STROKE */
+ { "$notarrowdblright", 0x21cf }, /* RIGHTWARDS DOUBLE ARROW WITH STROKE */
+ { "$notarrowleft", 0x219a }, /* LEFTWARDS ARROW WITH STROKE */
+ { "$notarrowright", 0x219b }, /* RIGHTWARDS ARROW WITH STROKE */
+ { "$notcongruent", 0x2247 }, /* NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO */
+ { "$notequivalent", 0x2262 }, /* NOT IDENTICAL TO */
+ { "$notexistential", 0x2204 }, /* THERE DOES NOT EXIST */
+ { "$notfollowsequal", 0x22e1 }, /* DOES NOT SUCCEED OR EQUAL */
+ { "$notforcesdoublehbar", 0x22af }, /* NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE */
+ { "$notgreater", 0x226f }, /* NOT GREATER-THAN */
+ { "$notgreaterequal", 0x2271 }, /* NEITHER GREATER-THAN NOR EQUAL TO */
+ { "$notgreaterequal2", 0x0010fff3 }, /* PRIVATE SPACE NEGATED GREATER-THAN OVER EQUAL TO */
+ { "$notgreaterequalslanted", 0x0010fff5 }, /* PRIVATE SPACE NEGATED GREATER-THAN OR SLANTED EQUAL TO */
+ { "$notless", 0x226e }, /* NOT LESS-THAN */
+ { "$notlessequal", 0x2270 }, /* NEITHER LESS-THAN NOR EQUAL TO */
+ { "$notlessequal2", 0x0010fff4 }, /* PRIVATE SPACE NEGATED LESS-THAN OVER EQUAL TO */
+ { "$notlessequalslanted", 0x0010fff6 }, /* PRIVATE SPACE NEGATED LESS-THAN OR SLANTED EQUAL TO */
+ { "$notnormalin", 0x22ea }, /* NOT NORMAL SUBGROUP OF */
+ { "$notnormalizes", 0x22eb }, /* DOES NOT CONTAIN AS NORMAL SUBGROUP */
+ { "$notparallel", 0x2226 }, /* NOT PARALLEL TO */
+ { "$notprecedesequal", 0x22e0 }, /* DOES NOT PRECEDE OR EQUAL */
+ { "$notreflexnormalin", 0x22ec }, /* NOT NORMAL SUBGROUP OF OR EQUAL TO */
+ { "$notreflexnormalizes", 0x22ed }, /* DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL */
+ { "$notsimilar", 0x2241 }, /* NOT TILDE */
+ { "$notsubsetequal", 0x2288 }, /* NEITHER A SUBSET OF NOR EQUAL TO */
+ { "$notsubsetequal2", 0x0010fff2 }, /* PRIVATE SPACE NEGATED SUBSET OF ABOVE EQUALS SIGN */
+ { "$notsupersetequal", 0x2289 }, /* NEITHER A SUPERSET OF NOR EQUAL TO */
+ { "$notsupersetequal2", 0x0010fff1 }, /* PRIVATE SPACE NEGATED SUPERSET OF ABOVE EQUALS SIGN */
+ { "$nottrue", 0x22ad }, /* NOT TRUE */
+ { "$numero", 0x2116 }, /* NUMERO SIGN; adobe has this as "afii61352" */
+ { "$ogonekcomb", 0x0328 }, /* COMBINING OGONEK */
+ { "$omathbb", 0x0001d560 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL O */
+ { "$omathfrak", 0x0001d52c }, /* MATHEMATICAL FRAKTUR SMALL O */
+ { "$onemathbb", 0x0001d7d9 }, /* MATHEMATICAL DOUBLE-STRUCK DIGIT ONE */
+ { "$overlinecomb", 0x0305 }, /* COMBINING OVERLINE */
+ { "$parallel", 0x2225 }, /* PARALLEL TO */
+ { "$parenleftBig", 0x0010ff10 }, /* PRIVATE SPACE VERY LARGE LEFT PARENTHESIS */
+ { "$parenleftBigg", 0x0010ff20 }, /* PRIVATE SPACE VERY HUGE LEFT PARENTHESIS */
+ { "$parenleftbig", 0x0010ff00 }, /* PRIVATE SPACE LARGE LEFT PARENTHESIS */
+ { "$parenleftbigg", 0x0010ff12 }, /* PRIVATE SPACE HUGE LEFT PARENTHESIS */
+ { "$parenleftbt", 0x239d }, /* LEFT PARENTHESIS LOWER HOOK; not Adobe's private space version */
+ { "$parenleftex", 0x239c }, /* LEFT PARENTHESIS EXTENSION; not Adobe's private space version */
+ { "$parenlefttp", 0x239b }, /* LEFT PARENTHESIS UPPER HOOK; not Adobe's private space version */
+ { "$parenleftwhite", 0x2985 }, /* LEFT WHITE PARENTHESIS */
+ { "$parenrightBig", 0x0010ff11 }, /* PRIVATE SPACE VERY LARGE RIGHT PARENTHESIS */
+ { "$parenrightBigg", 0x0010ff21 }, /* PRIVATE SPACE VERY HUGE RIGHT PARENTHESIS */
+ { "$parenrightbig", 0x0010ff01 }, /* PRIVATE SPACE LARGE RIGHT PARENTHESIS */
+ { "$parenrightbigg", 0x0010ff13 }, /* PRIVATE SPACE HUGE RIGHT PARENTHESIS */
+ { "$parenrightbt", 0x23a0 }, /* RIGHT PARENTHESIS LOWER HOOK; not Adobe's private space version */
+ { "$parenrightex", 0x239f }, /* RIGHT PARENTHESIS EXTENSION; not Adobe's private space version */
+ { "$parenrighttp", 0x239e }, /* RIGHT PARENTHESIS UPPER HOOK; not Adobe's private space version */
+ { "$parenrightwhite", 0x2986 }, /* RIGHT WHITE PARENTHESIS */
+ { "$periodcentered" , 0x00B7 }, /* MIDDLE DOT; distinguish Adobe duplicates */
+ { "$pertenthousand" , 0x2031 }, /* PER TEN THOUSAND SIGN */
+ { "$peso", 0x20b1 }, /* PESO SIGN */
+ { "$pfennig", 0x20b0 }, /* GERMAN PENNY SIGN */
+ { "$phonorecord", 0x2117 }, /* SOUND RECORDING COPYRIGHT */
+ { "$pi1", 0x03D6 }, /* GREEK PI SYMBOL; Adobe has this as "omega1" which is too confusing */
+ { "$pisces", 0x2653 }, /* PISCES */
+ { "$pitchfork", 0x22d4 }, /* PITCHFORK */
+ { "$planckhbar", 0x210f }, /* PLANCK CONSTANT OVER TWO PI */
+ { "$pluto", 0x2647 }, /* PLUTO */
+ { "$pmathbb", 0x0001d561 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL P */
+ { "$pmathfrak", 0x0001d52d }, /* MATHEMATICAL FRAKTUR SMALL P */
+ { "$polishstroke", 0x0010fff8 }, /* PRIVATE SPACE SHORT ASCENDING STROKE */
+ { "$polishstrokecomb", 0x0010fff7 }, /* PRIVATE SPACE COMBINING SHORT ASCENDING STROKE OVERLAY */
+ { "$pounds", 0x2114 }, /* L B BAR SYMBOL */
+ { "$precedes", 0x227a }, /* PRECEDES */
+ { "$precedesapprox", 0x2ab7 }, /* PRECEDES ABOVE ALMOST EQUAL TO */
+ { "$precedesequal", 0x227c }, /* PRECEDES OR EQUAL TO */
+ { "$precedesnot", 0x2280 }, /* DOES NOT PRECEDE */
+ { "$precedesnotapprox", 0x2ab9 }, /* PRECEDES ABOVE NOT ALMOST EQUAL TO */
+ { "$precedesnotequal", 0x2ab5 }, /* PRECEDES ABOVE NOT EQUAL TO */
+ { "$precedesnotsimilar", 0x22e8 }, /* PRECEDES BUT NOT EQUIVALENT TO */
+ { "$precedessimilar", 0x227e }, /* PRECEDES OR EQUIVALENT TO */
+ { "$productdisplay", 0x0010ff59 }, /* PRIVATE SPACE DISPLAY MATH N-ARY PRODUCT */
+ { "$producttext", 0x0010ff51 }, /* PRIVATE SPACE INLINE MATH N-ARY PRODUCT */
+ { "$provesnot", 0x22ac }, /* DOES NOT PROVE */
+ { "$qmathbb", 0x0001d562 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL Q */
+ { "$qmathfrak", 0x0001d52e }, /* MATHEMATICAL FRAKTUR SMALL Q */
+ { "$quillbracketleft", 0x2045 }, /* LEFT SQUARE BRACKET WITH QUILL */
+ { "$quillbracketright", 0x2046 }, /* RIGHT SQUARE BRACKET WITH QUILL */
+ { "$quotedblreversed", 0x201f }, /* DOUBLE HIGH-REVERSED-9 QUOTATION MARK */
+ { "$radicalBig", 0x0010ff71 }, /* PRIVATE SPACE VERY LARGE SQUARE ROOT */
+ { "$radicalBigg", 0x0010ff73 }, /* PRIVATE SPACE VERY HUGE SQUARE ROOT */
+ { "$radicalbig", 0x0010ff70 }, /* PRIVATE SPACE LARGE SQUARE ROOT */
+ { "$radicalbigg", 0x0010ff72 }, /* PRIVATE SPACE HUGE SQUARE ROOT */
+ { "$radicalbt", 0x0010ff74 }, /* PRIVATE SPACE SQUARE ROOT BOTTOM */
+ { "$radicaltp", 0x0010ff76 }, /* PRIVATE SPACE SQUARE ROOT TOP */
+ { "$radicalvertex", 0x0010ff75 }, /* PRIVATE SPACE SQUARE ROOT VERTICAL EXTENDER */
+ { "$radioactive", 0x2622 }, /* RADIOACTIVE SIGN */
+ { "$referencemark", 0x203b }, /* REFERENCE MARK */
+ { "$reflexnormalin", 0x22b4 }, /* NORMAL SUBGROUP OF OR EQUAL TO */
+ { "$reflexnormalizes", 0x22b5 }, /* CONTAINS AS NORMAL SUBGROUP OR EQUAL TO */
+ { "$reflexsubsetsq", 0x2291 }, /* SQUARE IMAGE OF OR EQUAL TO */
+ { "$reflexsupersetsq", 0x2292 }, /* SQUARE ORIGINAL OF OR EQUAL TO */
+ { "$rho1", 0x03f1 }, /* GREEK RHO SYMBOL */
+ { "$rightthreetimes", 0x22cc }, /* RIGHT SEMIDIRECT PRODUCT */
+ { "$righttimes", 0x22ca }, /* RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT */
+ { "$righttorque", 0x2938 }, /* RIGHT-SIDE ARC CLOCKWISE ARROW */
+ { "$ringcomb", 0x030a }, /* COMBINING RING ABOVE */
+ { "$ringequal", 0x2257 }, /* RING EQUAL TO */
+ { "$ringinequal", 0x2256 }, /* RING IN EQUAL TO */
+ { "$risingdotsequal", 0x2253 }, /* IMAGE OF OR APPROXIMATELY EQUAL TO */
+ { "$rmathbb", 0x0001d563 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL R */
+ { "$rmathfrak", 0x0001d52f }, /* MATHEMATICAL FRAKTUR SMALL R */
+ { "$sagittarius", 0x2650 }, /* SAGITTARIUS */
+ { "$saturn", 0x2644 }, /* SATURN */
+ { "$scedilla" , 0x015F }, /* LATIN SMALL LETTER S WITH CEDILLA; distinguish Adobe duplicates */
+ { "$scissors", 0x2702 }, /* BLACK SCISSORS */
+ { "$scissorsupperblade", 0x2701 }, /* UPPER BLADE SCISSORS */
+ { "$scorpius", 0x264f }, /* SCORPIUS */
+ { "$secondreversed", 0x2036 }, /* REVERSED DOUBLE PRIME */
+ { "$servicemark", 0x2120 }, /* SERVICE MARK */
+ { "$setminus", 0x2216 }, /* SET MINUS */
+ { "$sevenmathbb", 0x0001d7df }, /* MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN */
+ { "$sharp", 0x266f }, /* MUSIC SHARP SIGN */
+ { "$similarequal", 0x2243 }, /* ASYMPTOTICALLY EQUAL TO */
+ { "$similarequalreversed", 0x22cd }, /* REVERSED TILDE EQUALS */
+ { "$similarreversed", 0x223d }, /* REVERSED TILDE */
+ { "$sixmathbb", 0x0001d7de }, /* MATHEMATICAL DOUBLE-STRUCK DIGIT SIX */
+ { "$slashBig", 0x0010ff2e }, /* PRIVATE SPACE VERY LARGE SOLIDUS */
+ { "$slashBigg", 0x0010ff2c }, /* PRIVATE SPACE VERY HUGE SOLIDUS */
+ { "$slashbig", 0x0010ff0e }, /* PRIVATE SPACE LARGE SOLIDUS */
+ { "$slashbigg", 0x0010ff1e }, /* PRIVATE SPACE HUGE SOLIDUS */
+ { "$slashlongcomb", 0x0338 }, /* COMBINING LONG SOLIDUS OVERLAY */
+ { "$smathbb", 0x0001d564 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL S */
+ { "$smathfrak", 0x0001d530 }, /* MATHEMATICAL FRAKTUR SMALL S */
+ { "$smile", 0x2323 }, /* SMILE */
+ { "$snowflake", 0x2744 }, /* SNOWFLAKE */
+ { "$space" , 0x0020 }, /* SPACE; distinguish Adobe duplicates */
+ { "$spacenobreak" , 0x00A0 }, /* NO-BREAK SPACE; distinguish Adobe duplicates */
+ { "$spacesymbol", 0x2420 }, /* SYMBOL FOR SPACE */
+ { "$sphericalangle", 0x2222 }, /* SPHERICAL ANGLE */
+ { "$squigarrowright", 0x21dd }, /* RIGHTWARDS SQUIGGLE ARROW */
+ { "$st", 0xfb06 }, /* LATIN SMALL LIGATURE ST */
+ { "$star", 0x2605 }, /* BLACK STAR */
+ { "$starmath", 0x22c6 }, /* STAR OPERATOR */
+ { "$subsetdbl", 0x22d0 }, /* DOUBLE SUBSET */
+ { "$subsetequal2", 0x2ac5 }, /* SUBSET OF ABOVE EQUALS SIGN */
+ { "$subsetnotequal", 0x228a }, /* SUBSET OF WITH NOT EQUAL TO */
+ { "$subsetnotequal2", 0x2acb }, /* SUBSET OF ABOVE NOT EQUAL TO */
+ { "$subsetsq", 0x228f }, /* SQUARE IMAGE OF */
+ { "$summationdisplay", 0x0010ff58 }, /* PRIVATE SPACE DISPLAY MATH N-ARY SUMMATION */
+ { "$summationtext", 0x0010ff50 }, /* PRIVATE SPACE INLINE MATH N-ARY SUMMATION */
+ { "$sun", 0x2609 }, /* SUN */
+ { "$supersetdbl", 0x22d1 }, /* DOUBLE SUPERSET */
+ { "$supersetequal2", 0x2ac6 }, /* SUPERSET OF ABOVE EQUALS SIGN */
+ { "$supersetnotequal", 0x228b }, /* SUPERSET OF WITH NOT EQUAL TO */
+ { "$supersetnotequal2", 0x2acc }, /* SUPERSET OF ABOVE NOT EQUAL TO */
+ { "$supersetsq", 0x2290 }, /* SQUARE ORIGINAL OF */
+ { "$tailarrowleft", 0x21a2 }, /* LEFTWARDS ARROW WITH TAIL */
+ { "$tailarrowright", 0x21a3 }, /* RIGHTWARDS ARROW WITH TAIL */
+ { "$taurus", 0x2649 }, /* TAURUS */
+ { "$tcedilla", 0x0163 }, /* LATIN SMALL LETTER T WITH CEDILLA; distinguish Adobe duplicates */
+ { "$tcommaaccent", 0x021B }, /* LATIN SMALL LETTER T WITH COMMA BELOW; distinguish Adobe duplicates */
+ { "$telephone", 0x260e }, /* BLACK TELEPHONE */
+ { "$threemathbb", 0x0001d7db }, /* MATHEMATICAL DOUBLE-STRUCK DIGIT THREE */
+ { "$tie", 0x2040 }, /* CHARACTER TIE */
+ { "$tildewide", 0x0010ff65 }, /* PRIVATE SPACE WIDE TILDE MATH ACCENT */
+ { "$tildewider", 0x0010ff66 }, /* PRIVATE SPACE WIDER TILDE MATH ACCENT */
+ { "$tildewidest", 0x0010ff67 }, /* PRIVATE SPACE WIDEST TILDE MATH ACCENT */
+ { "$tildexwide", 0x0010fff0 }, /* PRIVATE SPACE EXTREMELY WIDE TILDE MATH ACCENT */
+ { "$tmathbb", 0x0001d565 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL T */
+ { "$tmathfrak", 0x0001d531 }, /* MATHEMATICAL FRAKTUR SMALL T */
+ { "$triagwhitedn", 0x25bd }, /* WHITE DOWN-POINTING TRIANGLE */
+ { "$triagwhiteup", 0x25b3 }, /* WHITE UP-POINTING TRIANGLE */
+ { "$triangleleft", 0x25c0 }, /* BLACK LEFT-POINTING TRIANGLE */
+ { "$triangleright", 0x25b6 }, /* BLACK RIGHT-POINTING TRIANGLE */
+ { "$true", 0x22a8 }, /* TRUE */
+ { "$turnstileleft", 0x22a2 }, /* RIGHT TACK */
+ { "$turnstileright", 0x22a3 }, /* LEFT TACK */
+ { "$twoheadarrowleft", 0x219e }, /* LEFTWARDS TWO HEADED ARROW */
+ { "$twoheadarrowright", 0x21a0 }, /* RIGHTWARDS TWO HEADED ARROW */
+ { "$twomathbb", 0x0001d7da }, /* MATHEMATICAL DOUBLE-STRUCK DIGIT TWO */
+ { "$ulcorner", 0x231c }, /* TOP LEFT CORNER */
+ { "$umathbb", 0x0001d566 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL U */
+ { "$umathfrak", 0x0001d532 }, /* MATHEMATICAL FRAKTUR SMALL U */
+ { "$uniondbl", 0x22d3 }, /* DOUBLE UNION */
+ { "$uniondisplay", 0x0010ff5b }, /* PRIVATE SPACE DISPLAY MATH UNION */
+ { "$unionmulti", 0x228e }, /* MULTISET UNION */
+ { "$unionmultidisplay", 0x0010ff5d }, /* PRIVATE SPACE DISPLAY MATH MULTISET UNION */
+ { "$unionmultitext", 0x0010ff55 }, /* PRIVATE SPACE INLINE MATH MULTISET UNION */
+ { "$unionsq", 0x2294 }, /* SQUARE CUP */
+ { "$unionsqdisplay", 0x0010ff47 }, /* PRIVATE SPACE DISPLAY MATH SQUARE CUP */
+ { "$unionsqtext", 0x0010ff46 }, /* PRIVATE SPACE INLINE MATH SQUARE CUP */
+ { "$uniontext", 0x0010ff53 }, /* PRIVATE SPACE INLINE MATH UNION */
+ { "$uranus", 0x2645 }, /* URANUS */
+ { "$urcorner", 0x231d }, /* TOP RIGHT CORNER */
+ { "$vector", 0x0010fffb }, /* PRIVATE SPACE SUPERSCRIPT RIGHTWARDS ARROW */
+ { "$vectorcomb", 0x20d7 }, /* COMBINING RIGHT ARROW ABOVE */
+ { "$veebar", 0x22bb }, /* XOR */
+ { "$vextenddouble", 0x0010ff0d }, /* PRIVATE SPACE DOUBLE VERTICAL LINE EXTENDER */
+ { "$vextendsingle", 0x0010ff0c }, /* PRIVATE SPACE VERTICAL LINE EXTENDER */
+ { "$virgo", 0x264d }, /* VIRGO */
+ { "$visualspace", 0x2423 }, /* OPEN BOX */
+ { "$vmathbb", 0x0001d567 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL V */
+ { "$vmathfrak", 0x0001d533 }, /* MATHEMATICAL FRAKTUR SMALL V */
+ { "$watch", 0x231a }, /* WATCH */
+ { "$wmathbb", 0x0001d568 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL W */
+ { "$wmathfrak", 0x0001d534 }, /* MATHEMATICAL FRAKTUR SMALL W */
+ { "$won", 0x20a9 }, /* WON SIGN */
+ { "$wreathproduct", 0x2240 }, /* WREATH PRODUCT */
+ { "$writinghand", 0x270d }, /* WRITING HAND */
+ { "$xmathbb", 0x0001d569 }, /* MATHEMATICAL DOUBLE-STRUCK SMALL X */
+ { "$xmathfrak", 0x0001d535 }, /* MATHEMATICAL FRAKTUR SMALL X */
+ { "$yinyang", 0x262f }, /* YIN YANG */
+ { "$ymathbb", 0x0001d56a }, /* MATHEMATICAL DOUBLE-STRUCK SMALL Y */
+ { "$ymathfrak", 0x0001d536 }, /* MATHEMATICAL FRAKTUR SMALL Y */
+ { "$zeromathbb", 0x0001d7d8 }, /* MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO */
+ { "$zigzagarrowdown", 0x21af }, /* DOWNWARDS ZIGZAG ARROW */
+ { "$zmathbb", 0x0001d56b }, /* MATHEMATICAL DOUBLE-STRUCK SMALL Z */
+ { "$zmathfrak", 0x0001d537 }, /* MATHEMATICAL FRAKTUR SMALL Z */
+ { ".notavail", 0xfffd }, /* REPLACEMENT CHARACTER */
+ { ".notdef", 0x003f }, /* QUESTION MARK */
+ { "A", 0x0041 }, /* LATIN CAPITAL LETTER A */
+ { "AE", 0x00C6 }, /* LATIN CAPITAL LETTER AE */
+ { "AEacute", 0x01FC }, /* LATIN CAPITAL LETTER AE WITH ACUTE */
+ { "AEsmall", 0xF7E6 }, /* LATIN SMALL CAPITAL LETTER AE */
+ { "Aacute", 0x00C1 }, /* LATIN CAPITAL LETTER A WITH ACUTE */
+ { "Aacutesmall", 0xF7E1 }, /* LATIN SMALL CAPITAL LETTER A WITH ACUTE */
+ { "Abreve", 0x0102 }, /* LATIN CAPITAL LETTER A WITH BREVE */
+ { "Acircumflex", 0x00C2 }, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+ { "Acircumflexsmall", 0xF7E2 }, /* LATIN SMALL CAPITAL LETTER A WITH CIRCUMFLEX */
+ { "Acute", 0xF6C9 }, /* CAPITAL ACUTE ACCENT */
+ { "Acutesmall", 0xF7B4 }, /* SMALL CAPITAL ACUTE ACCENT */
+ { "Adieresis", 0x00C4 }, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
+ { "Adieresissmall", 0xF7E4 }, /* LATIN SMALL CAPITAL LETTER A WITH DIAERESIS */
+ { "Agrave", 0x00C0 }, /* LATIN CAPITAL LETTER A WITH GRAVE */
+ { "Agravesmall", 0xF7E0 }, /* LATIN SMALL CAPITAL LETTER A WITH GRAVE */
+ { "Alpha", 0x0391 }, /* GREEK CAPITAL LETTER ALPHA */
+ { "Alphatonos", 0x0386 }, /* GREEK CAPITAL LETTER ALPHA WITH TONOS */
+ { "Amacron", 0x0100 }, /* LATIN CAPITAL LETTER A WITH MACRON */
+ { "Aogonek", 0x0104 }, /* LATIN CAPITAL LETTER A WITH OGONEK */
+ { "Aring", 0x00C5 }, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
+ { "Aringacute", 0x01FA }, /* LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE */
+ { "Aringsmall", 0xF7E5 }, /* LATIN SMALL CAPITAL LETTER A WITH RING ABOVE */
+ { "Asmall", 0xF761 }, /* LATIN SMALL CAPITAL LETTER A */
+ { "Atilde", 0x00C3 }, /* LATIN CAPITAL LETTER A WITH TILDE */
+ { "Atildesmall", 0xF7E3 }, /* LATIN SMALL CAPITAL LETTER A WITH TILDE */
+ { "B", 0x0042 }, /* LATIN CAPITAL LETTER B */
+ { "Beta", 0x0392 }, /* GREEK CAPITAL LETTER BETA */
+ { "Brevesmall", 0xF6F4 }, /* SMALL CAPITAL BREVE */
+ { "Bsmall", 0xF762 }, /* LATIN SMALL CAPITAL LETTER B */
+ { "C", 0x0043 }, /* LATIN CAPITAL LETTER C */
+ { "Cacute", 0x0106 }, /* LATIN CAPITAL LETTER C WITH ACUTE */
+ { "Caron", 0xF6CA }, /* CAPITAL CARON */
+ { "Caronsmall", 0xF6F5 }, /* SMALL CAPITAL CARON */
+ { "Ccaron", 0x010C }, /* LATIN CAPITAL LETTER C WITH CARON */
+ { "Ccedilla", 0x00C7 }, /* LATIN CAPITAL LETTER C WITH CEDILLA */
+ { "Ccedillasmall", 0xF7E7 }, /* LATIN SMALL CAPITAL LETTER C WITH CEDILLA */
+ { "Ccircumflex", 0x0108 }, /* LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+ { "Cdotaccent", 0x010A }, /* LATIN CAPITAL LETTER C WITH DOT ABOVE */
+ { "Cedillasmall", 0xF7B8 }, /* SMALL CAPITAL CEDILLA */
+ { "Chi", 0x03A7 }, /* GREEK CAPITAL LETTER CHI */
+ { "Circumflexsmall", 0xF6F6 }, /* SMALL CAPITAL MODIFIER LETTER CIRCUMFLEX ACCENT */
+ { "Csmall", 0xF763 }, /* LATIN SMALL CAPITAL LETTER C */
+ { "D", 0x0044 }, /* LATIN CAPITAL LETTER D */
+ { "Dcaron", 0x010E }, /* LATIN CAPITAL LETTER D WITH CARON */
+ { "Dcroat", 0x0110 }, /* LATIN CAPITAL LETTER D WITH STROKE */
+ { "Delta" DUP1, 0x2206 }, /* INCREMENT */
+ { "Delta" DUP2, 0x0394 }, /* GREEK CAPITAL LETTER DELTA;Duplicate */
+ { "Dieresis", 0xF6CB }, /* CAPITAL DIAERESIS */
+ { "DieresisAcute", 0xF6CC }, /* CAPITAL DIAERESIS ACUTE ACCENT */
+ { "DieresisGrave", 0xF6CD }, /* CAPITAL DIAERESIS GRAVE ACCENT */
+ { "Dieresissmall", 0xF7A8 }, /* SMALL CAPITAL DIAERESIS */
+ { "Dotaccentsmall", 0xF6F7 }, /* SMALL CAPITAL DOT ABOVE */
+ { "Dsmall", 0xF764 }, /* LATIN SMALL CAPITAL LETTER D */
+ { "E", 0x0045 }, /* LATIN CAPITAL LETTER E */
+ { "Eacute", 0x00C9 }, /* LATIN CAPITAL LETTER E WITH ACUTE */
+ { "Eacutesmall", 0xF7E9 }, /* LATIN SMALL CAPITAL LETTER E WITH ACUTE */
+ { "Ebreve", 0x0114 }, /* LATIN CAPITAL LETTER E WITH BREVE */
+ { "Ecaron", 0x011A }, /* LATIN CAPITAL LETTER E WITH CARON */
+ { "Ecircumflex", 0x00CA }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+ { "Ecircumflexsmall", 0xF7EA }, /* LATIN SMALL CAPITAL LETTER E WITH CIRCUMFLEX */
+ { "Edieresis", 0x00CB }, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
+ { "Edieresissmall", 0xF7EB }, /* LATIN SMALL CAPITAL LETTER E WITH DIAERESIS */
+ { "Edotaccent", 0x0116 }, /* LATIN CAPITAL LETTER E WITH DOT ABOVE */
+ { "Egrave", 0x00C8 }, /* LATIN CAPITAL LETTER E WITH GRAVE */
+ { "Egravesmall", 0xF7E8 }, /* LATIN SMALL CAPITAL LETTER E WITH GRAVE */
+ { "Emacron", 0x0112 }, /* LATIN CAPITAL LETTER E WITH MACRON */
+ { "Eng", 0x014A }, /* LATIN CAPITAL LETTER ENG */
+ { "Eogonek", 0x0118 }, /* LATIN CAPITAL LETTER E WITH OGONEK */
+ { "Epsilon", 0x0395 }, /* GREEK CAPITAL LETTER EPSILON */
+ { "Epsilontonos", 0x0388 }, /* GREEK CAPITAL LETTER EPSILON WITH TONOS */
+ { "Esmall", 0xF765 }, /* LATIN SMALL CAPITAL LETTER E */
+ { "Eta", 0x0397 }, /* GREEK CAPITAL LETTER ETA */
+ { "Etatonos", 0x0389 }, /* GREEK CAPITAL LETTER ETA WITH TONOS */
+ { "Eth", 0x00D0 }, /* LATIN CAPITAL LETTER ETH */
+ { "Ethsmall", 0xF7F0 }, /* LATIN SMALL CAPITAL LETTER ETH */
+ { "Euro", 0x20AC }, /* EURO SIGN */
+ { "F", 0x0046 }, /* LATIN CAPITAL LETTER F */
+ { "Fsmall", 0xF766 }, /* LATIN SMALL CAPITAL LETTER F */
+ { "G", 0x0047 }, /* LATIN CAPITAL LETTER G */
+ { "Gamma", 0x0393 }, /* GREEK CAPITAL LETTER GAMMA */
+ { "Gbreve", 0x011E }, /* LATIN CAPITAL LETTER G WITH BREVE */
+ { "Gcaron", 0x01E6 }, /* LATIN CAPITAL LETTER G WITH CARON */
+ { "Gcircumflex", 0x011C }, /* LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+ { "Gcommaaccent", 0x0122 }, /* LATIN CAPITAL LETTER G WITH CEDILLA */
+ { "Gdotaccent", 0x0120 }, /* LATIN CAPITAL LETTER G WITH DOT ABOVE */
+ { "Grave", 0xF6CE }, /* CAPITAL GRAVE ACCENT */
+ { "Gravesmall", 0xF760 }, /* SMALL CAPITAL GRAVE ACCENT */
+ { "Gsmall", 0xF767 }, /* LATIN SMALL CAPITAL LETTER G */
+ { "H", 0x0048 }, /* LATIN CAPITAL LETTER H */
+ { "H18533", 0x25CF }, /* BLACK CIRCLE */
+ { "H18543", 0x25AA }, /* BLACK SMALL SQUARE */
+ { "H18551", 0x25AB }, /* WHITE SMALL SQUARE */
+ { "H22073", 0x25A1 }, /* WHITE SQUARE */
+ { "Hbar", 0x0126 }, /* LATIN CAPITAL LETTER H WITH STROKE */
+ { "Hcircumflex", 0x0124 }, /* LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+ { "Hsmall", 0xF768 }, /* LATIN SMALL CAPITAL LETTER H */
+ { "Hungarumlaut", 0xF6CF }, /* CAPITAL DOUBLE ACUTE ACCENT */
+ { "Hungarumlautsmall", 0xF6F8 }, /* SMALL CAPITAL DOUBLE ACUTE ACCENT */
+ { "I", 0x0049 }, /* LATIN CAPITAL LETTER I */
+ { "IJ", 0x0132 }, /* LATIN CAPITAL LIGATURE IJ */
+ { "Iacute", 0x00CD }, /* LATIN CAPITAL LETTER I WITH ACUTE */
+ { "Iacutesmall", 0xF7ED }, /* LATIN SMALL CAPITAL LETTER I WITH ACUTE */
+ { "Ibreve", 0x012C }, /* LATIN CAPITAL LETTER I WITH BREVE */
+ { "Icircumflex", 0x00CE }, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+ { "Icircumflexsmall", 0xF7EE }, /* LATIN SMALL CAPITAL LETTER I WITH CIRCUMFLEX */
+ { "Idieresis", 0x00CF }, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
+ { "Idieresissmall", 0xF7EF }, /* LATIN SMALL CAPITAL LETTER I WITH DIAERESIS */
+ { "Idotaccent", 0x0130 }, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
+ { "Ifraktur", 0x2111 }, /* BLACK-LETTER CAPITAL I */
+ { "Igrave", 0x00CC }, /* LATIN CAPITAL LETTER I WITH GRAVE */
+ { "Igravesmall", 0xF7EC }, /* LATIN SMALL CAPITAL LETTER I WITH GRAVE */
+ { "Imacron", 0x012A }, /* LATIN CAPITAL LETTER I WITH MACRON */
+ { "Iogonek", 0x012E }, /* LATIN CAPITAL LETTER I WITH OGONEK */
+ { "Iota", 0x0399 }, /* GREEK CAPITAL LETTER IOTA */
+ { "Iotadieresis", 0x03AA }, /* GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+ { "Iotatonos", 0x038A }, /* GREEK CAPITAL LETTER IOTA WITH TONOS */
+ { "Ismall", 0xF769 }, /* LATIN SMALL CAPITAL LETTER I */
+ { "Itilde", 0x0128 }, /* LATIN CAPITAL LETTER I WITH TILDE */
+ { "J", 0x004A }, /* LATIN CAPITAL LETTER J */
+ { "Jcircumflex", 0x0134 }, /* LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+ { "Jsmall", 0xF76A }, /* LATIN SMALL CAPITAL LETTER J */
+ { "K", 0x004B }, /* LATIN CAPITAL LETTER K */
+ { "Kappa", 0x039A }, /* GREEK CAPITAL LETTER KAPPA */
+ { "Kcommaaccent", 0x0136 }, /* LATIN CAPITAL LETTER K WITH CEDILLA */
+ { "Ksmall", 0xF76B }, /* LATIN SMALL CAPITAL LETTER K */
+ { "L", 0x004C }, /* LATIN CAPITAL LETTER L */
+ { "LL", 0xF6BF }, /* LATIN CAPITAL LETTER LL */
+ { "Lacute", 0x0139 }, /* LATIN CAPITAL LETTER L WITH ACUTE */
+ { "Lambda", 0x039B }, /* GREEK CAPITAL LETTER LAMDA */
+ { "Lcaron", 0x013D }, /* LATIN CAPITAL LETTER L WITH CARON */
+ { "Lcommaaccent", 0x013B }, /* LATIN CAPITAL LETTER L WITH CEDILLA */
+ { "Ldot", 0x013F }, /* LATIN CAPITAL LETTER L WITH MIDDLE DOT */
+ { "Lslash", 0x0141 }, /* LATIN CAPITAL LETTER L WITH STROKE */
+ { "Lslashsmall", 0xF6F9 }, /* LATIN SMALL CAPITAL LETTER L WITH STROKE */
+ { "Lsmall", 0xF76C }, /* LATIN SMALL CAPITAL LETTER L */
+ { "M", 0x004D }, /* LATIN CAPITAL LETTER M */
+ { "Macron", 0xF6D0 }, /* CAPITAL MACRON */
+ { "Macronsmall", 0xF7AF }, /* SMALL CAPITAL MACRON */
+ { "Msmall", 0xF76D }, /* LATIN SMALL CAPITAL LETTER M */
+ { "Mu", 0x039C }, /* GREEK CAPITAL LETTER MU */
+ { "N", 0x004E }, /* LATIN CAPITAL LETTER N */
+ { "Nacute", 0x0143 }, /* LATIN CAPITAL LETTER N WITH ACUTE */
+ { "Ncaron", 0x0147 }, /* LATIN CAPITAL LETTER N WITH CARON */
+ { "Ncommaaccent", 0x0145 }, /* LATIN CAPITAL LETTER N WITH CEDILLA */
+ { "Nsmall", 0xF76E }, /* LATIN SMALL CAPITAL LETTER N */
+ { "Ntilde", 0x00D1 }, /* LATIN CAPITAL LETTER N WITH TILDE */
+ { "Ntildesmall", 0xF7F1 }, /* LATIN SMALL CAPITAL LETTER N WITH TILDE */
+ { "Nu", 0x039D }, /* GREEK CAPITAL LETTER NU */
+ { "O", 0x004F }, /* LATIN CAPITAL LETTER O */
+ { "OE", 0x0152 }, /* LATIN CAPITAL LIGATURE OE */
+ { "OEsmall", 0xF6FA }, /* LATIN SMALL CAPITAL LIGATURE OE */
+ { "Oacute", 0x00D3 }, /* LATIN CAPITAL LETTER O WITH ACUTE */
+ { "Oacutesmall", 0xF7F3 }, /* LATIN SMALL CAPITAL LETTER O WITH ACUTE */
+ { "Obreve", 0x014E }, /* LATIN CAPITAL LETTER O WITH BREVE */
+ { "Ocircumflex", 0x00D4 }, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+ { "Ocircumflexsmall", 0xF7F4 }, /* LATIN SMALL CAPITAL LETTER O WITH CIRCUMFLEX */
+ { "Odieresis", 0x00D6 }, /* LATIN CAPITAL LETTER O WITH DIAERESIS */
+ { "Odieresissmall", 0xF7F6 }, /* LATIN SMALL CAPITAL LETTER O WITH DIAERESIS */
+ { "Ogoneksmall", 0xF6FB }, /* SMALL CAPITAL OGONEK */
+ { "Ograve", 0x00D2 }, /* LATIN CAPITAL LETTER O WITH GRAVE */
+ { "Ogravesmall", 0xF7F2 }, /* LATIN SMALL CAPITAL LETTER O WITH GRAVE */
+ { "Ohorn", 0x01A0 }, /* LATIN CAPITAL LETTER O WITH HORN */
+ { "Ohungarumlaut", 0x0150 }, /* LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+ { "Omacron", 0x014C }, /* LATIN CAPITAL LETTER O WITH MACRON */
+ { "Omega" DUP1, 0x2126 }, /* OHM SIGN */
+ { "Omega" DUP2, 0x03A9 }, /* GREEK CAPITAL LETTER OMEGA;Duplicate */
+ { "Omegatonos", 0x038F }, /* GREEK CAPITAL LETTER OMEGA WITH TONOS */
+ { "Omicron", 0x039F }, /* GREEK CAPITAL LETTER OMICRON */
+ { "Omicrontonos", 0x038C }, /* GREEK CAPITAL LETTER OMICRON WITH TONOS */
+ { "Oslash", 0x00D8 }, /* LATIN CAPITAL LETTER O WITH STROKE */
+ { "Oslashacute", 0x01FE }, /* LATIN CAPITAL LETTER O WITH STROKE AND ACUTE */
+ { "Oslashsmall", 0xF7F8 }, /* LATIN SMALL CAPITAL LETTER O WITH STROKE */
+ { "Osmall", 0xF76F }, /* LATIN SMALL CAPITAL LETTER O */
+ { "Otilde", 0x00D5 }, /* LATIN CAPITAL LETTER O WITH TILDE */
+ { "Otildesmall", 0xF7F5 }, /* LATIN SMALL CAPITAL LETTER O WITH TILDE */
+ { "P", 0x0050 }, /* LATIN CAPITAL LETTER P */
+ { "Phi", 0x03A6 }, /* GREEK CAPITAL LETTER PHI */
+ { "Pi", 0x03A0 }, /* GREEK CAPITAL LETTER PI */
+ { "Psi", 0x03A8 }, /* GREEK CAPITAL LETTER PSI */
+ { "Psmall", 0xF770 }, /* LATIN SMALL CAPITAL LETTER P */
+ { "Q", 0x0051 }, /* LATIN CAPITAL LETTER Q */
+ { "Qsmall", 0xF771 }, /* LATIN SMALL CAPITAL LETTER Q */
+ { "R", 0x0052 }, /* LATIN CAPITAL LETTER R */
+ { "Racute", 0x0154 }, /* LATIN CAPITAL LETTER R WITH ACUTE */
+ { "Rcaron", 0x0158 }, /* LATIN CAPITAL LETTER R WITH CARON */
+ { "Rcommaaccent", 0x0156 }, /* LATIN CAPITAL LETTER R WITH CEDILLA */
+ { "Rfraktur", 0x211C }, /* BLACK-LETTER CAPITAL R */
+ { "Rho", 0x03A1 }, /* GREEK CAPITAL LETTER RHO */
+ { "Ringsmall", 0xF6FC }, /* SMALL CAPITAL RING ABOVE */
+ { "Rsmall", 0xF772 }, /* LATIN SMALL CAPITAL LETTER R */
+ { "S", 0x0053 }, /* LATIN CAPITAL LETTER S */
+ { "SF010000", 0x250C }, /* BOX DRAWINGS LIGHT DOWN AND RIGHT */
+ { "SF020000", 0x2514 }, /* BOX DRAWINGS LIGHT UP AND RIGHT */
+ { "SF030000", 0x2510 }, /* BOX DRAWINGS LIGHT DOWN AND LEFT */
+ { "SF040000", 0x2518 }, /* BOX DRAWINGS LIGHT UP AND LEFT */
+ { "SF050000", 0x253C }, /* BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+ { "SF060000", 0x252C }, /* BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+ { "SF070000", 0x2534 }, /* BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+ { "SF080000", 0x251C }, /* BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+ { "SF090000", 0x2524 }, /* BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+ { "SF100000", 0x2500 }, /* BOX DRAWINGS LIGHT HORIZONTAL */
+ { "SF110000", 0x2502 }, /* BOX DRAWINGS LIGHT VERTICAL */
+ { "SF190000", 0x2561 }, /* BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE */
+ { "SF200000", 0x2562 }, /* BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE */
+ { "SF210000", 0x2556 }, /* BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE */
+ { "SF220000", 0x2555 }, /* BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE */
+ { "SF230000", 0x2563 }, /* BOX DRAWINGS DOUBLE VERTICAL AND LEFT */
+ { "SF240000", 0x2551 }, /* BOX DRAWINGS DOUBLE VERTICAL */
+ { "SF250000", 0x2557 }, /* BOX DRAWINGS DOUBLE DOWN AND LEFT */
+ { "SF260000", 0x255D }, /* BOX DRAWINGS DOUBLE UP AND LEFT */
+ { "SF270000", 0x255C }, /* BOX DRAWINGS UP DOUBLE AND LEFT SINGLE */
+ { "SF280000", 0x255B }, /* BOX DRAWINGS UP SINGLE AND LEFT DOUBLE */
+ { "SF360000", 0x255E }, /* BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE */
+ { "SF370000", 0x255F }, /* BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE */
+ { "SF380000", 0x255A }, /* BOX DRAWINGS DOUBLE UP AND RIGHT */
+ { "SF390000", 0x2554 }, /* BOX DRAWINGS DOUBLE DOWN AND RIGHT */
+ { "SF400000", 0x2569 }, /* BOX DRAWINGS DOUBLE UP AND HORIZONTAL */
+ { "SF410000", 0x2566 }, /* BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL */
+ { "SF420000", 0x2560 }, /* BOX DRAWINGS DOUBLE VERTICAL AND RIGHT */
+ { "SF430000", 0x2550 }, /* BOX DRAWINGS DOUBLE HORIZONTAL */
+ { "SF440000", 0x256C }, /* BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL */
+ { "SF450000", 0x2567 }, /* BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE */
+ { "SF460000", 0x2568 }, /* BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE */
+ { "SF470000", 0x2564 }, /* BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE */
+ { "SF480000", 0x2565 }, /* BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE */
+ { "SF490000", 0x2559 }, /* BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE */
+ { "SF500000", 0x2558 }, /* BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE */
+ { "SF510000", 0x2552 }, /* BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE */
+ { "SF520000", 0x2553 }, /* BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE */
+ { "SF530000", 0x256B }, /* BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE */
+ { "SF540000", 0x256A }, /* BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE */
+ { "Sacute", 0x015A }, /* LATIN CAPITAL LETTER S WITH ACUTE */
+ { "Scaron", 0x0160 }, /* LATIN CAPITAL LETTER S WITH CARON */
+ { "Scaronsmall", 0xF6FD }, /* LATIN SMALL CAPITAL LETTER S WITH CARON */
+ { "Scedilla" DUP1, 0x015E }, /* LATIN CAPITAL LETTER S WITH CEDILLA */
+ { "Scedilla" DUP2, 0xF6C1 }, /* LATIN CAPITAL LETTER S WITH CEDILLA;Duplicate */
+ { "Scircumflex", 0x015C }, /* LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+ { "Scommaaccent", 0x0218 }, /* LATIN CAPITAL LETTER S WITH COMMA BELOW */
+ { "Sigma", 0x03A3 }, /* GREEK CAPITAL LETTER SIGMA */
+ { "Ssmall", 0xF773 }, /* LATIN SMALL CAPITAL LETTER S */
+ { "T", 0x0054 }, /* LATIN CAPITAL LETTER T */
+ { "Tau", 0x03A4 }, /* GREEK CAPITAL LETTER TAU */
+ { "Tbar", 0x0166 }, /* LATIN CAPITAL LETTER T WITH STROKE */
+ { "Tcaron", 0x0164 }, /* LATIN CAPITAL LETTER T WITH CARON */
+ { "Tcommaaccent" DUP1, 0x0162 }, /* LATIN CAPITAL LETTER T WITH CEDILLA */
+ { "Tcommaaccent" DUP2, 0x021A }, /* LATIN CAPITAL LETTER T WITH COMMA BELOW;Duplicate */
+ { "Theta", 0x0398 }, /* GREEK CAPITAL LETTER THETA */
+ { "Thorn", 0x00DE }, /* LATIN CAPITAL LETTER THORN */
+ { "Thornsmall", 0xF7FE }, /* LATIN SMALL CAPITAL LETTER THORN */
+ { "Tildesmall", 0xF6FE }, /* SMALL CAPITAL SMALL TILDE */
+ { "Tsmall", 0xF774 }, /* LATIN SMALL CAPITAL LETTER T */
+ { "U", 0x0055 }, /* LATIN CAPITAL LETTER U */
+ { "Uacute", 0x00DA }, /* LATIN CAPITAL LETTER U WITH ACUTE */
+ { "Uacutesmall", 0xF7FA }, /* LATIN SMALL CAPITAL LETTER U WITH ACUTE */
+ { "Ubreve", 0x016C }, /* LATIN CAPITAL LETTER U WITH BREVE */
+ { "Ucircumflex", 0x00DB }, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+ { "Ucircumflexsmall", 0xF7FB }, /* LATIN SMALL CAPITAL LETTER U WITH CIRCUMFLEX */
+ { "Udieresis", 0x00DC }, /* LATIN CAPITAL LETTER U WITH DIAERESIS */
+ { "Udieresissmall", 0xF7FC }, /* LATIN SMALL CAPITAL LETTER U WITH DIAERESIS */
+ { "Ugrave", 0x00D9 }, /* LATIN CAPITAL LETTER U WITH GRAVE */
+ { "Ugravesmall", 0xF7F9 }, /* LATIN SMALL CAPITAL LETTER U WITH GRAVE */
+ { "Uhorn", 0x01AF }, /* LATIN CAPITAL LETTER U WITH HORN */
+ { "Uhungarumlaut", 0x0170 }, /* LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+ { "Umacron", 0x016A }, /* LATIN CAPITAL LETTER U WITH MACRON */
+ { "Uogonek", 0x0172 }, /* LATIN CAPITAL LETTER U WITH OGONEK */
+ { "Upsilon", 0x03A5 }, /* GREEK CAPITAL LETTER UPSILON */
+ { "Upsilon1", 0x03D2 }, /* GREEK UPSILON WITH HOOK SYMBOL */
+ { "Upsilondieresis", 0x03AB }, /* GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+ { "Upsilontonos", 0x038E }, /* GREEK CAPITAL LETTER UPSILON WITH TONOS */
+ { "Uring", 0x016E }, /* LATIN CAPITAL LETTER U WITH RING ABOVE */
+ { "Usmall", 0xF775 }, /* LATIN SMALL CAPITAL LETTER U */
+ { "Utilde", 0x0168 }, /* LATIN CAPITAL LETTER U WITH TILDE */
+ { "V", 0x0056 }, /* LATIN CAPITAL LETTER V */
+ { "Vsmall", 0xF776 }, /* LATIN SMALL CAPITAL LETTER V */
+ { "W", 0x0057 }, /* LATIN CAPITAL LETTER W */
+ { "Wacute", 0x1E82 }, /* LATIN CAPITAL LETTER W WITH ACUTE */
+ { "Wcircumflex", 0x0174 }, /* LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
+ { "Wdieresis", 0x1E84 }, /* LATIN CAPITAL LETTER W WITH DIAERESIS */
+ { "Wgrave", 0x1E80 }, /* LATIN CAPITAL LETTER W WITH GRAVE */
+ { "Wsmall", 0xF777 }, /* LATIN SMALL CAPITAL LETTER W */
+ { "X", 0x0058 }, /* LATIN CAPITAL LETTER X */
+ { "Xi", 0x039E }, /* GREEK CAPITAL LETTER XI */
+ { "Xsmall", 0xF778 }, /* LATIN SMALL CAPITAL LETTER X */
+ { "Y", 0x0059 }, /* LATIN CAPITAL LETTER Y */
+ { "Yacute", 0x00DD }, /* LATIN CAPITAL LETTER Y WITH ACUTE */
+ { "Yacutesmall", 0xF7FD }, /* LATIN SMALL CAPITAL LETTER Y WITH ACUTE */
+ { "Ycircumflex", 0x0176 }, /* LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
+ { "Ydieresis", 0x0178 }, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
+ { "Ydieresissmall", 0xF7FF }, /* LATIN SMALL CAPITAL LETTER Y WITH DIAERESIS */
+ { "Ygrave", 0x1EF2 }, /* LATIN CAPITAL LETTER Y WITH GRAVE */
+ { "Ysmall", 0xF779 }, /* LATIN SMALL CAPITAL LETTER Y */
+ { "Z", 0x005A }, /* LATIN CAPITAL LETTER Z */
+ { "Zacute", 0x0179 }, /* LATIN CAPITAL LETTER Z WITH ACUTE */
+ { "Zcaron", 0x017D }, /* LATIN CAPITAL LETTER Z WITH CARON */
+ { "Zcaronsmall", 0xF6FF }, /* LATIN SMALL CAPITAL LETTER Z WITH CARON */
+ { "Zdotaccent", 0x017B }, /* LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+ { "Zeta", 0x0396 }, /* GREEK CAPITAL LETTER ZETA */
+ { "Zsmall", 0xF77A }, /* LATIN SMALL CAPITAL LETTER Z */
+ { "a", 0x0061 }, /* LATIN SMALL LETTER A */
+ { "aacute", 0x00E1 }, /* LATIN SMALL LETTER A WITH ACUTE */
+ { "abreve", 0x0103 }, /* LATIN SMALL LETTER A WITH BREVE */
+ { "acircumflex", 0x00E2 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
+ { "acute", 0x00B4 }, /* ACUTE ACCENT */
+ { "acutecomb", 0x0301 }, /* COMBINING ACUTE ACCENT */
+ { "adieresis", 0x00E4 }, /* LATIN SMALL LETTER A WITH DIAERESIS */
+ { "ae", 0x00E6 }, /* LATIN SMALL LETTER AE */
+ { "aeacute", 0x01FD }, /* LATIN SMALL LETTER AE WITH ACUTE */
+ { "afii00208", 0x2015 }, /* HORIZONTAL BAR */
+ { "afii10017", 0x0410 }, /* CYRILLIC CAPITAL LETTER A */
+ { "afii10018", 0x0411 }, /* CYRILLIC CAPITAL LETTER BE */
+ { "afii10019", 0x0412 }, /* CYRILLIC CAPITAL LETTER VE */
+ { "afii10020", 0x0413 }, /* CYRILLIC CAPITAL LETTER GHE */
+ { "afii10021", 0x0414 }, /* CYRILLIC CAPITAL LETTER DE */
+ { "afii10022", 0x0415 }, /* CYRILLIC CAPITAL LETTER IE */
+ { "afii10023", 0x0401 }, /* CYRILLIC CAPITAL LETTER IO */
+ { "afii10024", 0x0416 }, /* CYRILLIC CAPITAL LETTER ZHE */
+ { "afii10025", 0x0417 }, /* CYRILLIC CAPITAL LETTER ZE */
+ { "afii10026", 0x0418 }, /* CYRILLIC CAPITAL LETTER I */
+ { "afii10027", 0x0419 }, /* CYRILLIC CAPITAL LETTER SHORT I */
+ { "afii10028", 0x041A }, /* CYRILLIC CAPITAL LETTER KA */
+ { "afii10029", 0x041B }, /* CYRILLIC CAPITAL LETTER EL */
+ { "afii10030", 0x041C }, /* CYRILLIC CAPITAL LETTER EM */
+ { "afii10031", 0x041D }, /* CYRILLIC CAPITAL LETTER EN */
+ { "afii10032", 0x041E }, /* CYRILLIC CAPITAL LETTER O */
+ { "afii10033", 0x041F }, /* CYRILLIC CAPITAL LETTER PE */
+ { "afii10034", 0x0420 }, /* CYRILLIC CAPITAL LETTER ER */
+ { "afii10035", 0x0421 }, /* CYRILLIC CAPITAL LETTER ES */
+ { "afii10036", 0x0422 }, /* CYRILLIC CAPITAL LETTER TE */
+ { "afii10037", 0x0423 }, /* CYRILLIC CAPITAL LETTER U */
+ { "afii10038", 0x0424 }, /* CYRILLIC CAPITAL LETTER EF */
+ { "afii10039", 0x0425 }, /* CYRILLIC CAPITAL LETTER HA */
+ { "afii10040", 0x0426 }, /* CYRILLIC CAPITAL LETTER TSE */
+ { "afii10041", 0x0427 }, /* CYRILLIC CAPITAL LETTER CHE */
+ { "afii10042", 0x0428 }, /* CYRILLIC CAPITAL LETTER SHA */
+ { "afii10043", 0x0429 }, /* CYRILLIC CAPITAL LETTER SHCHA */
+ { "afii10044", 0x042A }, /* CYRILLIC CAPITAL LETTER HARD SIGN */
+ { "afii10045", 0x042B }, /* CYRILLIC CAPITAL LETTER YERU */
+ { "afii10046", 0x042C }, /* CYRILLIC CAPITAL LETTER SOFT SIGN */
+ { "afii10047", 0x042D }, /* CYRILLIC CAPITAL LETTER E */
+ { "afii10048", 0x042E }, /* CYRILLIC CAPITAL LETTER YU */
+ { "afii10049", 0x042F }, /* CYRILLIC CAPITAL LETTER YA */
+ { "afii10050", 0x0490 }, /* CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
+ { "afii10051", 0x0402 }, /* CYRILLIC CAPITAL LETTER DJE */
+ { "afii10052", 0x0403 }, /* CYRILLIC CAPITAL LETTER GJE */
+ { "afii10053", 0x0404 }, /* CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+ { "afii10054", 0x0405 }, /* CYRILLIC CAPITAL LETTER DZE */
+ { "afii10055", 0x0406 }, /* CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { "afii10056", 0x0407 }, /* CYRILLIC CAPITAL LETTER YI */
+ { "afii10057", 0x0408 }, /* CYRILLIC CAPITAL LETTER JE */
+ { "afii10058", 0x0409 }, /* CYRILLIC CAPITAL LETTER LJE */
+ { "afii10059", 0x040A }, /* CYRILLIC CAPITAL LETTER NJE */
+ { "afii10060", 0x040B }, /* CYRILLIC CAPITAL LETTER TSHE */
+ { "afii10061", 0x040C }, /* CYRILLIC CAPITAL LETTER KJE */
+ { "afii10062", 0x040E }, /* CYRILLIC CAPITAL LETTER SHORT U */
+ { "afii10063", 0xF6C4 }, /* CYRILLIC SMALL LETTER GHE VARIANT */
+ { "afii10064", 0xF6C5 }, /* CYRILLIC SMALL LETTER BE VARIANT */
+ { "afii10065", 0x0430 }, /* CYRILLIC SMALL LETTER A */
+ { "afii10066", 0x0431 }, /* CYRILLIC SMALL LETTER BE */
+ { "afii10067", 0x0432 }, /* CYRILLIC SMALL LETTER VE */
+ { "afii10068", 0x0433 }, /* CYRILLIC SMALL LETTER GHE */
+ { "afii10069", 0x0434 }, /* CYRILLIC SMALL LETTER DE */
+ { "afii10070", 0x0435 }, /* CYRILLIC SMALL LETTER IE */
+ { "afii10071", 0x0451 }, /* CYRILLIC SMALL LETTER IO */
+ { "afii10072", 0x0436 }, /* CYRILLIC SMALL LETTER ZHE */
+ { "afii10073", 0x0437 }, /* CYRILLIC SMALL LETTER ZE */
+ { "afii10074", 0x0438 }, /* CYRILLIC SMALL LETTER I */
+ { "afii10075", 0x0439 }, /* CYRILLIC SMALL LETTER SHORT I */
+ { "afii10076", 0x043A }, /* CYRILLIC SMALL LETTER KA */
+ { "afii10077", 0x043B }, /* CYRILLIC SMALL LETTER EL */
+ { "afii10078", 0x043C }, /* CYRILLIC SMALL LETTER EM */
+ { "afii10079", 0x043D }, /* CYRILLIC SMALL LETTER EN */
+ { "afii10080", 0x043E }, /* CYRILLIC SMALL LETTER O */
+ { "afii10081", 0x043F }, /* CYRILLIC SMALL LETTER PE */
+ { "afii10082", 0x0440 }, /* CYRILLIC SMALL LETTER ER */
+ { "afii10083", 0x0441 }, /* CYRILLIC SMALL LETTER ES */
+ { "afii10084", 0x0442 }, /* CYRILLIC SMALL LETTER TE */
+ { "afii10085", 0x0443 }, /* CYRILLIC SMALL LETTER U */
+ { "afii10086", 0x0444 }, /* CYRILLIC SMALL LETTER EF */
+ { "afii10087", 0x0445 }, /* CYRILLIC SMALL LETTER HA */
+ { "afii10088", 0x0446 }, /* CYRILLIC SMALL LETTER TSE */
+ { "afii10089", 0x0447 }, /* CYRILLIC SMALL LETTER CHE */
+ { "afii10090", 0x0448 }, /* CYRILLIC SMALL LETTER SHA */
+ { "afii10091", 0x0449 }, /* CYRILLIC SMALL LETTER SHCHA */
+ { "afii10092", 0x044A }, /* CYRILLIC SMALL LETTER HARD SIGN */
+ { "afii10093", 0x044B }, /* CYRILLIC SMALL LETTER YERU */
+ { "afii10094", 0x044C }, /* CYRILLIC SMALL LETTER SOFT SIGN */
+ { "afii10095", 0x044D }, /* CYRILLIC SMALL LETTER E */
+ { "afii10096", 0x044E }, /* CYRILLIC SMALL LETTER YU */
+ { "afii10097", 0x044F }, /* CYRILLIC SMALL LETTER YA */
+ { "afii10098", 0x0491 }, /* CYRILLIC SMALL LETTER GHE WITH UPTURN */
+ { "afii10099", 0x0452 }, /* CYRILLIC SMALL LETTER DJE */
+ { "afii10100", 0x0453 }, /* CYRILLIC SMALL LETTER GJE */
+ { "afii10101", 0x0454 }, /* CYRILLIC SMALL LETTER UKRAINIAN IE */
+ { "afii10102", 0x0455 }, /* CYRILLIC SMALL LETTER DZE */
+ { "afii10103", 0x0456 }, /* CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { "afii10104", 0x0457 }, /* CYRILLIC SMALL LETTER YI */
+ { "afii10105", 0x0458 }, /* CYRILLIC SMALL LETTER JE */
+ { "afii10106", 0x0459 }, /* CYRILLIC SMALL LETTER LJE */
+ { "afii10107", 0x045A }, /* CYRILLIC SMALL LETTER NJE */
+ { "afii10108", 0x045B }, /* CYRILLIC SMALL LETTER TSHE */
+ { "afii10109", 0x045C }, /* CYRILLIC SMALL LETTER KJE */
+ { "afii10110", 0x045E }, /* CYRILLIC SMALL LETTER SHORT U */
+ { "afii10145", 0x040F }, /* CYRILLIC CAPITAL LETTER DZHE */
+ { "afii10146", 0x0462 }, /* CYRILLIC CAPITAL LETTER YAT */
+ { "afii10147", 0x0472 }, /* CYRILLIC CAPITAL LETTER FITA */
+ { "afii10148", 0x0474 }, /* CYRILLIC CAPITAL LETTER IZHITSA */
+ { "afii10192", 0xF6C6 }, /* CYRILLIC SMALL LETTER DE VARIANT */
+ { "afii10193", 0x045F }, /* CYRILLIC SMALL LETTER DZHE */
+ { "afii10194", 0x0463 }, /* CYRILLIC SMALL LETTER YAT */
+ { "afii10195", 0x0473 }, /* CYRILLIC SMALL LETTER FITA */
+ { "afii10196", 0x0475 }, /* CYRILLIC SMALL LETTER IZHITSA */
+ { "afii10831", 0xF6C7 }, /* CYRILLIC SMALL LETTER PE VARIANT */
+ { "afii10832", 0xF6C8 }, /* CYRILLIC SMALL LETTER TE VARIANT */
+ { "afii10846", 0x04D9 }, /* CYRILLIC SMALL LETTER SCHWA */
+ { "afii299", 0x200E }, /* LEFT-TO-RIGHT MARK */
+ { "afii300", 0x200F }, /* RIGHT-TO-LEFT MARK */
+ { "afii301", 0x200D }, /* ZERO WIDTH JOINER */
+ { "afii57381", 0x066A }, /* ARABIC PERCENT SIGN */
+ { "afii57388", 0x060C }, /* ARABIC COMMA */
+ { "afii57392", 0x0660 }, /* ARABIC-INDIC DIGIT ZERO */
+ { "afii57393", 0x0661 }, /* ARABIC-INDIC DIGIT ONE */
+ { "afii57394", 0x0662 }, /* ARABIC-INDIC DIGIT TWO */
+ { "afii57395", 0x0663 }, /* ARABIC-INDIC DIGIT THREE */
+ { "afii57396", 0x0664 }, /* ARABIC-INDIC DIGIT FOUR */
+ { "afii57397", 0x0665 }, /* ARABIC-INDIC DIGIT FIVE */
+ { "afii57398", 0x0666 }, /* ARABIC-INDIC DIGIT SIX */
+ { "afii57399", 0x0667 }, /* ARABIC-INDIC DIGIT SEVEN */
+ { "afii57400", 0x0668 }, /* ARABIC-INDIC DIGIT EIGHT */
+ { "afii57401", 0x0669 }, /* ARABIC-INDIC DIGIT NINE */
+ { "afii57403", 0x061B }, /* ARABIC SEMICOLON */
+ { "afii57407", 0x061F }, /* ARABIC QUESTION MARK */
+ { "afii57409", 0x0621 }, /* ARABIC LETTER HAMZA */
+ { "afii57410", 0x0622 }, /* ARABIC LETTER ALEF WITH MADDA ABOVE */
+ { "afii57411", 0x0623 }, /* ARABIC LETTER ALEF WITH HAMZA ABOVE */
+ { "afii57412", 0x0624 }, /* ARABIC LETTER WAW WITH HAMZA ABOVE */
+ { "afii57413", 0x0625 }, /* ARABIC LETTER ALEF WITH HAMZA BELOW */
+ { "afii57414", 0x0626 }, /* ARABIC LETTER YEH WITH HAMZA ABOVE */
+ { "afii57415", 0x0627 }, /* ARABIC LETTER ALEF */
+ { "afii57416", 0x0628 }, /* ARABIC LETTER BEH */
+ { "afii57417", 0x0629 }, /* ARABIC LETTER TEH MARBUTA */
+ { "afii57418", 0x062A }, /* ARABIC LETTER TEH */
+ { "afii57419", 0x062B }, /* ARABIC LETTER THEH */
+ { "afii57420", 0x062C }, /* ARABIC LETTER JEEM */
+ { "afii57421", 0x062D }, /* ARABIC LETTER HAH */
+ { "afii57422", 0x062E }, /* ARABIC LETTER KHAH */
+ { "afii57423", 0x062F }, /* ARABIC LETTER DAL */
+ { "afii57424", 0x0630 }, /* ARABIC LETTER THAL */
+ { "afii57425", 0x0631 }, /* ARABIC LETTER REH */
+ { "afii57426", 0x0632 }, /* ARABIC LETTER ZAIN */
+ { "afii57427", 0x0633 }, /* ARABIC LETTER SEEN */
+ { "afii57428", 0x0634 }, /* ARABIC LETTER SHEEN */
+ { "afii57429", 0x0635 }, /* ARABIC LETTER SAD */
+ { "afii57430", 0x0636 }, /* ARABIC LETTER DAD */
+ { "afii57431", 0x0637 }, /* ARABIC LETTER TAH */
+ { "afii57432", 0x0638 }, /* ARABIC LETTER ZAH */
+ { "afii57433", 0x0639 }, /* ARABIC LETTER AIN */
+ { "afii57434", 0x063A }, /* ARABIC LETTER GHAIN */
+ { "afii57440", 0x0640 }, /* ARABIC TATWEEL */
+ { "afii57441", 0x0641 }, /* ARABIC LETTER FEH */
+ { "afii57442", 0x0642 }, /* ARABIC LETTER QAF */
+ { "afii57443", 0x0643 }, /* ARABIC LETTER KAF */
+ { "afii57444", 0x0644 }, /* ARABIC LETTER LAM */
+ { "afii57445", 0x0645 }, /* ARABIC LETTER MEEM */
+ { "afii57446", 0x0646 }, /* ARABIC LETTER NOON */
+ { "afii57448", 0x0648 }, /* ARABIC LETTER WAW */
+ { "afii57449", 0x0649 }, /* ARABIC LETTER ALEF MAKSURA */
+ { "afii57450", 0x064A }, /* ARABIC LETTER YEH */
+ { "afii57451", 0x064B }, /* ARABIC FATHATAN */
+ { "afii57452", 0x064C }, /* ARABIC DAMMATAN */
+ { "afii57453", 0x064D }, /* ARABIC KASRATAN */
+ { "afii57454", 0x064E }, /* ARABIC FATHA */
+ { "afii57455", 0x064F }, /* ARABIC DAMMA */
+ { "afii57456", 0x0650 }, /* ARABIC KASRA */
+ { "afii57457", 0x0651 }, /* ARABIC SHADDA */
+ { "afii57458", 0x0652 }, /* ARABIC SUKUN */
+ { "afii57470", 0x0647 }, /* ARABIC LETTER HEH */
+ { "afii57505", 0x06A4 }, /* ARABIC LETTER VEH */
+ { "afii57506", 0x067E }, /* ARABIC LETTER PEH */
+ { "afii57507", 0x0686 }, /* ARABIC LETTER TCHEH */
+ { "afii57508", 0x0698 }, /* ARABIC LETTER JEH */
+ { "afii57509", 0x06AF }, /* ARABIC LETTER GAF */
+ { "afii57511", 0x0679 }, /* ARABIC LETTER TTEH */
+ { "afii57512", 0x0688 }, /* ARABIC LETTER DDAL */
+ { "afii57513", 0x0691 }, /* ARABIC LETTER RREH */
+ { "afii57514", 0x06BA }, /* ARABIC LETTER NOON GHUNNA */
+ { "afii57519", 0x06D2 }, /* ARABIC LETTER YEH BARREE */
+ { "afii57534", 0x06D5 }, /* ARABIC LETTER AE */
+ { "afii57636", 0x20AA }, /* NEW SHEQEL SIGN */
+ { "afii57645", 0x05BE }, /* HEBREW PUNCTUATION MAQAF */
+ { "afii57658", 0x05C3 }, /* HEBREW PUNCTUATION SOF PASUQ */
+ { "afii57664", 0x05D0 }, /* HEBREW LETTER ALEF */
+ { "afii57665", 0x05D1 }, /* HEBREW LETTER BET */
+ { "afii57666", 0x05D2 }, /* HEBREW LETTER GIMEL */
+ { "afii57667", 0x05D3 }, /* HEBREW LETTER DALET */
+ { "afii57668", 0x05D4 }, /* HEBREW LETTER HE */
+ { "afii57669", 0x05D5 }, /* HEBREW LETTER VAV */
+ { "afii57670", 0x05D6 }, /* HEBREW LETTER ZAYIN */
+ { "afii57671", 0x05D7 }, /* HEBREW LETTER HET */
+ { "afii57672", 0x05D8 }, /* HEBREW LETTER TET */
+ { "afii57673", 0x05D9 }, /* HEBREW LETTER YOD */
+ { "afii57674", 0x05DA }, /* HEBREW LETTER FINAL KAF */
+ { "afii57675", 0x05DB }, /* HEBREW LETTER KAF */
+ { "afii57676", 0x05DC }, /* HEBREW LETTER LAMED */
+ { "afii57677", 0x05DD }, /* HEBREW LETTER FINAL MEM */
+ { "afii57678", 0x05DE }, /* HEBREW LETTER MEM */
+ { "afii57679", 0x05DF }, /* HEBREW LETTER FINAL NUN */
+ { "afii57680", 0x05E0 }, /* HEBREW LETTER NUN */
+ { "afii57681", 0x05E1 }, /* HEBREW LETTER SAMEKH */
+ { "afii57682", 0x05E2 }, /* HEBREW LETTER AYIN */
+ { "afii57683", 0x05E3 }, /* HEBREW LETTER FINAL PE */
+ { "afii57684", 0x05E4 }, /* HEBREW LETTER PE */
+ { "afii57685", 0x05E5 }, /* HEBREW LETTER FINAL TSADI */
+ { "afii57686", 0x05E6 }, /* HEBREW LETTER TSADI */
+ { "afii57687", 0x05E7 }, /* HEBREW LETTER QOF */
+ { "afii57688", 0x05E8 }, /* HEBREW LETTER RESH */
+ { "afii57689", 0x05E9 }, /* HEBREW LETTER SHIN */
+ { "afii57690", 0x05EA }, /* HEBREW LETTER TAV */
+ { "afii57694", 0xFB2A }, /* HEBREW LETTER SHIN WITH SHIN DOT */
+ { "afii57695", 0xFB2B }, /* HEBREW LETTER SHIN WITH SIN DOT */
+ { "afii57700", 0xFB4B }, /* HEBREW LETTER VAV WITH HOLAM */
+ { "afii57705", 0xFB1F }, /* HEBREW LIGATURE YIDDISH YOD YOD PATAH */
+ { "afii57716", 0x05F0 }, /* HEBREW LIGATURE YIDDISH DOUBLE VAV */
+ { "afii57717", 0x05F1 }, /* HEBREW LIGATURE YIDDISH VAV YOD */
+ { "afii57718", 0x05F2 }, /* HEBREW LIGATURE YIDDISH DOUBLE YOD */
+ { "afii57723", 0xFB35 }, /* HEBREW LETTER VAV WITH DAGESH */
+ { "afii57793", 0x05B4 }, /* HEBREW POINT HIRIQ */
+ { "afii57794", 0x05B5 }, /* HEBREW POINT TSERE */
+ { "afii57795", 0x05B6 }, /* HEBREW POINT SEGOL */
+ { "afii57796", 0x05BB }, /* HEBREW POINT QUBUTS */
+ { "afii57797", 0x05B8 }, /* HEBREW POINT QAMATS */
+ { "afii57798", 0x05B7 }, /* HEBREW POINT PATAH */
+ { "afii57799", 0x05B0 }, /* HEBREW POINT SHEVA */
+ { "afii57800", 0x05B2 }, /* HEBREW POINT HATAF PATAH */
+ { "afii57801", 0x05B1 }, /* HEBREW POINT HATAF SEGOL */
+ { "afii57802", 0x05B3 }, /* HEBREW POINT HATAF QAMATS */
+ { "afii57803", 0x05C2 }, /* HEBREW POINT SIN DOT */
+ { "afii57804", 0x05C1 }, /* HEBREW POINT SHIN DOT */
+ { "afii57806", 0x05B9 }, /* HEBREW POINT HOLAM */
+ { "afii57807", 0x05BC }, /* HEBREW POINT DAGESH OR MAPIQ */
+ { "afii57839", 0x05BD }, /* HEBREW POINT METEG */
+ { "afii57841", 0x05BF }, /* HEBREW POINT RAFE */
+ { "afii57842", 0x05C0 }, /* HEBREW PUNCTUATION PASEQ */
+ { "afii57929", 0x02BC }, /* MODIFIER LETTER APOSTROPHE */
+ { "afii61248", 0x2105 }, /* CARE OF */
+ { "afii61289", 0x2113 }, /* SCRIPT SMALL L */
+ { "afii61352", 0x2116 }, /* NUMERO SIGN */
+ { "afii61573", 0x202C }, /* POP DIRECTIONAL FORMATTING */
+ { "afii61574", 0x202D }, /* LEFT-TO-RIGHT OVERRIDE */
+ { "afii61575", 0x202E }, /* RIGHT-TO-LEFT OVERRIDE */
+ { "afii61664", 0x200C }, /* ZERO WIDTH NON-JOINER */
+ { "afii63167", 0x066D }, /* ARABIC FIVE POINTED STAR */
+ { "afii64937", 0x02BD }, /* MODIFIER LETTER REVERSED COMMA */
+ { "agrave", 0x00E0 }, /* LATIN SMALL LETTER A WITH GRAVE */
+ { "aleph", 0x2135 }, /* ALEF SYMBOL */
+ { "alpha", 0x03B1 }, /* GREEK SMALL LETTER ALPHA */
+ { "alphatonos", 0x03AC }, /* GREEK SMALL LETTER ALPHA WITH TONOS */
+ { "amacron", 0x0101 }, /* LATIN SMALL LETTER A WITH MACRON */
+ { "ampersand", 0x0026 }, /* AMPERSAND */
+ { "ampersandsmall", 0xF726 }, /* SMALL CAPITAL AMPERSAND */
+ { "angle", 0x2220 }, /* ANGLE */
+ { "angleleft", 0x2329 }, /* LEFT-POINTING ANGLE BRACKET */
+ { "angleright", 0x232A }, /* RIGHT-POINTING ANGLE BRACKET */
+ { "anoteleia", 0x0387 }, /* GREEK ANO TELEIA */
+ { "aogonek", 0x0105 }, /* LATIN SMALL LETTER A WITH OGONEK */
+ { "approxequal", 0x2248 }, /* ALMOST EQUAL TO */
+ { "aring", 0x00E5 }, /* LATIN SMALL LETTER A WITH RING ABOVE */
+ { "aringacute", 0x01FB }, /* LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE */
+ { "arrowboth", 0x2194 }, /* LEFT RIGHT ARROW */
+ { "arrowdblboth", 0x21D4 }, /* LEFT RIGHT DOUBLE ARROW */
+ { "arrowdbldown", 0x21D3 }, /* DOWNWARDS DOUBLE ARROW */
+ { "arrowdblleft", 0x21D0 }, /* LEFTWARDS DOUBLE ARROW */
+ { "arrowdblright", 0x21D2 }, /* RIGHTWARDS DOUBLE ARROW */
+ { "arrowdblup", 0x21D1 }, /* UPWARDS DOUBLE ARROW */
+ { "arrowdown", 0x2193 }, /* DOWNWARDS ARROW */
+ { "arrowhorizex", 0xF8E7 }, /* HORIZONTAL ARROW EXTENDER */
+ { "arrowleft", 0x2190 }, /* LEFTWARDS ARROW */
+ { "arrowright", 0x2192 }, /* RIGHTWARDS ARROW */
+ { "arrowup", 0x2191 }, /* UPWARDS ARROW */
+ { "arrowupdn", 0x2195 }, /* UP DOWN ARROW */
+ { "arrowupdnbse", 0x21A8 }, /* UP DOWN ARROW WITH BASE */
+ { "arrowvertex", 0xF8E6 }, /* VERTICAL ARROW EXTENDER */
+ { "asciicircum", 0x005E }, /* CIRCUMFLEX ACCENT */
+ { "asciitilde", 0x007E }, /* TILDE */
+ { "asterisk", 0x002A }, /* ASTERISK */
+ { "asteriskmath", 0x2217 }, /* ASTERISK OPERATOR */
+ { "asuperior", 0xF6E9 }, /* SUPERSCRIPT LATIN SMALL LETTER A */
+ { "at", 0x0040 }, /* COMMERCIAL AT */
+ { "atilde", 0x00E3 }, /* LATIN SMALL LETTER A WITH TILDE */
+ { "b", 0x0062 }, /* LATIN SMALL LETTER B */
+ { "backslash", 0x005C }, /* REVERSE SOLIDUS */
+ { "bar", 0x007C }, /* VERTICAL LINE */
+ { "beta", 0x03B2 }, /* GREEK SMALL LETTER BETA */
+ { "block", 0x2588 }, /* FULL BLOCK */
+ { "braceex", 0xF8F4 }, /* CURLY BRACKET EXTENDER */
+ { "braceleft", 0x007B }, /* LEFT CURLY BRACKET */
+ { "braceleftbt", 0xF8F3 }, /* LEFT CURLY BRACKET BOTTOM */
+ { "braceleftmid", 0xF8F2 }, /* LEFT CURLY BRACKET MID */
+ { "bracelefttp", 0xF8F1 }, /* LEFT CURLY BRACKET TOP */
+ { "braceright", 0x007D }, /* RIGHT CURLY BRACKET */
+ { "bracerightbt", 0xF8FE }, /* RIGHT CURLY BRACKET BOTTOM */
+ { "bracerightmid", 0xF8FD }, /* RIGHT CURLY BRACKET MID */
+ { "bracerighttp", 0xF8FC }, /* RIGHT CURLY BRACKET TOP */
+ { "bracketleft", 0x005B }, /* LEFT SQUARE BRACKET */
+ { "bracketleftbt", 0xF8F0 }, /* LEFT SQUARE BRACKET BOTTOM */
+ { "bracketleftex", 0xF8EF }, /* LEFT SQUARE BRACKET EXTENDER */
+ { "bracketlefttp", 0xF8EE }, /* LEFT SQUARE BRACKET TOP */
+ { "bracketright", 0x005D }, /* RIGHT SQUARE BRACKET */
+ { "bracketrightbt", 0xF8FB }, /* RIGHT SQUARE BRACKET BOTTOM */
+ { "bracketrightex", 0xF8FA }, /* RIGHT SQUARE BRACKET EXTENDER */
+ { "bracketrighttp", 0xF8F9 }, /* RIGHT SQUARE BRACKET TOP */
+ { "breve", 0x02D8 }, /* BREVE */
+ { "brokenbar", 0x00A6 }, /* BROKEN BAR */
+ { "bsuperior", 0xF6EA }, /* SUPERSCRIPT LATIN SMALL LETTER B */
+ { "bullet", 0x2022 }, /* BULLET */
+ { "c", 0x0063 }, /* LATIN SMALL LETTER C */
+ { "cacute", 0x0107 }, /* LATIN SMALL LETTER C WITH ACUTE */
+ { "caron", 0x02C7 }, /* CARON */
+ { "carriagereturn", 0x21B5 }, /* DOWNWARDS ARROW WITH CORNER LEFTWARDS */
+ { "ccaron", 0x010D }, /* LATIN SMALL LETTER C WITH CARON */
+ { "ccedilla", 0x00E7 }, /* LATIN SMALL LETTER C WITH CEDILLA */
+ { "ccircumflex", 0x0109 }, /* LATIN SMALL LETTER C WITH CIRCUMFLEX */
+ { "cdotaccent", 0x010B }, /* LATIN SMALL LETTER C WITH DOT ABOVE */
+ { "cedilla", 0x00B8 }, /* CEDILLA */
+ { "cent", 0x00A2 }, /* CENT SIGN */
+ { "centinferior", 0xF6DF }, /* SUBSCRIPT CENT SIGN */
+ { "centoldstyle", 0xF7A2 }, /* OLDSTYLE CENT SIGN */
+ { "centsuperior", 0xF6E0 }, /* SUPERSCRIPT CENT SIGN */
+ { "chi", 0x03C7 }, /* GREEK SMALL LETTER CHI */
+ { "circle", 0x25CB }, /* WHITE CIRCLE */
+ { "circlemultiply", 0x2297 }, /* CIRCLED TIMES */
+ { "circleplus", 0x2295 }, /* CIRCLED PLUS */
+ { "circumflex", 0x02C6 }, /* MODIFIER LETTER CIRCUMFLEX ACCENT */
+ { "club", 0x2663 }, /* BLACK CLUB SUIT */
+ { "colon", 0x003A }, /* COLON */
+ { "colonmonetary", 0x20A1 }, /* COLON SIGN */
+ { "comma", 0x002C }, /* COMMA */
+ { "commaaccent", 0xF6C3 }, /* COMMA BELOW */
+ { "commainferior", 0xF6E1 }, /* SUBSCRIPT COMMA */
+ { "commasuperior", 0xF6E2 }, /* SUPERSCRIPT COMMA */
+ { "congruent", 0x2245 }, /* APPROXIMATELY EQUAL TO */
+ { "copyright", 0x00A9 }, /* COPYRIGHT SIGN */
+ { "copyrightsans", 0xF8E9 }, /* COPYRIGHT SIGN SANS SERIF */
+ { "copyrightserif", 0xF6D9 }, /* COPYRIGHT SIGN SERIF */
+ { "currency", 0x00A4 }, /* CURRENCY SIGN */
+ { "cyrBreve", 0xF6D1 }, /* CAPITAL CYRILLIC BREVE */
+ { "cyrFlex", 0xF6D2 }, /* CAPITAL CYRILLIC CIRCUMFLEX */
+ { "cyrbreve", 0xF6D4 }, /* CYRILLIC BREVE */
+ { "cyrflex", 0xF6D5 }, /* CYRILLIC CIRCUMFLEX */
+ { "d", 0x0064 }, /* LATIN SMALL LETTER D */
+ { "dagger", 0x2020 }, /* DAGGER */
+ { "daggerdbl", 0x2021 }, /* DOUBLE DAGGER */
+ { "dblGrave", 0xF6D3 }, /* CAPITAL DOUBLE GRAVE ACCENT */
+ { "dblgrave", 0xF6D6 }, /* DOUBLE GRAVE ACCENT */
+ { "dcaron", 0x010F }, /* LATIN SMALL LETTER D WITH CARON */
+ { "dcroat", 0x0111 }, /* LATIN SMALL LETTER D WITH STROKE */
+ { "degree", 0x00B0 }, /* DEGREE SIGN */
+ { "delta", 0x03B4 }, /* GREEK SMALL LETTER DELTA */
+ { "diamond", 0x2666 }, /* BLACK DIAMOND SUIT */
+ { "dieresis", 0x00A8 }, /* DIAERESIS */
+ { "dieresisacute", 0xF6D7 }, /* DIAERESIS ACUTE ACCENT */
+ { "dieresisgrave", 0xF6D8 }, /* DIAERESIS GRAVE ACCENT */
+ { "dieresistonos", 0x0385 }, /* GREEK DIALYTIKA TONOS */
+ { "divide", 0x00F7 }, /* DIVISION SIGN */
+ { "dkshade", 0x2593 }, /* DARK SHADE */
+ { "dnblock", 0x2584 }, /* LOWER HALF BLOCK */
+ { "dollar", 0x0024 }, /* DOLLAR SIGN */
+ { "dollarinferior", 0xF6E3 }, /* SUBSCRIPT DOLLAR SIGN */
+ { "dollaroldstyle", 0xF724 }, /* OLDSTYLE DOLLAR SIGN */
+ { "dollarsuperior", 0xF6E4 }, /* SUPERSCRIPT DOLLAR SIGN */
+ { "dong", 0x20AB }, /* DONG SIGN */
+ { "dotaccent", 0x02D9 }, /* DOT ABOVE */
+ { "dotbelowcomb", 0x0323 }, /* COMBINING DOT BELOW */
+ { "dotlessi", 0x0131 }, /* LATIN SMALL LETTER DOTLESS I */
+ { "dotlessj", 0xF6BE }, /* LATIN SMALL LETTER DOTLESS J */
+ { "dotmath", 0x22C5 }, /* DOT OPERATOR */
+ { "dsuperior", 0xF6EB }, /* SUPERSCRIPT LATIN SMALL LETTER D */
+ { "e", 0x0065 }, /* LATIN SMALL LETTER E */
+ { "eacute", 0x00E9 }, /* LATIN SMALL LETTER E WITH ACUTE */
+ { "ebreve", 0x0115 }, /* LATIN SMALL LETTER E WITH BREVE */
+ { "ecaron", 0x011B }, /* LATIN SMALL LETTER E WITH CARON */
+ { "ecircumflex", 0x00EA }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
+ { "edieresis", 0x00EB }, /* LATIN SMALL LETTER E WITH DIAERESIS */
+ { "edotaccent", 0x0117 }, /* LATIN SMALL LETTER E WITH DOT ABOVE */
+ { "egrave", 0x00E8 }, /* LATIN SMALL LETTER E WITH GRAVE */
+ { "eight", 0x0038 }, /* DIGIT EIGHT */
+ { "eightinferior", 0x2088 }, /* SUBSCRIPT EIGHT */
+ { "eightoldstyle", 0xF738 }, /* OLDSTYLE DIGIT EIGHT */
+ { "eightsuperior", 0x2078 }, /* SUPERSCRIPT EIGHT */
+ { "element", 0x2208 }, /* ELEMENT OF */
+ { "ellipsis", 0x2026 }, /* HORIZONTAL ELLIPSIS */
+ { "emacron", 0x0113 }, /* LATIN SMALL LETTER E WITH MACRON */
+ { "emdash", 0x2014 }, /* EM DASH */
+ { "emptyset", 0x2205 }, /* EMPTY SET */
+ { "endash", 0x2013 }, /* EN DASH */
+ { "eng", 0x014B }, /* LATIN SMALL LETTER ENG */
+ { "eogonek", 0x0119 }, /* LATIN SMALL LETTER E WITH OGONEK */
+ { "epsilon", 0x03B5 }, /* GREEK SMALL LETTER EPSILON */
+ { "epsilontonos", 0x03AD }, /* GREEK SMALL LETTER EPSILON WITH TONOS */
+ { "equal", 0x003D }, /* EQUALS SIGN */
+ { "equivalence", 0x2261 }, /* IDENTICAL TO */
+ { "estimated", 0x212E }, /* ESTIMATED SYMBOL */
+ { "esuperior", 0xF6EC }, /* SUPERSCRIPT LATIN SMALL LETTER E */
+ { "eta", 0x03B7 }, /* GREEK SMALL LETTER ETA */
+ { "etatonos", 0x03AE }, /* GREEK SMALL LETTER ETA WITH TONOS */
+ { "eth", 0x00F0 }, /* LATIN SMALL LETTER ETH */
+ { "exclam", 0x0021 }, /* EXCLAMATION MARK */
+ { "exclamdbl", 0x203C }, /* DOUBLE EXCLAMATION MARK */
+ { "exclamdown", 0x00A1 }, /* INVERTED EXCLAMATION MARK */
+ { "exclamdownsmall", 0xF7A1 }, /* SMALL CAPITAL INVERTED EXCLAMATION MARK */
+ { "exclamsmall", 0xF721 }, /* SMALL CAPITAL EXCLAMATION MARK */
+ { "existential", 0x2203 }, /* THERE EXISTS */
+ { "f", 0x0066 }, /* LATIN SMALL LETTER F */
+ { "female", 0x2640 }, /* FEMALE SIGN */
+ { "ff", 0xFB00 }, /* LATIN SMALL LIGATURE FF */
+ { "ffi", 0xFB03 }, /* LATIN SMALL LIGATURE FFI */
+ { "ffl", 0xFB04 }, /* LATIN SMALL LIGATURE FFL */
+ { "fi", 0xFB01 }, /* LATIN SMALL LIGATURE FI */
+ { "figuredash", 0x2012 }, /* FIGURE DASH */
+ { "filledbox", 0x25A0 }, /* BLACK SQUARE */
+ { "filledrect", 0x25AC }, /* BLACK RECTANGLE */
+ { "five", 0x0035 }, /* DIGIT FIVE */
+ { "fiveeighths", 0x215D }, /* VULGAR FRACTION FIVE EIGHTHS */
+ { "fiveinferior", 0x2085 }, /* SUBSCRIPT FIVE */
+ { "fiveoldstyle", 0xF735 }, /* OLDSTYLE DIGIT FIVE */
+ { "fivesuperior", 0x2075 }, /* SUPERSCRIPT FIVE */
+ { "fl", 0xFB02 }, /* LATIN SMALL LIGATURE FL */
+ { "florin", 0x0192 }, /* LATIN SMALL LETTER F WITH HOOK */
+ { "four", 0x0034 }, /* DIGIT FOUR */
+ { "fourinferior", 0x2084 }, /* SUBSCRIPT FOUR */
+ { "fouroldstyle", 0xF734 }, /* OLDSTYLE DIGIT FOUR */
+ { "foursuperior", 0x2074 }, /* SUPERSCRIPT FOUR */
+ { "fraction" DUP1, 0x2044 }, /* FRACTION SLASH */
+ { "fraction" DUP2, 0x2215 }, /* DIVISION SLASH;Duplicate */
+ { "franc", 0x20A3 }, /* FRENCH FRANC SIGN */
+ { "g", 0x0067 }, /* LATIN SMALL LETTER G */
+ { "gamma", 0x03B3 }, /* GREEK SMALL LETTER GAMMA */
+ { "gbreve", 0x011F }, /* LATIN SMALL LETTER G WITH BREVE */
+ { "gcaron", 0x01E7 }, /* LATIN SMALL LETTER G WITH CARON */
+ { "gcircumflex", 0x011D }, /* LATIN SMALL LETTER G WITH CIRCUMFLEX */
+ { "gcommaaccent", 0x0123 }, /* LATIN SMALL LETTER G WITH CEDILLA */
+ { "gdotaccent", 0x0121 }, /* LATIN SMALL LETTER G WITH DOT ABOVE */
+ { "germandbls", 0x00DF }, /* LATIN SMALL LETTER SHARP S */
+ { "gradient", 0x2207 }, /* NABLA */
+ { "grave", 0x0060 }, /* GRAVE ACCENT */
+ { "gravecomb", 0x0300 }, /* COMBINING GRAVE ACCENT */
+ { "greater", 0x003E }, /* GREATER-THAN SIGN */
+ { "greaterequal", 0x2265 }, /* GREATER-THAN OR EQUAL TO */
+ { "guillemotleft", 0x00AB }, /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
+ { "guillemotright", 0x00BB }, /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
+ { "guilsinglleft", 0x2039 }, /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
+ { "guilsinglright", 0x203A }, /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
+ { "h", 0x0068 }, /* LATIN SMALL LETTER H */
+ { "hbar", 0x0127 }, /* LATIN SMALL LETTER H WITH STROKE */
+ { "hcircumflex", 0x0125 }, /* LATIN SMALL LETTER H WITH CIRCUMFLEX */
+ { "heart", 0x2665 }, /* BLACK HEART SUIT */
+ { "hookabovecomb", 0x0309 }, /* COMBINING HOOK ABOVE */
+ { "house", 0x2302 }, /* HOUSE */
+ { "hungarumlaut", 0x02DD }, /* DOUBLE ACUTE ACCENT */
+ { "hyphen" DUP1, 0x002D }, /* HYPHEN-MINUS */
+ { "hyphen" DUP2, 0x00AD }, /* SOFT HYPHEN;Duplicate */
+ { "hypheninferior", 0xF6E5 }, /* SUBSCRIPT HYPHEN-MINUS */
+ { "hyphensuperior", 0xF6E6 }, /* SUPERSCRIPT HYPHEN-MINUS */
+ { "i", 0x0069 }, /* LATIN SMALL LETTER I */
+ { "iacute", 0x00ED }, /* LATIN SMALL LETTER I WITH ACUTE */
+ { "ibreve", 0x012D }, /* LATIN SMALL LETTER I WITH BREVE */
+ { "icircumflex", 0x00EE }, /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
+ { "idieresis", 0x00EF }, /* LATIN SMALL LETTER I WITH DIAERESIS */
+ { "igrave", 0x00EC }, /* LATIN SMALL LETTER I WITH GRAVE */
+ { "ij", 0x0133 }, /* LATIN SMALL LIGATURE IJ */
+ { "imacron", 0x012B }, /* LATIN SMALL LETTER I WITH MACRON */
+ { "infinity", 0x221E }, /* INFINITY */
+ { "integral", 0x222B }, /* INTEGRAL */
+ { "integralbt", 0x2321 }, /* BOTTOM HALF INTEGRAL */
+ { "integralex", 0xF8F5 }, /* INTEGRAL EXTENDER */
+ { "integraltp", 0x2320 }, /* TOP HALF INTEGRAL */
+ { "intersection", 0x2229 }, /* INTERSECTION */
+ { "invbullet", 0x25D8 }, /* INVERSE BULLET */
+ { "invcircle", 0x25D9 }, /* INVERSE WHITE CIRCLE */
+ { "invsmileface", 0x263B }, /* BLACK SMILING FACE */
+ { "iogonek", 0x012F }, /* LATIN SMALL LETTER I WITH OGONEK */
+ { "iota", 0x03B9 }, /* GREEK SMALL LETTER IOTA */
+ { "iotadieresis", 0x03CA }, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+ { "iotadieresistonos", 0x0390 }, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+ { "iotatonos", 0x03AF }, /* GREEK SMALL LETTER IOTA WITH TONOS */
+ { "isuperior", 0xF6ED }, /* SUPERSCRIPT LATIN SMALL LETTER I */
+ { "itilde", 0x0129 }, /* LATIN SMALL LETTER I WITH TILDE */
+ { "j", 0x006A }, /* LATIN SMALL LETTER J */
+ { "jcircumflex", 0x0135 }, /* LATIN SMALL LETTER J WITH CIRCUMFLEX */
+ { "k", 0x006B }, /* LATIN SMALL LETTER K */
+ { "kappa", 0x03BA }, /* GREEK SMALL LETTER KAPPA */
+ { "kcommaaccent", 0x0137 }, /* LATIN SMALL LETTER K WITH CEDILLA */
+ { "kgreenlandic", 0x0138 }, /* LATIN SMALL LETTER KRA */
+ { "l", 0x006C }, /* LATIN SMALL LETTER L */
+ { "lacute", 0x013A }, /* LATIN SMALL LETTER L WITH ACUTE */
+ { "lambda", 0x03BB }, /* GREEK SMALL LETTER LAMDA */
+ { "lcaron", 0x013E }, /* LATIN SMALL LETTER L WITH CARON */
+ { "lcommaaccent", 0x013C }, /* LATIN SMALL LETTER L WITH CEDILLA */
+ { "ldot", 0x0140 }, /* LATIN SMALL LETTER L WITH MIDDLE DOT */
+ { "less", 0x003C }, /* LESS-THAN SIGN */
+ { "lessequal", 0x2264 }, /* LESS-THAN OR EQUAL TO */
+ { "lfblock", 0x258C }, /* LEFT HALF BLOCK */
+ { "lira", 0x20A4 }, /* LIRA SIGN */
+ { "ll", 0xF6C0 }, /* LATIN SMALL LETTER LL */
+ { "logicaland", 0x2227 }, /* LOGICAL AND */
+ { "logicalnot", 0x00AC }, /* NOT SIGN */
+ { "logicalor", 0x2228 }, /* LOGICAL OR */
+ { "longs", 0x017F }, /* LATIN SMALL LETTER LONG S */
+ { "lozenge", 0x25CA }, /* LOZENGE */
+ { "lslash", 0x0142 }, /* LATIN SMALL LETTER L WITH STROKE */
+ { "lsuperior", 0xF6EE }, /* SUPERSCRIPT LATIN SMALL LETTER L */
+ { "ltshade", 0x2591 }, /* LIGHT SHADE */
+ { "m", 0x006D }, /* LATIN SMALL LETTER M */
+ { "macron" DUP1, 0x00AF }, /* MACRON */
+ { "macron" DUP2, 0x02C9 }, /* MODIFIER LETTER MACRON;Duplicate */
+ { "male", 0x2642 }, /* MALE SIGN */
+ { "minus", 0x2212 }, /* MINUS SIGN */
+ { "minute", 0x2032 }, /* PRIME */
+ { "msuperior", 0xF6EF }, /* SUPERSCRIPT LATIN SMALL LETTER M */
+ { "mu" DUP1, 0x00B5 }, /* MICRO SIGN */
+ { "mu" DUP2, 0x03BC }, /* GREEK SMALL LETTER MU;Duplicate */
+ { "multiply", 0x00D7 }, /* MULTIPLICATION SIGN */
+ { "musicalnote", 0x266A }, /* EIGHTH NOTE */
+ { "musicalnotedbl", 0x266B }, /* BEAMED EIGHTH NOTES */
+ { "n", 0x006E }, /* LATIN SMALL LETTER N */
+ { "nacute", 0x0144 }, /* LATIN SMALL LETTER N WITH ACUTE */
+ { "napostrophe", 0x0149 }, /* LATIN SMALL LETTER N PRECEDED BY APOSTROPHE */
+ { "ncaron", 0x0148 }, /* LATIN SMALL LETTER N WITH CARON */
+ { "ncommaaccent", 0x0146 }, /* LATIN SMALL LETTER N WITH CEDILLA */
+ { "nine", 0x0039 }, /* DIGIT NINE */
+ { "nineinferior", 0x2089 }, /* SUBSCRIPT NINE */
+ { "nineoldstyle", 0xF739 }, /* OLDSTYLE DIGIT NINE */
+ { "ninesuperior", 0x2079 }, /* SUPERSCRIPT NINE */
+ { "notelement", 0x2209 }, /* NOT AN ELEMENT OF */
+ { "notequal", 0x2260 }, /* NOT EQUAL TO */
+ { "notsubset", 0x2284 }, /* NOT A SUBSET OF */
+ { "nsuperior", 0x207F }, /* SUPERSCRIPT LATIN SMALL LETTER N */
+ { "ntilde", 0x00F1 }, /* LATIN SMALL LETTER N WITH TILDE */
+ { "nu", 0x03BD }, /* GREEK SMALL LETTER NU */
+ { "numbersign", 0x0023 }, /* NUMBER SIGN */
+ { "o", 0x006F }, /* LATIN SMALL LETTER O */
+ { "oacute", 0x00F3 }, /* LATIN SMALL LETTER O WITH ACUTE */
+ { "obreve", 0x014F }, /* LATIN SMALL LETTER O WITH BREVE */
+ { "ocircumflex", 0x00F4 }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
+ { "odieresis", 0x00F6 }, /* LATIN SMALL LETTER O WITH DIAERESIS */
+ { "oe", 0x0153 }, /* LATIN SMALL LIGATURE OE */
+ { "ogonek", 0x02DB }, /* OGONEK */
+ { "ograve", 0x00F2 }, /* LATIN SMALL LETTER O WITH GRAVE */
+ { "ohorn", 0x01A1 }, /* LATIN SMALL LETTER O WITH HORN */
+ { "ohungarumlaut", 0x0151 }, /* LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+ { "omacron", 0x014D }, /* LATIN SMALL LETTER O WITH MACRON */
+ { "omega", 0x03C9 }, /* GREEK SMALL LETTER OMEGA */
+ { "omega1", 0x03D6 }, /* GREEK PI SYMBOL */
+ { "omegatonos", 0x03CE }, /* GREEK SMALL LETTER OMEGA WITH TONOS */
+ { "omicron", 0x03BF }, /* GREEK SMALL LETTER OMICRON */
+ { "omicrontonos", 0x03CC }, /* GREEK SMALL LETTER OMICRON WITH TONOS */
+ { "one", 0x0031 }, /* DIGIT ONE */
+ { "onedotenleader", 0x2024 }, /* ONE DOT LEADER */
+ { "oneeighth", 0x215B }, /* VULGAR FRACTION ONE EIGHTH */
+ { "onefitted", 0xF6DC }, /* PROPORTIONAL DIGIT ONE */
+ { "onehalf", 0x00BD }, /* VULGAR FRACTION ONE HALF */
+ { "oneinferior", 0x2081 }, /* SUBSCRIPT ONE */
+ { "oneoldstyle", 0xF731 }, /* OLDSTYLE DIGIT ONE */
+ { "onequarter", 0x00BC }, /* VULGAR FRACTION ONE QUARTER */
+ { "onesuperior", 0x00B9 }, /* SUPERSCRIPT ONE */
+ { "onethird", 0x2153 }, /* VULGAR FRACTION ONE THIRD */
+ { "openbullet", 0x25E6 }, /* WHITE BULLET */
+ { "ordfeminine", 0x00AA }, /* FEMININE ORDINAL INDICATOR */
+ { "ordmasculine", 0x00BA }, /* MASCULINE ORDINAL INDICATOR */
+ { "orthogonal", 0x221F }, /* RIGHT ANGLE */
+ { "oslash", 0x00F8 }, /* LATIN SMALL LETTER O WITH STROKE */
+ { "oslashacute", 0x01FF }, /* LATIN SMALL LETTER O WITH STROKE AND ACUTE */
+ { "osuperior", 0xF6F0 }, /* SUPERSCRIPT LATIN SMALL LETTER O */
+ { "otilde", 0x00F5 }, /* LATIN SMALL LETTER O WITH TILDE */
+ { "p", 0x0070 }, /* LATIN SMALL LETTER P */
+ { "paragraph", 0x00B6 }, /* PILCROW SIGN */
+ { "parenleft", 0x0028 }, /* LEFT PARENTHESIS */
+ { "parenleftbt", 0xF8ED }, /* LEFT PAREN BOTTOM */
+ { "parenleftex", 0xF8EC }, /* LEFT PAREN EXTENDER */
+ { "parenleftinferior", 0x208D }, /* SUBSCRIPT LEFT PARENTHESIS */
+ { "parenleftsuperior", 0x207D }, /* SUPERSCRIPT LEFT PARENTHESIS */
+ { "parenlefttp", 0xF8EB }, /* LEFT PAREN TOP */
+ { "parenright", 0x0029 }, /* RIGHT PARENTHESIS */
+ { "parenrightbt", 0xF8F8 }, /* RIGHT PAREN BOTTOM */
+ { "parenrightex", 0xF8F7 }, /* RIGHT PAREN EXTENDER */
+ { "parenrightinferior", 0x208E }, /* SUBSCRIPT RIGHT PARENTHESIS */
+ { "parenrightsuperior", 0x207E }, /* SUPERSCRIPT RIGHT PARENTHESIS */
+ { "parenrighttp", 0xF8F6 }, /* RIGHT PAREN TOP */
+ { "partialdiff", 0x2202 }, /* PARTIAL DIFFERENTIAL */
+ { "percent", 0x0025 }, /* PERCENT SIGN */
+ { "period", 0x002E }, /* FULL STOP */
+ { "periodcentered" DUP1, 0x00B7 }, /* MIDDLE DOT */
+ { "periodcentered" DUP2, 0x2219 }, /* BULLET OPERATOR;Duplicate */
+ { "periodinferior", 0xF6E7 }, /* SUBSCRIPT FULL STOP */
+ { "periodsuperior", 0xF6E8 }, /* SUPERSCRIPT FULL STOP */
+ { "perpendicular", 0x22A5 }, /* UP TACK */
+ { "perthousand", 0x2030 }, /* PER MILLE SIGN */
+ { "peseta", 0x20A7 }, /* PESETA SIGN */
+ { "phi", 0x03C6 }, /* GREEK SMALL LETTER PHI */
+ { "phi1", 0x03D5 }, /* GREEK PHI SYMBOL */
+ { "pi", 0x03C0 }, /* GREEK SMALL LETTER PI */
+ { "plus", 0x002B }, /* PLUS SIGN */
+ { "plusminus", 0x00B1 }, /* PLUS-MINUS SIGN */
+ { "prescription", 0x211E }, /* PRESCRIPTION TAKE */
+ { "product", 0x220F }, /* N-ARY PRODUCT */
+ { "propersubset", 0x2282 }, /* SUBSET OF */
+ { "propersuperset", 0x2283 }, /* SUPERSET OF */
+ { "proportional", 0x221D }, /* PROPORTIONAL TO */
+ { "psi", 0x03C8 }, /* GREEK SMALL LETTER PSI */
+ { "q", 0x0071 }, /* LATIN SMALL LETTER Q */
+ { "question", 0x003F }, /* QUESTION MARK */
+ { "questiondown", 0x00BF }, /* INVERTED QUESTION MARK */
+ { "questiondownsmall", 0xF7BF }, /* SMALL CAPITAL INVERTED QUESTION MARK */
+ { "questionsmall", 0xF73F }, /* SMALL CAPITAL QUESTION MARK */
+ { "quotedbl", 0x0022 }, /* QUOTATION MARK */
+ { "quotedblbase", 0x201E }, /* DOUBLE LOW-9 QUOTATION MARK */
+ { "quotedblleft", 0x201C }, /* LEFT DOUBLE QUOTATION MARK */
+ { "quotedblright", 0x201D }, /* RIGHT DOUBLE QUOTATION MARK */
+ { "quoteleft", 0x2018 }, /* LEFT SINGLE QUOTATION MARK */
+ { "quotereversed", 0x201B }, /* SINGLE HIGH-REVERSED-9 QUOTATION MARK */
+ { "quoteright", 0x2019 }, /* RIGHT SINGLE QUOTATION MARK */
+ { "quotesinglbase", 0x201A }, /* SINGLE LOW-9 QUOTATION MARK */
+ { "quotesingle", 0x0027 }, /* APOSTROPHE */
+ { "r", 0x0072 }, /* LATIN SMALL LETTER R */
+ { "racute", 0x0155 }, /* LATIN SMALL LETTER R WITH ACUTE */
+ { "radical", 0x221A }, /* SQUARE ROOT */
+ { "radicalex", 0xF8E5 }, /* RADICAL EXTENDER */
+ { "rcaron", 0x0159 }, /* LATIN SMALL LETTER R WITH CARON */
+ { "rcommaaccent", 0x0157 }, /* LATIN SMALL LETTER R WITH CEDILLA */
+ { "reflexsubset", 0x2286 }, /* SUBSET OF OR EQUAL TO */
+ { "reflexsuperset", 0x2287 }, /* SUPERSET OF OR EQUAL TO */
+ { "registered", 0x00AE }, /* REGISTERED SIGN */
+ { "registersans", 0xF8E8 }, /* REGISTERED SIGN SANS SERIF */
+ { "registerserif", 0xF6DA }, /* REGISTERED SIGN SERIF */
+ { "revlogicalnot", 0x2310 }, /* REVERSED NOT SIGN */
+ { "rho", 0x03C1 }, /* GREEK SMALL LETTER RHO */
+ { "ring", 0x02DA }, /* RING ABOVE */
+ { "rsuperior", 0xF6F1 }, /* SUPERSCRIPT LATIN SMALL LETTER R */
+ { "rtblock", 0x2590 }, /* RIGHT HALF BLOCK */
+ { "rupiah", 0xF6DD }, /* RUPIAH SIGN */
+ { "s", 0x0073 }, /* LATIN SMALL LETTER S */
+ { "sacute", 0x015B }, /* LATIN SMALL LETTER S WITH ACUTE */
+ { "scaron", 0x0161 }, /* LATIN SMALL LETTER S WITH CARON */
+ { "scedilla" DUP1, 0x015F }, /* LATIN SMALL LETTER S WITH CEDILLA */
+ { "scedilla" DUP2, 0xF6C2 }, /* LATIN SMALL LETTER S WITH CEDILLA;Duplicate */
+ { "scircumflex", 0x015D }, /* LATIN SMALL LETTER S WITH CIRCUMFLEX */
+ { "scommaaccent", 0x0219 }, /* LATIN SMALL LETTER S WITH COMMA BELOW */
+ { "second", 0x2033 }, /* DOUBLE PRIME */
+ { "section", 0x00A7 }, /* SECTION SIGN */
+ { "semicolon", 0x003B }, /* SEMICOLON */
+ { "seven", 0x0037 }, /* DIGIT SEVEN */
+ { "seveneighths", 0x215E }, /* VULGAR FRACTION SEVEN EIGHTHS */
+ { "seveninferior", 0x2087 }, /* SUBSCRIPT SEVEN */
+ { "sevenoldstyle", 0xF737 }, /* OLDSTYLE DIGIT SEVEN */
+ { "sevensuperior", 0x2077 }, /* SUPERSCRIPT SEVEN */
+ { "shade", 0x2592 }, /* MEDIUM SHADE */
+ { "sigma", 0x03C3 }, /* GREEK SMALL LETTER SIGMA */
+ { "sigma1", 0x03C2 }, /* GREEK SMALL LETTER FINAL SIGMA */
+ { "similar", 0x223C }, /* TILDE OPERATOR */
+ { "six", 0x0036 }, /* DIGIT SIX */
+ { "sixinferior", 0x2086 }, /* SUBSCRIPT SIX */
+ { "sixoldstyle", 0xF736 }, /* OLDSTYLE DIGIT SIX */
+ { "sixsuperior", 0x2076 }, /* SUPERSCRIPT SIX */
+ { "slash", 0x002F }, /* SOLIDUS */
+ { "smileface", 0x263A }, /* WHITE SMILING FACE */
+ { "space" DUP1, 0x0020 }, /* SPACE */
+ { "space" DUP2, 0x00A0 }, /* NO-BREAK SPACE;Duplicate */
+ { "spade", 0x2660 }, /* BLACK SPADE SUIT */
+ { "ssuperior", 0xF6F2 }, /* SUPERSCRIPT LATIN SMALL LETTER S */
+ { "sterling", 0x00A3 }, /* POUND SIGN */
+ { "suchthat", 0x220B }, /* CONTAINS AS MEMBER */
+ { "summation", 0x2211 }, /* N-ARY SUMMATION */
+ { "sun", 0x263C }, /* WHITE SUN WITH RAYS */
+ { "t", 0x0074 }, /* LATIN SMALL LETTER T */
+ { "tau", 0x03C4 }, /* GREEK SMALL LETTER TAU */
+ { "tbar", 0x0167 }, /* LATIN SMALL LETTER T WITH STROKE */
+ { "tcaron", 0x0165 }, /* LATIN SMALL LETTER T WITH CARON */
+ { "tcommaaccent" DUP1, 0x0163 }, /* LATIN SMALL LETTER T WITH CEDILLA */
+ { "tcommaaccent" DUP2, 0x021B }, /* LATIN SMALL LETTER T WITH COMMA BELOW;Duplicate */
+ { "therefore", 0x2234 }, /* THEREFORE */
+ { "theta", 0x03B8 }, /* GREEK SMALL LETTER THETA */
+ { "theta1", 0x03D1 }, /* GREEK THETA SYMBOL */
+ { "thorn", 0x00FE }, /* LATIN SMALL LETTER THORN */
+ { "three", 0x0033 }, /* DIGIT THREE */
+ { "threeeighths", 0x215C }, /* VULGAR FRACTION THREE EIGHTHS */
+ { "threeinferior", 0x2083 }, /* SUBSCRIPT THREE */
+ { "threeoldstyle", 0xF733 }, /* OLDSTYLE DIGIT THREE */
+ { "threequarters", 0x00BE }, /* VULGAR FRACTION THREE QUARTERS */
+ { "threequartersemdash", 0xF6DE }, /* THREE QUARTERS EM DASH */
+ { "threesuperior", 0x00B3 }, /* SUPERSCRIPT THREE */
+ { "tilde", 0x02DC }, /* SMALL TILDE */
+ { "tildecomb", 0x0303 }, /* COMBINING TILDE */
+ { "tonos", 0x0384 }, /* GREEK TONOS */
+ { "trademark", 0x2122 }, /* TRADE MARK SIGN */
+ { "trademarksans", 0xF8EA }, /* TRADE MARK SIGN SANS SERIF */
+ { "trademarkserif", 0xF6DB }, /* TRADE MARK SIGN SERIF */
+ { "triagdn", 0x25BC }, /* BLACK DOWN-POINTING TRIANGLE */
+ { "triaglf", 0x25C4 }, /* BLACK LEFT-POINTING POINTER */
+ { "triagrt", 0x25BA }, /* BLACK RIGHT-POINTING POINTER */
+ { "triagup", 0x25B2 }, /* BLACK UP-POINTING TRIANGLE */
+ { "tsuperior", 0xF6F3 }, /* SUPERSCRIPT LATIN SMALL LETTER T */
+ { "two", 0x0032 }, /* DIGIT TWO */
+ { "twodotenleader", 0x2025 }, /* TWO DOT LEADER */
+ { "twoinferior", 0x2082 }, /* SUBSCRIPT TWO */
+ { "twooldstyle", 0xF732 }, /* OLDSTYLE DIGIT TWO */
+ { "twosuperior", 0x00B2 }, /* SUPERSCRIPT TWO */
+ { "twothirds", 0x2154 }, /* VULGAR FRACTION TWO THIRDS */
+ { "u", 0x0075 }, /* LATIN SMALL LETTER U */
+ { "uacute", 0x00FA }, /* LATIN SMALL LETTER U WITH ACUTE */
+ { "ubreve", 0x016D }, /* LATIN SMALL LETTER U WITH BREVE */
+ { "ucircumflex", 0x00FB }, /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
+ { "udieresis", 0x00FC }, /* LATIN SMALL LETTER U WITH DIAERESIS */
+ { "ugrave", 0x00F9 }, /* LATIN SMALL LETTER U WITH GRAVE */
+ { "uhorn", 0x01B0 }, /* LATIN SMALL LETTER U WITH HORN */
+ { "uhungarumlaut", 0x0171 }, /* LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+ { "umacron", 0x016B }, /* LATIN SMALL LETTER U WITH MACRON */
+ { "underscore", 0x005F }, /* LOW LINE */
+ { "underscoredbl", 0x2017 }, /* DOUBLE LOW LINE */
+ { "union", 0x222A }, /* UNION */
+ { "universal", 0x2200 }, /* FOR ALL */
+ { "uogonek", 0x0173 }, /* LATIN SMALL LETTER U WITH OGONEK */
+ { "upblock", 0x2580 }, /* UPPER HALF BLOCK */
+ { "upsilon", 0x03C5 }, /* GREEK SMALL LETTER UPSILON */
+ { "upsilondieresis", 0x03CB }, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+ { "upsilondieresistonos", 0x03B0 }, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+ { "upsilontonos", 0x03CD }, /* GREEK SMALL LETTER UPSILON WITH TONOS */
+ { "uring", 0x016F }, /* LATIN SMALL LETTER U WITH RING ABOVE */
+ { "utilde", 0x0169 }, /* LATIN SMALL LETTER U WITH TILDE */
+ { "v", 0x0076 }, /* LATIN SMALL LETTER V */
+ { "w", 0x0077 }, /* LATIN SMALL LETTER W */
+ { "wacute", 0x1E83 }, /* LATIN SMALL LETTER W WITH ACUTE */
+ { "wcircumflex", 0x0175 }, /* LATIN SMALL LETTER W WITH CIRCUMFLEX */
+ { "wdieresis", 0x1E85 }, /* LATIN SMALL LETTER W WITH DIAERESIS */
+ { "weierstrass", 0x2118 }, /* SCRIPT CAPITAL P */
+ { "wgrave", 0x1E81 }, /* LATIN SMALL LETTER W WITH GRAVE */
+ { "x", 0x0078 }, /* LATIN SMALL LETTER X */
+ { "xi", 0x03BE }, /* GREEK SMALL LETTER XI */
+ { "y", 0x0079 }, /* LATIN SMALL LETTER Y */
+ { "yacute", 0x00FD }, /* LATIN SMALL LETTER Y WITH ACUTE */
+ { "ycircumflex", 0x0177 }, /* LATIN SMALL LETTER Y WITH CIRCUMFLEX */
+ { "ydieresis", 0x00FF }, /* LATIN SMALL LETTER Y WITH DIAERESIS */
+ { "yen", 0x00A5 }, /* YEN SIGN */
+ { "ygrave", 0x1EF3 }, /* LATIN SMALL LETTER Y WITH GRAVE */
+ { "z", 0x007A }, /* LATIN SMALL LETTER Z */
+ { "zacute", 0x017A }, /* LATIN SMALL LETTER Z WITH ACUTE */
+ { "zcaron", 0x017E }, /* LATIN SMALL LETTER Z WITH CARON */
+ { "zdotaccent", 0x017C }, /* LATIN SMALL LETTER Z WITH DOT ABOVE */
+ { "zero", 0x0030 }, /* DIGIT ZERO */
+ { "zeroinferior", 0x2080 }, /* SUBSCRIPT ZERO */
+ { "zerooldstyle", 0xF730 }, /* OLDSTYLE DIGIT ZERO */
+ { "zerosuperior", 0x2070 }, /* SUPERSCRIPT ZERO */
+ { "zeta", 0x03B6 } /* GREEK SMALL LETTER ZETA */
+};
+
+#endif /* ADOBETBL_H */
diff --git a/dviware/catdvi/build.sh b/dviware/catdvi/build.sh
new file mode 100644
index 0000000000..bff0c0d041
--- /dev/null
+++ b/dviware/catdvi/build.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+set -e
+# You can use this script to build catdvi 0.14 in case you don't have GNU make
+
+###########################################################################
+# configuration
+###########################################################################
+
+# if the C library has getopt_long()
+#
+# GETOPT=""
+# CPPFLAGS="$CPPFLAGS -DCFG_HAS_GETOPT_LONG"
+#
+# else if the kpathsea library has getopt_long() -- it should
+#
+GETOPT=""
+CPPFLAGS="$CPPFLAGS -DCFG_KPATHSEA_HAS_GETOPT_LONG"
+#
+# else
+#
+# GETOPT="getopt getopt1"
+
+# if you have the kpathsea library
+FINDTFM="kpathsea"
+LDLIBS="-lkpathsea"
+# else
+# echo "sorry, you need the kpathsea library"
+# exit 1
+
+# set your C compiler and append any desired flags and libraries here
+CC="gcc"
+CFLAGS="$CFLAGS"
+CPPFLAGS="$CPPFLAGS"
+LDFLAGS="$LDFLAGS"
+
+COMPILE="$CC $CFLAGS $CPPFLAGS -c"
+LINK="$CC $LDFLAGS"
+
+###########################################################################
+# you should not need to touch anything below
+###########################################################################
+
+# create autogenerated header files: glyphenm.h
+$COMPILE -o adobe2h.o adobe2h.c
+$LINK adobe2h.o $LDLIBS -o adobe2h
+./adobe2h > glyphenm.h
+
+# create autogenerated header files: font encodings
+$COMPILE -o pse2unic.o pse2unic.c
+$COMPILE -o util.o util.c
+$LINK pse2unic.o util.o $LDLIBS -o pse2unic
+cd enc
+for x in *.enc; do
+ y=`basename $x .enc`
+ ../pse2unic -w $y.enc $y.h $y.tex
+done
+cd ..
+
+# compile everything else
+PIECES="bytesex canvas catdvi density fixword fntenc fontinfo glyphops layout \
+linebuf outenc page pageref readdvi regsta sparse vlist $FINDTFM $GETOPT"
+
+for x in $PIECES; do
+ $COMPILE -o $x.o $x.c
+done
+
+# link all required object files into the catdvi executable
+OBJFILES="util.o"
+for x in $PIECES; do
+ OBJFILES="$OBJFILES $x.o"
+done
+
+$LINK $OBJFILES $LDLIBS -o catdvi
+
+# create the test cases
+cd test
+for x in *.tex; do
+ latex $x
+done
+cd ..
diff --git a/dviware/catdvi/bytesex.c b/dviware/catdvi/bytesex.c
new file mode 100644
index 0000000000..cfac9d5e35
--- /dev/null
+++ b/dviware/catdvi/bytesex.c
@@ -0,0 +1,135 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl>
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include "bytesex.h"
+#include "util.h"
+
+#define SKIPBYTES_BUFLEN 128
+
+void efread(void *ptr, size_t size, size_t nmemb,
+ FILE *stream, char *errmsg)
+{
+ if (fread(ptr, size, nmemb, stream) != nmemb) {
+ if (feof(stream)) {
+ panic("Unexpected end of file\n");
+ } else {
+ panic("%s\n", strerror(errno));
+ }
+ panic(errmsg);
+ }
+}
+
+byte readbyte(FILE * stream)
+{
+ byte b;
+
+ efread(&b, 1, 1, stream, "Failed to read byte\n");
+
+ return b;
+}
+
+/* A portable reader for unsigned muli-octet big-endian numbers. */
+uint32 u_readbigendiannumber(byte count, FILE *stream)
+{
+ uint32 ures = 0;
+ int i;
+ unsigned char buf[4];
+
+ assert(count <= 4);
+
+ efread(buf, count, 1, stream, "Failed to read big endian number.\n");
+ /* We want to read one chunk of count bytes, not count chunks
+ * of one byte.
+ */
+ for (i = 0; i < count; i++) {
+ ures = (ures << 8) + buf[i];
+ }
+
+ return ures;
+}
+
+/* An extremely portable reader for signed (two's complement)
+ muli-octet big-endian numbers. */
+sint32 s_readbigendiannumber(byte count, FILE *stream)
+{
+ uint32 ures;
+ const uint32 msb_bitmask = ((uint32) 1) << (8 * count - 1);
+ /* Beware of overflow! 2 * msb_bitmask may be too much for
+ uint32. */
+ const uint32 allset_bitmask = msb_bitmask + (msb_bitmask - 1);
+
+ assert(count <= 4);
+
+ /* First read the octets, taking care of the bytesex. */
+ ures = u_readbigendiannumber(count, stream);
+
+ assert(ures <= allset_bitmask);
+
+ /* We need to handle the sign conversion ourselves, as a
+ simple cast is implementation-defined. The value in ures
+ is in two's complement format. */
+
+ if (ures >= msb_bitmask) {
+ /* It is negative. */
+ return - (sint32) (ures ^ allset_bitmask) - 1;
+ }
+ else {
+ /* Positive (or 0). */
+ return ures;
+ }
+}
+
+void readbcblstring(byte * buffer, uint32 slen, FILE * fp)
+{
+ uint32 len;
+
+ len = u_readbigendiannumber(1, fp);
+
+ if (len > slen - 1) {
+ warning("invalid BCBL string length");
+ len = 0;
+ }
+
+ if (len > 0) {
+ efread(buffer, 1, len, fp, "unable to read BCBL string");
+ }
+ buffer[len] = 0;
+
+ skipbytes(slen - len - 1, fp);
+}
+
+void skipbytes(int count, FILE *stream)
+{
+ byte buf[SKIPBYTES_BUFLEN];
+
+ while (count > 0) {
+ int numbytes = count > SKIPBYTES_BUFLEN
+ ? SKIPBYTES_BUFLEN
+ : count;
+ count = count - SKIPBYTES_BUFLEN;
+ efread(buf, 1, numbytes, stream,
+ "Error while skipping bytes\n");
+ }
+}
+
diff --git a/dviware/catdvi/bytesex.d b/dviware/catdvi/bytesex.d
new file mode 100644
index 0000000000..e00ae3766f
--- /dev/null
+++ b/dviware/catdvi/bytesex.d
@@ -0,0 +1 @@
+bytesex.o bytesex.d : bytesex.c bytesex.h util.h
diff --git a/dviware/catdvi/bytesex.h b/dviware/catdvi/bytesex.h
new file mode 100644
index 0000000000..954eefd29f
--- /dev/null
+++ b/dviware/catdvi/bytesex.h
@@ -0,0 +1,67 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl>
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef BYTESEX_H
+#define BYTESEX_H
+
+#include <limits.h>
+#include <stdio.h>
+
+#if !defined(CHAR_BIT) || CHAR_BIT < 8
+# error "the C environment is not standards compliant"
+#elif CHAR_BIT > 8
+# warning "char is wider than octet; problems may occur"
+#endif
+
+typedef unsigned char byte;
+/* FIXME ? */
+typedef unsigned long uint32;
+typedef signed long sint32;
+
+/* The limit macros should not need machine-specific fixing even if there's no
+ * type exactly 32 bit wide on the machine -- we will never have to deal
+ * with values that do not fit into 32 bits.
+ */
+#ifndef UINT32_MAX
+#define UINT32_MAX 0xffffffffUL
+#endif
+#ifndef SINT32_MAX
+#define SINT32_MAX 0x7fffffffL
+#endif
+#ifndef SINT32_MIN
+#define SINT32_MIN (-SINT32_MAX - 1L)
+#endif
+
+void efread(void *ptr, size_t size, size_t nmemb,
+ FILE *stream, char *errmsg);
+
+/* A portable reader for muli-octet big-endian numbers. */
+uint32 u_readbigendiannumber(byte count, FILE *stream);
+sint32 s_readbigendiannumber(byte count, FILE *stream);
+
+byte readbyte(FILE * stream);
+
+/* Read a string in BCBL format. len is the expected length of the
+ string. */
+void readbcblstring(byte * buffer, uint32 slen, FILE *);
+
+void skipbytes(int count, FILE *stream);
+
+#endif /* BYTESEX_H */
diff --git a/dviware/catdvi/canvas.c b/dviware/catdvi/canvas.c
new file mode 100644
index 0000000000..f4d1186aa7
--- /dev/null
+++ b/dviware/catdvi/canvas.c
@@ -0,0 +1,368 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdlib.h>
+#include <assert.h>
+#include "util.h"
+#include "canvas.h"
+#include "glyphenm.h"
+#include "outenc.h"
+
+
+typedef enum canv_celltype_t {
+ CCT_UNUSED,
+ CCT_BLACK,
+ CCT_LINEDRAW,
+ CCT_LINEBUF_CONT,
+ CCT_GLYPH,
+ CCT_LINEBUF_START
+} canv_celltype_t;
+ /* The order matters. */
+
+typedef enum canv_linedraw_t {
+ CLD_RIGHT = 1 << 1,
+ CLD_UP = 1 << 2,
+ CLD_LEFT = 1 << 3,
+ CLD_DOWN = 1 << 4
+} canv_linedraw_t;
+
+typedef union canv_celldata_t {
+ /* */ /* CCT_UNUSED */
+ /* */ /* CCT_BLACK */
+ canv_linedraw_t draw; /* CCT_LINEDRAW */
+ glyph_t glyph; /* CCT_GLYPH */
+ linebuf_t * lb; /* CCT_LINEBUF_START, CCT_LINEBUF_CONT */
+} canv_celldata_t;
+
+struct canv_cell_t {
+ canv_celltype_t type;
+ canv_celldata_t data;
+};
+
+struct canv_line_t {
+ canv_cell_t * cells;
+ sint32 cols_used;
+};
+
+#define canv_cell(this, x, y) ((this)->lines[(y)].cells + (x))
+
+#define CANV_CHECK_X(this, x) {assert(0 <= (x)); assert((x) < (this)->ncols);}
+#define CANV_CHECK_Y(this, y) {assert(0 <= (y)); assert((y) < (this)->nlines);}
+
+
+/* Claim cell at (x, y) for use as celltype whatfor.
+ * Returns pointer to cell if succesful, NULL if cell already used
+ * for something equally or more important.
+ */
+static canv_cell_t * canv_allocate_cell(
+ canv_t * this,
+ sint32 x,
+ sint32 y,
+ canv_celltype_t whatfor
+);
+
+/* Add line drawings draw to cell at (x, y).
+ * Returns pointer to cell if succesful, NULL if cell already used
+ * for something more important.
+ */
+static canv_cell_t * canv_linedraw_to_cell(
+ canv_t * this,
+ sint32 x,
+ sint32 y,
+ canv_linedraw_t draw
+);
+
+
+void canv_init(canv_t * this, sint32 ncols, sint32 nlines)
+{
+ sint32 i, j;
+ canv_line_t * l;
+
+ assert(ncols > 0);
+ assert(nlines > 0);
+ this->ncols = ncols;
+ this->nlines = nlines;
+
+ this->cells = xmalloc(ncols * nlines * sizeof(canv_cell_t));
+ this->lines = xmalloc(nlines * sizeof(canv_line_t));
+
+ for(i = 0; i < nlines; ++i) {
+ l = this->lines + i;
+ l->cols_used = 0;
+ l->cells = this->cells + i * ncols;
+ for(j = 0; j < ncols; ++j) {
+ l->cells[j].type = CCT_UNUSED;
+ }
+ }
+}
+
+void canv_done(canv_t * this)
+{
+ sint32 i, j;
+ canv_cell_t * c;
+
+ for(i = 0; i < this->nlines; ++i) {
+ for(j = 0; j < this->ncols; ++j) {
+ c = canv_cell(this, j, i);
+ if(c->type == CCT_LINEBUF_START) {
+ linebuf_done(c->data.lb);
+ free(c->data.lb);
+ }
+ }
+ }
+
+ free(this->lines);
+ free(this->cells);
+}
+
+void canv_put_linebuf(
+ canv_t * this,
+ linebuf_t * lb,
+ sint32 xleft,
+ sint32 y,
+ sint32 width
+)
+{
+ canv_cell_t * cell;
+ sint32 x;
+
+ CANV_CHECK_X(this, xleft);
+ CANV_CHECK_Y(this, y);
+
+ if(width <= 0) {
+ /* This shouldn't happen, but is no reason to bomb out. */
+ linebuf_done(lb);
+ free(lb);
+ pmesg(
+ 10,
+ "Attempt to put <= 0 (%ld) width linebuf at (%ld, %ld) !\n",
+ width,
+ xleft,
+ y
+ );
+ return;
+ }
+
+ cell = canv_allocate_cell(this, xleft, y, CCT_LINEBUF_START);
+ if(cell == NULL) {
+ /* If we can't get it started, we just forget the whole thing. */
+ linebuf_done(lb);
+ free(lb);
+ return;
+ }
+ cell->data.lb = lb;
+
+ for(x = xleft + 1; x < xleft + width; ++x) {
+ cell = canv_allocate_cell(this, x, y, CCT_LINEBUF_CONT);
+ if(cell != NULL) cell->data.lb = lb;
+ }
+
+}
+
+void canv_put_glyph(canv_t * this, glyph_t glyph, sint32 x, sint32 y)
+{
+ canv_cell_t * cell;
+
+ CANV_CHECK_X(this, x);
+ CANV_CHECK_Y(this, y);
+
+ cell = canv_allocate_cell(this, x, y, CCT_GLYPH);
+ if(cell != NULL) cell->data.glyph = glyph;
+}
+
+void canv_put_hline(canv_t * this, sint32 xleft, sint32 y, sint32 xright)
+{
+ sint32 x;
+
+ CANV_CHECK_X(this, xleft);
+ CANV_CHECK_Y(this, y);
+ CANV_CHECK_X(this, xright);
+ assert(xleft <= xright);
+
+ canv_linedraw_to_cell(this, xleft, y, CLD_RIGHT);
+ for(x = xleft + 1; x < xright; ++x) {
+ canv_linedraw_to_cell(this, x, y, CLD_LEFT | CLD_RIGHT);
+ }
+ canv_linedraw_to_cell(this, xright, y, CLD_LEFT);
+ /* If xleft == xright, we have the cell drawn with CLD_LEFT | CLD_RIGHT.
+ * This is intentional.
+ */
+}
+
+void canv_put_vline(canv_t * this, sint32 x, sint32 ybottom, sint32 ytop)
+{
+ sint32 y;
+
+ CANV_CHECK_X(this, x);
+ CANV_CHECK_Y(this, ybottom);
+ CANV_CHECK_Y(this, ytop);
+ assert(ybottom >= ytop);
+
+ canv_linedraw_to_cell(this, x, ytop, CLD_DOWN);
+ for(y = ytop + 1; y < ybottom; ++y) {
+ canv_linedraw_to_cell(this, x, y, CLD_UP | CLD_DOWN);
+ }
+ canv_linedraw_to_cell(this, x, ybottom, CLD_UP);
+ /* If ytop == ybottom, we have the cell drawn with CLD_UP | CLD_DOWN.
+ * This is intentional.
+ */
+}
+
+void canv_put_black_box(
+ canv_t * this,
+ sint32 xleft,
+ sint32 ybottom,
+ sint32 xright,
+ sint32 ytop
+)
+{
+ sint32 x, y;
+
+ CANV_CHECK_X(this, xleft);
+ CANV_CHECK_Y(this, ybottom);
+ CANV_CHECK_X(this, xright);
+ CANV_CHECK_Y(this, ytop);
+ assert(xleft <= xright);
+ assert(ybottom >= ytop);
+
+ for(y = ytop; y <= ybottom; ++y) {
+ for(x = xleft; x <= xright; ++x) {
+ canv_allocate_cell(this, x, y, CCT_BLACK);
+ /* If the cell is already black this call fails, but the
+ * cell is then black anyway.
+ */
+ }
+ }
+}
+
+
+static const glyph_t linedraw_glyphs[16] = {
+ GLYPH_UNI_space,
+ GLYPH_UNI_bdrawlightrt,
+ GLYPH_UNI_bdrawlightup,
+ GLYPH_UNI_bdrawlightuprt,
+ GLYPH_UNI_bdrawlightlf,
+ GLYPH_UNI_bdrawlighthorz,
+ GLYPH_UNI_bdrawlightuplf,
+ GLYPH_UNI_bdrawlightuphorz,
+ GLYPH_UNI_bdrawlightdn,
+ GLYPH_UNI_bdrawlightdnrt,
+ GLYPH_UNI_bdrawlightvert,
+ GLYPH_UNI_bdrawlightvertrt,
+ GLYPH_UNI_bdrawlightdnlf,
+ GLYPH_UNI_bdrawlightdnhorz,
+ GLYPH_UNI_bdrawlightvertlf,
+ GLYPH_UNI_bdrawlightverthorz
+};
+
+void canv_write(const canv_t * this, FILE * f)
+{
+ linebuf_t lb;
+ canv_line_t * pl;
+ canv_cell_t * pc;
+ sint32 x, y;
+
+ linebuf_init(&lb, this->ncols);
+ /* lb's initial size should be about right for most lines */
+ for(y = 0; y < this->nlines; ++y) {
+ pl = this->lines + y;
+ assert(pl->cols_used <= this->ncols); /* consistency check */
+
+ linebuf_clear(&lb);
+ pc = pl->cells;
+ for(x = 0; x < pl->cols_used; ++x) {
+ switch(pc[x].type) {
+ case CCT_UNUSED:
+ linebuf_putg(&lb, GLYPH_UNI_space);
+ /*linebuf_putg(&lb, GLYPH_asterisk);*/
+ break;
+ case CCT_BLACK:
+ linebuf_putg(&lb, GLYPH_block);
+ break;
+ case CCT_LINEDRAW:
+ linebuf_putg(&lb, linedraw_glyphs[pc[x].data.draw]);
+ break;
+ case CCT_LINEBUF_CONT:
+ break;
+ case CCT_GLYPH:
+ linebuf_putg(&lb, pc[x].data.glyph);
+ break;
+ case CCT_LINEBUF_START:
+ linebuf_append(&lb, pc[x].data.lb);
+ break;
+ default:
+ NOTREACHED;
+ }
+ } /* for x */
+ outenc_write(f, &lb);
+ putc('\n', f);
+ } /* for y */
+
+ linebuf_done(&lb);
+}
+
+static canv_cell_t * canv_allocate_cell(
+ canv_t * this,
+ sint32 x,
+ sint32 y,
+ canv_celltype_t whatfor
+)
+{
+ canv_cell_t * res;
+ canv_line_t * l;
+
+ res = canv_cell(this, x, y);
+ if(res->type >= whatfor) {
+ pmesg(
+ 80,
+ "cell at (%ld, %ld) already used for %d, cannot use for %d\n",
+ x,
+ y,
+ res->type,
+ whatfor
+ );
+ return NULL;
+ }
+ res->type = whatfor;
+
+ l = this->lines + y;
+ if(l->cols_used < x + 1) l->cols_used = x + 1;
+ return res;
+}
+
+static canv_cell_t * canv_linedraw_to_cell(
+ canv_t * this,
+ sint32 x,
+ sint32 y,
+ canv_linedraw_t draw
+)
+{
+ canv_cell_t * res;
+
+ res = canv_cell(this, x, y);
+ if(res->type == CCT_LINEDRAW) {
+ /* already in use for line drawing */
+ res->data.draw |= draw;
+ }
+ else {
+ /* try to claim for line drawing */
+ res = canv_allocate_cell(this, x, y, CCT_LINEDRAW);
+ if(res != NULL) res->data.draw = draw;
+ }
+ return res;
+}
diff --git a/dviware/catdvi/canvas.d b/dviware/catdvi/canvas.d
new file mode 100644
index 0000000000..fcec796985
--- /dev/null
+++ b/dviware/catdvi/canvas.d
@@ -0,0 +1,2 @@
+canvas.o canvas.d : canvas.c util.h canvas.h linebuf.h page.h bytesex.h \
+ pageref.h glyphenm.h outenc.h
diff --git a/dviware/catdvi/canvas.h b/dviware/catdvi/canvas.h
new file mode 100644
index 0000000000..ec2fe17512
--- /dev/null
+++ b/dviware/catdvi/canvas.h
@@ -0,0 +1,82 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CANVAS_H
+#define CANVAS_H
+
+#include "linebuf.h"
+#include "bytesex.h"
+
+typedef struct canv_cell_t canv_cell_t;
+
+typedef struct canv_line_t canv_line_t;
+
+typedef struct canv_t canv_t;
+struct canv_t {
+ sint32 ncols;
+ sint32 nlines;
+
+ canv_line_t * lines;
+ canv_cell_t * cells;
+};
+
+/* constructor */
+void canv_init(canv_t * this, sint32 ncols, sint32 nlines);
+
+/* destructor */
+void canv_done(canv_t * this);
+
+/* Put unicode string *lb starting at (x, y) -- this is the leftmost
+ * glyph in the string. Coordinates are 0 <= x < ncols, 0 <= y < nlines
+ * and increase left to right, top to bottom.
+ * lb is assumed to be on the heap. canv takes ownership of lb
+ * (e.g. canv_done will destruct and free it). If this is not desirable,
+ * create a copy and pass that.
+ */
+void canv_put_linebuf(
+ canv_t * this,
+ linebuf_t * lb,
+ sint32 xleft,
+ sint32 y,
+ sint32 width
+);
+
+/* Put a single unicode glyph. It is assumed to have output width 1. */
+void canv_put_glyph(canv_t * this, glyph_t glyph, sint32 x, sint32 y);
+
+/* Put a horizontal line (it is made up from line drawing characters) */
+void canv_put_hline(canv_t * this, sint32 xleft, sint32 y, sint32 xright);
+
+/* Put a vertical line (it is made up from line drawing characters) */
+void canv_put_vline(canv_t * this, sint32 x, sint32 ybottom, sint32 ytop);
+
+/* Put a rectangle of black ink */
+void canv_put_black_box(
+ canv_t * this,
+ sint32 xleft,
+ sint32 ybottom,
+ sint32 xright,
+ sint32 ytop
+);
+
+/* Write the whole character grid to f, using the current output encoding.
+ * Trailing whitespace in each line is omitted.
+ */
+void canv_write(const canv_t * this, FILE * f);
+
+#endif /* !defined CANVAS_H */
diff --git a/dviware/catdvi/catdvi.1 b/dviware/catdvi/catdvi.1
new file mode 100644
index 0000000000..b772793bd9
--- /dev/null
+++ b/dviware/catdvi/catdvi.1
@@ -0,0 +1,371 @@
+.TH CATDVI 1 "8 November 2002"
+.SH NAME
+catdvi \- a DVI to plain text converter
+.\"
+.\"
+.\"
+.SH SYNOPSIS
+.B catdvi
+[\fB\-d\ \fIdebuglevel\fB, \-\-debug=\fIdebuglevel\fR]
+[\fB\-e\ \fIoutenc\fB, \-\-output-encoding=\fIoutenc\fR]
+[\fB\-p\ \fIpagespec\fB, \-\-first-page=\fIpagespec\fR]
+[\fB\-l\ \fIpagespec\fB, \-\-last-page=\fIpagespec\fR]
+.RB [ \-N,
+.BR \-\-list-page-numbers ]
+.RB [ \-s,
+.BR \-\-sequential ]
+.RB [ \-U,
+.BR \-\-show-unknown-glyphs ]
+.RB [ \-h,
+.BR \-\-help ]
+.RB [ \-\-version ]
+.RB [ \-\-copyright ]
+.RI [ dvi-file ]
+.br
+.\"
+.\"
+.\"
+.SH DESCRIPTION
+This manual page documents
+.B catdvi
+version 0.14
+.PP
+.B catdvi
+reads the
+.SM DVI
+(typesetter DeVice Independent) file
+.I dvi-file
+and dumps a plain text approximation of the document it describes to stdout.
+If the argument
+.I dvi-file
+is omitted or a dash (`\-'),
+.B catdvi
+will read from stdin.
+Several
+.I output encodings
+(different character sets of the plain text output) are supported,
+most notably
+.SM UTF-8.
+.PP
+The current version of
+.B catdvi
+is a work in progress;
+it may not be robust enough for production use,
+but already works fine with linear english text.
+Many mathematical symbols (e.g.\& the uppercase greek letters)
+and moderately complex formulae also come out right.
+.PP
+The program needs to read the
+.SM TFM
+(Tex Font Metric) files corresponding to the fonts used in the
+.SM DVI
+file.
+These are searched (and, if necessary and possible, created on the
+fly) through the
+.I Kpathsea
+library.
+.PP
+In order to correctly translate a
+.SM DVI
+file to text, the
+.I input encoding
+of the fonts used in it (i.e. a meaning-preserving mapping from
+font code points to Unicode) must be known. There are a lot of different
+font encodings in use. At the time of writing,
+.B catdvi
+understands the following input encodings:
+.TP
+`TEX TEXT'
+Knuth's original font encoding, also known as OT1.
+.TP
+`TEX TEXT WITHOUT F-LIGATURES'
+A variant of the above.
+.TP
+`EXTENDED TEX FONT ENCODING \- LATIN'
+The Cork encoding, also known as T1.
+.TP
+`TEX MATH ITALIC'
+The encoding of Knuth's math italic fonts, also known as OML.
+.TP
+`TEX MATH SYMBOLS'
+The encoding of Knuth's math symbol fonts, also known as OMS.
+.TP
+`TEX MATH EXTENSION' (most of it)
+The encoding of Knuth's math extension fonts (big operators, brackets, etc.),
+also known as OMX.
+.TP
+`TEX TYPEWRITER TEXT'
+The encoding of Knuth's typewriter type fonts.
+.TP
+`LATEX SYMBOLS'
+The encoding of the lasy fonts.
+.TP
+Henrik Theilings European currency symbol (`eurosym') font.
+.TP
+`TEX TEXT COMPANION SYMBOLS 1---TS1' (almost everything)
+The encoding of the text companion fonts.
+.TP
+Martin Vogels symbol (`MarVoSym') font.
+Both the 1998 and the 2000 version are supported as far as possible --
+about half of the symbols are not representable in Unicode.
+.TP
+`BLACKBOARD'
+The encoding of the blackboard bold math (`bbm') fonts.
+.TP
+All AMS fonts except the Cyrillic ones.
+This includes the AMS math symbols group A and group B, Euler fraktur,
+Euler cursive, Euler script and Euler compatible extension fonts.
+.PP
+It is impossible to do perfect translation from unmarked-up
+.SM DVI
+to plain text,
+since the former does only describe the layout of a page,
+and a translator such as this should really know where words and
+paragraphs end, and more importantly, which glyphs should be aligned
+vertically and which shouldn't.
+The current alignment algorithm tries to preserve the relative
+horizontal positions of word beginnings; this works well in most cases.
+Word breaks are detected using simple heuristics;
+paragraphs are not detected at all (and no paragraph fill is attempted).
+.PP
+The price of alignment is that the output will likely be more than 80
+columns wide, even though
+.B catdvi
+tries very hard not to use more columns than strictly necessary.
+Output is usually less than 120 columns, almost always less than 132
+columns wide. It may be a good idea to switch your terminal to one of
+these modes if possible.
+.PP
+.\"
+.\"
+.\"
+.SH OPTIONS
+The program follows the usual GNU command line syntax, with long
+options starting with two dashes.
+.TP
+.BI \-d\ debuglevel ,\ \-\-debug= debuglevel
+Set the debug output level to
+.I debuglevel
+(default is 10).
+Large values will result in lots of debug output, 0 in none at all.
+The maximal debug output level currently used is 150.
+.\"
+.\"
+.TP
+.BI \-e\ outenc ,\ \-\-output-encoding= outenc
+Specify the encoding of the output character set.
+.I outenc
+can be one of the numbers or names from the table below.
+Names are case insensitive.
+The following output encodings should be available:
+.br
+\&
+.br
+0:\ UTF-8
+.br
+1:\ US-ASCII
+.br
+2:\ ISO-8859-1
+.br
+3:\ ISO-8859-15
+.br
+\&
+.br
+The command
+.B catdvi \-\-help
+(see below) will give a more up-to-date list of all compiled-in output
+encodings. The default encoding is 1.
+.\"
+.\"
+.TP
+.BI \-p\ pagespec ,\ \-\-first-page= pagespec
+Do not output pages before page
+.IR pagespec .
+Pages can be specified in three different ways; the first two
+are exactly the same as for
+.BR dvips (1).
+.RS
+.PP
+A (possibly negative) number
+.I num
+specifies a TeX page number, which is stored as the so-called
+.I count0
+value in the
+.SM DVI
+file for every page.
+Plain TeX uses negative page numbers for roman-numbered frontmatter
+(title page, preface,
+.SM TOC,
+etc.) so the
+.I count0
+values compare as
+.RS
+-1 < -2 < -3 < ... < 1 < 2 < 3 < ...
+.RE
+There may be several pages with the same
+.I count0
+value in a single
+.SM DVI
+file. This usually happens in documents with a per-chapter page numbering
+scheme.
+.PP
+A number prefixed by an equals sign
+.RI (`= num ')
+specifies a physical page, i\.e\. the
+.IR num -th
+page appearing in the
+.SM DVI
+file. Numbering starts with 1.
+Note that with the long form of the option you actually need
+.I two
+equals signs, one as part of the long option and one as part of the
+page specification. Example:
+.RS
+.B catdvi
+\-\-first-page==5 foo.dvi
+.RE
+.PP
+The third form of a page specification, two numbers separated by a colon
+.RI (` num1 : num2 '),
+is useful for documents with separately-numbered parts, e.g. chapters.
+It refers to the page with
+.I count0
+value equal to
+.I num2
+that
+.B catdvi
+believes to be in part
+.IB num1 .
+Since those part numbers are not stored in the
+.SM DVI
+file, the program has to guess them:
+an internal
+.I chapter
+counter is increased by one every time
+the
+.I count0
+value of the current page is not greater (in above ordering) than that
+of the previous page.
+The counter is initialized to 1 if the first page
+has negative
+.I count0
+value and to 0 otherwise. (A document with separately numbered parts
+will probably have separately numbered frontmatter as well, and then this
+rule keeps the internal counter equal to
+real world part numbers.)
+.RE
+.\"
+.\"
+.TP
+.BI \-l\ pagespec ,\ \-\-last-page= pagespec
+Do not output pages after page
+.IR pagespec .
+Pages are specified exactly as for the
+.B \-\-first-page
+option above.
+.\"
+.\"
+.TP
+.B \-N, \-\-list-page-numbers
+Instead of the contents of pages, output their
+physical page count,
+.I count0
+value and
+.I chapter
+count (see the
+.B \-\-first-page
+option above for a definition of these).
+.\"
+.\"
+.TP
+.B \-s, \-\-sequential
+Do not attempt to reproduce the page layout;
+output glyphs in the order they appear in the
+.SM DVI
+file. This may be useful with e.g. multi-column page layouts.
+.\"
+.\"
+.TP
+.B \-U, \-\-show-unknown-glyphs
+Show the Unicode number of unknown glyphs instead of `?'.
+.\"
+.\"
+.TP
+.B \-h, \-\-help
+Show usage information and a list of available output encodings,
+then exit.
+.\"
+.\"
+.TP
+.B \-\-version
+Show version information and exit.
+.\"
+.\"
+.TP
+.B \-\-copyright
+Show copyright information and exit.
+.\"
+.\"
+.\"
+.SH ENVIRONMENT
+The usual environment variables TFMFONTS, TEXFONTS, etc.\& for
+.I Kpathsea
+font search and creation apply.
+Refer to the
+.I Kpathsea
+documentation for details.
+.\"
+.\"
+.\"
+.SH "SEE ALSO"
+.BR xdvi (1),
+.BR dvips (1),
+.BR tex (1),
+.BR mktextfm (1),
+the
+.I Kpathsea
+texinfo documentation,
+.BR utf-8 (7).
+.\"
+.\"
+.\"
+.SH BUGS
+These things do not work (yet):
+.IP \(bu
+No rules are converted.
+.IP \(bu
+Extensible recipes (very large brackets, braces, etc. built out of several
+smaller pieces) are not properly handled.
+.IP \(bu
+Complicated math formulae are sometimes misaligned (mostly due to lack
+of appropriate word break heuristics).
+.IP \(bu
+Some fonts and font encodings are not recognised yet.
+.IP \(bu
+Most mathematical symbols have no representation in the available
+output character sets except Unicode, and hence show up as `?' unless
+.SM UTF-8
+output encoding is selected. A textual transcription would be desirable.
+.LP
+Watch out for these:
+.IP \(bu
+If there is a space where it does not belong or if there is no space
+where there should be one,
+report this as a bug (send the
+.SM DVI
+file to the
+.B catdvi
+maintainer, stating where in the file the bug is seen).
+.\"
+.\"
+.\"
+.SH AUTHORS
+.B catdvi
+was written by
+Antti-Juhani Kaijanaho <gaia@iki.fi>,
+based on a skeletal version by J.H.M.\ Dassen (Ray).
+Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+did further improvements and currently maintains the program.
+.PP
+The manual page was compiled by Bjoern Brill, using
+material written by the first two program authors.
diff --git a/dviware/catdvi/catdvi.c b/dviware/catdvi/catdvi.c
new file mode 100644
index 0000000000..0d3fcfa25e
--- /dev/null
+++ b/dviware/catdvi/catdvi.c
@@ -0,0 +1,245 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl>
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2001 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#if defined CFG_HAS_GETOPT_LONG
+# include <getopt.h>
+#elif defined CFG_KPATHSEA_HAS_GETOPT_LONG
+# include <kpathsea/getopt.h>
+#else
+# include "getopt.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "findtfm.h"
+#include "readdvi.h"
+#include "outenc.h"
+#include "util.h"
+#include "version.h"
+#include "page.h"
+#include "glyphops.h"
+
+#define OPT_COPYRIGHT (UCHAR_MAX + 1)
+#define OPT_VERSION (OPT_COPYRIGHT + 1)
+
+static void print_encodings(void)
+{
+ enum outenc_num_t i;
+
+ for (i = 0; i < OE_TOOBIG; i++) {
+ printf(" %2i. %s\n", i, outenc_names[i]);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ FILE *dvifile = NULL;
+ static struct option lopt[] = {
+ { "copyright", no_argument, 0, OPT_COPYRIGHT },
+ { "version", no_argument, 0, OPT_VERSION },
+ { "help", no_argument, 0, 'h' },
+ { "output-encoding", required_argument, 0, 'e' },
+ { "debug", required_argument, 0, 'd' },
+ { "list-page-numbers", no_argument, 0, 'N' },
+ { "show-unkown-glyphs", no_argument, 0, 'U' },
+ { "sequential", no_argument, 0, 's' },
+ { "start-page", required_argument, 0, 'p' },
+ { "last-page", required_argument, 0, 'l' },
+ { 0, 0, 0, 0 }
+ };
+ static char const * shopt = "d:e:hl:p:NUs";
+
+ setlocale(LC_ALL, "");
+
+ msglevel = 10; /* Level of verbosity for pmesg */
+
+#ifdef USE_MALLOC0
+ /* Simulate malloc(0) == NULL behaviour with GNU libc for debugging */
+ use_malloc0();
+#endif
+
+ setup_findtfm(argv[0]);
+
+ /* Parse options */
+ while (1) {
+ int opt;
+
+ opt = getopt_long(argc, argv, shopt, lopt, 0);
+ if (opt == -1) break;
+
+ switch (opt) {
+ long arg;
+ char * suffix;
+
+ case OPT_VERSION:
+ printf("%s %s\n", PACKAGE, VERSION);
+ version_findtfm();
+ exit(EXIT_SUCCESS);
+
+ case 'h':
+ printf("Usage: %s [options] [file]\n",
+ argv[0] == 0 ? PACKAGE : argv[0]);
+ puts("");
+ puts("Options:");
+ puts(" -d DEBUGLEVEL, --debug=DEBUGLEVEL");
+ puts(" Set the debug output level. Smaller is less output.");
+ puts(" -e ENCODING, --output-encoding=ENCODING");
+ puts(" Set the output encoding.");
+ puts(" (ENCODING can be a number or name "
+ "from the table below.)");
+ puts(" -p PAGESPEC, --first-page=PAGESPEC");
+ puts(" Do not output pages before page PAGESPEC.");
+ puts(" PAGESPEC is either count0, =physicalpage or chapter:count0 .");
+ puts(" -l PAGESPEC, --last-page=PAGESPEC");
+ puts(" Do not output pages after page PAGESPEC.");
+ puts(" -N , --list-page-numbers");
+ puts(" Output physical page count, count0 value and chapter count instead");
+ puts(" of page contents.");
+ puts(" -U, --show-unknown-glyphs");
+ puts(" Show the Unicode number of unknown glyphs instead of `?'.");
+ puts(" -s, --sequential");
+ puts(" Do not attempt to reproduce the page layout; output glyphs");
+ puts(" in the order they appear in the DVI file.");
+ puts(" -h, --help");
+ puts(" Show this help page.");
+ puts(" --version");
+ puts(" Show version information.");
+ puts(" --copyright");
+ puts(" Show copyright information.");
+ puts("");
+ puts("The following output encodings are available:");
+ print_encodings();
+ puts("");
+ puts("Please, report bugs to <brill@fs.math.uni-frankfurt.de>");
+ exit(EXIT_SUCCESS);
+
+ case 'e':
+ arg = strtol(optarg, &suffix, 10);
+ if (suffix[0] != 0) {
+ /* not a number */
+ char * upoptarg;
+
+ upoptarg = strupcasedup(optarg);
+ if(upoptarg == NULL) enomem();
+
+ for(arg = 0; arg < OE_TOOBIG; ++arg) {
+ if(!strcmp(upoptarg, outenc_names[arg])) break;
+ }
+ free(upoptarg);
+
+ if(arg == OE_TOOBIG) {
+ panic("Unknown encoding `%s'.\n", optarg);
+ }
+ }
+ else if (arg < 0 || arg >= OE_TOOBIG) {
+ panic("Encoding must be between %i and %i\n",
+ 0, OE_TOOBIG - 1);
+ }
+ outenc_num = arg;
+ break;
+
+ case 'd':
+ arg = strtol(optarg, &suffix, 10);
+ if (suffix[0] != 0) {
+ panic("Debug level must be a number.\n");
+ }
+ msglevel = arg;
+ break;
+
+ case 'l':
+ if(!pageref_parse(&page_last_output, optarg))
+ panic("Unable to parse last page argument.\n");
+ break;
+
+ case 'p':
+ if(!pageref_parse(&page_start_output, optarg))
+ panic("Unable to parse start page argument.\n");
+ break;
+
+ case 'N':
+ page_list_numbers = 1;
+ break;
+
+ case 'U':
+ outenc_show_unicode_number = 1;
+ break;
+
+ case 's':
+ page_sequential = 1;
+ break;
+
+ case OPT_COPYRIGHT:
+ puts("This is " PACKAGE ".");
+ puts("");
+ puts("Copyright 1999-2001 Antti-Juhani Kaijanaho");
+ puts("Copyright 1999 J.H.M. Dassen (Ray)");
+ puts("Copyright 2000-2002 Bjoern Brill");
+ puts("Copyright 1987-1999 Free Software Foundation, Inc.");
+ copyright_findtfm();
+ puts("");
+ puts("This program is free software; you can redistribute it and/or modify");
+ puts("it under the terms of the GNU General Public License as published by");
+ puts("the Free Software Foundation; either version 2 of the License, or");
+ puts("(at your option) any later version.");
+ puts("");
+ puts("This program is distributed in the hope that it will be useful,");
+ puts("but WITHOUT ANY WARRANTY; without even the implied warranty of");
+ puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the");
+ puts("GNU General Public License for more details.");
+ puts("");
+ puts("You should have received a copy of the GNU General Public License");
+ puts("along with this program; if not, write to the Free Software");
+ puts("Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.");
+ exit(EXIT_SUCCESS);
+
+ default:
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if ((argc-optind != 0) && (argc-optind != 1)) {
+ panic("Expecting zero or one arguments; got %i.\n", argc-optind);
+ }
+
+ /* No arguments, or argument `-': read from stdin */
+ if ((argc-optind == 0) || ((argc-optind == 1) && !strcmp(argv[optind], "-"))) {
+ dvifile = stdin;
+ } else {
+ dvifile = fopen(argv[optind], "rb");
+ if (!dvifile)
+ panic("Attempt to open '%s' failed: %s\n", argv[optind],
+ strerror(errno));
+ }
+
+ glyphops_init();
+ outenc_init();
+ /* set up some internal data structures */
+
+ process_file(dvifile);
+
+ fclose(dvifile);
+
+ return 0;
+}
diff --git a/dviware/catdvi/catdvi.d b/dviware/catdvi/catdvi.d
new file mode 100644
index 0000000000..35eb5cbf00
--- /dev/null
+++ b/dviware/catdvi/catdvi.d
@@ -0,0 +1,2 @@
+catdvi.o catdvi.d : catdvi.c findtfm.h readdvi.h bytesex.h outenc.h linebuf.h \
+ page.h pageref.h util.h version.h glyphops.h
diff --git a/dviware/catdvi/catdvi.pdf b/dviware/catdvi/catdvi.pdf
new file mode 100644
index 0000000000..e020f7b837
--- /dev/null
+++ b/dviware/catdvi/catdvi.pdf
Binary files differ
diff --git a/dviware/catdvi/catdvi.txt b/dviware/catdvi/catdvi.txt
new file mode 100644
index 0000000000..965124f6c4
--- /dev/null
+++ b/dviware/catdvi/catdvi.txt
@@ -0,0 +1,258 @@
+CATDVI(1) CATDVI(1)
+
+
+
+NAME
+ catdvi - a DVI to plain text converter
+
+SYNOPSIS
+ catdvi [-d debuglevel, --debug=debuglevel] [-e outenc,
+ --output-encoding=outenc] [-p pagespec, --first-page=page-
+ spec] [-l pagespec, --last-page=pagespec] [-N, --list-
+ page-numbers] [-s, --sequential] [-U, --show-unknown-
+ glyphs] [-h, --help] [--version] [--copyright] [dvi-file]
+
+DESCRIPTION
+ This manual page documents catdvi version 0.14
+
+ catdvi reads the DVI (typesetter DeVice Independent) file
+ dvi-file and dumps a plain text approximation of the docu-
+ ment it describes to stdout. If the argument dvi-file is
+ omitted or a dash (`-'), catdvi will read from stdin.
+ Several output encodings (different character sets of the
+ plain text output) are supported, most notably UTF-8.
+
+ The current version of catdvi is a work in progress; it
+ may not be robust enough for production use, but already
+ works fine with linear english text. Many mathematical
+ symbols (e.g. the uppercase greek letters) and moderately
+ complex formulae also come out right.
+
+ The program needs to read the TFM (Tex Font Metric) files
+ corresponding to the fonts used in the DVI file. These
+ are searched (and, if necessary and possible, created on
+ the fly) through the Kpathsea library.
+
+ In order to correctly translate a DVI file to text, the
+ input encoding of the fonts used in it (i.e. a meaning-
+ preserving mapping from font code points to Unicode) must
+ be known. There are a lot of different font encodings in
+ use. At the time of writing, catdvi understands the fol-
+ lowing input encodings:
+
+ `TEX TEXT'
+ Knuth's original font encoding, also known as OT1.
+
+ `TEX TEXT WITHOUT F-LIGATURES'
+ A variant of the above.
+
+ `EXTENDED TEX FONT ENCODING - LATIN'
+ The Cork encoding, also known as T1.
+
+ `TEX MATH ITALIC'
+ The encoding of Knuth's math italic fonts, also
+ known as OML.
+
+ `TEX MATH SYMBOLS'
+ The encoding of Knuth's math symbol fonts, also
+ known as OMS.
+
+ `TEX MATH EXTENSION' (most of it)
+ The encoding of Knuth's math extension fonts (big
+ operators, brackets, etc.), also known as OMX.
+
+ `TEX TYPEWRITER TEXT'
+ The encoding of Knuth's typewriter type fonts.
+
+ `LATEX SYMBOLS'
+ The encoding of the lasy fonts.
+
+ Henrik Theilings European currency symbol (`eurosym')
+ font.
+
+ `TEX TEXT COMPANION SYMBOLS 1---TS1' (almost everything)
+ The encoding of the text companion fonts.
+
+ Martin Vogels symbol (`MarVoSym') font.
+ Both the 1998 and the 2000 version are supported as
+ far as possible -- about half of the symbols are
+ not representable in Unicode.
+
+ `BLACKBOARD'
+ The encoding of the blackboard bold math (`bbm')
+ fonts.
+
+ All AMS fonts except the Cyrillic ones.
+ This includes the AMS math symbols group A and
+ group B, Euler fraktur, Euler cursive, Euler script
+ and Euler compatible extension fonts.
+
+ It is impossible to do perfect translation from unmarked-
+ up DVI to plain text, since the former does only describe
+ the layout of a page, and a translator such as this should
+ really know where words and paragraphs end, and more
+ importantly, which glyphs should be aligned vertically and
+ which shouldn't. The current alignment algorithm tries to
+ preserve the relative horizontal positions of word begin-
+ nings; this works well in most cases. Word breaks are
+ detected using simple heuristics; paragraphs are not
+ detected at all (and no paragraph fill is attempted).
+
+ The price of alignment is that the output will likely be
+ more than 80 columns wide, even though catdvi tries very
+ hard not to use more columns than strictly necessary.
+ Output is usually less than 120 columns, almost always
+ less than 132 columns wide. It may be a good idea to
+ switch your terminal to one of these modes if possible.
+
+
+OPTIONS
+ The program follows the usual GNU command line syntax,
+ with long options starting with two dashes.
+
+ -d debuglevel, --debug=debuglevel
+ Set the debug output level to debuglevel (default
+ is 10). Large values will result in lots of debug
+ output, 0 in none at all. The maximal debug output
+ level currently used is 150.
+
+ -e outenc, --output-encoding=outenc
+ Specify the encoding of the output character set.
+ outenc can be one of the numbers or names from the
+ table below. Names are case insensitive. The fol-
+ lowing output encodings should be available:
+
+ 0: UTF-8
+ 1: US-ASCII
+ 2: ISO-8859-1
+ 3: ISO-8859-15
+
+ The command catdvi --help (see below) will give a
+ more up-to-date list of all compiled-in output
+ encodings. The default encoding is 1.
+
+ -p pagespec, --first-page=pagespec
+ Do not output pages before page pagespec. Pages
+ can be specified in three different ways; the first
+ two are exactly the same as for dvips(1).
+
+ A (possibly negative) number num specifies a TeX
+ page number, which is stored as the so-called
+ count0 value in the DVI file for every page. Plain
+ TeX uses negative page numbers for roman-numbered
+ frontmatter (title page, preface, TOC, etc.) so the
+ count0 values compare as
+ -1 < -2 < -3 < ... < 1 < 2 < 3 < ...
+ There may be several pages with the same count0
+ value in a single DVI file. This usually happens in
+ documents with a per-chapter page numbering scheme.
+
+ A number prefixed by an equals sign (`=num') speci-
+ fies a physical page, i.e. the num-th page appear-
+ ing in the DVI file. Numbering starts with 1. Note
+ that with the long form of the option you actually
+ need two equals signs, one as part of the long
+ option and one as part of the page specification.
+ Example:
+ catdvi --first-page==5 foo.dvi
+
+ The third form of a page specification, two numbers
+ separated by a colon (`num1:num2'), is useful for
+ documents with separately-numbered parts, e.g.
+ chapters. It refers to the page with count0 value
+ equal to num2 that catdvi believes to be in part
+ num1. Since those part numbers are not stored in
+ the DVI file, the program has to guess them: an
+ internal chapter counter is increased by one every
+ time the count0 value of the current page is not
+ greater (in above ordering) than that of the previ-
+ ous page. The counter is initialized to 1 if the
+ first page has negative count0 value and to 0 oth-
+ erwise. (A document with separately numbered parts
+ will probably have separately numbered frontmatter
+ as well, and then this rule keeps the internal
+ counter equal to real world part numbers.)
+
+ -l pagespec, --last-page=pagespec
+ Do not output pages after page pagespec. Pages are
+ specified exactly as for the --first-page option
+ above.
+
+ -N, --list-page-numbers
+ Instead of the contents of pages, output their
+ physical page count, count0 value and chapter count
+ (see the --first-page option above for a definition
+ of these).
+
+ -s, --sequential
+ Do not attempt to reproduce the page layout; output
+ glyphs in the order they appear in the DVI file.
+ This may be useful with e.g. multi-column page lay-
+ outs.
+
+ -U, --show-unknown-glyphs
+ Show the Unicode number of unknown glyphs instead
+ of `?'.
+
+ -h, --help
+ Show usage information and a list of available
+ output encodings, then exit.
+
+ --version
+ Show version information and exit.
+
+ --copyright
+ Show copyright information and exit.
+
+ENVIRONMENT
+ The usual environment variables TFMFONTS, TEXFONTS, etc.
+ for Kpathsea font search and creation apply. Refer to the
+ Kpathsea documentation for details.
+
+SEE ALSO
+ xdvi(1), dvips(1), tex(1), mktextfm(1), the Kpathsea tex-
+ info documentation, utf-8(7).
+
+BUGS
+ These things do not work (yet):
+
+ o No rules are converted.
+
+ o Extensible recipes (very large brackets, braces,
+ etc. built out of several smaller pieces) are not
+ properly handled.
+
+ o Complicated math formulae are sometimes misaligned
+ (mostly due to lack of appropriate word break
+ heuristics).
+
+ o Some fonts and font encodings are not recognised
+ yet.
+
+ o Most mathematical symbols have no representation in
+ the available output character sets except Unicode,
+ and hence show up as `?' unless UTF-8 output encod-
+ ing is selected. A textual transcription would be
+ desirable.
+
+ Watch out for these:
+
+ o If there is a space where it does not belong or if
+ there is no space where there should be one, report
+ this as a bug (send the DVI file to the catdvi
+ maintainer, stating where in the file the bug is
+ seen).
+
+AUTHORS
+ catdvi was written by Antti-Juhani Kaijanaho
+ <gaia@iki.fi>, based on a skeletal version by
+ J.H.M. Dassen (Ray). Bjoern Brill <brill@fs.math.uni-
+ frankfurt.de> did further improvements and currently main-
+ tains the program.
+
+ The manual page was compiled by Bjoern Brill, using mate-
+ rial written by the first two program authors.
+
+
+
+ 8 November 2002 CATDVI(1)
diff --git a/dviware/catdvi/changelog-authors b/dviware/catdvi/changelog-authors
new file mode 100644
index 0000000000..1863a53acf
--- /dev/null
+++ b/dviware/catdvi/changelog-authors
@@ -0,0 +1,2 @@
+ajk:'Antti-Juhani Kaijanaho <gaia@iki.fi>'
+bjoernb:'Björn Brill <bjoernb@users.sourceforge.net>'
diff --git a/dviware/catdvi/config.mk.in b/dviware/catdvi/config.mk.in
new file mode 100644
index 0000000000..3d5a86c0cc
--- /dev/null
+++ b/dviware/catdvi/config.mk.in
@@ -0,0 +1,44 @@
+# -*- Makefile -*-
+# catdvi - get text from DVI files
+# Copyright (C) 1999 J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl>
+# Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+# Copyright (C) 2001 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+package = @PACKAGE@
+version = @VERSION@
+
+CFG_HAS_GETOPT_LONG = @CFG_HAS_GETOPT_LONG@
+CFG_HAS_KPATHSEA = @CFG_HAS_KPATHSEA@
+CFG_KPATHSEA_HAS_GETOPT_LONG = @CFG_KPATHSEA_HAS_GETOPT_LONG@
+CFG_SHOW_PSE2UNIC_WARNINGS = @CFG_SHOW_PSETOUNIC_WARNINGS@
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+mandir = @mandir@
+man1dir = ${mandir}/man1
+
+INSTALL = install
+INSTALL_PROGRAM = $(INSTALL)
+INSTALL_DATA = $(INSTALL)
+
+CVS2CL = cvs2cl
diff --git a/dviware/catdvi/configure b/dviware/catdvi/configure
new file mode 100644
index 0000000000..d108d893a7
--- /dev/null
+++ b/dviware/catdvi/configure
@@ -0,0 +1,1188 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-kpathsea-prefix=PREFIX
+ kpathsea library installed in PREFIX (optional)"
+ac_help="$ac_help
+ --enable-developer-warnings"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+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=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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 ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$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" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$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)
+ # 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 << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$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" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ 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)
+ 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" ;;
+
+ -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 ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=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" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=catdvi.c
+
+# 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 its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ 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
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+PACKAGE=catdvi
+VERSION=0.14
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:539: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+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
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:569: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_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 $# -gt 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
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:620: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:652: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 663 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:694: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:699: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:708: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:727: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&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
+
+
+echo $ac_n "checking for getopt_long""... $ac_c" 1>&6
+echo "configure:760: checking for getopt_long" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getopt_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 765 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getopt_long(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getopt_long();
+
+int main() {
+
+/* 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_getopt_long) || defined (__stub___getopt_long)
+choke me
+#else
+getopt_long();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:788: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_getopt_long=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_getopt_long=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'getopt_long`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ CFG_HAS_GETOPT_LONG=yes
+else
+ echo "$ac_t""no" 1>&6
+CFG_HAS_GETOPT_LONG=no
+fi
+
+
+
+# Check whether --with-kpathsea-prefix or --without-kpathsea-prefix was given.
+if test "${with_kpathsea_prefix+set}" = set; then
+ withval="$with_kpathsea_prefix"
+ kpathsea_prefix="$withval"
+else
+ kpathsea_prefix=""
+fi
+
+
+if test x"$kpathsea_prefix" = "xyes"; then
+ { echo "configure: error: *** --with-kpathsea-prefix requires an argument ***" 1>&2; exit 1; }
+fi
+if test x"$kpathsea_prefix" != "x"; then
+ LDFLAGS="$LDFLAGS -L$kpathsea_prefix/lib"
+ CPPFLAGS="$CPPFLAGS -I$kpathsea_prefix/include"
+fi
+
+
+echo $ac_n "checking for kpse_set_program_name in -lkpathsea""... $ac_c" 1>&6
+echo "configure:829: checking for kpse_set_program_name in -lkpathsea" >&5
+ac_lib_var=`echo kpathsea'_'kpse_set_program_name | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lkpathsea $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 837 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char kpse_set_program_name();
+
+int main() {
+kpse_set_program_name()
+; return 0; }
+EOF
+if { (eval echo configure:848: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ CFG_HAS_KPATHSEA=yes
+else
+ echo "$ac_t""no" 1>&6
+CFG_HAS_KPATHSEA=no
+fi
+
+
+
+if test x"$CFG_HAS_KPATHSEA" = "xno"; then
+ { echo "configure: error: *** kpathsea library (required) not found; try to use the --with-kpathsea-prefix option ***" 1>&2; exit 1; }
+fi
+
+if test x"$CFG_HAS_GETOPT_LONG" = "xno"; then
+ echo $ac_n "checking for getopt_long in -lkpathsea""... $ac_c" 1>&6
+echo "configure:877: checking for getopt_long in -lkpathsea" >&5
+ac_lib_var=`echo kpathsea'_'getopt_long | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lkpathsea $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 885 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getopt_long();
+
+int main() {
+getopt_long()
+; return 0; }
+EOF
+if { (eval echo configure:896: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ CFG_KPATHSEA_HAS_GETOPT_LONG=yes
+else
+ echo "$ac_t""no" 1>&6
+CFG_KPATHSEA_HAS_GETOPT_LONG=no
+fi
+
+else
+ CFG_KPATHSEA_HAS_GETOPT_LONG="no"
+fi
+
+
+# Check whether --enable-developer-warnings or --disable-developer-warnings was given.
+if test "${enable_developer_warnings+set}" = set; then
+ enableval="$enable_developer_warnings"
+ CFG_SHOW_PSETOUNIC_WARNINGS=yes
+else
+ CFG_SHOW_PSETOUNIC_WARNINGS=no
+fi
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# 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. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# 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.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "config.mk version.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@CC@%$CC%g
+s%@CFG_HAS_GETOPT_LONG@%$CFG_HAS_GETOPT_LONG%g
+s%@CFG_HAS_KPATHSEA@%$CFG_HAS_KPATHSEA%g
+s%@CFG_KPATHSEA_HAS_GETOPT_LONG@%$CFG_KPATHSEA_HAS_GETOPT_LONG%g
+s%@CFG_SHOW_PSETOUNIC_WARNINGS@%$CFG_SHOW_PSETOUNIC_WARNINGS%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"config.mk version.h"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/dviware/catdvi/configure.in b/dviware/catdvi/configure.in
new file mode 100644
index 0000000000..3640e0a295
--- /dev/null
+++ b/dviware/catdvi/configure.in
@@ -0,0 +1,70 @@
+dnl catdvi - get text from DVI files
+dnl Copyright (C) 2000, 2001 Antti-Juhani Kaijanaho <gaia@iki.fi>
+dnl Copyright (C) 2001 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+AC_INIT(catdvi.c)
+
+PACKAGE=catdvi
+VERSION=0.14
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+AC_PROG_CC
+
+AC_CHECK_FUNC(getopt_long, CFG_HAS_GETOPT_LONG=yes, CFG_HAS_GETOPT_LONG=no)
+AC_SUBST(CFG_HAS_GETOPT_LONG)
+
+AC_ARG_WITH(kpathsea-prefix,
+[ --with-kpathsea-prefix=PREFIX
+ kpathsea library installed in PREFIX (optional)],
+kpathsea_prefix="$withval", kpathsea_prefix="")
+
+if test x"$kpathsea_prefix" = "xyes"; then
+ AC_MSG_ERROR([*** --with-kpathsea-prefix requires an argument ***])
+fi
+if test x"$kpathsea_prefix" != "x"; then
+ LDFLAGS="$LDFLAGS -L$kpathsea_prefix/lib"
+ CPPFLAGS="$CPPFLAGS -I$kpathsea_prefix/include"
+fi
+
+
+AC_CHECK_LIB(kpathsea, kpse_set_program_name, CFG_HAS_KPATHSEA=yes, CFG_HAS_KPATHSEA=no)
+AC_SUBST(CFG_HAS_KPATHSEA)
+
+if test x"$CFG_HAS_KPATHSEA" = "xno"; then
+ AC_MSG_ERROR([*** kpathsea library (required) not found; try to use the --with-kpathsea-prefix option ***])
+fi
+
+dnl It seem libkpathsea provides a getopt_long() implementation
+dnl if and only if the C library does not.
+dnl
+dnl If the C library DOES have getopt_long, we can't check for another one
+dnl in libkpathsea without extra complications, because linking the
+dnl test program always succeeds. And we don't need it anyway.
+dnl
+if test x"$CFG_HAS_GETOPT_LONG" = "xno"; then
+ AC_CHECK_LIB(kpathsea, getopt_long, CFG_KPATHSEA_HAS_GETOPT_LONG=yes, CFG_KPATHSEA_HAS_GETOPT_LONG=no)
+else
+ CFG_KPATHSEA_HAS_GETOPT_LONG="no"
+fi
+AC_SUBST(CFG_KPATHSEA_HAS_GETOPT_LONG)
+
+AC_ARG_ENABLE(developer-warnings, [ --enable-developer-warnings],
+ CFG_SHOW_PSETOUNIC_WARNINGS=yes,
+ CFG_SHOW_PSETOUNIC_WARNINGS=no)
+AC_SUBST(CFG_SHOW_PSETOUNIC_WARNINGS)
+
+AC_OUTPUT(config.mk version.h)
diff --git a/dviware/catdvi/cvsparser.pl b/dviware/catdvi/cvsparser.pl
new file mode 100755
index 0000000000..325a617505
--- /dev/null
+++ b/dviware/catdvi/cvsparser.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/perl -w
+# Written by Antti-Juhani Kaijanaho for the GZigZag project
+
+use strict 'vars';
+
+sub main {
+ my @dirs = ();
+ my $dn = "";
+ push @dirs, ".";
+ DIRS : while ($#dirs >= 0) {
+ $dn = pop @dirs;
+ print STDERR "Finding files in `$dn'...";
+ open(ENTRIES, "<$dn/CVS/Entries") || next DIRS;
+ while (<ENTRIES>) {
+ if (m|^(D?)/([^/]+)/([0-9]+(\.[0-9]+)*)?/[^/]*/[^/]*/.*$|) {
+ my $dir = ($1 eq "D");
+ my $name = $2;
+ if ($dir) {
+ push @dirs, "$dn/$name";
+ } else {
+ print "$dn/$name\n";
+ }
+ } elsif (/^D$/) {
+ # ignore
+ } else {
+ print STDERR "###$_###";
+ die "syntax error"
+ }
+ }
+ close(ENTRIES);
+ print STDERR "done.\n";
+ }
+}
+main();
diff --git a/dviware/catdvi/density.c b/dviware/catdvi/density.c
new file mode 100644
index 0000000000..9c8d11bb21
--- /dev/null
+++ b/dviware/catdvi/density.c
@@ -0,0 +1,349 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2000-01 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "density.h"
+#include <assert.h>
+#include <stdlib.h>
+#include "util.h" /* for enomem() and xmalloc() */
+#include <stdio.h> /* used by scdf_dump only */
+#include <errno.h>
+
+/* Insert a step at x, with value f to the right. where is the nearest
+ * existing step to the left.
+ * Returns address of the newly created step.
+ */
+scdf_step_t * scdf_insert_after(
+ scdf_t * this,
+ scdf_step_t * where,
+ scdf_domain_t x,
+ scdf_range_t f
+);
+
+
+/* Delete the step _after_ (i.e. _right from_ ) where */
+void scdf_delete_after(scdf_t * this, scdf_step_t * where);
+
+
+/* Let scdf.curr point to the step in which x lies. Returns new curr. */
+scdf_step_t * scdf_set_curr_to_x(scdf_t * this, scdf_domain_t x);
+
+/**************************************************************************
+ **************************************************************************/
+
+
+void scdf_init(
+ scdf_t * this,
+ scdf_domain_t xmin,
+ scdf_domain_t xmax,
+ scdf_range_t f
+)
+{
+ scdf_step_t * pa, * pb;
+
+ assert(xmin < xmax);
+
+ this->xmin = xmin;
+ this->xmax = xmax;
+
+ pa = malloc(sizeof(scdf_step_t));
+ if(pa == NULL) enomem();
+ pb = malloc(sizeof(scdf_step_t));
+ if(pb == NULL) enomem();
+
+ pa->x = xmin;
+ pa->f = f;
+ pa->next = pb;
+ pb->x = xmax;
+ pb->f = f;
+ pb->next = NULL;
+
+ this->curr = this->head = pa;
+}
+
+void scdf_done(scdf_t * this)
+{
+ scdf_step_t * p0, * p1;
+
+ for(p0 = this->head; p0 != NULL; p0 = p1) {
+ p1 = p0->next;
+ free(p0);
+ }
+ this->curr = this->head = NULL;
+ this->xmin = this->xmax = 0;
+}
+
+
+scdf_step_t * scdf_insert_after(
+ scdf_t * this,
+ scdf_step_t * where,
+ scdf_domain_t x,
+ scdf_range_t f
+)
+{
+ scdf_step_t * p;
+
+ assert(where->next != NULL);
+ /* Can't insert after the end of the interval */
+ assert(where->x < x ); assert(x < where->next->x);
+
+ p = malloc(sizeof(scdf_step_t));
+ if(p == NULL) enomem();
+
+ p->x = x;
+ p->f = f;
+ p->next = where->next;
+ where->next = p;
+
+ return p;
+}
+
+
+void scdf_delete_after(scdf_t * this, scdf_step_t * where)
+{
+ scdf_step_t * p;
+
+ p = where->next;
+ assert(p != NULL);
+ /* Can't delete after the end of the interval */
+ assert(p->next != NULL);
+ /* Don't delete the "step" at xmax */
+
+ where->next = p->next;
+ if(this->curr == p) this->curr = where;
+ /* don't leave dangling curr */
+ free(p);
+}
+
+
+scdf_step_t * scdf_set_curr_to_x(scdf_t * this, scdf_domain_t x)
+{
+ scdf_step_t * p0, * p1;
+
+ assert(this->xmin <= x); assert(x <= this->xmax);
+
+ p0 = this->curr;
+ if(p0->x > x) p0 = this->head;
+ /* too far to the right, start at the left */
+
+ while(p1 = p0->next, p1 != NULL && p1->x <= x) p0 = p1;
+
+ this->curr = p0;
+ return p0;
+}
+
+
+void scdf_force_min_value(
+ scdf_t * this,
+ scdf_domain_t x0,
+ scdf_domain_t x1,
+ scdf_range_t fmin
+)
+{
+ scdf_step_t * p0, * p1;
+
+ assert(this->xmin <= x0); assert(x0 < x1); assert(x1 <= this->xmax);
+
+ p0 = scdf_set_curr_to_x(this, x0);
+ p1 = p0->next;
+
+ for( ; x0 < x1; x0 = p1->x, p0 = p1, p1 = p1->next) {
+
+ if(p1->x > x1) p1 = scdf_insert_after(this, p0, x1, p0->f);
+ /* Avoid complications that would arise in the last iteration
+ * if x1 wasn't a step boundary by forcing it to be one.
+ * A final scdf_normalize() will clean up this crap.
+ */
+
+ if(fmin <= p0->f) continue;
+ /* the nothing-to-do case: f is already large enough */
+
+ if(p0->x < x0) {
+ /* If we change the function value in the middle of a step
+ * we have to subdivide. The newly created step is automatically
+ * skipped by the for loop iteration code.
+ */
+ scdf_insert_after(this, p0, x0, fmin);
+ continue;
+ }
+
+ /* Now we know p0->x == x0 && x1 <= p1->x && p0->f < fmin ,
+ * i.e. we have a step which is completely contained in [x0, x1]
+ * and its value is too small.
+ */
+ p0->f = fmin;
+ }
+
+ this->curr = p0;
+ /* p0 points to the step containing x1 now - this is where the
+ * next call will most probably start.
+ */
+}
+
+
+void scdf_force_min_integral(
+ scdf_t * this,
+ scdf_domain_t x0,
+ scdf_domain_t x1,
+ scdf_range_t Jmin
+)
+{
+ if(Jmin > scdf_integral(this, x0, x1)) {
+ scdf_force_min_value(this, x0, x1, Jmin / (x1 - x0));
+ }
+}
+
+void scdf_normalize(scdf_t * this)
+{
+ scdf_step_t * p0, * p1, * p2;
+
+ p0 = this->head;
+ p1 = p0->next; /* always != NULL */
+ p2 = p1->next; /* could be NULL */
+
+ this->curr = this->head;
+ /* May point to free()d memory otherwise. Besides, we expect to
+ * be called after processing the whole interval of definition
+ * anyway.
+ */
+
+ while(p2 != NULL) {
+ if(p0->f == p1->f) scdf_delete_after(this, p0);
+ else p0 = p1;
+
+ p1 = p2;
+ p2 = p2->next;
+ }
+}
+
+
+scdf_domain_t scdf_solve_integral_for_x1(
+ scdf_t * this,
+ scdf_domain_t x0,
+ scdf_range_t J
+)
+{
+ scdf_step_t * p0, * p1;
+ scdf_range_t K;
+
+ assert(this->xmin <= x0); assert(x0 < this->xmax);
+ assert(J > 0);
+
+ p0 = scdf_set_curr_to_x(this, x0);
+
+ while(p1 = p0->next, p1 != NULL) {
+ K = p0->f * (p1->x - x0);
+ if(K > J) {
+ return x0 + (scdf_domain_t) (J / p0->f);
+ }
+
+ J -= K;
+ x0 = p1->x;
+ p0 = p1;
+ }
+ errno = EDOM;
+ return this->xmax;
+}
+
+scdf_range_t scdf_eval(scdf_t * this, scdf_domain_t x)
+{
+ return scdf_set_curr_to_x(this, x)->f;
+}
+
+
+scdf_range_t scdf_integral(scdf_t * this, scdf_domain_t x0, scdf_domain_t x1)
+{
+ scdf_step_t * p0, * p1;
+ scdf_domain_t d;
+ scdf_range_t J = 0;
+
+ assert(this->xmin <= x0); assert(x0 < x1); assert(x1 <= this->xmax);
+
+ p0 = scdf_set_curr_to_x(this, x0);
+ p1 = p0->next;
+
+ for( ; x0 < x1; x0 = p1->x, p0 = p1, p1 = p1->next) {
+
+ /* Sum it up step by step - and be careful with the last one. */
+ if(x1 < p1->x) d = x1 - x0;
+ else d = p1->x - x0;
+ J += d * p0->f;
+ }
+
+ return J;
+}
+
+void scdf_dump(scdf_t * this)
+{
+ scdf_step_t * p;
+
+ p = this->head;
+ fprintf(stderr, "scdf at %p {\n", (void *) this);
+ for(p = this->head; p != NULL; p = p->next) {
+ fprintf(stderr, "\tf(%10.8g) = %10.8g\n", (double) p->x, (double) p->f);
+ /* should work with any type of domain and range */
+ }
+ fputs("}\n", stderr);
+}
+
+
+scdf_t * scdf_floor_of_integral(scdf_t * this)
+{
+ scdf_domain_t x0, x1;
+ scdf_range_t f = 0;
+ scdf_t * result;
+ scdf_step_t * p;
+
+ result = xmalloc(sizeof(scdf_t));
+ scdf_init(result, this->xmin, this->xmax, 0);
+ /* we start with result identically 0 */
+ p = result->head;
+ x0 = this->xmin;
+
+ for( ; ; ) {
+ /* Where should the next jump by 1 of result be? */
+ errno = 0;
+ x1 = scdf_solve_integral_for_x1(this, x0, 1);
+
+ if(errno == EDOM) {
+ /* EDOM means not enough density right from x0 to give integral 1,
+ * i.e. no more jumps and we're done.
+ */
+ break;
+ }
+
+ /* OK, result should jump by 1 at x1 */
+ f += 1;
+ if(x1 == this->xmax) {
+ /* Jump is at the right margin, result already has a pseudo step
+ * there and we're done.
+ */
+ break;
+ }
+
+ /* Insert a step at x1 with value f */
+ p = scdf_insert_after(result, p, x1, f);
+
+ x0 = x1;
+ }
+
+ /* The pseudo step at xmax still has to get its f value */
+ p = scdf_set_curr_to_x(result, this->xmax);
+ p->f = f;
+
+ return result;
+}
diff --git a/dviware/catdvi/density.d b/dviware/catdvi/density.d
new file mode 100644
index 0000000000..55e63383cb
--- /dev/null
+++ b/dviware/catdvi/density.d
@@ -0,0 +1 @@
+density.o density.d : density.c density.h bytesex.h util.h
diff --git a/dviware/catdvi/density.h b/dviware/catdvi/density.h
new file mode 100644
index 0000000000..ae15febbdf
--- /dev/null
+++ b/dviware/catdvi/density.h
@@ -0,0 +1,157 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2000-01 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef DENSITY_H
+#define DENSITY_H
+
+/* Implements a staircase (i.e. piecewise constant) density function
+ * on an interval [xmin, xmax].
+ *
+ * The domain can be integral or "real" (float, double), the range should
+ * be "real".
+ *
+ * The implementation is NOT numerically sophisticated, so don't expect
+ * miracles.
+ */
+
+
+/* There's no need to use these two typdefs in an application. They
+ * are here for logical clarity and easy customization and can be changed
+ * as needed.
+ */
+#include "bytesex.h" /* for sint32 */
+typedef sint32 scdf_domain_t;
+typedef double scdf_range_t;
+
+/* convenience defs - c++ does this automatically */
+#ifndef __cplusplus
+typedef struct scdf_t scdf_t;
+typedef struct scdf_step_t scdf_step_t;
+#endif
+
+/* The function is stored as a (singly) linked list of steps. Its value
+ * f(x) is step.f for x in the half-open interval [step.x, step.next->x) .
+ * For technical reasons, we keep a last step with last.x = xmax and
+ * last.next = NULL. last.f is not important since any value f(xmax) will
+ * give the same integral of f.
+ *
+ * Typical applications will traverse [xmin, xmax) as a union of subintervals
+ * [x0, x1) from left to right. We try to keep this direction efficient.
+ */
+
+struct scdf_step_t {
+ scdf_domain_t x;
+ scdf_range_t f;
+ scdf_step_t * next;
+};
+
+struct scdf_t {
+ scdf_domain_t xmin;
+ scdf_domain_t xmax;
+ scdf_step_t * head;
+ scdf_step_t * curr;
+};
+
+
+void scdf_init(
+ scdf_t * this,
+ scdf_domain_t xmin,
+ scdf_domain_t xmax,
+ scdf_range_t f /* The initial (constant) value of f - usually 0 */
+);
+
+
+void scdf_done(scdf_t * this);
+
+/* Join neighbouring steps with the same f. This should be done at the
+ * end of a sequence of operations traversing [xmin, xmax] .
+ */
+void scdf_normalize(scdf_t * this);
+
+
+/* Force the density function to have at least value fmin in the interval
+ * [x0, x1). Mathematically: let g have value fmin on [x0, x1) and value
+ * (-infinity) elsewhere, then f is replaced by the pointwise maximum of
+ * f and g.
+ */
+void scdf_force_min_value(
+ scdf_t * this,
+ scdf_domain_t x0,
+ scdf_domain_t x1,
+ scdf_range_t fmin
+);
+
+
+/* Force f to have at least integral Jmin on [x0, x1]. This is currently
+ * done by first checking if the integral is large enough anyway, and
+ * forcing f to have value at least Jmin / (x1 - x0) if not. More
+ * sophisticated (keeping f smaller in some cases) methods are possible.
+ * However, some experiments with real world data for the intended application
+ * (catdvi) have shown that:
+ * - Methods that tend to evenly distribute the density (like the
+ * one implemented here) do in almost all cases yield better results
+ * (both in terms of appearance of output and of shorter lines) than
+ * an exact "additive" method which gives rather uneven distributions.
+ * - Replacing Jmin / (x1 - x0) by a quantity deviating at most 1/128
+ * from the minimal possible value gains 1-3 columns for some lines
+ * and nothing most of the time.
+ * Since the currently implemented method is fast and seems to be nearly
+ * optimal for typical catdvi input, we'll probably stick with it.
+ */
+void scdf_force_min_integral(
+ scdf_t * this,
+ scdf_domain_t x0,
+ scdf_domain_t x1,
+ scdf_range_t Jmin
+);
+
+
+/* Find the value of f at x */
+scdf_range_t scdf_eval(scdf_t * this, scdf_domain_t x);
+
+
+/* Compute the integral of f on [x0, x1] */
+scdf_range_t scdf_integral(scdf_t * this, scdf_domain_t x0, scdf_domain_t x1);
+
+
+/* Solve the equation "integral of f on [x0, x1] = J" for x1;
+ * set errno = EDOM if this is not possible.
+ *
+ * The algorithm used has to do a conversion from scdf_range_t to
+ * scdf_domain_t, which is done by casting a _positive_ value of
+ * type scdf_range_t to scdf_domain_t. This should result in rounding
+ * the return value towards (-infinity) in cases where loss of precision
+ * occurs.
+ */
+scdf_domain_t scdf_solve_integral_for_x1(
+ scdf_t * this,
+ scdf_domain_t x0,
+ scdf_range_t J
+);
+
+/* Create new staircase function
+ * F(x) = floor(integral(f(t), t = f.xmin..x))
+ * on the heap; return pointer to it. Abort if OOM.
+ * F obviously has the same domain of definition as f.
+ */
+scdf_t * scdf_floor_of_integral(scdf_t * this);
+
+/* Dump a textual representation of f to stderr */
+void scdf_dump(scdf_t * this);
+
+#endif
diff --git a/dviware/catdvi/enc/README b/dviware/catdvi/enc/README
new file mode 100644
index 0000000000..14c1b9c492
--- /dev/null
+++ b/dviware/catdvi/enc/README
@@ -0,0 +1,89 @@
+The *.enc files in this directory are in the DVIPS ENC format.
+
+Here's the description of that format, pasted from the dvips manual.
+Note that we ignore the ligature and kerning information.
+
+-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
+
+ Afm2tfm's encoding files have the same format as an encoding vector
+in a PostScript font. Here is a skeletal example:
+
+ % Comments are ignored, unless the first word after the percent sign
+ % is `LIGKERN'; see below.
+ /MyEncoding [ % exactly 256 entries follow, each with a leading `/'
+ /Alpha /Beta /Gamma /Delta ...
+ /A /B ... /Z
+ ... /.notdef /xfooaccent /yfooaccent /zfooaccent
+ ] def
+
+ These encoding files are downloaded as part of changing the encoding
+at the PostScript level (see the previous section).
+
+ Comments, which start with a percent sign and continue until the end
+of the line, are ignored unless they start with `LIGKERN' (see below).
+
+ The first non-comment word of the file must start with a forward slash
+`/' (i.e., a PostScript literal name) and defines the name of the
+encoding. The next word must be an left bracket `['. Following that
+must be precisely 256 character names; use `/.notdef' for any that you
+want to leave undefined. Then there must be a matching right bracket
+`]'. A final `def' token is optional. All names are case-sensitive.
+
+ Any ligature or kern information is given as a comment. If the first
+word after the `%' is `LIGKERN', then the entire rest of the line is
+parsed for ligature and kern information. This ligature and kern
+information is given in groups of words: each group is terminated by a
+space and a semicolon and (unless the semicolon is at the end of a
+line) another space.
+
+ In these `LIGKERN' statements, three types of information may be
+specified. These three types are ligature pairs, kerns to ignore, and
+the character value of this font's boundary character.
+
+ Throughout a `LIGKERN' statement, the boundary character is specified
+as `||'. To set the font's boundary character value for TeX:
+
+ % LIGKERN || = 39 ;
+
+ To indicate a kern to remove, give the names of the two characters
+(without the leading slash) separated by `{}', as in `one {} one ;'.
+This is intended to be reminiscent of the way you might use `{}' in a
+TeX file to turn off ligatures or kerns at a particular location.
+Either or both of the character names can be given as `*', which is a
+wild card matching any character; thus, all kerns can be removed with
+`* {} * ;'.
+
+ To specify a ligature, specify the names of the pair of characters,
+followed by the ligature operation (as in Metafont), followed by the
+replacing character name. Either (but not both) of the first two
+characters can be `||' to indicate a word boundary.
+
+ The most common operation is `=:' meaning that both characters are
+removed and replaced by the third character, but by adding the `|'
+character on either side of the `=:', you can retain either or both of
+the two leading characters. In addition, by suffixing the ligature
+operation with one or two `>' signs, you can make the ligature scanning
+operation skip that many resulting characters before proceeding. This
+works just like in Metafont. For example, the `fi' ligature is
+specified with `f i =: fi ;'. A more convoluted ligature is `one one
+|=:|>> exclam ;' which separates a pair of adjacent `1''s with an
+exclamation point, and then skips over two of the resulting characters
+before continuing searching for ligatures and kerns. You cannot give
+more >'s than |'s in an ligature operation, so there are a total of
+eight possibilities:
+
+ =: |=: |=:> =:| =:|> |=:| |=:|> |=:|>>
+
+ The default set of ligatures and kerns built in to Afm2tfm is:
+
+ % LIGKERN question quoteleft =: questiondown ;
+ % LIGKERN exclam quoteleft =: exclamdown ;
+ % LIGKERN hyphen hyphen =: endash ; endash hyphen =: emdash ;
+ % LIGKERN quoteleft quoteleft =: quotedblleft ;
+ % LIGKERN quoteright quoteright =: quotedblright ;
+ % LIGKERN space {} * ; * {} space ; 0 {} * ; * {} 0 ;
+ % LIGKERN 1 {} * ; * {} 1 ; 2 {} * ; * {} 2 ; 3 {} * ; * {} 3 ;
+ % LIGKERN 4 {} * ; * {} 4 ; 5 {} * ; * {} 5 ; 6 {} * ; * {} 6 ;
+ % LIGKERN 7 {} * ; * {} 7 ; 8 {} * ; * {} 8 ; 9 {} * ; * {} 9 ;
+
+-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- \ No newline at end of file
diff --git a/dviware/catdvi/enc/amssymba.enc b/dviware/catdvi/enc/amssymba.enc
new file mode 100644
index 0000000000..ccd7e9e4fd
--- /dev/null
+++ b/dviware/catdvi/enc/amssymba.enc
@@ -0,0 +1,220 @@
+% Encoding of AMS math symbols, group A (MSAM)
+%
+/AMSSymbolsAEncoding [
+% 0x00 ( 0)
+/$boxdot
+/$boxplus
+/$boxmultiply
+/$box
+
+/filledbox
+/$filledboxsmall
+/lozenge
+/$filledlozenge
+
+/$arrowclockwise
+/$arrowanticlockwise
+/$harpoonsrightleft
+/$harpoonsleftright
+
+/$boxminus
+/$forces
+/$forcestriplevbar
+/$true
+
+% 0x10 ( 16)
+/$twoheadarrowright
+/$twoheadarrowleft
+/$arrowsleftleft
+/$arrowsrightright
+
+/$arrowsupup
+/$arrowsdowndown
+/$harpoonupbarbright
+/$harpoondownbarbright
+
+/$harpoonupbarbleft
+/$harpoondownbarbleft
+/$tailarrowright
+/$tailarrowleft
+
+/$arrowsleftright
+/$arrowsrightleft
+/$arrowuptipleft
+/$arrowuptipright
+
+% 0x20 ( 32)
+/$squigarrowright
+/.notavail % leftrightsquigarrow
+/$looparrowleft
+/$looparrowright
+
+/$ringequal
+/$followssimilar
+/$greatersimilar
+/$greaterapprox
+
+/$multimap
+/therefore
+/$because
+/$dotequaldot
+
+/$deltaequal
+/$precedessimilar
+/$lesssimilar
+/$lessapprox
+
+% 0x30 ( 48)
+/$equalslantedless
+/$equalslantedgreater
+/$equalprecedes
+/$equalfollows
+
+/$precedesequal
+/$lessequal2
+/$lessequalslanted
+/$lessgreater
+
+/$minutereversed
+/.notavail % dash for shaft of dashed arrows
+/$risingdotsequal
+/$fallingdotsequal
+
+/$followsequal
+/$greaterequal2
+/$greaterequalslanted
+/$greaterless
+
+% 0x40 ( 64)
+/$subsetsq
+/$supersetsq
+/$normalizes
+/$normalin
+
+/$reflexnormalizes
+/$reflexnormalin
+/$star
+/$between
+
+/triagdn
+/$triangleright
+/$triangleleft
+/.notavail % right pointing tip for dashed arrows
+
+/.notavail % left pointing tip for dashed arrows
+/$triagwhiteup
+/triagup
+/$triagwhitedn
+
+% 0x50 ( 80)
+/$ringinequal
+/$lessequalgreater
+/$greaterequalless
+/$lessequalgreaterstacked
+
+/$greaterequallessstacked
+/yen
+/$arrowtripleright
+/$arrowtripleleft
+
+/$checkmark
+/$veebar
+/$barwedge
+/$doublebarwedge
+
+/angle
+/$measuredangle
+/$sphericalangle
+/proportional
+
+% 0x60 ( 96)
+/$smile %smallsmile
+/$frown %smallfrown
+/$subsetdbl
+/$supersetdbl
+
+/$uniondbl
+/$intersectiondbl
+/$curlywedge
+/$curlyvee
+
+/$leftthreetimes
+/$rightthreetimes
+/$subsetequal2
+/$supersetequal2
+
+/$bumpequal
+/$bumpdentequal
+/$lessverymuch
+/$greaterverymuch
+
+% 0x70 (112)
+/$ulcorner
+/$urcorner
+/registered
+/$circleS
+
+/$pitchfork
+/$dotplus
+/$similarreversed
+/$similarequalreversed
+
+/$llcorner
+/$lrcorner
+/$maltesecross
+/$complement
+
+/$intercalate
+/$circlering
+/$circleasterisk
+/$circledash
+
+% 0x80 (128)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x90 (144)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xa0 (160)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xb0 (176)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xc0 (192)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xd0 (208)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xe0 (224)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0 (240)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+] def
diff --git a/dviware/catdvi/enc/amssymbb.enc b/dviware/catdvi/enc/amssymbb.enc
new file mode 100644
index 0000000000..b6c64a1e8d
--- /dev/null
+++ b/dviware/catdvi/enc/amssymbb.enc
@@ -0,0 +1,220 @@
+% Encoding of AMS math symbols, group B (MSBM)
+%
+/AMSSymbolsBEncoding [
+% 0x00 ( 0)
+/$lessnotequal % glyph variant of code point 0x07
+/$greaternotequal % glyph variant of code point 0x08
+/$notlessequal
+/$notgreaterequal
+
+/$notless
+/$notgreater
+/$precedesnot
+/$followsnot
+
+/$lessnotequal
+/$greaternotequal
+/$notlessequalslanted
+/$notgreaterequalslanted
+
+/$lessnotequal1
+/$greaternotequal1
+/$notprecedesequal % Unicode character chart has slightly different shape
+/$notfollowsequal % Unicode character chart has slightly different shape
+
+% 0x10 ( 16)
+/$precedesnotsimilar
+/$followsnotsimilar
+/$lessnotsimilar
+/$greaternotsimilar
+
+/$notlessequal2
+/$notgreaterequal2
+/$precedesnotequal
+/$followsnotequal
+
+/$precedesnotapprox
+/$followsnotapprox
+/$lessnotapprox
+/$greaternotapprox
+
+/$notsimilar % bold glyph variant
+/$notcongruent
+/$divisionslashbig
+/$divisionbackslashbig
+
+% 0x20 ( 32)
+/$subsetnotequal % glyph variant of code point 0x28
+/$supersetnotequal % glyph variant of code point 0x29
+/$notsubsetequal2
+/$notsupersetequal2
+
+/$subsetnotequal2
+/$supersetnotequal2
+/$subsetnotequal2 % glyph variant of code point 0x24
+/$supersetnotequal2 % glyph variant of code point 0x25
+
+/$subsetnotequal
+/$supersetnotequal
+/$notsubsetequal
+/$notsupersetequal
+
+/$notparallel
+/$dividesnot
+/$dividesnot % short glyph variant
+/$notparallel % short glyph variant
+
+% 0x30 ( 48)
+/$provesnot
+/$forcesnot
+/$nottrue
+/$notforcesdoublehbar
+
+/$notreflexnormalizes
+/$notreflexnormalin
+/$notnormalin
+/$notnormalizes
+
+/$notarrowleft
+/$notarrowright
+/$notarrowdblleft
+/$notarrowdblright
+
+/$notarrowdblboth
+/$notarrowboth
+/$divideontimes
+/emptyset
+
+% 0x40 ( 64)
+/$notexistential
+/$Amathbb
+/$Bmathbb
+/$Cdblstruck
+
+/$Dmathbb
+/$Emathbb
+/$Fmathbb
+/$Gmathbb
+
+/$Hdblstruck
+/$Imathbb
+/$Jmathbb
+/$Kmathbb
+
+/$Lmathbb
+/$Mmathbb
+/$Ndblstruck
+/$Omathbb
+
+% 0x50 ( 80)
+/$Pdblstruck
+/$Qdblstruck
+/$Rdblstruck
+/$Smathbb
+
+/$Tmathbb
+/$Umathbb
+/$Vmathbb
+/$Wmathbb
+
+/$Xmathbb
+/$Ymathbb
+/$Zdblstruck
+/$hatxwide
+
+/$hatxwide
+/$tildexwide
+/$tildexwide
+/.notdef
+
+% 0x60 ( 96)
+/$Finv
+/$Game
+/.notdef
+/.notdef
+
+/.notdef
+/.notdef
+/$Mho
+/eth
+
+/$equalsimilar
+/$beth
+/$gimel
+/$daleth
+
+/$lessdot
+/$greaterdot
+/$lefttimes
+/$righttimes
+
+% 0x70 (112)
+/bar % short glyph variant
+/$parallel % short glyph variant
+/$setminus
+/similar % bold glyph variant
+
+/approxequal % bold glyph variant
+/$approxequal1
+/$followsapprox
+/$precedesapprox
+
+/$curvearrowleft
+/$curvearrowright
+/$digamma
+/$kappa1
+
+/$kmathbb
+/$planckhbar % glyph variant of code point 0x7e
+/$planckhbar
+/$epsilon1inv
+
+% 0x80 (128)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x90 (144)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xa0 (160)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xb0 (176)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xc0 (192)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xd0 (208)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xe0 (224)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0 (240)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+] def
diff --git a/dviware/catdvi/enc/blackboard.enc b/dviware/catdvi/enc/blackboard.enc
new file mode 100644
index 0000000000..19e9f8410d
--- /dev/null
+++ b/dviware/catdvi/enc/blackboard.enc
@@ -0,0 +1,163 @@
+% The encoding of the `blackboard bold math' (bbm) fonts.
+%
+/BlackboardEncoding [
+% 0x00 ( 0)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x10 ( 16)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x20 ( 32)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/$parenleftwhite
+/$parenrightwhite
+/.notdef
+/.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x30 ( 48)
+/.notdef
+/$onemathbb
+/$twomathbb
+/.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x40 ( 64)
+/.notdef
+/$Amathbb
+/$Bmathbb
+/$Cdblstruck
+
+/$Dmathbb
+/$Emathbb
+/$Fmathbb
+/$Gmathbb
+
+/$Hdblstruck
+/$Imathbb
+/$Jmathbb
+/$Kmathbb
+
+/$Lmathbb
+/$Mmathbb
+/$Ndblstruck
+/$Omathbb
+
+% 0x50 ( 80)
+/$Pdblstruck
+/$Qdblstruck
+/$Rdblstruck
+/$Smathbb
+
+/$Tmathbb
+/$Umathbb
+/$Vmathbb
+/$Wmathbb
+
+/$Xmathbb
+/$Ymathbb
+/$Zdblstruck
+/$bracketleftwhitemath
+
+/.notdef
+/$bracketrightwhitemath
+/.notdef
+/.notdef
+
+% 0x60 ( 96)
+/.notdef
+/$amathbb
+/$bmathbb
+/$cmathbb
+
+/$dmathbb
+/$emathbb
+/$fmathbb
+/$gmathbb
+
+/$hmathbb
+/$imathbb
+/$jmathbb
+/$kmathbb
+
+/$lmathbb
+/$mmathbb
+/$nmathbb
+/$omathbb
+
+% 0x70 (112)
+/$pmathbb
+/$qmathbb
+/$rmathbb
+/$smathbb
+
+/$tmathbb
+/$umathbb
+/$vmathbb
+/$wmathbb
+
+/$xmathbb
+/$ymathbb
+/$zmathbb
+/.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x80 (128)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x90 (144)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xa0 (160)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xb0 (176)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xc0 (192)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xd0 (208)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xe0 (224)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0 (240)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+] def
diff --git a/dviware/catdvi/enc/cork.enc b/dviware/catdvi/enc/cork.enc
new file mode 100644
index 0000000000..12b77c53a3
--- /dev/null
+++ b/dviware/catdvi/enc/cork.enc
@@ -0,0 +1,100 @@
+% This is the Cork encoding, aka EC, Cork, aka TeX Latin 1, as
+% described in TTN 1(4), December 1992, and TUGboat 11(4), November
+% 1990, page 514. EC is the name of the Computer Modern-based fonts in
+% this encoding. NFSS and Fontinst know it by `T1'.
+%
+% These are the ligs and kerns in addition to those found in the
+% AFM file. (The only ligs in the Times-Roman.afm file are the
+% fi and fl ligatures.)
+%
+% LIGKERN space l =: lslash ; space L =: Lslash ;
+% LIGKERN question quoteleft =: questiondown ; exclam quoteleft =: exclamdown ;
+% LIGKERN hyphen hyphen =: endash ; endash hyphen =: emdash ;
+% LIGKERN quoteleft quoteleft =: quotedblleft ;
+% LIGKERN quoteright quoteright =: quotedblright ;
+%
+% We blow away kerns to and from spaces (TeX doesn't have a
+% space) and also remove any kerns from the numbers (although
+% the only kern pair that mentions a number in Times-Roman.afm
+% is one one.)
+%
+% LIGKERN space {} * ; * {} space ; zero {} * ; * {} zero ;
+% LIGKERN one {} * ; * {} one ; two {} * ; * {} two ;
+% LIGKERN three {} * ; * {} three ; four {} * ; * {} four ;
+% LIGKERN five {} * ; * {} five ; six {} * ; * {} six ;
+% LIGKERN seven {} * ; * {} seven ; eight {} * ; * {} eight ;
+% LIGKERN nine {} * ; * {} nine ;
+% LIGKERN comma comma =: quotedblbase ; less less =: guillemotleft ;
+% LIGKERN greater greater =: guillemotright ;
+%
+/CorkEncoding [ % now 256 chars follow
+% 0x00
+ /grave /acute /circumflex /tilde /dieresis /hungarumlaut /ring /caron
+ /breve /$macron /dotaccent /cedilla
+ /ogonek /quotesinglbase /guilsinglleft /guilsinglright
+% 0x10
+ /quotedblleft /quotedblright /quotedblbase /guillemotleft
+ /guillemotright /endash /emdash
+/$ZWNJ %/compworkmark
+/zero %/perthousandzero
+ /dotlessi /dotlessj /ff /fi /fl /ffi /ffl
+% 0x20
+/$visualspace
+ /exclam /quotedbl /numbersign
+ /dollar /percent /ampersand /quoteright
+ /parenleft /parenright /asterisk /plus /comma /$hyphen /period /slash
+% 0x30
+ /zero /one /two /three /four /five /six /seven
+ /eight /nine /colon /semicolon /less /equal /greater /question
+% 0x40
+ /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O
+% 0x50
+ /P /Q /R /S /T /U /V /W
+ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+% 0x60
+ /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
+% 0x70
+ /p /q /r /s /t /u /v /w
+ /x /y /z /braceleft /bar /braceright /asciitilde /$hyphen
+% 0x80
+ /Abreve /Aogonek /Cacute /Ccaron /Dcaron /Ecaron /Eogonek /Gbreve
+ /Lacute /Lcaron /Lslash /Nacute /Ncaron
+/Eng %/Ng
+ /Ohungarumlaut /Racute
+% 0x90
+ /Rcaron /Sacute /Scaron /$Scedilla
+ /Tcaron
+ /$Tcedilla %was: /Tcedilla
+ /Uhungarumlaut /Uring
+ /Ydieresis /Zacute /Zcaron /Zdotaccent /IJ /Idotaccent
+ /dcroat %was: /dbar
+ /section
+% 0xA0
+ /abreve /aogonek /cacute /ccaron /dcaron /ecaron /eogonek /gbreve
+ /lacute /lcaron /lslash /nacute /ncaron
+/eng %/ng
+ /ohungarumlaut /racute
+% 0xB0
+ /rcaron /sacute /scaron /$scedilla
+ /tcaron %was: /tquoteright but is just the form of tcaron preferred
+ %in typograpy (see e.g. the Unicode charts)
+ /$tcedilla %was: /tcedilla
+ /uhungarumlaut /uring
+ /ydieresis /zacute /zcaron /zdotaccent
+ /ij /exclamdown /questiondown /sterling
+% 0xC0
+ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+ /Egrave /Eacute /Ecircumflex /Edieresis
+ /Igrave /Iacute /Icircumflex /Idieresis
+% 0xD0
+ /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /OE
+ /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn
+/$DoubleS %/Germandbls
+% 0xE0
+ /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+ /egrave /eacute /ecircumflex /edieresis
+ /igrave /iacute /icircumflex /idieresis
+% 0xF0
+ /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /oe
+ /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /germandbls
+] def
diff --git a/dviware/catdvi/enc/dummy.enc b/dviware/catdvi/enc/dummy.enc
new file mode 100644
index 0000000000..edde9263ea
--- /dev/null
+++ b/dviware/catdvi/enc/dummy.enc
@@ -0,0 +1,103 @@
+% Empty dummy encoding --
+% used for some fonts who lie about their encoding and for which we don't
+% have a real encoding vector yet (some AMS fonts, for example, pretend to
+% be `TEX TEXT' encoded, but are not).
+%
+/DummyEncoding [
+% 0x00 ( 0)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x10 ( 16)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x20 ( 32)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x30 ( 48)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x40 ( 64)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x50 ( 80)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x60 ( 96)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x70 (112)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x80 (128)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x90 (144)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xa0 (160)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xb0 (176)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xc0 (192)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xd0 (208)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xe0 (224)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0 (240)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+] def
diff --git a/dviware/catdvi/enc/euex.enc b/dviware/catdvi/enc/euex.enc
new file mode 100644
index 0000000000..c7eadb8243
--- /dev/null
+++ b/dviware/catdvi/enc/euex.enc
@@ -0,0 +1,171 @@
+% Euler-compatible extension (euex) font encoding.
+%
+/EulerExtensionEncoding [
+% 0x00 ( 0)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+/$braceleftbig
+/$bracerightbig
+/$braceleftBig
+/$bracerightBig
+
+/$braceleftbigg
+/$bracerightbigg
+/$braceleftBigg
+/$bracerightBigg
+
+% 0x10 ( 16)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+/$harpoonleftbarbup
+/$harpoonleftbarbdown
+/$harpoonrightbarbup
+/$harpoonrightbarbdown
+
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x20 ( 32)
+/arrowleft
+/arrowright
+/arrowup
+/arrowdown
+
+/arrowboth
+/$arrownortheast
+/$arrowsoutheast
+/.notdef
+
+/arrowdblleft
+/arrowdblright
+/arrowdblup
+/arrowdbldown
+
+/arrowdblboth
+/$arrownorthwest
+/$arrowsouthwest
+/.notdef
+
+% 0x30 ( 48)
+/.notdef
+/infinity
+/.notdef
+/.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+
+/$bracelefttp
+/$bracerighttp
+/$braceleftbt
+/$bracerightbt
+
+/$braceleftmid
+/$bracerightmid
+/$braceex
+/.notdef
+
+% 0x40 ( 64)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+/$contintegraltext
+/$contintegraldisplay
+/.notdef
+/.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x50 ( 80)
+/$summationtext
+/$producttext
+/$integraltext
+/.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+
+/$summationdisplay
+/$productdisplay
+/$integraldisplay
+/.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x60 ( 96)
+/$coproducttext
+/$coproductdisplay
+/.notdef
+/.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+
+/arrowupdn
+/$arrowdblupdn
+/.notdef
+/.notdef
+
+% 0x70 (112)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+/.notdef
+/.notdef
+/$bracehtipdownleft
+/$bracehtipdownright
+
+/$bracehtipupleft
+/$bracehtipupright
+/.notdef
+/.notdef
+
+% 0x80 (128)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x90 (144)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xa0 (160)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xb0 (176)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xc0 (192)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xd0 (208)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xe0 (224)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0 (240)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+] def
diff --git a/dviware/catdvi/enc/eufrak.enc b/dviware/catdvi/enc/eufrak.enc
new file mode 100644
index 0000000000..d5ccd7f6d3
--- /dev/null
+++ b/dviware/catdvi/enc/eufrak.enc
@@ -0,0 +1,202 @@
+% Encoding of the Euler Fraktur fonts (part of the AMS fonts)
+%
+/EulerFrakturEncoding [
+% 0x00 ( 0)
+/$dmathfrak % alternate shape
+/$dmathfrak % alternate shape
+/$fmathfrak % alternate shape
+/$fmathfrak % alternate shape
+
+/$gmathfrak % alternate shape
+/$kmathfrak % alternate shape
+/$tmathfrak % alternate shape
+/$umathfrak % alternate shape
+
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x10 ( 16)
+/.notdef
+/.notdef
+/quoteleft
+/quoteright
+
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x20 ( 32)
+/.notdef
+/exclam
+/.notdef
+/.notdef
+
+/.notdef
+/.notdef
+/ampersand
+/quotesingle
+
+/parenleft
+/parenright
+/asterisk
+/plus
+
+/comma
+/minus
+/period
+/slash
+
+% 0x30 ( 48)
+/zerooldstyle
+/oneoldstyle
+/twooldstyle
+/threeoldstyle
+
+/fouroldstyle
+/fiveoldstyle
+/sixoldstyle
+/sevenoldstyle
+
+/eightoldstyle
+/nineoldstyle
+/colon
+/semicolon
+
+/.notdef
+/equal
+/.notdef
+/question
+
+% 0x40 ( 64)
+/.notdef
+/$Amathfrak
+/$Bmathfrak
+/$Cfraktur
+
+/$Dmathfrak
+/$Emathfrak
+/$Fmathfrak
+/$Gmathfrak
+
+/$Hfraktur
+/Ifraktur
+/$Jmathfrak
+/$Kmathfrak
+
+/$Lmathfrak
+/$Mmathfrak
+/$Nmathfrak
+/$Omathfrak
+
+% 0x50 ( 80)
+/$Pmathfrak
+/$Qmathfrak
+/Rfraktur
+/$Smathfrak
+
+/$Tmathfrak
+/$Umathfrak
+/$Vmathfrak
+/$Wmathfrak
+
+/$Xmathfrak
+/$Ymathfrak
+/$Zfraktur
+/bracketleft
+
+/.notdef
+/bracketright
+/asciicircum
+/.notdef
+
+% 0x60 ( 96)
+/.notdef
+/$amathfrak
+/$bmathfrak
+/$cmathfrak
+
+/$dmathfrak
+/$emathfrak
+/$fmathfrak
+/$gmathfrak
+
+/$hmathfrak
+/$imathfrak
+/$jmathfrak
+/$kmathfrak
+
+/$lmathfrak
+/$mmathfrak
+/$nmathfrak
+/$omathfrak
+
+% 0x70 (112)
+/$pmathfrak
+/$qmathfrak
+/$rmathfrak
+/$smathfrak
+
+/$tmathfrak
+/$umathfrak
+/$vmathfrak
+/$wmathfrak
+
+/$xmathfrak
+/$ymathfrak
+/$zmathfrak
+/.notdef
+
+/.notdef
+/quotedbl
+/.notdef
+/one % alternate shape
+
+% 0x80 (128)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x90 (144)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xa0 (160)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xb0 (176)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xc0 (192)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xd0 (208)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xe0 (224)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0 (240)
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+] def
diff --git a/dviware/catdvi/enc/eurosym.enc b/dviware/catdvi/enc/eurosym.enc
new file mode 100644
index 0000000000..4b28e84e17
--- /dev/null
+++ b/dviware/catdvi/enc/eurosym.enc
@@ -0,0 +1,100 @@
+%The encoding of the fey?? Euro symbol fonts in the eurosym package.
+%
+/EurosymEncoding [
+% 0x00
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x10
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x20
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x30
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x40
+/.notdef /$Eurodblstroke /$Eurodblstroke /$Eurodblstroke
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x50
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x60
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /Euro /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x70
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x80
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x90
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xa0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xb0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xc0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xd0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xe0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+] def
diff --git a/dviware/catdvi/enc/latexsym.enc b/dviware/catdvi/enc/latexsym.enc
new file mode 100644
index 0000000000..6ddae26ca6
--- /dev/null
+++ b/dviware/catdvi/enc/latexsym.enc
@@ -0,0 +1,127 @@
+% The LaTeX symbols encoding
+%
+% Ligs and kerns left out.
+
+/LaTeXSymbolsEncoding [
+% 0x00
+/.notdef
+/$normalin
+/$reflexnormalin
+/$normalizes
+
+/$reflexnormalizes
+/.notdef
+/.notdef
+/.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x10
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x20
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+/.notavail % left arrowhead, not in Unicode 3.2
+/.notavail % right arrowhead, not in Unicode 3.2
+/$arrowheadup
+/$arrowheaddown
+
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x30
+/$Mho
+/$bowtie
+/$box
+/$diamondshape
+
+/.notdef /.notdef /.notdef /.notdef
+
+/.notdef
+/.notdef
+/.notavail % leadsto horizontal extension, not in Unicode 3.2
+/$squigarrowright % leadsto
+
+/$subsetsq
+/$supersetsq
+/.notdef
+/.notdef
+
+% 0x40
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x50
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x60
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x70
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x80
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x90
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xa0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xb0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xc0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xd0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xe0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+] def
diff --git a/dviware/catdvi/enc/marvo00.enc b/dviware/catdvi/enc/marvo00.enc
new file mode 100644
index 0000000000..1766911b6a
--- /dev/null
+++ b/dviware/catdvi/enc/marvo00.enc
@@ -0,0 +1,305 @@
+%The encoding of the marvosym ("Martin Vogels Symbole") font released 2000.
+%An earlier version had a substantially different encoding.
+%
+/Marvosym2000Encoding [
+% 0x00
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x10
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x20
+/.notdef
+/.notavail %/stopsign
+/.notavail %/beam
+/.notavail %/bearing
+
+/.notavail %/loosebearing
+/.notavail %/fixedbearing
+/$lefttorque
+/$righttorque
+
+/parenleft
+/parenright
+/multiply
+/plus
+
+/comma
+/$hyphen
+/period
+/slash
+
+% 0x30
+/zero
+/one
+/two
+/three
+
+/four
+/five
+/six
+/seven
+
+/eight
+/nine
+/$dingbatarrow2794
+/arrowdblright
+
+/lessequal
+/$corresponds
+/greaterequal
+/arrowdblboth
+
+% 0x40
+/at
+/$answerphone
+/$envelope
+/.notavail %/CEsign
+
+/Euro
+/$zigzagarrowdown
+/.notavail %/FHBOlogo
+/.notdef
+
+/.notavail %/mobilefone
+/.notavail %/industry
+/.notavail %/electrostatic
+/.notavail %/coffeecup
+
+/.notavail %/lineload
+/.notdef
+/.notdef %something here, a box? undocumented.
+/.notdef %something here, a box? undocumented.
+
+% 0x50
+/$vector
+/$scissors
+/.notavail %/kutline
+/.notavail %/leftscissors
+
+/$telephone
+/$watch
+/$checkedbox
+/$sphericalangle
+
+/$crossedbox
+/$yinyang
+/$fist
+/$fractionslash
+
+/$dividesnot
+/equivalence
+/$notequivalent
+/$negationslash
+
+% 0x60
+/.notavail %/explosionsafe
+/.notavail %/laserbeam
+/$writinghand
+/Euro
+
+/Euro
+/Euro
+/.notavail %/FHBOLOGO
+/$macron
+
+/$biohazard
+/$information
+/$radioactive
+/.notavail %/email
+
+/arrowdown
+/.notavail %/mundus
+/.notavail %/bsefree
+/.notavail %/football
+
+% 0x70
+/$vector
+/$scissorsupperblade
+/.notavail %/cutline
+/.notavail %/cutleft
+
+/.notavail %/fax
+/.notavail %/FAX
+/.notavail %/faxmachine
+/.notavail %/wheelchair
+
+/.notavail %/gentsroom
+/.notavail %/ladiesroom
+/.notavail %/emailct
+/circle %neutral
+
+/male
+/.notavail %/hermaphrodite
+/female
+/.notdef % something here; a copy of MALE?
+
+% 0x80
+/.notavail %/HERMAPHRODITE
+/.notavail %/FEMALE
+/.notavail %/MALE
+/.notavail %/malemale
+
+/.notavail %/femalefemale
+/.notavail %/femalemale
+/$latincross
+/.notavail %/celtcross
+
+/$ankh
+/.notavail %/WashCotton
+/.notavail %/WashSynthetics
+/.notavail %/WashWool
+
+/$heartwhite
+/.notavail %/Ecommerce
+/.notavail %/FullFHBO
+/.notavail %/Tumbler
+
+% 0x90
+/.notavail %/NoTumbler
+/.notavail %/Octosteel
+/.notavail %/Hexasteel
+/filledbox %/Squaresteel
+
+/.notavail %/Rectsteel
+/$filledcircle %/Circsteel
+/.notavail %/flatsteel
+/.notavail %/squarepipe
+
+/.notavail %/rectpipe
+/.notavail %/Lsteel
+/.notavail %/TTsteel
+/.notavail %/circpipe
+
+/.notavail %/Tsteel
+/.notavail %/RoundedTsteel
+/.notavail %/RoundedTTsteel
+/.notavail %/RoundedLsteel
+
+% 0xa0
+/.notdef %something here, undocumented
+/.notavail %/Shilling
+/$pfennig
+/$pounds
+
+/Euro
+/.notavail %/Bouquet
+/dollar
+/$frownface
+
+/.notavail %/NoChemicalCleaning
+/smileface
+/.notavail %marvosym.sty calls this \CircledA, but it's the anarchist symbol.
+/$circleA %/CleaningA
+
+/$circleP %/CleaningP
+/.notavail %/CleaningPP
+/.notavail %/bicycle
+/.notavail %/IroningI
+
+% 0xb0
+/.notavail %/IroningII
+/.notavail %/IroningIII
+/.notavail %/NoIroning
+/.notdef
+
+/.notavail %/RewindToIndex
+/.notavail %/RewindToStart
+/triaglf %/Rewind
+/triagrt %/Forward
+
+/.notavail %/ForwardToEnd
+/.notavail %/ForwardToIndex
+/triagup %/MoveUp
+/triagdn %/MoveDown
+
+/.notavail %/ToTop
+/.notavail %/ToBottom
+/$circleF %/CleaningF
+/.notavail %/CleaningFF
+
+% 0xc0
+/sun
+/$moonfirstquarter
+/$mercury
+/female
+
+/male
+/$jupiter
+/$saturn
+/$uranus
+
+/$neptune
+/$pluto
+/$earth
+/$triagwhiteup %/Bleech
+
+/.notavail %/NoBleech
+/.notavail %/ComputerMouse
+/.notavail %/SerialInterface
+/$keyboard
+
+% 0xd0
+/.notavail %/SerialPort
+/.notavail %/ParallelPort
+/.notavail %/Printer
+/.notavail %/AtNinetyFive
+
+/.notavail %/ShortNinetyFive
+/.notavail %/AtSixty
+/.notavail %/ShortSixty
+/.notavail %/ShortFifty
+
+/.notavail %/AtForty
+/.notavail %/ShortForty
+/.notavail %/SpecialForty
+/.notavail %/ShortThirty
+
+/.notavail %/Handwash
+/.notavail %/Dontwash
+/.notdef
+/.notdef
+
+% 0xe0
+/$aries
+/$taurus
+/$gemini
+/$cancer
+
+/$leo
+/$virgo
+/$libra
+/$scorpius
+
+/$sagittarius
+/$capricorn
+/$aquarius
+/$pisces
+
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0
+/A %very bold
+/p %very bold
+/.notdef
+/.notdef
+
+/.notdef
+/.notdef
+/.notdef
+/$filledboxsmall %squaredot
+
+/.notdef /.notdef /.notdef /.notdef
+
+/.notdef
+/.notavail %/bat
+/.notavail %/womanface
+/.notavail %/MartinVogel
+
+] def
diff --git a/dviware/catdvi/enc/marvo98.enc b/dviware/catdvi/enc/marvo98.enc
new file mode 100644
index 0000000000..a032287881
--- /dev/null
+++ b/dviware/catdvi/enc/marvo98.enc
@@ -0,0 +1,256 @@
+%The encoding of the marvosym ("Martin Vogels Symbole") font released 1998.
+%A later version has a substantially different encoding.
+%
+/Marvosym1998Encoding [
+% 0x00
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x10
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x20
+/.notdef
+/.notavail %/stopsign
+/.notavail %/beam
+/.notavail %/bearing
+
+/.notavail %/loosebearing
+/.notavail %/fixedbearing
+/$lefttorque
+/$righttorque
+
+/arrowdown
+/.notavail %/lineload
+/$snowflake
+/$maltesecross
+
+/.notdef
+/.notdef
+/.notavail %/circles
+/.notdef
+
+% 0x30
+/zero
+/one
+/two
+/three
+
+/four
+/five
+/six
+/seven
+
+/eight
+/nine
+/.notdef
+/.notdef
+
+/.notdef
+/$corresponds
+/$dingbatarrow2794
+/.notdef
+
+% 0x40
+/at
+/$answerphone
+/$envelope
+/.notavail %/CEsign
+
+/.notdef
+/$zigzagarrowdown
+/.notavail %/FHBOlogo
+/.notdef
+
+/.notavail %/mobilefone
+/.notavail %/industry
+/.notdef
+/.notavail %/coffeecup
+
+/.notdef
+/$yinyang
+/.notdef
+/.notdef %something here, a box? undocumented.
+
+% 0x50
+/$vector
+/$scissors
+/.notavail %/kutline
+/.notavail %/leftscissors
+
+/$telephone
+/$watch
+/$checkedbox
+/.notdef
+
+/$crossedbox
+/.notdef
+/$fist
+/.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x60
+/.notdef
+/.notdef
+/$writinghand
+/Euro
+
+/Euro
+/Euro
+/.notavail %/FHBOLOGO
+/.notdef
+
+/.notdef
+/$information
+/.notdef
+/.notdef
+
+/.notdef
+/.notdef
+/.notdef
+/.notavail %/football
+
+% 0x70
+/$vector
+/$scissorsupperblade
+/.notavail %/cutline
+/.notavail %/cutleft
+
+/.notavail %/fax
+/.notavail %/FAX
+/.notavail %/faxmachine
+/.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0x80
+/.notdef /.notdef /.notdef /.notdef
+
+/.notdef
+/.notdef
+/$latincross
+/.notavail %/celtcross
+
+/$ankh
+/.notdef
+/.notdef
+/.notdef
+
+/$heartwhite
+/.notdef
+/.notdef
+/.notdef
+
+% 0x90
+/.notdef /.notdef /.notdef /.notdef
+
+/.notdef
+/.notdef
+/.notavail %/flatsteel
+/.notavail %/squarepipe
+
+/.notavail %/rectpipe
+/.notavail %/Lsteel
+/.notavail %/TTsteel
+/.notavail %/circpipe
+
+/.notavail %/Tsteel
+/.notdef
+/.notdef
+/.notdef
+
+% 0xa0
+/.notdef /.notdef /.notdef /.notdef
+
+/Euro
+/.notdef
+/.notdef
+/$frownface
+
+/.notdef
+/smileface
+/.notdef
+/.notdef
+
+/.notdef
+/.notdef
+/.notavail %/bicycle
+/.notdef
+
+% 0xb0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xc0
+/sun
+/$moonfirstquarter
+/$mercury
+/female
+
+/male
+/$jupiter
+/$saturn
+/$uranus
+
+/$neptune
+/$pluto
+/.notdef
+/.notdef
+
+/.notavail %/womanside
+/.notavail %/manside
+/.notavail %/womanfront
+/.notavail %/manfront
+
+% 0xd0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xe0
+/$aries
+/$taurus
+/$gemini
+/$cancer
+
+/$leo
+/$virgo
+/$libra
+/$scorpius
+
+/$sagittarius
+/$capricorn
+/$aquarius
+/$pisces
+
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0
+/A %very bold
+/p %very bold
+/.notdef
+/.notdef
+
+/.notdef
+/.notdef
+/.notdef
+/$filledboxsmall
+
+/.notdef /.notdef /.notdef /.notdef
+
+/.notdef
+/.notavail %/bat
+/.notavail %/womanface
+/.notavail %/MartinVogel
+
+] def
diff --git a/dviware/catdvi/enc/ot1.enc b/dviware/catdvi/enc/ot1.enc
new file mode 100644
index 0000000000..919d08e94e
--- /dev/null
+++ b/dviware/catdvi/enc/ot1.enc
@@ -0,0 +1,38 @@
+/OT1Encoding [
+ /Gamma /$Delta /Theta /Lambda /Xi /Pi /Sigma /Upsilon /Phi
+ /Psi /$Omega /ff /fi /fl /ffi /ffl
+ /dotlessi /dotlessj /grave /acute /caron /breve /$macron /ring
+ /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash
+ /$polishstroke /exclam /quotedblright /numbersign
+ /dollar /percent /ampersand /quoteright
+ /parenleft /parenright /asterisk /plus /comma /$hyphen /period /slash
+ /zero /one /two /three /four /five /six /seven
+ /eight /nine /colon /semicolon /exclamdown /equal /questiondown /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 /quotedblleft /bracketright /circumflex /dotaccent
+ /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 /endash /emdash /quotedbl /tilde /dieresis
+
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef ] def
diff --git a/dviware/catdvi/enc/ot1wofl.enc b/dviware/catdvi/enc/ot1wofl.enc
new file mode 100644
index 0000000000..832cbaf1f6
--- /dev/null
+++ b/dviware/catdvi/enc/ot1wofl.enc
@@ -0,0 +1,51 @@
+% Definition of the `TeX Text without f-ligatures' encoding.
+%
+% Ligatures and kernings left out.
+
+/OT1woflEncoding [
+ % 0x00
+ /Gamma /$Delta /Theta /Lambda /Xi /Pi /Sigma /Upsilon
+ /Phi /Psi /$Omega /arrowup /arrowdown /quotesingle /exclamdown /questiondown
+ % 0x10
+ /dotlessi /dotlessj /grave /acute /caron /breve /$macron /ring
+ /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash
+ % 0x20
+ /$polishstroke /exclam /quotedblright /numbersign
+ /dollar /percent /ampersand /quoteright
+ /parenleft /parenright /asterisk /plus /comma /$hyphen /period /slash
+ % 0x30
+ /zero /one /two /three /four /five /six /seven
+ /eight /nine /colon /semicolon /less /equal /greater /question
+ % 0x40
+ /at /A /B /C /D /E /F /G
+ /H /I /J /K /L /M /N /O
+ % 0x50
+ /P /Q /R /S /T /U /V /W
+ /X /Y /Z /bracketleft /quotedblleft /bracketright /circumflex /dotaccent
+ % 0x60
+ /quoteleft /a /b /c /d /e /f /g
+ /h /i /j /k /l /m /n /o
+ % 0x70
+ /p /q /r /s /t /u /v /w
+ /x /y /z /endash /emdash /quotedbl /tilde /dieresis
+
+ % 0x80
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef ] def
diff --git a/dviware/catdvi/enc/texmext.enc b/dviware/catdvi/enc/texmext.enc
new file mode 100644
index 0000000000..36af31e9ea
--- /dev/null
+++ b/dviware/catdvi/enc/texmext.enc
@@ -0,0 +1,184 @@
+% TeX math extension encoding.
+% No ligatures or kerns.
+%
+/TeXMathExtensionEncoding [ % now 256 chars follow
+
+% 0x0
+/$parenleftbig
+/$parenrightbig
+/$bracketleftbig
+/$bracketrightbig
+/$floorleftbig
+/$floorrightbig
+/$ceilingleftbig
+/$ceilingrightbig
+
+% 0x8
+/$braceleftbig
+/$bracerightbig
+/$angbracketleftbig
+/$angbracketrightbig
+/$vextendsingle
+/$vextenddouble
+/$slashbig
+/$backslashbig
+
+% 0x10
+/$parenleftBig
+/$parenrightBig
+/$parenleftbigg
+/$parenrightbigg
+/$bracketleftbigg
+/$bracketrightbigg
+/$floorleftbigg
+/$floorrightbigg
+
+% 0x18
+/$ceilingleftbigg
+/$ceilingrightbigg
+/$braceleftbigg
+/$bracerightbigg
+/$angbracketleftbigg
+/$angbracketrightbigg
+/$slashbigg
+/$backslashbigg
+
+% 0x20
+/$parenleftBigg
+/$parenrightBigg
+/$bracketleftBigg
+/$bracketrightBigg
+/$floorleftBigg
+/$floorrightBigg
+/$ceilingleftBigg
+/$ceilingrightBigg
+
+% 0x28
+/$braceleftBigg
+/$bracerightBigg
+/$angbracketleftBigg
+/$angbracketrightBigg
+/$slashBigg
+/$backslashBigg
+/$slashBig
+/$backslashBig
+
+% 0x30
+/$parenlefttp
+/$parenrighttp
+/$bracketlefttp
+/$bracketrighttp
+/$bracketleftbt
+/$bracketrightbt
+/$bracketleftex
+/$bracketrightex
+
+% 0x38
+/$bracelefttp
+/$bracerighttp
+/$braceleftbt
+/$bracerightbt
+/$braceleftmid
+/$bracerightmid
+/$braceex
+/arrowvertex
+
+% 0x40
+/$parenleftbt
+/$parenrightbt
+/$parenleftex
+/$parenrightex
+/$angbracketleftBig
+/$angbracketrightBig
+/$unionsqtext
+/$unionsqdisplay
+
+% 0x48
+/$contintegraltext
+/$contintegraldisplay
+/$circledottext
+/$circledotdisplay
+/$circleplustext
+/$circleplusdisplay
+/$circlemultiplytext
+/$circlemultiplydisplay
+
+% 0x50
+/$summationtext
+/$producttext
+/$integraltext
+/$uniontext
+/$intersectiontext
+/$unionmultitext
+/$logicalandtext
+/$logicalortext
+
+% 0x58
+/$summationdisplay
+/$productdisplay
+/$integraldisplay
+/$uniondisplay
+/$intersectiondisplay
+/$unionmultidisplay
+/$logicalanddisplay
+/$logicalordisplay
+
+% 0x60
+/$coproducttext
+/$coproductdisplay
+/$hatwide
+/$hatwider
+/$hatwidest
+/$tildewide
+/$tildewider
+/$tildewidest
+
+% 0x68
+/$bracketleftBig
+/$bracketrightBig
+/$floorleftBig
+/$floorrightBig
+/$ceilingleftBig
+/$ceilingrightBig
+/$braceleftBig
+/$bracerightBig
+
+% 0x70
+/$radicalbig
+/$radicalBig
+/$radicalbigg
+/$radicalBigg
+/$radicalbt
+/$radicalvertex
+/$radicaltp
+/$arrowvertexdbl
+
+% 0x78
+/$arrowtp
+/$arrowbt
+/$bracehtipdownleft
+/$bracehtipdownright
+/$bracehtipupleft
+/$bracehtipupright
+/$arrowdbltp
+/$arrowdblbt
+
+% Have to have 128 .notdef's now to fill things out.
+%
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+] def
diff --git a/dviware/catdvi/enc/texmital.enc b/dviware/catdvi/enc/texmital.enc
new file mode 100644
index 0000000000..a1398c89ca
--- /dev/null
+++ b/dviware/catdvi/enc/texmital.enc
@@ -0,0 +1,183 @@
+% TeX math italic encoding.
+% No ligatures or kerns.
+%
+/TeXMathItalicEncoding [ % now 256 chars follow
+% 0x0
+/Gamma
+/$Delta
+/Theta
+/Lambda
+/Xi
+/Pi
+/Sigma
+/Upsilon
+
+% 0x8
+/Phi
+/Psi
+/$Omega
+/alpha
+/beta
+/gamma
+/delta
+/$epsilon1
+
+% 0x10
+/zeta
+/eta
+/theta
+/iota
+/kappa
+/lambda
+/$mu
+/nu
+
+% 0x18
+/xi
+/pi
+/rho
+/sigma
+/tau
+/upsilon
+/phi1 % was: /phi but it's the other way round in Unicode
+/chi
+
+% 0x20
+/psi
+/omega
+/epsilon
+/theta1
+/$pi1
+/$rho1
+/sigma1
+/phi % was: /phi1 but it's the other way round in Unicode
+
+% 0x28
+/$harpoonleftbarbup % was: /arrowlefttophalf
+/$harpoonleftbarbdown % was: /arrowleftbothalf
+/$harpoonrightbarbup % was: /arrowrighttophalf
+/$harpoonrightbarbdown % was: /arrowrightbothalf
+/arrowhookleft
+/arrowhookright
+/$normalizes % was: /triangleright
+/$normalin % was: /triangleleft
+
+% 0x30
+/zerooldstyle
+/oneoldstyle
+/twooldstyle
+/threeoldstyle
+/fouroldstyle
+/fiveoldstyle
+/sixoldstyle
+/sevenoldstyle
+
+% 0x38
+/eightoldstyle
+/nineoldstyle
+/period
+/comma
+/less
+/slash
+/greater
+/$starmath % was: /star
+
+% 0x40
+/partialdiff
+/A
+/B
+/C
+/D
+/E
+/F
+/G
+
+% 0x48
+/H
+/I
+/J
+/K
+/L
+/M
+/N
+/O
+
+% 0x50
+/P
+/Q
+/R
+/S
+/T
+/U
+/V
+/W
+
+% 0x58
+/X
+/Y
+/Z
+/$flat
+/$natural
+/$sharp
+/$smile % was: /slurbelow
+/$frown % was: /slurabove
+
+% 0x60
+/$lscript
+/a
+/b
+/c
+/d
+/e
+/f
+/g
+
+% 0x68
+/h
+/i
+/j
+/k
+/l
+/m
+/n
+/o
+
+% 0x70
+/p
+/q
+/r
+/s
+/t
+/u
+/v
+/w
+
+% 0x78
+/x
+/y
+/z
+/dotlessi
+/dotlessj
+/weierstrass
+/$vector
+/$tie
+
+% Have to have 128 .notdef's now to fill things out.
+%
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+] def
diff --git a/dviware/catdvi/enc/texmsym.enc b/dviware/catdvi/enc/texmsym.enc
new file mode 100644
index 0000000000..e2e7367325
--- /dev/null
+++ b/dviware/catdvi/enc/texmsym.enc
@@ -0,0 +1,183 @@
+% TeX math symbols encoding.
+% No ligatures or kerns.
+%
+/TeXMathSymbolEncoding [ % now 256 chars follow
+% 0x0
+/minus
+/$periodcentered
+/multiply
+/asteriskmath
+/divide
+/$diamondmath
+/plusminus
+/$minusplus
+
+% 0x8
+/circleplus
+/$circleminus
+/circlemultiply
+/$circledivide
+/$circledot
+/$circlelarge %/circlecopyrt
+/openbullet
+/bullet
+
+% 0x10
+/$equivasymptotic
+/equivalence
+/reflexsubset
+/reflexsuperset
+/lessequal
+/greaterequal
+/$precedesequal
+/$followsequal
+
+% 0x18
+/similar
+/approxequal
+/propersubset
+/propersuperset
+/$lessmuch
+/$greatermuch
+/$precedes
+/$follows
+
+% 0x20
+/arrowleft
+/arrowright
+/arrowup
+/arrowdown
+/arrowboth
+/$arrownortheast
+/$arrowsoutheast
+/$similarequal
+
+% 0x28
+/arrowdblleft
+/arrowdblright
+/arrowdblup
+/arrowdbldown
+/arrowdblboth
+/$arrownorthwest
+/$arrowsouthwest
+/proportional
+
+% 0x30
+/minute %/prime
+/infinity
+/element
+/suchthat %/owner
+/$triagwhiteup %/triangle
+/$triagwhitedn %/triangleinv
+/$negationslash
+/mapsto
+
+% 0x38
+/universal
+/existential
+/logicalnot
+/emptyset
+/Rfraktur %/Rfractur
+/Ifraktur %/Ifractur
+/$latticetop
+/perpendicular
+
+% 0x40
+/aleph
+/$Amathscript
+/$Bscript
+/$Cmathscript
+/$Dmathscript
+/$Escript
+/$Fscript
+/$Gmathscript
+
+% 0x48
+/$Hscript
+/$Iscript
+/$Jmathscript
+/$Kmathscript
+/$Lscript
+/$Mscript
+/$Nmathscript
+/$Omathscript
+
+% 0x50
+/$Pmathscript
+/$Qmathscript
+/$Rscript
+/$Smathscript
+/$Tmathscript
+/$Umathscript
+/$Vmathscript
+/$Wmathscript
+
+% 0x58
+/$Xmathscript
+/$Ymathscript
+/$Zmathscript
+/union
+/intersection
+/$unionmulti
+/logicaland
+/logicalor
+
+% 0x60
+/$turnstileleft
+/$turnstileright
+/$floorleft
+/$floorright
+/$ceilingleft
+/$ceilingright
+/braceleft
+/braceright
+
+% 0x68
+/$angleleftmath %/angbracketleft
+/$anglerightmath %/angbracketright
+/bar
+/$parallel %/bardbl
+/arrowupdn %/arrowbothv
+/$arrowdblupdn %/arrowdblbothv
+/backslash
+/$wreathproduct
+
+% 0x70
+/radical
+/$coproduct
+/gradient %/nabla
+/integral
+/$unionsq
+/$intersectionsq
+/$reflexsubsetsq %/subsetsqequal
+/$reflexsupersetsq %/supersetsqequal
+
+% 0x78
+/section
+/dagger
+/daggerdbl
+/paragraph
+/club
+/$diamondwhite
+/$heartwhite
+/spade
+
+% Have to have 128 .notdef's now to fill things out.
+%
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+] def
diff --git a/dviware/catdvi/enc/textcomp.enc b/dviware/catdvi/enc/textcomp.enc
new file mode 100644
index 0000000000..c9b74ba512
--- /dev/null
+++ b/dviware/catdvi/enc/textcomp.enc
@@ -0,0 +1,154 @@
+%The TeX text companion (TS1) encoding.
+%
+/TextCompanionEncoding [
+% 0x00
+/grave /acute /circumflex /tilde
+/dieresis /hungarumlaut /ring /caron
+/breve /$macron /dotaccent /cedilla
+/ogonek
+/.notavail % quotestraightbase, not in Unicode 3.2
+/.notdef
+/.notdef
+
+% 0x10
+/.notdef
+/.notdef
+/.notavail % quotestraightdblbase, not in Unicode 3.2
+/.notdef
+
+/.notdef
+/.notavail % twelveudash (a 2/3 em dash), not in Unicode 3.2
+/threequartersemdash
+/$ZWNJ
+
+/arrowleft /arrowright /$tie /$tie
+
+/$tie /$tie /.notdef /$ZWNJ
+
+% 0x20
+/$blank /.notdef /.notdef /.notdef
+/dollar /.notdef /.notdef /quotesingle
+/.notdef /.notdef /$asterisklow /.notdef
+/comma
+/$hyphen % Actually a double hyphen (similar to an equals sign), but this
+ % is not present in Unicode (or considered a typographic variant).
+ % This one is "hanging", the other one below normal ?
+/period
+/$fractionslash
+
+% 0x30
+/zerooldstyle /oneoldstyle /twooldstyle /threeoldstyle
+/fouroldstyle /fiveoldstyle /sixoldstyle /sevenoldstyle
+/eightoldstyle /nineoldstyle /.notdef /.notdef
+/angleleft /minus /angleright /.notdef
+
+% 0x40
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /$Mho /.notdef /$circlelarge
+
+% 0x50
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /$Ohm
+/.notdef /.notdef /.notdef /$bracketleftwhite
+/.notdef /$bracketrightwhite /arrowup /arrowdown
+
+% 0x60
+/grave % perhaps /$minutereversed ?
+/.notdef
+/$star
+/.notavail % divorced, not in Unicode 3.2
+
+/$latincross /.notdef /.notdef /.notdef
+
+/.notdef /.notdef /.notdef /.notdef
+
+/.notavail % leaf, not in Unicode 3.2
+/.notavail % married, not in Unicode 3.2
+/musicalnote
+/.notdef
+
+% 0x70
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef
+/.notdef
+/asciitilde
+/$hyphen % Actually a double hyphen (similar to an equals sign), but this
+ % is not present in Unicode (or considered a typographic variant).
+
+% 0x80
+/breve /caron /second /$secondreversed
+/dagger /daggerdbl /$bardbl /perthousand
+/bullet /$celsius /dollaroldstyle /centoldstyle
+/florin /colonmonetary /$won /$naira
+
+% 0x90
+/.notavail % guarani (a currency sign), not in Unicode 3.2
+/$peso
+/lira
+/prescription
+
+/$interrobang
+/.notavail % interrobangdown, not in Unicode 3.2
+/dong
+/trademark
+
+/$pertenthousand
+/paragraph % typographic variant with single stem, not distinguished in Unicode
+/$baht
+/$numero
+
+/$discount /estimated /openbullet /$servicemark
+
+% 0xa0
+/$quillbracketleft /$quillbracketright /cent /sterling
+/currency /yen /brokenbar /section
+/dieresis
+/copyright
+/ordfeminine
+/.notavail % copyleft (inverted copyright), not in Unicode 3.2
+/logicalnot /$phonorecord /registered /$macron
+
+% 0xb0
+/degree /plusminus /twosuperior /threesuperior
+
+/acute % perhaps /minute ?
+/$micro
+/paragraph
+/$periodcentered
+
+/$referencemark
+/onesuperior
+/ordmasculine
+/radical % This is NOT hanging like the math font radicals!
+
+/onequarter /onehalf /threequarters /Euro
+
+% 0xc0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xd0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /multiply /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xe0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+% 0xf0
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /divide /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+
+] def
diff --git a/dviware/catdvi/enc/textt.enc b/dviware/catdvi/enc/textt.enc
new file mode 100644
index 0000000000..54beff0d36
--- /dev/null
+++ b/dviware/catdvi/enc/textt.enc
@@ -0,0 +1,50 @@
+% Definition of the TeX Typewriter Text (\tt) encoding.
+%
+% Ligatures and kernings left out.
+
+/TeXTypewriterTextEncoding [
+ % 0x00
+ /Gamma /$Delta /Theta /Lambda /Xi /Pi /Sigma /Upsilon
+ /Phi /Psi /$Omega /arrowup /arrowdown /quotesingle /exclamdown /questiondown
+ % 0x10
+ /dotlessi /dotlessj /grave /acute /caron /breve /$macron /ring
+ /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash
+ % 0x20
+ /$visualspace /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright
+ /parenleft /parenright /asterisk /plus /comma /$hyphen /period /slash
+ % 0x30
+ /zero /one /two /three /four /five /six /seven
+ /eight /nine /colon /semicolon /less /equal /greater /question
+ % 0x40
+ /at /A /B /C /D /E /F /G
+ /H /I /J /K /L /M /N /O
+ % 0x50
+ /P /Q /R /S /T /U /V /W
+ /X /Y /Z /bracketleft /backslash /bracketright /circumflex /underscore
+ % 0x60
+ /quoteleft /a /b /c /d /e /f /g
+ /h /i /j /k /l /m /n /o
+ % 0x70
+ /p /q /r /s /t /u /v /w
+ /x /y /z /braceleft /bar /braceright /tilde /dieresis
+
+ % 0x80
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef ] def
diff --git a/dviware/catdvi/findtfm.h b/dviware/catdvi/findtfm.h
new file mode 100644
index 0000000000..d205ea3f76
--- /dev/null
+++ b/dviware/catdvi/findtfm.h
@@ -0,0 +1,34 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef FINDTFM_H
+#define FINDTFM_H
+
+/* Call this first, and pass argv[0] as progname. */
+void setup_findtfm(char const * progname);
+
+/* This prints out the copyright and information on the code that is
+ used to look up the TFM files. */
+void copyright_findtfm(void);
+void version_findtfm(void);
+
+/* Find the name of the TFM file corresponding to the font named. */
+char const * find_tfm(char const * fontname);
+
+
+#endif /* FINDTFM_H */
diff --git a/dviware/catdvi/fixword.c b/dviware/catdvi/fixword.c
new file mode 100644
index 0000000000..52ccf297a4
--- /dev/null
+++ b/dviware/catdvi/fixword.c
@@ -0,0 +1,45 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "bytesex.h"
+#include "fixword.h"
+#include "util.h"
+
+fix_word_t fw_remainder = 0;
+
+double fw2double(fix_word_t fw)
+{
+ return ((double) fw) / (((uint32) 1) << FW_FRACTION_BIT);
+}
+
+
+fix_word_t fw_prod(fix_word_t a, fix_word_t b)
+{
+ fix_word_t al, bl;
+
+ if (a < 0) return - fw_prod(-a, b);
+ if (b < 0) return - fw_prod(a, -b);
+
+ /* We have to compute a*b >> 20 without overflowing 32 bits */
+ al = a & 32767;
+ bl = b & 32767;
+ a >>= 15;
+ b >>= 15;
+
+ return (((al*bl >> 15) + a*bl + al*b) >> 5) + (a*b << 10);
+}
diff --git a/dviware/catdvi/fixword.d b/dviware/catdvi/fixword.d
new file mode 100644
index 0000000000..b2c60d90a2
--- /dev/null
+++ b/dviware/catdvi/fixword.d
@@ -0,0 +1 @@
+fixword.o fixword.d : fixword.c bytesex.h fixword.h util.h
diff --git a/dviware/catdvi/fixword.h b/dviware/catdvi/fixword.h
new file mode 100644
index 0000000000..3ef36cf8bf
--- /dev/null
+++ b/dviware/catdvi/fixword.h
@@ -0,0 +1,54 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef FIXWORD_H
+#define FIXWORD_H
+
+#include "bytesex.h"
+
+/* fix_word is used in TFM files; read the TFM file spec for more
+ info. */
+
+#define FW_FIX_WORD_BIT 32
+#define FW_WHOLEPART_BIT 12
+#define FW_FRACTION_BIT (FW_FIX_WORD_BIT - FW_WHOLEPART_BIT)
+
+typedef sint32 fix_word_t;
+
+/* fix_word_t read_fw(FILE *); */
+#define read_fw(fp) (s_readbigendiannumber(4,(fp)))
+
+double fw2double(fix_word_t);
+
+/* fix_word_t double2fw(double); */
+#define double2fw(dbl) ((fix_word_t) ((dbl) * (1 << FW_FRACTION_BIT)))
+
+#define fw2int(fw) ((fw) / (1 << FW_FRACTION_BIT))
+
+/* fix_word_t fw_negate(fix_word_t); */
+#define fw_negate(fw) (-(fw))
+
+/* fix_word_t fw_sum(fix_word_t, fix_word_t); */
+#define fw_sum(fw1,fw2) ((fw1) + (fw2))
+
+/* Calculates x * y. */
+fix_word_t fw_prod(fix_word_t x, fix_word_t y);
+
+
+
+#endif /* FIXWORD_H */
diff --git a/dviware/catdvi/fntenc.c b/dviware/catdvi/fntenc.c
new file mode 100644
index 0000000000..1cc20b88e7
--- /dev/null
+++ b/dviware/catdvi/fntenc.c
@@ -0,0 +1,156 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "fntenc.h"
+#include "util.h"
+
+/* Font encodings */
+#include "enc/blackboard.h"
+#include "enc/cork.h"
+#include "enc/ot1.h"
+#include "enc/ot1wofl.h"
+#include "enc/texmext.h"
+#include "enc/texmital.h"
+#include "enc/texmsym.h"
+#include "enc/textt.h"
+#include "enc/eurosym.h"
+#include "enc/textcomp.h"
+#include "enc/marvo98.h"
+#include "enc/marvo00.h"
+#include "enc/latexsym.h"
+#include "enc/eufrak.h"
+#include "enc/dummy.h"
+#include "enc/amssymba.h"
+#include "enc/amssymbb.h"
+#include "enc/euex.h"
+
+#define TBLLEN(t) (sizeof((t))/sizeof((t)[0]))
+
+struct fontenc_t {
+ char const * encname;
+ char const * familypat;
+ sint32 * tbl;
+ size_t len_tbl;
+};
+
+#define DEF_FONTENC(encname, familypat, tbl) \
+ { (encname), (familypat), (tbl), TBLLEN((tbl)) }
+
+static struct fontenc_t fontenctbl[] = {
+ /* Encoding and family names all uppercase!
+ * If more than one entry matches: first come, first serve.
+ */
+
+ /* The first entry will be taken as fallback if necessary. */
+ DEF_FONTENC("TEX TEXT", "*", OT1Encoding),
+
+ /* blacklist of fonts lying about their encoding */
+ DEF_FONTENC("TEX TEXT WITHOUT F-LIGATURES", "WNCY? V*.*", DummyEncoding),
+ DEF_FONTENC("TEX TEXT WITHOUT F-LIGATURES", "WNCY?? V*.*", DummyEncoding),
+ DEF_FONTENC("TEX MATH SYMBOLS", "MSAM V2.2", AMSSymbolsAEncoding),
+ DEF_FONTENC("TEX MATH SYMBOLS", "MSAM V*.*", DummyEncoding),
+ DEF_FONTENC("TEX MATH SYMBOLS", "MSBM V2.2", AMSSymbolsBEncoding),
+ DEF_FONTENC("TEX MATH SYMBOLS", "MSBM V*.*", DummyEncoding),
+
+ /* the other real encodings */
+ DEF_FONTENC("TEX TEXT WITHOUT F-LIGATURES", "*", OT1woflEncoding),
+ DEF_FONTENC("EXTENDED TEX FONT ENCODING - LATIN", "*", CorkEncoding),
+ DEF_FONTENC("TEX MATH ITALIC", "*", TeXMathItalicEncoding),
+ DEF_FONTENC("TEX MATH SYMBOLS", "*", TeXMathSymbolEncoding),
+ DEF_FONTENC("TEX MATH EXTENSION", "*", TeXMathExtensionEncoding),
+ DEF_FONTENC("TEX TYPEWRITER TEXT", "*", TeXTypewriterTextEncoding),
+ DEF_FONTENC("U", "EUROSYM", EurosymEncoding),
+ DEF_FONTENC("TEX TEXT COMPANION SYMBOLS 1---TS1", "*", TextCompanionEncoding),
+ DEF_FONTENC("UNSPECIFIED", "MARTIN_VOGELS_SYMBO", Marvosym1998Encoding),
+ DEF_FONTENC("FONTSPECIFIC", "MARVOSYM", Marvosym2000Encoding),
+ DEF_FONTENC("LATEX SYMBOLS", "*", LaTeXSymbolsEncoding),
+ DEF_FONTENC("BLACKBOARD", "*", BlackboardEncoding),
+ DEF_FONTENC("TEX TEXT SUBSET", "EUF? V2.2", EulerFrakturEncoding),
+ DEF_FONTENC("TEX MATH SYMBOLS SUBSET", "*", TeXMathSymbolEncoding),
+ DEF_FONTENC("TEX MATH ITALIC SUBSET", "*", TeXMathItalicEncoding),
+ DEF_FONTENC("EULER SUBSTITUTIONS ONLY", "*", EulerExtensionEncoding)
+};
+
+int find_fntenc(char const * encname, char const * family)
+{
+ int rv = 0; /* default is TeX text */
+ int i;
+ char * upenc, * upfamily;
+
+ if (encname == 0 || family == 0) return rv;
+
+ upenc = strupcasedup(encname);
+ if(upenc == NULL) enomem();
+ upfamily = strupcasedup(family);
+ if(upfamily == NULL) enomem();
+
+ for (i = 0; i < TBLLEN(fontenctbl); i++) {
+ pmesg(85, "[matching fontenc %s to %s... ",
+ fontenctbl[i].encname, upenc);
+ if (strcmp(fontenctbl[i].encname, upenc) != 0) {
+ pmesg(85, "failed]\n");
+ continue;
+ }
+ pmesg(85, "OK]\n");
+
+ pmesg(85, "[matching font family %s to %s... ",
+ fontenctbl[i].familypat, upfamily);
+ if(!patmatch(fontenctbl[i].familypat, upfamily)) {
+ pmesg(85, "failed]\n");
+ continue;
+ }
+ pmesg(85, "OK]\n");
+
+ rv = i;
+ goto exit;
+ }
+
+ warning(
+ "unknown font encoding `%s' for family `%s',"
+ " reverting to `%s'\n",
+ encname,
+ family,
+ fontenctbl[rv].encname
+ );
+
+ exit:
+ free(upenc);
+ free(upfamily);
+ pmesg(70, "[returning fontenc %i]\n", rv);
+ return rv;
+}
+
+sint32 fnt_convert(int fontenc, sint32 sglyph)
+{
+ const int def = 0;
+ uint32 glyph = sglyph;
+
+ if (fontenc < 0 || (size_t) fontenc > TBLLEN(fontenctbl)) {
+ warning("invalid fontenc `%i', reverting to `%i'\n",
+ fontenc, def);
+ fontenc = def;
+ }
+ if (glyph >= fontenctbl[fontenc].len_tbl) {
+ warning("glyph out of range\n");
+ glyph = 0;
+ }
+ pmesg(99, "[Converting glyph %li to fontenc %i]\n", glyph, fontenc);
+ return fontenctbl[fontenc].tbl[glyph];
+}
diff --git a/dviware/catdvi/fntenc.d b/dviware/catdvi/fntenc.d
new file mode 100644
index 0000000000..0294c2698b
--- /dev/null
+++ b/dviware/catdvi/fntenc.d
@@ -0,0 +1,5 @@
+fntenc.o fntenc.d : fntenc.c fntenc.h bytesex.h util.h enc/blackboard.h \
+ enc/cork.h enc/ot1.h enc/ot1wofl.h enc/texmext.h enc/texmital.h \
+ enc/texmsym.h enc/textt.h enc/eurosym.h enc/textcomp.h enc/marvo98.h \
+ enc/marvo00.h enc/latexsym.h enc/eufrak.h enc/dummy.h enc/amssymba.h \
+ enc/amssymbb.h enc/euex.h
diff --git a/dviware/catdvi/fntenc.h b/dviware/catdvi/fntenc.h
new file mode 100644
index 0000000000..bf5833fbcd
--- /dev/null
+++ b/dviware/catdvi/fntenc.h
@@ -0,0 +1,28 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef FNTENC_H
+#define FNTENC_H
+
+#include "bytesex.h"
+
+int find_fntenc(char const * encname, char const * family);
+
+sint32 fnt_convert(int fontenc, sint32);
+
+#endif /* FNTENC_H */
diff --git a/dviware/catdvi/fontinfo.c b/dviware/catdvi/fontinfo.c
new file mode 100644
index 0000000000..29cf874507
--- /dev/null
+++ b/dviware/catdvi/fontinfo.c
@@ -0,0 +1,597 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* The TFM format is described in the DVI Driver Standard, Level 0,
+ available from CTAN. */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "bytesex.h"
+#include "findtfm.h"
+#include "fixword.h"
+#include "fontinfo.h"
+#include "readdvi.h"
+#include "util.h"
+#include "fntenc.h"
+
+/* Don't make this smaller than 256, you'd break the spec that way. */
+#define LEN_TFM_TBL 256
+
+/* These values are from the spec... don't touch them! */
+#define ENCODING_LEN 40
+#define FAMILY_LEN 20
+
+struct char_info_t {
+ unsigned width_index : 8;
+ unsigned height_index : 4;
+ unsigned depth_index : 4;
+ unsigned italic_index : 6;
+ unsigned tag : 2;
+ unsigned remainder : 8;
+};
+
+struct lig_kern_command_t {
+ byte skip_byte;
+ byte next_char;
+ byte op_byte;
+ byte remainder;
+};
+
+struct extensible_recipe_t {
+ byte top;
+ byte mid;
+ byte bot;
+ byte rep;
+};
+
+struct tfm_t {
+ /* Info from the font definition in DVI */
+ fix_word_t scale;
+ fix_word_t design;
+ /* Header */
+ uint32 lf;
+ uint32 lh;
+ uint32 bc;
+ uint32 ec;
+ uint32 nw;
+ uint32 nh;
+ uint32 nd;
+ uint32 ni;
+ uint32 nl;
+ uint32 nk;
+ uint32 ne;
+ uint32 np;
+
+ /* Data header */
+ uint32 checksum;
+ fix_word_t design_size;
+ char encoding[ENCODING_LEN];
+ char family[FAMILY_LEN];
+
+ /* Param array */
+ fix_word_t slant;
+ fix_word_t space;
+ fix_word_t space_stretch;
+ fix_word_t space_shrink;
+ fix_word_t x_height;
+ fix_word_t quad;
+ fix_word_t extra_space;
+ fix_word_t * other_params;
+
+ /* Data arrays */
+ struct char_info_t * char_info;
+ fix_word_t * width;
+ fix_word_t * height;
+ fix_word_t * depth;
+ fix_word_t * italic;
+ struct lig_kern_command_t * lig_kern;
+ fix_word_t * kern;
+ struct extensible_recipe_t * exten;
+
+ /* misc precomputed stuff */
+ fix_word_t axis_height; /* 0 if the font doesn't have it */
+ sint32 scaled_thinspace; /* space - space_shrink, guarded against
+ * missing parameters and already scaled
+ */
+ sint32 scaled_usequad; /* ditto for quad */
+};
+
+static struct tfm_t tfm_tbl[LEN_TFM_TBL];
+
+static const double spaces_per_quad = 4.0;
+ /* font_w_to_space() [see below] uses the quantity
+ * (tfm_tbl[font].space - tfm_tbl[font].space_shrink)
+ * for the conversion (DVI x distances) -> (number of spaces in text).
+ * Some fonts don't supply spacing information (i.e. .space is zero)
+ * and we have to estimate above quantity by tfm_tbl[font].quad .
+ *
+ * The correct factor is not clear, but here are some data points:
+ *
+ * - q&d statistics over calls to font_w_to_space with .space != 0
+ * on several large files gave (rounded to two decimals)
+ * .quad / .space : arithmetic mean 2.93, median 3.00
+ * .quad / (.space - .space_shrink) : arithmetic mean 4.31, median 4.50
+ *
+ * - The main examples of fonts with .space == 0 are the math fonts.
+ * In math mode we have multiple spacing instructions: \, \: \; yield
+ * {3/18 = 1/6, 4/18 = 1/4.5, 5/18 = 1/3.6} .quad respectively.
+ * I'm not sure whether \, and \: should result in printed-out spaces,
+ * but I'd say \; should.
+ */
+
+static struct char_info_t * read_char_info_array(uint32 bc, uint32 ec,
+ FILE * fp)
+{
+ struct char_info_t * rv;
+ uint32 i, count;
+
+ count = ec - bc + 1;
+
+ rv = xmalloc(count * sizeof(struct char_info_t));
+
+ for (i = 0; i < count; i++) {
+ byte b;
+
+ rv[i].width_index = readbyte(fp);
+
+ b = readbyte(fp);
+ rv[i].height_index = b / 16;
+ rv[i].depth_index = b % 16;
+
+ b = readbyte(fp);
+ rv[i].italic_index = b / 4;
+ rv[i].tag = b % 4;
+
+ rv[i].remainder = readbyte(fp);
+ }
+
+ return rv;
+}
+
+static fix_word_t * read_fixword_array(uint32 count, FILE * fp)
+{
+ uint32 i;
+ fix_word_t * rv;
+
+ rv = xmalloc(count * sizeof(fix_word_t));
+
+ for (i = 0; i < count; i++) rv[i] = read_fw(fp);
+
+ return rv;
+}
+
+static struct tfm_t read_tfm(char const * fname)
+{
+ FILE * fp;
+ size_t dh_already_read = 0; /* of data header */
+
+ struct tfm_t rv = {
+ 0, /* scale */
+ 0, /* design */
+
+ 0, /* lf */
+ 0, /* lh */
+ 0, /* bc */
+ 0, /* ec */
+ 0, /* nw */
+ 0, /* nh */
+ 0, /* nd */
+ 0, /* ni */
+ 0, /* nl */
+ 0, /* nk */
+ 0, /* ne */
+ 0, /* np */
+
+ 0, /* checksum */
+ 0, /* design_size */
+ {0}, /* encoding[ENCODING_LEN] */
+ {0}, /* family[FAMILY_LEN] */
+
+ 0, /* slant */
+ 0, /* space */
+ 0, /* space_stretch */
+ 0, /* space_shrink */
+ 0, /* x_height */
+ 0, /* quad */
+ 0, /* extra_space */
+ 0, /* other_params */
+
+ 0, /* char_info */
+ 0, /* width */
+ 0, /* height */
+ 0, /* depth */
+ 0, /* italic */
+ 0, /* lig_kern */
+ 0, /* kern */
+ 0, /* exten */
+
+ 0, /* axis_height */
+ 0, /* scaled_thinspace */
+ 0 /* scaled_usequad */
+ };
+
+ fp = fopen(fname, "rb");
+ if (fp == 0) {
+ panic("Could not open %s: %s\n", fname, strerror(errno));
+ }
+
+ /* Header */
+ rv.lf = u_readbigendiannumber(2, fp);
+ rv.lh = u_readbigendiannumber(2, fp);
+ rv.bc = u_readbigendiannumber(2, fp);
+ rv.ec = u_readbigendiannumber(2, fp);
+ rv.nw = u_readbigendiannumber(2, fp);
+ rv.nh = u_readbigendiannumber(2, fp);
+ rv.nd = u_readbigendiannumber(2, fp);
+ rv.ni = u_readbigendiannumber(2, fp);
+ rv.nl = u_readbigendiannumber(2, fp);
+ rv.nk = u_readbigendiannumber(2, fp);
+ rv.ne = u_readbigendiannumber(2, fp);
+ rv.np = u_readbigendiannumber(2, fp);
+
+ /* Header data */
+ rv.checksum = u_readbigendiannumber(4, fp);
+ rv.design_size = s_readbigendiannumber(4, fp);
+
+ dh_already_read = 4 + 4;
+
+ if (4 * rv.lh > dh_already_read) {
+ readbcblstring((byte *) rv.encoding, ENCODING_LEN, fp);
+ dh_already_read += ENCODING_LEN;
+ }
+
+ if (4 * rv.lh > dh_already_read) {
+ readbcblstring((byte *) rv.family, FAMILY_LEN, fp);
+ dh_already_read += FAMILY_LEN;
+ }
+
+ pmesg(95, "TFM file %s, encoding %s, family %s\n",
+ fname, rv.encoding, rv.family);
+
+ /* Ignore the rest of the data header */
+ skipbytes(4 * rv.lh - dh_already_read, fp);
+
+ if (rv.bc <= rv.ec) {
+ rv.char_info = read_char_info_array(rv.bc, rv.ec, fp);
+ }
+
+ rv.width = read_fixword_array(rv.nw, fp);
+
+ rv.height = read_fixword_array(rv.nh, fp);
+
+ rv.depth = read_fixword_array(rv.nd, fp);
+
+ rv.italic = read_fixword_array(rv.ni, fp);
+
+ /* FIXME: Read lig_kern array for real. */
+ skipbytes(4 * rv.nl, fp);
+
+ rv.kern = read_fixword_array(rv.nk, fp);
+
+ /* FIXME: Read exten array for real. */
+ skipbytes(4 * rv.ne, fp);
+
+ /* Read the param array. */
+ /**/ if (rv.np == 0) goto skip;
+ rv.slant = read_fw(fp); if (rv.np == 1) goto skip;
+ rv.space = read_fw(fp); if (rv.np == 2) goto skip;
+ rv.space_stretch = read_fw(fp); if (rv.np == 3) goto skip;
+ rv.space_shrink = read_fw(fp); if (rv.np == 4) goto skip;
+ rv.x_height = read_fw(fp); if (rv.np == 5) goto skip;
+ rv.quad = read_fw(fp); if (rv.np == 6) goto skip;
+ rv.extra_space = read_fw(fp); if (rv.np == 7) goto skip;
+ rv.other_params = read_fixword_array(rv.np - 7, fp);
+ skip:
+ /* We should have reached the end of the tfm file now. */
+
+ fclose(fp);
+
+ return rv;
+}
+
+void font_def(sint32 k, uint32 c, uint32 s, uint32 d,
+ byte a, byte l, char const * n)
+{
+ static const char fallback_font[] = "cmr10";
+ char const * fname;
+ fix_word_t thinspace, usequad;
+
+ pmesg(90, "FONT DEF: k = %li, c = %lu, s = %lu, d = %lu,\n"
+ " a = %u, l = %u, n = %s\n",
+ k, c, s, d, a, l, n);
+
+ if (k < 0 || k >= LEN_TFM_TBL) {
+ warning("Font index out of range, ignoring font definition\n");
+ return;
+ }
+
+ fname = find_tfm(n);
+ if(fname == NULL) {
+ fname = find_tfm(fallback_font);
+ if(fname != NULL) {
+ warning(
+ "Could not find font metrics file %s.tfm --" \
+ " using %s.tfm instead. Expect incorrect output.\n",
+ n,
+ fallback_font
+ );
+ c = 0; /* Don't compare checksums, they will not match. */
+ }
+ else {
+ panic(
+ "Cannot find font metrics file %s.tfm, fallback" \
+ " %s.tfm is also missing.\nAborting.\n",
+ n,
+ fallback_font
+ );
+ }
+ }
+
+ tfm_tbl[k] = read_tfm(fname);
+ if (tfm_tbl[k].checksum != c && c && tfm_tbl[k].checksum) {
+ /* don't compare checksums if either is zero */
+ warning("Checksum mismatch reading font `%s'\n", n);
+ }
+ tfm_tbl[k].scale = s;
+ tfm_tbl[k].design = d;
+
+ /* do we have axis_height ? */
+ if(tfm_tbl[k].np == 22) {
+ /* We are a little bit lax here and just assume that a font
+ * carries the same set of parameters as OMS encoded fonts
+ * iff it has the same _number_ of parameters (which is 22,
+ * and axis_height happens to be the last one).
+ */
+ tfm_tbl[k].axis_height = font_param(k, 22);
+ }
+ else tfm_tbl[k].axis_height = 0;
+
+ /* Compute two values required by font_w_to_space(). That function
+ * is called VERY often, so it makes sense to precompute the values.
+ */
+ usequad = tfm_tbl[k].quad;
+ if(usequad <= 0) {
+ /* Some fonts (e.g. cmman) don't even have quad set. Last
+ * resort: assume quad == design size (usually about right).
+ */
+ usequad = double2fw(1.0);
+ }
+ tfm_tbl[k].scaled_usequad = font_scale_fw(k, usequad);
+
+ thinspace = tfm_tbl[k].space - tfm_tbl[k].space_shrink;
+ if (thinspace > 0) {
+ tfm_tbl[k].scaled_thinspace = font_scale_fw(k, thinspace);
+ }
+ else {
+ /* Some fonts (e.g. math) don't have space set - we have
+ * to estimate a useful value.
+ */
+ tfm_tbl[k].scaled_thinspace = font_scale_fw(k, usequad) /
+ spaces_per_quad;
+ }
+}
+
+
+char const * font_enc(sint32 k)
+{
+ if (k < 0 || k >= LEN_TFM_TBL) {
+ warning("Font index out of range, reverting to TeX text\n");
+ return "TEX TEXT";
+ }
+ pmesg(80, "[font %li, encoding: %s]\n", k, tfm_tbl[k].encoding);
+ return tfm_tbl[k].encoding;
+}
+
+char const * font_family(sint32 k)
+{
+ static const char fallback[] = "CMR";
+ if (k < 0 || k >= LEN_TFM_TBL) {
+ warning("Font index out of range, reverting to CMR\n");
+ return fallback;
+ }
+ return tfm_tbl[k].family;
+}
+
+fix_word_t font_scale_fw(sint32 font, fix_word_t fw)
+{
+ return fw_prod(fw, tfm_tbl[font].scale);
+}
+
+uint32 font_char_width(sint32 font, sint32 glyph)
+{
+ uint32 wi, ugly, rv;
+
+ if (glyph < 0) {
+ warning("ignoring negative glyph index");
+ return 0;
+ }
+ ugly = glyph;
+
+ if (font < 0 || font >= LEN_TFM_TBL) {
+ warning("Font index out of range, pretending like glyph were empty\n");
+ return 0;
+ }
+
+ if (ugly < tfm_tbl[font].bc || ugly > tfm_tbl[font].ec) {
+ warning("Glyph does not exist in font\n");
+ return 0;
+ }
+
+ wi = tfm_tbl[font].char_info[ugly - tfm_tbl[font].bc].width_index;
+
+ if (wi >= tfm_tbl[font].nw) {
+ warning("TFM file corrupt - width index out of bounds\n");
+ return 0;
+ }
+
+ rv = font_scale_fw(font, tfm_tbl[font].width[wi]);
+ pmesg(105, "FONT_CHAR_WIDTH: font %li, glyph %li, width %li\n",
+ font, glyph, rv);
+ return rv;
+
+}
+
+uint32 font_char_height(sint32 font, sint32 glyph)
+{
+ uint32 he, ugly, rv;
+
+ if (glyph < 0) {
+ warning("ignoring negative glyph index");
+ return 0;
+ }
+ ugly = glyph;
+
+ if (font < 0 || font >= LEN_TFM_TBL) {
+ warning("Font index out of range, pretending like glyph were empty\n");
+ return 0;
+ }
+
+ if (ugly < tfm_tbl[font].bc || ugly > tfm_tbl[font].ec) {
+ warning("Glyph does not exist in font\n");
+ return 0;
+ }
+
+ he = tfm_tbl[font].char_info[ugly - tfm_tbl[font].bc].height_index;
+
+ if (he >= tfm_tbl[font].nh) {
+ warning("TFM file corrupt - height index out of bounds\n");
+ return 0;
+ }
+
+ rv = font_scale_fw(font, tfm_tbl[font].height[he]);
+ pmesg(105, "FONT_CHAR_HEIGH: font %li, glyph %li, height %li\n",
+ font, glyph, rv);
+ return rv;
+
+}
+
+uint32 font_char_depth(sint32 font, sint32 glyph)
+{
+ uint32 de, ugly, rv;
+
+ if (glyph < 0) {
+ warning("ignoring negative glyph index");
+ return 0;
+ }
+ ugly = glyph;
+
+ if (font < 0 || font >= LEN_TFM_TBL) {
+ warning("Font index out of range, pretending like glyph were empty\n");
+ return 0;
+ }
+
+ if (ugly < tfm_tbl[font].bc || ugly > tfm_tbl[font].ec) {
+ warning("Glyph does not exist in font\n");
+ return 0;
+ }
+
+ de = tfm_tbl[font].char_info[ugly - tfm_tbl[font].bc].depth_index;
+
+ if (de >= tfm_tbl[font].nd) {
+ warning("TFM file corrupt - depth index out of bounds\n");
+ return 0;
+ }
+
+ rv = font_scale_fw(font, tfm_tbl[font].depth[de]);
+ pmesg(105, "FONT_CHAR_DEPTH: font %li, glyph %li, depth %li\n",
+ font, glyph, rv);
+ return rv;
+
+}
+
+unsigned int font_nparams(sint32 font)
+{
+ if (font < 0 || font >= LEN_TFM_TBL) {
+ warning("Font index out of range, pretending 0 parameters\n");
+ return 0;
+ }
+ return tfm_tbl[font].np;
+}
+
+fix_word_t font_param(sint32 font, unsigned int num)
+{
+ struct tfm_t * pf;
+
+ if (font < 0 || font >= LEN_TFM_TBL) {
+ warning("Font index out of range, assuming parameter = 0\n");
+ return 0;
+ }
+ pf = tfm_tbl + font;
+
+ if (num == 0 || num > pf->np) {
+ warning("Parameter not defined in font, assuming zero value\n");
+ return 0;
+ }
+
+ switch(num) {
+ case 1: return pf->slant;
+ case 2: return pf->space;
+ case 3: return pf->space_stretch;
+ case 4: return pf->space_shrink;
+ case 5: return pf->x_height;
+ case 6: return pf->quad;
+ case 7: return pf->extra_space;
+ default: return pf->other_params[num - 8];
+ }
+}
+
+
+uint32 font_axis_height(sint32 font)
+{
+ if (font < 0 || font >= LEN_TFM_TBL) {
+ warning("Font index out of range\n");
+ return 0;
+ }
+ return tfm_tbl[font].axis_height;
+}
+
+int font_w_to_space(sint32 font, sint32 width)
+{
+ sint32 rv;
+
+ if (font < 0 || font >= LEN_TFM_TBL) {
+ warning("Font index out of range\n");
+ return 0;
+ }
+
+
+ rv = width / tfm_tbl[font].scaled_thinspace;
+
+ if (rv >= 2) {
+ rv = width / tfm_tbl[font].scaled_usequad;
+ if (rv < 1) rv = 1;
+ }
+
+ pmesg(
+ 80,
+ "W_TO_SPACE: thinspace = %li, usequad = %li"
+ " width = %li, return value = %li\n",
+ tfm_tbl[font].scaled_thinspace,
+ tfm_tbl[font].scaled_usequad,
+ width,
+ rv
+ );
+
+ return rv;
+}
+
diff --git a/dviware/catdvi/fontinfo.d b/dviware/catdvi/fontinfo.d
new file mode 100644
index 0000000000..4df164bb42
--- /dev/null
+++ b/dviware/catdvi/fontinfo.d
@@ -0,0 +1,2 @@
+fontinfo.o fontinfo.d : fontinfo.c bytesex.h findtfm.h fixword.h fontinfo.h \
+ readdvi.h util.h fntenc.h
diff --git a/dviware/catdvi/fontinfo.h b/dviware/catdvi/fontinfo.h
new file mode 100644
index 0000000000..965bb64fc1
--- /dev/null
+++ b/dviware/catdvi/fontinfo.h
@@ -0,0 +1,58 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef FONTINFO_H
+#define FONTINFO_H
+
+#include "bytesex.h"
+#include "fixword.h"
+
+/* Parameter names as with DVI fnt_defX command. */
+void font_def(sint32 k, uint32 c, uint32 s, uint32 d,
+ byte a, byte l, char const * n);
+
+
+/* Return the encoding name of the referenced font. */
+char const * font_enc(sint32 k);
+
+/* Return the family name (aka identifier) of the referenced font. */
+char const * font_family(sint32 k);
+
+/* Return the width/height/depth of the refereced glyph in
+ * the referenced font.
+ */
+uint32 font_char_width(sint32 font, sint32 glyph);
+uint32 font_char_height(sint32 font, sint32 glyph);
+uint32 font_char_depth(sint32 font, sint32 glyph);
+
+/* Return the unscaled(!) axis height, or 0 for fonts without this parameter */
+uint32 font_axis_height(sint32 font);
+
+/* scale a fixword in font units to DVI units */
+fix_word_t font_scale_fw(sint32 font, fix_word_t fw);
+
+/* Parameter numbers as in the TFM format definition */
+unsigned int font_nparams(sint32 font);
+fix_word_t font_param(sint32 font, unsigned int num);
+
+/* Return a count of space characters that approximately fit in the
+ given width. */
+int font_w_to_space(sint32 font, sint32 width);
+
+#endif /* FONTINFO_H */
diff --git a/dviware/catdvi/getopt.c b/dviware/catdvi/getopt.c
new file mode 100644
index 0000000000..832ed29450
--- /dev/null
+++ b/dviware/catdvi/getopt.c
@@ -0,0 +1,1051 @@
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
+ Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with the GNU C Library; see the file COPYING. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+# ifndef const
+# define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library. */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+# include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.
+ When compiling libc, the _ macro is predefined. */
+# ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# define _(msgid) gettext (msgid)
+# else
+# define _(msgid) (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include <string.h>
+# define my_index strchr
+#else
+
+# if HAVE_STRING_H
+# include <string.h>
+# else
+# include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+ is valid for the getopt call we must make sure that the ARGV passed
+ to getopt is that one passed to the process. */
+static void
+__attribute__ ((unused))
+store_args_and_env (int argc, char *const *argv)
+{
+ /* XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+ original_argc = argc;
+ original_argv = argv;
+}
+# ifdef text_set_element
+text_set_element (__libc_subinit, store_args_and_env);
+# endif /* text_set_element */
+
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#ifdef _LIBC
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#ifdef _LIBC
+ if (posixly_correct == NULL
+ && argc == original_argc && argv == original_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ optarg = NULL;
+
+ if (optind == 0 || !__getopt_initialized)
+ {
+ if (optind == 0)
+ optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#ifdef _LIBC
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > optind)
+ last_nonopt = optind;
+ if (first_nonopt > optind)
+ first_nonopt = optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc && NONOPTION_P)
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ {
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ _("%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ _("%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+ }
+
+ nextchar += strlen (nextchar);
+
+ optopt = pfound->val;
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (opterr)
+ {
+ if (argv[optind][1] == '-')
+ /* --option */
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (opterr)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+ else
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/dviware/catdvi/getopt.d b/dviware/catdvi/getopt.d
new file mode 100644
index 0000000000..9ca0b7a5ce
--- /dev/null
+++ b/dviware/catdvi/getopt.d
@@ -0,0 +1 @@
+getopt.o getopt.d : getopt.c
diff --git a/dviware/catdvi/getopt.h b/dviware/catdvi/getopt.h
new file mode 100644
index 0000000000..93f85641a1
--- /dev/null
+++ b/dviware/catdvi/getopt.h
@@ -0,0 +1,169 @@
+/* Declarations for getopt.
+ Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with the GNU C Library; see the file COPYING. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+# if defined __STDC__ && __STDC__
+ const char *name;
+# else
+ char *name;
+# endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+#if defined __STDC__ && __STDC__
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
+# else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+extern int getopt_long_only (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only);
+# endif
+#else /* not __STDC__ */
+extern int getopt ();
+# ifndef __need_getopt
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations. */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/dviware/catdvi/getopt1.c b/dviware/catdvi/getopt1.c
new file mode 100644
index 0000000000..432755faae
--- /dev/null
+++ b/dviware/catdvi/getopt1.c
@@ -0,0 +1,188 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with the GNU C Library; see the file COPYING. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/dviware/catdvi/getopt1.d b/dviware/catdvi/getopt1.d
new file mode 100644
index 0000000000..f1b785e434
--- /dev/null
+++ b/dviware/catdvi/getopt1.d
@@ -0,0 +1 @@
+getopt1.o getopt1.d : getopt1.c getopt.h
diff --git a/dviware/catdvi/glyphops.c b/dviware/catdvi/glyphops.c
new file mode 100644
index 0000000000..57ee40f368
--- /dev/null
+++ b/dviware/catdvi/glyphops.c
@@ -0,0 +1,320 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2000, 2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "glyphops.h"
+#include "sparse.h"
+#include "glyphenm.h"
+
+#define EOT 0x04 /* end-of-table mark */
+
+
+/* known formatting hints */
+struct glyph_hintentry_t {
+ glyph_t glyph;
+ enum glyph_hint_t hint;
+};
+
+static struct glyph_hintentry_t hints[] = {
+ {GLYPH_asciicircum, GH_DIACRITIC},
+ {GLYPH_grave, GH_DIACRITIC},
+ {GLYPH_asciitilde, GH_DIACRITIC},
+
+ {GLYPH_dieresis, GH_DIACRITIC},
+ {GLYPH_UNI_macron, GH_DIACRITIC},
+ {GLYPH_acute, GH_DIACRITIC},
+ {GLYPH_cedilla, GH_DIACRITIC},
+
+ {GLYPH_circumflex, GH_DIACRITIC},
+ {GLYPH_caron, GH_DIACRITIC},
+ {GLYPH_UNI_macronmodifier, GH_DIACRITIC},
+ {GLYPH_UNI_acutemodifier, GH_DIACRITIC},
+ {GLYPH_UNI_gravemodifier, GH_DIACRITIC},
+ {GLYPH_breve, GH_DIACRITIC},
+ {GLYPH_dotaccent, GH_DIACRITIC},
+ {GLYPH_ring, GH_DIACRITIC},
+ {GLYPH_ogonek, GH_DIACRITIC},
+ {GLYPH_tilde, GH_DIACRITIC},
+ {GLYPH_CATDVI_polishstroke, GH_DIACRITIC},
+
+ {GLYPH_CATDVI_negationslash, GH_DIACRITIC},
+ {GLYPH_UNI_circlelarge, GH_DIACRITIC},
+ {GLYPH_CATDVI_vector, GH_DIACRITIC},
+
+ {GLYPH_gravecomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_acutecomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_circumflexcomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_tildecomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_macroncomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_overlinecomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_brevecomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_dotaccentcomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_dieresiscomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_hookabovecomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_ringcomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_caroncomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_cedillacomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_ogonekcomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_CATDVI_polishstrokecomb, GH_COMBINING_DIACRITIC},
+
+ {GLYPH_UNI_slashlongcomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_circlecomb, GH_COMBINING_DIACRITIC},
+ {GLYPH_UNI_vectorcomb, GH_COMBINING_DIACRITIC},
+
+ {GLYPH_ADOBE_periodsuperior, GH_DIACRITIC},
+
+ {GLYPH_CATDVI_Eurodblstroke, GH_DIACRITIC},
+ {GLYPH_CATDVI_Eurodblstrokecomb, GH_COMBINING_DIACRITIC},
+
+ {GLYPH_radical, GH_RADICAL},
+ /* Is in the math symbols font but used just like the big
+ * variants in the math extension font.
+ */
+
+ /* The TeX math extension stuff */
+ {GLYPH_CATDVI_parenleftbig, GH_ON_AXIS},
+ {GLYPH_CATDVI_parenrightbig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_bracketleftbig, GH_ON_AXIS},
+ {GLYPH_CATDVI_bracketrightbig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_floorleftbig, GH_ON_AXIS},
+ {GLYPH_CATDVI_floorrightbig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_ceilingleftbig, GH_ON_AXIS},
+ {GLYPH_CATDVI_ceilingrightbig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_braceleftbig, GH_ON_AXIS},
+ {GLYPH_CATDVI_bracerightbig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_angbracketleftbig, GH_ON_AXIS},
+ {GLYPH_CATDVI_angbracketrightbig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_vextendsingle, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_CATDVI_vextenddouble, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_CATDVI_slashbig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_backslashbig, GH_ON_AXIS},
+ {GLYPH_CATDVI_parenleftBig, GH_ON_AXIS},
+ {GLYPH_CATDVI_parenrightBig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_parenleftbigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_parenrightbigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_bracketleftbigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_bracketrightbigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_floorleftbigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_floorrightbigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_ceilingleftbigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_ceilingrightbigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_braceleftbigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_bracerightbigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_angbracketleftbigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_angbracketrightbigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_slashbigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_backslashbigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_parenleftBigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_parenrightBigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_bracketleftBigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_bracketrightBigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_floorleftBigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_floorrightBigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_ceilingleftBigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_ceilingrightBigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_braceleftBigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_bracerightBigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_angbracketleftBigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_angbracketrightBigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_slashBigg, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_backslashBigg, GH_ON_AXIS},
+ {GLYPH_CATDVI_slashBig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_backslashBig, GH_ON_AXIS},
+ {GLYPH_ADOBE_parenlefttp, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_parenrighttp, GH_EXTENSIBLE_RECIPE | GH_MOREMATH_LEFT},
+ {GLYPH_ADOBE_bracketlefttp, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_bracketrighttp, GH_EXTENSIBLE_RECIPE | GH_MOREMATH_LEFT},
+ {GLYPH_ADOBE_bracketleftbt, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_bracketrightbt, GH_EXTENSIBLE_RECIPE | GH_MOREMATH_LEFT},
+ {GLYPH_ADOBE_bracketleftex, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_bracketrightex, GH_EXTENSIBLE_RECIPE | GH_MOREMATH_LEFT},
+ {GLYPH_ADOBE_bracelefttp, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_bracerighttp, GH_EXTENSIBLE_RECIPE | GH_MOREMATH_LEFT},
+ {GLYPH_ADOBE_braceleftbt, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_bracerightbt, GH_EXTENSIBLE_RECIPE | GH_MOREMATH_LEFT},
+ {GLYPH_ADOBE_braceleftmid, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_bracerightmid, GH_EXTENSIBLE_RECIPE | GH_MOREMATH_LEFT},
+ {GLYPH_ADOBE_braceex, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_arrowvertex, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_parenleftbt, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_parenrightbt, GH_EXTENSIBLE_RECIPE | GH_MOREMATH_LEFT},
+ {GLYPH_ADOBE_parenleftex, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_ADOBE_parenrightex, GH_EXTENSIBLE_RECIPE | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_angbracketleftBig, GH_ON_AXIS},
+ {GLYPH_CATDVI_angbracketrightBig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_unionsqtext, GH_ON_AXIS},
+ {GLYPH_CATDVI_unionsqdisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_contintegraltext, GH_ON_AXIS},
+ {GLYPH_CATDVI_contintegraldisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_circledottext, GH_ON_AXIS},
+ {GLYPH_CATDVI_circledotdisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_circleplustext, GH_ON_AXIS},
+ {GLYPH_CATDVI_circleplusdisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_circlemultiplytext, GH_ON_AXIS},
+ {GLYPH_CATDVI_circlemultiplydisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_summationtext, GH_ON_AXIS},
+ {GLYPH_CATDVI_producttext, GH_ON_AXIS},
+ {GLYPH_CATDVI_integraltext, GH_ON_AXIS},
+ {GLYPH_CATDVI_uniontext, GH_ON_AXIS},
+ {GLYPH_CATDVI_intersectiontext, GH_ON_AXIS},
+ {GLYPH_CATDVI_unionmultitext, GH_ON_AXIS},
+ {GLYPH_CATDVI_logicalandtext, GH_ON_AXIS},
+ {GLYPH_CATDVI_logicalortext, GH_ON_AXIS},
+ {GLYPH_CATDVI_summationdisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_productdisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_integraldisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_uniondisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_intersectiondisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_unionmultidisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_logicalanddisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_logicalordisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_coproducttext, GH_ON_AXIS},
+ {GLYPH_CATDVI_coproductdisplay, GH_ON_AXIS},
+ {GLYPH_CATDVI_hatwide, GH_WIDE_DIACRITIC},
+ {GLYPH_CATDVI_hatwider, GH_WIDE_DIACRITIC},
+ {GLYPH_CATDVI_hatwidest, GH_WIDE_DIACRITIC},
+ {GLYPH_CATDVI_tildewide, GH_WIDE_DIACRITIC},
+ {GLYPH_CATDVI_tildewider, GH_WIDE_DIACRITIC},
+ {GLYPH_CATDVI_tildewidest, GH_WIDE_DIACRITIC},
+ {GLYPH_CATDVI_bracketleftBig, GH_ON_AXIS},
+ {GLYPH_CATDVI_bracketrightBig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_floorleftBig, GH_ON_AXIS},
+ {GLYPH_CATDVI_floorrightBig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_ceilingleftBig, GH_ON_AXIS},
+ {GLYPH_CATDVI_ceilingrightBig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_braceleftBig, GH_ON_AXIS},
+ {GLYPH_CATDVI_bracerightBig, GH_ON_AXIS | GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_radicalbig, GH_RADICAL},
+ {GLYPH_CATDVI_radicalBig, GH_RADICAL},
+ {GLYPH_CATDVI_radicalbigg, GH_RADICAL},
+ {GLYPH_CATDVI_radicalBigg, GH_RADICAL},
+ {GLYPH_CATDVI_radicalbt, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_CATDVI_radicalvertex, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_CATDVI_radicaltp, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_CATDVI_arrowvertexdbl, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_CATDVI_arrowtp, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_CATDVI_arrowbt, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_CATDVI_bracehtipdownright, GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_bracehtipupright, GH_MOREMATH_LEFT},
+ {GLYPH_CATDVI_arrowdbltp, GH_EXTENSIBLE_RECIPE},
+ {GLYPH_CATDVI_arrowdblbt, GH_EXTENSIBLE_RECIPE},
+ /* end TeX math extension */
+
+ {GLYPH_CATDVI_tildexwide, GH_WIDE_DIACRITIC},
+ {GLYPH_CATDVI_hatxwide, GH_WIDE_DIACRITIC},
+
+ /* end of table */
+ {0, 0}
+};
+
+static struct spars32_t hint_spars32;
+
+
+/* known mappings between combining and non-combining diacritics.
+ * Incomplete. Use 0 for unavailable or unknown variants.
+ *
+ * variant3 and variant4 are for diacritics that are doubled in the
+ * unicode character set (doubled at least for our purposes and IMHO -
+ * if there is some underlying philosophy, I just can't see it) and
+ * should be mapped to something canonical.
+ *
+ * we try to keep the spacing variant in the ISO 8859-1 range if possible.
+ */
+struct diacritic_variantentry_t {
+ glyph_t spacing;
+ glyph_t combining;
+ glyph_t variant3;
+ glyph_t variant4;
+};
+
+static struct diacritic_variantentry_t diavars[] =
+{
+ {GLYPH_acute, GLYPH_acutecomb, GLYPH_UNI_acutemodifier, 0},
+ {GLYPH_grave, GLYPH_gravecomb, GLYPH_UNI_gravemodifier, 0},
+ {GLYPH_asciicircum, GLYPH_UNI_circumflexcomb, GLYPH_circumflex, 0},
+ {GLYPH_dieresis, GLYPH_UNI_dieresiscomb, 0, 0},
+ {GLYPH_tilde, GLYPH_tildecomb, GLYPH_asciitilde, 0},
+ {GLYPH_ring, GLYPH_UNI_ringcomb, 0, 0},
+
+ {GLYPH_cedilla, GLYPH_UNI_cedillacomb, 0, 0},
+
+ {GLYPH_caron, GLYPH_UNI_caroncomb, 0, 0},
+ {GLYPH_UNI_macron, GLYPH_UNI_macroncomb, GLYPH_UNI_macronmodifier, 0},
+ {GLYPH_breve, GLYPH_UNI_brevecomb, 0, 0},
+ {GLYPH_dotaccent, GLYPH_UNI_dotaccentcomb, GLYPH_ADOBE_periodsuperior, 0},
+
+ {GLYPH_ogonek, GLYPH_UNI_ogonekcomb, 0, 0},
+ {GLYPH_CATDVI_polishstroke, GLYPH_CATDVI_polishstrokecomb, 0, 0},
+
+ {GLYPH_CATDVI_negationslash, GLYPH_UNI_slashlongcomb, 0, 0},
+ {GLYPH_UNI_circlelarge, GLYPH_UNI_circlecomb, 0, 0},
+ {GLYPH_CATDVI_vector, GLYPH_UNI_vectorcomb, 0, 0},
+
+ {GLYPH_CATDVI_Eurodblstroke, GLYPH_CATDVI_Eurodblstrokecomb, 0, 0},
+
+ /* end of table */
+ {EOT, 0, 0, 0}
+};
+
+static struct sparp_t diavar_sparp;
+
+void glyphops_init()
+{
+ struct glyph_hintentry_t * ph;
+ struct diacritic_variantentry_t * pd;
+
+ /* The glyph hint sparp is indexed by the glyph and points directly to
+ * the hint.
+ */
+ spars32_init(&hint_spars32, 0);
+ for(ph = hints; ph->glyph != 0; ++ph) {
+ spars32_write(&hint_spars32, ph->glyph, ph->hint);
+ }
+
+ /* The diacritics variant sparp is indexed by any variant of the diacritic.
+ * The values point to the corresponding dicaritic_variantentry_t .
+ */
+ sparp_init(&diavar_sparp);
+ for(pd = diavars; pd->spacing != EOT; ++pd) {
+ if(pd->spacing != 0) sparp_write(&diavar_sparp, pd->spacing, pd);
+ if(pd->combining != 0) sparp_write(&diavar_sparp, pd->combining, pd);
+ if(pd->variant3 != 0) sparp_write(&diavar_sparp, pd->variant3, pd);
+ if(pd->variant4 != 0) sparp_write(&diavar_sparp, pd->variant4, pd);
+ }
+
+}
+
+enum glyph_hint_t glyph_get_hint(glyph_t glyph)
+{
+ return (enum glyph_hint_t) spars32_read(&hint_spars32, glyph);
+}
+
+glyph_t diacritic_combining_variant(glyph_t diacritic)
+{
+ struct diacritic_variantentry_t * p;
+
+ p = sparp_read(&diavar_sparp, diacritic);
+ return (p != NULL) ? p->combining : 0;
+}
+
+glyph_t diacritic_spacing_variant(glyph_t diacritic)
+{
+ struct diacritic_variantentry_t * p;
+
+ p = sparp_read(&diavar_sparp, diacritic);
+ return (p != NULL) ? p->spacing : 0;
+}
diff --git a/dviware/catdvi/glyphops.d b/dviware/catdvi/glyphops.d
new file mode 100644
index 0000000000..9235594957
--- /dev/null
+++ b/dviware/catdvi/glyphops.d
@@ -0,0 +1,2 @@
+glyphops.o glyphops.d : glyphops.c glyphops.h page.h bytesex.h pageref.h sparse.h \
+ glyphenm.h
diff --git a/dviware/catdvi/glyphops.h b/dviware/catdvi/glyphops.h
new file mode 100644
index 0000000000..f629360003
--- /dev/null
+++ b/dviware/catdvi/glyphops.h
@@ -0,0 +1,65 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2000 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef GLYPHOPS_H
+#define GLYPHOPS_H
+
+/* for definition of glyph_t */
+#include "page.h"
+
+/* assorted magic with unicode characters ("glyphs")
+ */
+
+/* bit flags for certain possible properties of glyphs. useful as
+ * hints for correct rendering. Most are still unused.
+ */
+enum glyph_hint_t {
+ GH_DIACRITIC = 1 << 0,
+ GH_COMBINING = 1 << 1,
+ GH_NON_SPACING = 1 << 2,
+ GH_GRAPHIC = 1 << 3,
+ GH_MATH = 1 << 4,
+ GH_LIGATURE = 1 << 5,
+ GH_ON_AXIS = 1 << 6,
+ GH_EXTENSIBLE_RECIPE = 1 << 7, /* TeX specific */
+ GH_WIDE_DIACRITIC = 1 << 8,
+ GH_MOREMATH_LEFT = 1 << 9, /* e.g. for right math delimiters */
+ GH_RADICAL = 1 << 10
+};
+
+#define GH_COMBINING_DIACRITIC (GH_DIACRITIC | GH_COMBINING | GH_NON_SPACING)
+
+/* set up internal tables used by the other functions */
+void glyphops_init(void);
+
+/* returns our ORed wisdom abut the given glyph */
+enum glyph_hint_t glyph_get_hint(glyph_t glyph);
+
+/* unicode knows two kinds of diacritics: combining diacritics are by
+ * themselves unprintable characters that change the meaning of the
+ * preceding glyph. spacing diacritics are printable (roughly
+ * equivalent to space followed by the corresponding combining diacritic).
+ *
+ * the following functions translate one into the other. idempotent.
+ * return zero on failure.
+ */
+glyph_t diacritic_combining_variant(glyph_t diacritic);
+glyph_t diacritic_spacing_variant(glyph_t diacritic);
+
+#endif
diff --git a/dviware/catdvi/kpathsea.c b/dviware/catdvi/kpathsea.c
new file mode 100644
index 0000000000..c0e407d1c4
--- /dev/null
+++ b/dviware/catdvi/kpathsea.c
@@ -0,0 +1,46 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <kpathsea/kpathsea.h>
+#include <stdio.h>
+#include "findtfm.h"
+#include "version.h"
+
+void setup_findtfm(char const * progname)
+{
+ kpse_set_program_name(progname, PACKAGE);
+ kpse_init_format(kpse_tfm_format);
+ kpse_set_program_enabled(kpse_tfm_format, 1, kpse_src_cmdline);
+}
+
+void copyright_findtfm(void)
+{
+ /* This is for kpathsea 3.2 */
+ puts("Copyright Karl Berry, Olaf Weber and others (kpathsea library)");
+}
+
+void version_findtfm(void)
+{
+ extern char * kpathsea_version_string;
+ puts(kpathsea_version_string);
+}
+
+char const * find_tfm(char const * fontname)
+{
+ return kpse_find_tfm(fontname);
+}
diff --git a/dviware/catdvi/kpathsea.d b/dviware/catdvi/kpathsea.d
new file mode 100644
index 0000000000..781d61aa92
--- /dev/null
+++ b/dviware/catdvi/kpathsea.d
@@ -0,0 +1 @@
+kpathsea.o kpathsea.d : kpathsea.c findtfm.h version.h
diff --git a/dviware/catdvi/layout.c b/dviware/catdvi/layout.c
new file mode 100644
index 0000000000..fa3275c7e3
--- /dev/null
+++ b/dviware/catdvi/layout.c
@@ -0,0 +1,1119 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2000-02 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdlib.h>
+#include <assert.h>
+#include "layout.h"
+#include "util.h"
+#include "page2.h"
+#include "outenc.h"
+#include "linebuf.h"
+#include "density.h"
+#include "canvas.h"
+#include "vlist.h"
+#include "fontinfo.h"
+
+/* page margins */
+static sint32 left_margin, right_margin;
+static sint32 top_margin, bottom_margin;
+
+/* other page metrics */
+int linecount = 0;
+uint32 boxcount = 0;
+double average_box_width = 0;
+double average_box_totheight = 0;
+
+/* layout parameters */
+sint32 max_col_width, max_row_height;
+double min_col_density, min_line_density;
+scdf_t col_density, line_density;
+scdf_t * x2col, * y2line;
+
+
+/* some obvious stuff about rectangles */
+typedef struct rect_t rect_t;
+struct rect_t {
+ sint32 xmin;
+ sint32 xmax;
+ sint32 ymin;
+ sint32 ymax;
+};
+
+int intervals_intersect(
+ sint32 a, sint32 b,
+ sint32 c, sint32 d
+);
+
+int rect_intersects(const rect_t * this, const rect_t * that);
+
+int rect_contains_point(const rect_t * this, sint32 x, sint32 y);
+
+/* create rect */
+void rect_set(
+ rect_t * this,
+ sint32 xmin,
+ sint32 xmax,
+ sint32 ymin,
+ sint32 ymax
+);
+
+void rect_set_empty(rect_t * this);
+
+int rect_is_empty(const rect_t * this);
+
+/* *this = smallest rect containing *this and *that */
+void rect_union_with(rect_t * this, const rect_t * that);
+
+
+/* a page_word is a sequence of contiguous box_t which should remain
+ * contiguous in printout.
+ */
+typedef struct page_word_t page_word_t;
+struct page_word_t {
+ list_node_t * alpha; /* node of first box in word */
+ list_node_t * omega; /* node of last box in word */
+ linebuf_t * text;
+ rect_t brect; /* bounding rectangle: the smallest rectangle
+ * containing the part _avove the baseline_
+ * of all boxes in the word
+ */
+ sint32 ceiling; /* stuff with y <= ceiling should appear top of
+ * our row in printout.
+ */
+ sint32 right_wall; /* stuff with x >= right_wall should appear right
+ * from our rightmost glyph in printout.
+ */
+ sint32 right_corridor; /* stuff on the same row with x >= right_corridor
+ * should appear trailing_spaces columns right from
+ * our rightmost glyph in printout.
+ */
+ int output_width;
+ int trailing_spaces; /* usually 1, somtetimes 0 */
+ int row;
+ int column;
+};
+
+/* The page has one global list of page_words */
+vlist_t page_words;
+
+/* constructor */
+static void page_word_init(
+ page_word_t * this,
+ list_node_t * alpha,
+ list_node_t * omega,
+ int trailing_spaces
+);
+
+/* destructor */
+static void page_word_done(page_word_t * this);
+
+/* Try to resolve collisions (i.e. situations where the bounding rects of
+ * two words intersect).
+ */
+static void page_words_collide(vitor_t vi, vitor_t vj);
+
+/* Split *this before where; i.e. :
+ * - create a new page_word containing the boxes from where to this->omega
+ * on the heap ("right half")
+ * - shrink *this to the boxes from this->alpha to where->prev ("left half")
+ * - return pointer to new page_word
+ * Both the left and right half are brought into shape by constructor calls,
+ * so any information about ceilings, right walls, etc. gets lost.
+ */
+static page_word_t * page_word_split_at(
+ page_word_t * this,
+ struct list_node_t * where
+);
+
+
+/* Estimate number of spaces from distance between boxes */
+static int decide_space_count(
+ struct list_node_t * prev_p,
+ struct list_node_t * p
+);
+
+/* Look at the midpoints of two boxes. If either midpoint lies in the other
+ * box, the boxes compare "equal". Otherwise, we compare x of midpoints.
+ */
+sint32 box_sloppy_x_cmp(const struct box_t * p1, const struct box_t * p2);
+
+
+static void page_collect_statistics(void);
+
+/* Make an initial pass at cutting the page into words, based on the distance
+ * between adjacent boxes. This will be refined in a later pass.
+ */
+static void page_cut_words(void);
+
+
+/* If the bounding rectangles of two words on the page collide, we have
+ * likely hit a word breaking problem (example: math subscripts are
+ * too thin to cause a word break between adjacent variables). If a
+ * collission occurs, we call a function that tries to resolve it
+ * by introducing additional word breaks.
+ */
+static void page_check_word_collisions(void);
+
+/* The idea: words with x coordinates close to each other and different
+ * y coordinates should appear on different rows in printout.
+ */
+static void page_find_ceilings(void);
+
+/* If two words end up on the same line in printout, then the left one
+ * needs to put its trailing_spaces before the right one starts.
+ * Obviously, this has to be called _after_ we know our rows.
+ */
+static void page_find_right_corridors(void);
+
+/* If the y intervals of the bounding rectangles of two words intersect,
+ * then the left one should end in printout before the right one starts.
+ * This should be called _after_ page_find_right_corridors() because we want
+ * to ensure right_wall <= right_corridor .
+ */
+static void page_find_right_walls(void);
+
+/* Determine on which row in printout words end up. The main vehicle here
+ * is a line density function; we force it to have integral >=1 on the
+ * interval [word->ceiling, word->brect->ymax].
+ * The words are then positioned so that their baseline is in the correct row.
+ */
+static void page_determine_lines(void);
+
+/* Determine on which column in printout words end up. The main vehicle here
+ * is a column density function; we force it to have large enough integrals
+ * on the intervals [word->brect->xmin, word->right_wall] resp.
+ * [word->brect->xmin, word->right_wall] to accomodate word->output_width
+ * resp. word->output_width + word->trailing_spaces columns.
+ * The words are then positioned so that their left boundary is in the correct
+ * column.
+ */
+static void page_determine_cols(void);
+
+
+void page_print_formatted(void)
+{
+ canv_t canvas;
+ vitor_t pwi;
+
+ pmesg(50, "BEGIN page_print_formatted\n");
+
+ /* Life is much easier if we don't have to care for the case
+ * of an empty page all the time.
+ */
+ if(list_head == NULL) {
+ puts("\f\n");
+ pmesg(80, "This page is empty.\n");
+ pmesg(50, "END page_print_formatted\n");
+ return;
+ }
+
+ page_adjust_diacritics();
+ page_adjust_texmext();
+ page_adjust_radicals();
+
+ page_collect_statistics();
+
+ max_col_width = (sint32) (4.0 * average_box_width);
+ max_row_height = (sint32) (3.0 * average_box_totheight);
+ min_col_density = 1.0 / max_col_width;
+ min_line_density = 1.0 / max_row_height;
+ /*
+ * The minimal densities should ensure that large amounts of white space
+ * do not completely get lost. The factors 3.0, 4.0 have been determined
+ * by rules of thumb and experiments.
+ * The (unverified) expectation is that a printout column will be
+ * about average_box_width DVI units wide and a printout row will be
+ * about 1.5 * average_box_totheight DVI units high.
+ */
+ scdf_init(&col_density, left_margin, right_margin, min_col_density);
+ /* col_density measures the column density at every point between
+ * left and right margin which is required to do proper positioning
+ * of every word.
+ */
+ scdf_init(&line_density, top_margin, bottom_margin, min_line_density);
+ /* Similar for line_density and lines */
+
+ vlist_init(&page_words);
+ page_cut_words();
+ page_check_word_collisions();
+
+ page_find_ceilings();
+ page_determine_lines();
+
+ page_find_right_corridors();
+ page_find_right_walls();
+ page_determine_cols();
+
+ /* Now print out everything */
+ canv_init(
+ &canvas,
+ (sint32) scdf_eval(x2col, right_margin) + 1,
+ (sint32) scdf_eval(y2line, bottom_margin) + 1
+ );
+ for(
+ pwi = vlist_begin(&page_words);
+ pwi != vlist_end(&page_words);
+ pwi = pwi->next
+ ) {
+ page_word_t * pw;
+
+ pw = vitor2ptr(pwi, page_word_t);
+ canv_put_linebuf(
+ &canvas,
+ pw->text,
+ pw->column,
+ pw->row,
+ pw->output_width
+ );
+ pw->text = NULL; /* text is now owned by the canvas */
+ }
+ canv_write(&canvas, stdout);
+ puts("\f\n");
+
+ /* clean up */
+
+ canv_done(&canvas);
+
+ for(
+ pwi = vlist_begin(&page_words);
+ pwi != vlist_end(&page_words);
+ pwi = pwi->next
+ ) {
+ page_word_done(pwi->data);
+ free(pwi->data);
+ }
+ vlist_done(&page_words);
+
+ scdf_done(y2line); free(y2line);
+ scdf_done(x2col); free(x2col);
+ scdf_done(&col_density);
+ scdf_done(&line_density);
+
+ pmesg(50, "END page_print_formatted\n");
+}
+
+
+void page_print_sequential(void)
+{
+ struct list_node_t * p;
+ struct box_t prev_box, curr_box;
+
+ sint32 delta_x = 0, delta_y = 0;
+ sint32 dist_x = 0;
+ sint32 epsilon_x = 0, epsilon_y = 0;
+
+ /* begin-of-page flag */
+ int bop = 1;
+ /* begin-of-line flag */
+ int bol = 1;
+
+ int spaces, spaces_by_prev, spaces_by_curr;
+ struct linebuf_t lb;
+
+ pmesg(50, "BEGIN page_print_sequential\n");
+
+ page_adjust_diacritics();
+
+ linebuf_init(&lb, 0);
+ prev_box.width = 1;
+ prev_box.height = 1;
+
+ for (p = list_head; p != 0; p = p->next) {
+
+ pmesg(80, "node: X = %li, Y = %li, glyph = %li (%c), font = %li\n",
+ p->b.x, p->b.y, p->b.glyph, (unsigned char) p->b.glyph, p->b.font);
+
+ curr_box = p->b;
+ if (curr_box.width == 0) curr_box.width = prev_box.width;
+ if (curr_box.height == 0) curr_box.height = prev_box.height;
+
+ if (!bop) {
+ delta_x = curr_box.x - prev_box.x;
+ delta_y = curr_box.y - prev_box.y;
+ dist_x = delta_x - prev_box.width;
+
+ /* (arithmetic mean of current and previous) / 20 */
+ epsilon_x = (curr_box.width + prev_box.width + 39) / 40;
+ epsilon_y = (curr_box.height + prev_box.height + 39) / 40;
+
+ /* check for new line */
+ if (
+ /* new line */
+ delta_y >= 22*epsilon_y ||
+ /* new column */
+ delta_y <= -60*epsilon_y ||
+ /* weird step back */
+ dist_x <= -100*epsilon_x
+ ) {
+ pmesg(80, "end of line\n");
+ outenc_write(stdout, &lb);
+ linebuf_clear(&lb);
+ puts("");
+ bol = 1;
+ }
+
+ /* check for word breaks, but not at the beginning of a line */
+ if ((dist_x > 0) && (!bol)) {
+ spaces_by_prev =
+ font_w_to_space(prev_box.font, dist_x);
+ spaces_by_curr =
+ font_w_to_space(curr_box.font, dist_x);
+ spaces = (spaces_by_prev + spaces_by_curr + 1) / 2;
+
+ if (spaces > 0) {
+ pmesg(80, "setting space\n");
+ linebuf_putg(&lb, ' ');
+ }
+ }
+
+ } /* end if (!bop) */
+
+ linebuf_putg(&lb, curr_box.glyph);
+ prev_box = curr_box;
+ bop = 0;
+ bol = 0;
+ }
+ /* flush line buffer and end page */
+ outenc_write(stdout, &lb);
+ puts("\n\f\n");
+
+ linebuf_done(&lb);
+
+ pmesg(50, "END page_print_sequential\n");
+}
+
+static int decide_space_count(
+ struct list_node_t * prev_p,
+ struct list_node_t * p
+)
+{
+ font_t prev_font, curr_font;
+ sint32 prev_x, prev_width;
+ sint32 curr_x;
+ sint32 delta;
+ int (* const f2spc)(sint32, sint32) = font_w_to_space;
+
+ prev_font = prev_p->b.font;
+ prev_x = prev_p->b.x;
+ prev_width = prev_p->b.width;
+
+ curr_font = p->b.font;
+ curr_x = p->b.x;
+
+ delta = curr_x - (prev_x + prev_width);
+ return (1 + f2spc(curr_font, delta) + f2spc(prev_font, delta)) / 2;
+}
+
+
+/*************** page_word_t method implementations ****************/
+void page_word_init(
+ page_word_t * this,
+ list_node_t * alpha,
+ list_node_t * omega,
+ int trailing_spaces
+)
+{
+ list_node_t * p, * q;
+ rect_t r;
+
+ this->alpha = alpha;
+ this->omega = omega;
+ this->text = xmalloc(sizeof(linebuf_t));
+ linebuf_init(this->text, 20);
+ /* 20 seems a good tradeoff between memory usage and
+ * avoiding reallocs.
+ */
+ rect_set_empty(&(this->brect));
+ this->ceiling = SINT32_MIN;
+ /* The top line has no ceiling -- it fits automatically */
+ this->right_wall = right_margin;
+ this->right_corridor = right_margin;
+ /* this->output_width will be set below */
+ this->trailing_spaces = trailing_spaces;
+ this->row = -1; /* will be filled in later */
+ this->column = -1; /* will be filled in later */
+
+ q = omega->next;
+ for(p = alpha; p != q; p = p->next) {
+ /* add p->b to bounding rect */
+ rect_set(
+ &r,
+ p->b.x,
+ p->b.x + p->b.width,
+ p->b.y - p->b.height,
+ p->b.y
+ );
+ rect_union_with(&(this->brect), &r);
+
+ /* add p->b.glyph to text */
+ linebuf_putg(this->text, p->b.glyph);
+ }
+
+ this->output_width = outenc_get_width(this->text);
+}
+
+
+void page_word_done(page_word_t * this)
+{
+ this->alpha = NULL;
+ this->omega = NULL;
+ /* this->text will be NULL after it has been passed to canvas */
+ if(this->text != NULL) {
+ linebuf_done(this->text);
+ free(this->text);
+ this->text = NULL;
+ }
+}
+
+static void page_words_collide(vitor_t vi, vitor_t vj)
+{
+ page_word_t * wp, * wq;
+ list_node_t * bp, * bq;
+ sint32 c;
+
+ pmesg(60, "BEGIN page_words_collide\n");
+
+ wp = vi->data;
+ wq = vj->data;
+
+ bp = wp->alpha;
+ bq = wq->alpha;
+ if(box_sloppy_x_cmp(&bp->b, &bq->b) > 0) {
+ /* We want to assume that *wp starts left from *wq */
+ pmesg(60, "calling myself with exchanged arguments\n");
+ page_words_collide(vj, vi);
+ pmesg(60, "END page_words_collide\n");
+ return;
+ }
+
+ /* Skip all letters of *wp left of *wq. We allow a certain margin overlap
+ * to accomodate italics correction, kerning, etc.
+ */
+ while(c = box_sloppy_x_cmp(&bp->b, &bq->b), c < 0) {
+ if(bp == wp->omega) {
+ /* We're at the end of *wp, so either really no collision
+ * at all, or only the last box collides. Anyway, nothing
+ * to do.
+ */
+ pmesg(60, "nothing to do\n");
+ pmesg(60, "END page_words_collide\n");
+ return;
+ }
+ bp = bp->next;
+ }
+
+ if(c == 0) {
+ /* Ouch, full crash */
+ pmesg(60, "unresolvable collision\n");
+ pmesg(60, "END page_words_collide\n");
+ return;
+ }
+
+ /* We've moved bp across the beginning of *wq */
+ pmesg(60, "resolving collision by splitting word\n");
+ vlist_insert_after(&page_words, vi, page_word_split_at(wp, bp));
+
+ /* Check for further collisions between *wq and the right piece of *wp */
+ pmesg(60, "checking for further collisions\n");
+ page_words_collide(vj, vi->next);
+ pmesg(60, "END page_words_collide\n");
+}
+
+static page_word_t * page_word_split_at(
+ page_word_t * this,
+ struct list_node_t * where
+)
+{
+ page_word_t * righthalf;
+ list_node_t * alpha;
+
+ /* No splitting with one half empty, please. */
+ assert(where != this->alpha);
+ assert(where != this->omega->next);
+
+ /* create right half */
+ righthalf = xmalloc(sizeof(page_word_t));
+ page_word_init(righthalf, where, this->omega, this->trailing_spaces);
+
+ /* reinit left half (ourselves) */
+ alpha = this->alpha;
+ page_word_done(this);
+ page_word_init(this, alpha, where->prev, 0);
+
+ return righthalf;
+}
+
+
+sint32 box_sloppy_x_cmp(const struct box_t * p1, const struct box_t * p2)
+{
+ sint32 m1, m2; /* midpoints */
+
+ m1 = p1->x + p1->width / 2;
+ m2 = p2->x + p2->width / 2;
+
+ /* If the x midpoint of one box is in the x interval of the other,
+ * the two are considered close together (and compare "equal").
+ * Otherwise, the x midpoints are compared.
+ */
+ if(p1->x <= m2 && m2 <= p1->x + p1->width) return 0;
+ if(p2->x <= m1 && m1 <= p2->x + p2->width) return 0;
+ return m1 - m2;
+}
+
+
+/*************** page layout passes ********************************/
+void page_collect_statistics(void)
+{
+ struct list_node_t * p;
+ sint32 prev_y;
+
+ pmesg(80, "BEGIN page_collect_statistics\n");
+
+ left_margin = SINT32_MAX;
+ right_margin = SINT32_MIN;
+ top_margin = SINT32_MAX;
+ bottom_margin = SINT32_MIN;
+
+ average_box_width = 0;
+ average_box_totheight = 0;
+ linecount = 0;
+ boxcount = 0;
+
+ prev_y = list_head->b.y;
+ for (p = list_head; p != 0; p = p->next) {
+ sint32 x, y, width, height, depth;
+
+ x = p->b.x;
+ y = p->b.y;
+ width = p->b.width;
+ height = p->b.height;
+ depth = p->b.depth;
+
+ left_margin = min(left_margin, x);
+ right_margin = max(right_margin, x + width);
+ top_margin = min(top_margin, y - height);
+ bottom_margin = max(bottom_margin, y + depth);
+
+ if (y > prev_y) {
+ prev_y = y;
+ linecount++;
+ }
+
+ average_box_width += width;
+ average_box_totheight += (height + depth);
+ ++boxcount;
+ }
+ ++linecount; /* The last line hasn't been counted */
+ average_box_width = average_box_width / boxcount;
+ average_box_totheight = average_box_totheight / boxcount;
+
+ pmesg(80, "left margin: %ld, right margin: %ld.\n", \
+ left_margin, right_margin);
+ pmesg(80, "top margin: %ld, bottom margin: %ld.\n", \
+ top_margin, bottom_margin);
+
+ pmesg(80, "END page_collect_statistics\n");
+}
+
+
+void page_cut_words(void)
+{
+ struct list_node_t * p;
+
+ int bop, eop, bol, eol, bow, eow;
+ /* {begin,end} of {page, line, word} flags */
+
+ pmesg(50, "BEGIN page_cut_words\n");
+
+ bop = 1;
+ bol = 1;
+ bow = 1;
+ for (p = list_head; p != NULL; p = p->next) {
+ sint32 y;
+ list_node_t * curr_alpha;
+
+ pmesg(80, "node: X = %li, Y = %li, glyph = %li (%c), font = %li\n",
+ p->b.x, p->b.y, p->b.glyph, (unsigned char) p->b.glyph, p->b.font);
+
+ y = p->b.y;
+ eop = (p->next == NULL);
+ eol = eop || (p->next->b.y != y);
+ eow = eol || (decide_space_count(p, p->next) > 0);
+
+ if(bow) {
+ curr_alpha = p;
+ }
+
+ if(eow) {
+ int trailing_space;
+ page_word_t * new_word;
+
+ if(eol) {
+ trailing_space = 0;
+ }
+ else {
+ trailing_space = 1;
+ }
+
+ /* Make up a page_word_t from the collected data and insert
+ * it into the page_words list
+ */
+ new_word = xmalloc(sizeof(page_word_t));
+ page_word_init(new_word, curr_alpha, p, trailing_space);
+ vlist_push_back(&page_words, new_word);
+ }
+
+ if(eol) {
+ pmesg(80, "end of line\n");
+ }
+
+ bop = 0;
+ bol = eol;
+ bow = eow;
+
+ } /* for p */
+
+ pmesg(50, "END page_cut_words\n");
+
+}
+
+
+static void page_check_word_collisions(void)
+{
+ vitor_t vi, nvi, vj, llvi;
+ page_word_t * p, * np, * q;
+ int eop, eol;
+
+ pmesg(50, "BEGIN page_check_word_collisions\n");
+
+ llvi = vlist_rend(&page_words);
+
+ for(
+ vi = vlist_begin(&page_words);
+ vi != vlist_end(&page_words);
+ vi = nvi
+ ) {
+ p = vi->data;
+ nvi = vi->next;
+ np = nvi->data;
+
+ eop = (nvi == vlist_end(&page_words));
+ eol = eop || np->brect.ymax != p->brect.ymax;
+
+ /* We only need to look upwards, a collision will then always be caught
+ * by the lower one of the colliding words.
+ * Collisions between words on the same baseline cannot occur
+ * (by design of the basic word break algorithm) and shouldn't
+ * result in new word breaks anyway.
+ *
+ * We keep an iterator to the last word in the previous line (upwards)
+ * to avoid repeated skipping backwards over preceding words
+ * on the same baseline.
+ */
+ for(vj = llvi; vj != vlist_rend(&page_words); vj = vj->prev) {
+ q = vj->data;
+ if(q->brect.ymax < p->brect.ymin) break;
+ /* We are too far up to find any more collisions. Note
+ * this happens _immediately_ in the standard (one column
+ * text without intersecting lines) case.
+ */
+ if(!intervals_intersect(
+ p->brect.xmin, p->brect.xmax,
+ q->brect.xmin, q->brect.xmax
+ )) continue;
+ page_words_collide(vi, vj);
+ /* We do _not_ break if q->brect.xmax < p->brect.xmin
+ * because there may be more than one line with
+ * possible collisions.
+ */
+ }
+
+ if(eol) llvi = vi;
+ }
+
+ pmesg(50, "END page_check_word_collisions\n");
+}
+
+
+static void page_find_ceilings(void)
+{
+ vitor_t vi, nvi, vj, llvi;
+ page_word_t * p, * np, * q;
+ int eop, eol;
+
+ pmesg(50, "BEGIN page_find_ceilings\n");
+
+ llvi = vlist_rend(&page_words);
+
+ /* Our policy is the following:
+ * a. Stuff that has its baseline above our head (read p->brect.ymin) must
+ * end up on a higher line.
+ * b. Stuff that is near us in x direction and has its baseline above
+ * ours must end up on a higher line.
+ */
+
+ for(
+ vi = vlist_begin(&page_words);
+ vi != vlist_end(&page_words);
+ vi = nvi
+ ) {
+ sint32 xmin, xmax; /* the x interval we're interested in */
+ sint32 ymin; /* we need not care for stuff higher that that */
+
+ p = vi->data;
+ nvi = vi->next;
+ np = nvi->data;
+
+ xmin = p->brect.xmin - 2 * average_box_width;
+ xmax = p->brect.xmax + 2 * average_box_width;
+ ymin = p->brect.ymax - max_row_height;
+
+ eop = (nvi == vlist_end(&page_words));
+ eol = eop || np->brect.ymax != p->brect.ymax;
+
+ /* We only need to look upwards, and no further than max_row_hight
+ *
+ * We keep an iterator to the last word in the previous line (upwards)
+ * to avoid repeated skipping backwards over preceding words
+ * on the same baseline.
+ * Since the list is traversed bottom-to-top, we can stop looking
+ * as soon as we've found the first ceiling candidate.
+ */
+ for(vj = llvi; vj != vlist_rend(&page_words); vj = vj->prev) {
+ q = vj->data;
+ if(q->brect.ymax < ymin) {
+ /* stuff so high will end up on another line automatically */
+ break;
+ }
+ if(q->brect.ymax < p->brect.ymin) {
+ p->ceiling = q->brect.ymax;
+ break;
+ }
+ if(intervals_intersect(
+ xmin, xmax,
+ q->brect.xmin, q->brect.xmax
+ )) {
+ p->ceiling = q->brect.ymax;
+ break;
+ }
+ }
+
+ if(eol) llvi = vi;
+ }
+
+ pmesg(50, "END page_find_ceilings\n");
+}
+
+
+static void page_find_right_corridors(void)
+{
+ vitor_t vi, nvi, vj, llvi;
+ page_word_t * p, * np, * q;
+ int eop, eol;
+
+ pmesg(50, "BEGIN page_find_right_corridors\n");
+
+ llvi = vlist_rend(&page_words);
+
+ for(
+ vi = vlist_begin(&page_words);
+ vi != vlist_end(&page_words);
+ vi = nvi
+ ) {
+ p = vi->data;
+ nvi = vi->next;
+ np = nvi->data;
+
+ eop = (nvi == vlist_end(&page_words));
+ eol = eop || np->brect.ymax != p->brect.ymax;
+
+ /* first we look directly right */
+ if(!eol) {
+ p->right_corridor = min(p->right_corridor, np->brect.xmin);
+ }
+
+ /* Now we look upwards (left and right).
+ *
+ * We keep an iterator to the last word in the previous line (upwards)
+ * to avoid repeated skipping backwards over preceding words
+ * on the same baseline.
+ */
+ for(vj = llvi; vj != vlist_rend(&page_words); vj = vj->prev) {
+ q = vj->data;
+ if(q->row < p->row) break;
+ /* We need not look further up */
+ if(q->brect.xmin < p->brect.xmin) {
+ q->right_corridor = min(q->right_corridor, p->brect.xmin);
+ }
+ else if(p->brect.xmin < q->brect.xmin) {
+ p->right_corridor = min(p->right_corridor, q->brect.xmin);
+ }
+ }
+
+ if(eol) llvi = vi;
+ }
+
+ pmesg(50, "END page_find_right_corridors\n");
+}
+
+
+static void page_find_right_walls(void)
+{
+ vitor_t vi, nvi, vj, llvi;
+ page_word_t * p, * np, * q;
+ int eop, eol;
+
+ pmesg(50, "BEGIN page_find_right_walls\n");
+
+ llvi = vlist_rend(&page_words);
+
+ for(
+ vi = vlist_begin(&page_words);
+ vi != vlist_end(&page_words);
+ vi = nvi
+ ) {
+ p = vi->data;
+ nvi = vi->next;
+ np = nvi->data;
+
+ eop = (nvi == vlist_end(&page_words));
+ eol = eop || np->brect.ymax != p->brect.ymax;
+
+ /* This has to be done somewhere. The most natural place is here. */
+ p->right_wall = min(p->right_wall, p->right_corridor);
+
+ /* We need not look directly right, we've already done so to
+ * find right_corridor. But if we are at the end of the line,
+ * we want stuff on other lines starting clearly right from where we
+ * end to appear right of us.
+ */
+ if(eol) {
+ p->right_wall = min(
+ p->right_wall,
+ p->brect.xmax + average_box_width
+ );
+ /* FIXME: is average_box_width the right amount of slack? Or
+ * use no slack at all ?
+ */
+ }
+
+ /* Now we look upwards (left and right).
+ *
+ * We keep an iterator to the last word in the previous line (upwards)
+ * to avoid repeated skipping backwards over preceding words
+ * on the same baseline.
+ */
+ for(vj = llvi; vj != vlist_rend(&page_words); vj = vj->prev) {
+ q = vj->data;
+ if(q->brect.ymax < p->brect.ymin) break;
+ /* We need not look further up */
+ if(box_sloppy_x_cmp(&(q->omega->b), &(p->alpha->b)) < 0) {
+ /* *q ends left from *p */
+ q->right_wall = min(q->right_wall, p->brect.xmin);
+ }
+ else if(box_sloppy_x_cmp(&(p->omega->b), &(q->alpha->b)) < 0) {
+ /* *q starts right from *p */
+ p->right_wall = min(p->right_wall, q->brect.xmin);
+ }
+ /* FIXME: what about crashing words? Should we do something here?
+ * And is box_sloppy_x_cmp() really the right criterion?
+ */
+ }
+
+ if(eol) llvi = vi;
+ }
+
+ pmesg(50, "END page_find_right_walls\n");
+}
+
+
+static void page_determine_lines(void)
+{
+ vitor_t vi;
+ page_word_t * p;
+
+ pmesg(50, "BEGIN page_determine_lines\n");
+
+ for(
+ vi = vlist_begin(&page_words);
+ vi != vlist_end(&page_words);
+ vi = vi->next
+ ) {
+ p = vi->data;
+ pmesg(
+ 100,
+ "x = %ld, y = %ld, ceiling = %ld\n",
+ p->brect.xmin,
+ p->brect.ymax,
+ p->ceiling
+ );
+
+ if(p->ceiling >= top_margin) {
+ scdf_force_min_integral(
+ &line_density,
+ p->ceiling,
+ p->brect.ymax,
+ 1
+ );
+ }
+ }
+
+ scdf_normalize(&line_density);
+ y2line = scdf_floor_of_integral(&line_density);
+
+ for(
+ vi = vlist_begin(&page_words);
+ vi != vlist_end(&page_words);
+ vi = vi->next
+ ) {
+ p = vi->data;
+ p->row = (sint32) scdf_eval(y2line, p->brect.ymax);
+ pmesg(100, "word at row %i\n", p->row);
+ }
+
+ pmesg(50, "END page_determine_lines\n");
+}
+
+
+static void page_determine_cols(void)
+{
+ vitor_t vi, vj;
+ page_word_t * p;
+ int eop, eol;
+
+ pmesg(50, "BEGIN page_determine_cols\n");
+
+ for(
+ vi = vlist_begin(&page_words);
+ vi != vlist_end(&page_words);
+ vi = vj
+ ) {
+ p = vi->data;
+ pmesg(
+ 100,
+ "x = %ld, y = %ld, right_wall = %ld, right_corridor = %ld\n",
+ p->brect.xmin,
+ p->brect.ymax,
+ p->right_wall,
+ p->right_corridor
+ );
+ assert(p->right_wall <= p->right_corridor);
+ assert(p->right_corridor <= right_margin);
+
+ if(p->right_wall < p->right_corridor) {
+ scdf_force_min_integral(
+ &col_density,
+ p->brect.xmin,
+ p->right_wall,
+ p->output_width
+ );
+ }
+ if(p->right_wall == p->right_corridor || p->trailing_spaces > 0) {
+ scdf_force_min_integral(
+ &col_density,
+ p->brect.xmin,
+ p->right_corridor,
+ p->output_width + p->trailing_spaces
+ );
+ }
+
+ vj = vi->next;
+ eop = (vj == vlist_end(&page_words));
+ eol = eop || (p->brect.ymax != vitor2ptr(vj, page_word_t)->brect.ymax);
+ if(eol) scdf_normalize(&col_density);
+ }
+
+ x2col = scdf_floor_of_integral(&col_density);
+
+ for(
+ vi = vlist_begin(&page_words);
+ vi != vlist_end(&page_words);
+ vi = vi->next
+ ) {
+ p = vi->data;
+ p->column = (sint32) scdf_eval(x2col, p->brect.xmin);
+ pmesg(100, "word at column %i\n", p->column);
+ }
+
+ pmesg(50, "END page_determine_cols\n");
+}
+
+
+/***************** rect_t method implementations **********************/
+int intervals_intersect(
+ sint32 a, sint32 b,
+ sint32 c, sint32 d
+)
+{
+ if(a > b || c > d) return 0; /* One of the intervals is empty */
+ return c <= b && a <= d; /* yes, this works in ALL remaining cases :) */
+}
+
+int rect_intersects(const rect_t * this, const rect_t * that)
+{
+ return (
+ intervals_intersect(this->xmin, this->xmax, that->xmin, that->xmax)
+ && intervals_intersect(this->ymin, this->ymax, that->ymin, that->ymax)
+ );
+}
+
+int rect_contains_point(const rect_t * this, sint32 x, sint32 y)
+{
+ return (
+ this->xmin <= x && x <= this->xmax
+ && this->ymin <= y && y <= this->ymax
+ );
+}
+
+void rect_set(
+ rect_t * this,
+ sint32 xmin,
+ sint32 xmax,
+ sint32 ymin,
+ sint32 ymax
+)
+{
+ this->xmin = xmin;
+ this->xmax = xmax;
+ this->ymin = ymin;
+ this->ymax = ymax;
+}
+
+void rect_set_empty(rect_t * this)
+{
+ rect_set(this, 1, 0, 1, 0);
+}
+
+int rect_is_empty(const rect_t * this)
+{
+ return this->xmin > this->xmax || this->ymin > this->ymax;
+}
+
+void rect_union_with(rect_t * this, const rect_t * that)
+{
+ if(rect_is_empty(that)) return;
+
+ if(rect_is_empty(this)) *this = *that;
+ else {
+ this->xmin = min(this->xmin, that->xmin);
+ this->xmax = max(this->xmax, that->xmax);
+ this->ymin = min(this->ymin, that->ymin);
+ this->ymax = max(this->ymax, that->ymax);
+ }
+}
diff --git a/dviware/catdvi/layout.d b/dviware/catdvi/layout.d
new file mode 100644
index 0000000000..a0c648d02c
--- /dev/null
+++ b/dviware/catdvi/layout.d
@@ -0,0 +1,2 @@
+layout.o layout.d : layout.c layout.h util.h page2.h page.h bytesex.h pageref.h \
+ outenc.h linebuf.h density.h canvas.h vlist.h fontinfo.h fixword.h
diff --git a/dviware/catdvi/layout.h b/dviware/catdvi/layout.h
new file mode 100644
index 0000000000..8e82306450
--- /dev/null
+++ b/dviware/catdvi/layout.h
@@ -0,0 +1,21 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2000-02 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+void page_print_sequential(void);
+void page_print_formatted(void);
diff --git a/dviware/catdvi/linebuf.c b/dviware/catdvi/linebuf.c
new file mode 100644
index 0000000000..e4720ccffa
--- /dev/null
+++ b/dviware/catdvi/linebuf.c
@@ -0,0 +1,137 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2000 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include "linebuf.h"
+#include "util.h"
+
+void linebuf_init(linebuf_t * this, size_t initial_size_alloc)
+{
+ if (initial_size_alloc == 0) initial_size_alloc = 81;
+ this->size_alloc = initial_size_alloc;
+
+ this->gstring = malloc(initial_size_alloc * sizeof(glyph_t));
+ if(!this->gstring) enomem();
+
+ linebuf_clear(this);
+}
+
+void linebuf_garray_init(linebuf_t * this, const glyph_t garray[], size_t len)
+{
+ this->size_curr = len;
+ this->size_alloc = len + 1;
+
+ this->gstring = malloc(this->size_alloc * sizeof(glyph_t));
+ if(!this->gstring) enomem();
+
+ memcpy(this->gstring, garray, sizeof(glyph_t) * this->size_alloc);
+ this->gstring[this->size_curr] = 0;
+}
+
+void linebuf_garray0_init(linebuf_t * this, const glyph_t garray0[])
+{
+ int len = 0;
+ while(garray0[len] != 0) ++len;
+ linebuf_garray_init(this, garray0, len);
+}
+
+void linebuf_done(linebuf_t * this)
+{
+ assert(this->gstring);
+
+ free(this->gstring);
+ this->gstring = NULL;
+}
+
+
+void linebuf_clear(linebuf_t * this)
+{
+ assert(this->gstring);
+
+ this->size_curr = 0;
+ this->gstring[0] = 0;
+}
+
+static void linebuf_need_size(linebuf_t * this, size_t size)
+{
+ assert(this->gstring);
+
+ if (size < this->size_alloc) return;
+
+ while(size >= this->size_alloc) this->size_alloc *= 2;
+ this->gstring = realloc(
+ this->gstring,
+ this->size_alloc * sizeof(glyph_t)
+ );
+ if (!this->gstring) enomem();
+}
+
+void linebuf_putg(linebuf_t * this, glyph_t g)
+{
+ assert(this->gstring);
+
+ this->gstring[this->size_curr++] = g;
+ if(this->size_curr >= this->size_alloc) {
+ /* This check is not required before calling linebuf_need_size(),
+ * but saves a function call in most cases.
+ */
+ linebuf_need_size(this, this->size_curr);
+ }
+ this->gstring[this->size_curr] = 0;
+}
+
+
+glyph_t linebuf_peekg(linebuf_t * this)
+{
+ assert(this->gstring);
+
+ if(this->size_curr == 0) return(0);
+ return(this->gstring[this->size_curr - 1]);
+}
+
+
+glyph_t linebuf_unputg(linebuf_t * this)
+{
+ glyph_t last;
+
+ assert(this->gstring);
+
+ if(this->size_curr == 0) return(0);
+
+ last = this->gstring[--(this->size_curr)];
+ this->gstring[this->size_curr] = 0;
+ return(last);
+}
+
+void linebuf_append(linebuf_t * this, const linebuf_t * appendix)
+{
+ assert(this->gstring);
+
+ linebuf_need_size(this, this->size_curr + appendix->size_curr);
+ memcpy(
+ this->gstring + this->size_curr,
+ appendix->gstring,
+ sizeof(glyph_t) * appendix->size_curr
+ );
+ this->size_curr += appendix->size_curr;
+ this->gstring[this->size_curr] = 0;
+}
+
diff --git a/dviware/catdvi/linebuf.d b/dviware/catdvi/linebuf.d
new file mode 100644
index 0000000000..d12a04e7dc
--- /dev/null
+++ b/dviware/catdvi/linebuf.d
@@ -0,0 +1 @@
+linebuf.o linebuf.d : linebuf.c linebuf.h page.h bytesex.h pageref.h util.h
diff --git a/dviware/catdvi/linebuf.h b/dviware/catdvi/linebuf.h
new file mode 100644
index 0000000000..cf796dbb21
--- /dev/null
+++ b/dviware/catdvi/linebuf.h
@@ -0,0 +1,67 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2000, 2001 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+/* Implements a simplistic "string of glyph_t" class. Can grow dynamically.
+ * Null termination is provided, but not used by the class methods.
+ */
+
+#ifndef LINEBUF_H
+#define LINEBUF_H
+
+#include <stddef.h>
+
+/* for definition of glyph_t */
+#include "page.h"
+
+typedef struct linebuf_t linebuf_t;
+struct linebuf_t {
+ size_t size_alloc;
+ size_t size_curr;
+ glyph_t * gstring;
+};
+
+/* Construct as empty string. Specify initially allocated space (to avoid
+ * continuous realloc()s). Use 0 for default size (currently 80 glyphs).
+ */
+void linebuf_init(struct linebuf_t * this, size_t initial_size_alloc);
+
+/* Construct from array garray of length len. */
+void linebuf_garray_init(linebuf_t * this, const glyph_t garray[], size_t len);
+
+/* Construct from 0-terminated array garray0. */
+void linebuf_garray0_init(linebuf_t * this, const glyph_t garray0[]);
+
+/* destructor */
+void linebuf_done(struct linebuf_t * this);
+
+void linebuf_clear(struct linebuf_t * this);
+
+/* Append another linebuf */
+void linebuf_append(linebuf_t * this, const linebuf_t * appendix);
+
+/* Append one glpyh */
+void linebuf_putg(struct linebuf_t * this, glyph_t g);
+
+/* Look at last glyph */
+glyph_t linebuf_peekg(struct linebuf_t * this);
+
+/* Remove last glyph */
+glyph_t linebuf_unputg(struct linebuf_t * this);
+
+#endif
diff --git a/dviware/catdvi/manifest-filter.lst b/dviware/catdvi/manifest-filter.lst
new file mode 100644
index 0000000000..4ea2971b0b
--- /dev/null
+++ b/dviware/catdvi/manifest-filter.lst
@@ -0,0 +1,8 @@
+- \.cvsignore
++ Manifest
++ ChangeLog
++ MD5SUMS
++ configure
++ version.h
++ catdvi.txt
+! ^(.*)\.c$ $1.d
diff --git a/dviware/catdvi/manifest-filter.pl b/dviware/catdvi/manifest-filter.pl
new file mode 100755
index 0000000000..cef0e39ab3
--- /dev/null
+++ b/dviware/catdvi/manifest-filter.pl
@@ -0,0 +1,37 @@
+#!/usr/bin/perl -w
+
+
+# Read in the filter list.
+# Print out lines starting with + directly.
+# Save the lines starting with - in the array @del for deleting
+# the files from input later
+# Save the lines starting with ! in the array @gen for transforming
+# the files in input later
+#
+open FILTER, "<manifest-filter.lst";
+while (<FILTER>) {
+ /^\+ *(.*)$/ and print "$1\n";
+ /^- *(.*)$/ and push @del, $1;
+ /^! *([^ ]+) +(.*)$/ and push @gen, { pat => $1, rep => $2};
+}
+
+# Loop through the standard input, deleting lines that match regexes
+# in @del and performing any matching transformations.
+@lines = <>;
+LINE: foreach (@lines) {
+ for $f (@del) {
+ /$f/ and next LINE;
+ }
+ $l = $_;
+ for $f (@gen) {
+ %h = %$f;
+ $r =$l;
+ if ($r =~ /$h{pat}/) {
+ eval "\$r =~ s\@$h{pat}\@$h{rep}\@";
+ push @lines, $r;
+ }
+
+ }
+ print $l;
+}
+
diff --git a/dviware/catdvi/outenc.c b/dviware/catdvi/outenc.c
new file mode 100644
index 0000000000..aa97f62fe6
--- /dev/null
+++ b/dviware/catdvi/outenc.c
@@ -0,0 +1,1367 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2001-2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "outenc.h"
+#include "util.h"
+#include "sparse.h"
+#include "vlist.h"
+#include "glyphenm.h"
+#include "glyphops.h"
+#include "page.h" /* for definition of glyph_t */
+
+
+/* these are declared extern in the header */
+enum outenc_num_t outenc_num = OE_ASCII;
+int outenc_show_unicode_number = 0;
+static char const * const outenc_name_tbl[OE_TOOBIG] = {
+ "UTF-8",
+ "US-ASCII",
+ "ISO-8859-1",
+ "ISO-8859-15"
+};
+char const * const * const outenc_names = outenc_name_tbl;
+
+
+/***********************************************************************
+ * private methods + data
+ ***********************************************************************/
+
+/* How many columns would that glyph use in printout. */
+static int outenc_glyph_width(glyph_t g);
+
+/* Same for compositions, i.e. a glyph followed by one or more combining
+ * diacritics.
+ */
+static int (* outenc_composition_width)(const glyph_t c[], int length) = NULL;
+
+/* In some cases, a glyph can't be directly mapped to the output encoding,
+ * but we know another glyph (or sequence of glyphs) that can and gives a
+ * good visual approximation.
+ * If such a translation is known to be neccessary for the given glyph g,
+ * perform it and append the result to the existing linebuf l. If not
+ * (usual case), just append the glyph.
+ */
+static void outenc_xlat_glyph(glyph_t g, linebuf_t * l);
+
+/* Ditto for compositions. */
+static void (* outenc_xlat_composition)(
+ const glyph_t c[],
+ int length,
+ linebuf_t * l
+) = NULL;
+
+/* take a glyph (translations already performed), convert
+ * it into a sequence of bytes appropriate for the output encoding
+ * (like utf-8, ucs-2, ebcdic, koi-8r, ...) and write that to f.
+ */
+static void (* outenc_write_raw_glyph)(FILE * f, glyph_t g) = NULL;
+
+#define WIDTH_AUTO (-1)
+typedef struct glyphtweak_t glyphtweak_t;
+struct glyphtweak_t {
+ glyph_t glyph;
+ /* the one to "tweak" */
+ const glyph_t * xlat;
+ /* null-terminated array of glyph_t, the translation.
+ * Use NULL if you want to override the output width
+ * but no translation should be done.
+ * (maybe we want to support e.g. double-width glyphs
+ * some time).
+ * Note the translation is still Unicode! Mapping from
+ * Unicode to the output encoding should be done in
+ * outenc_write_raw_glyph().
+ * This two-level system is required because sometimes
+ * output width != number of bytes for the output
+ * encoding (nearly always for utf-8).
+ */
+ int width;
+ /* The output width. Use WIDTH_AUTO to get it filled
+ * in automatically with the length of the translation
+ * string or specify an explicit override.
+ */
+};
+/* FIXME: at the moment we don't support iterated translations (e.g.
+ * minus -> hyphen -> dash). We could as long as we care for the
+ * right order of initialization (i.e the translation tables), but it adds
+ * complexity and overhead. Check if there is any real need.
+ */
+
+/* Insert the table tweaks[] of glyph tweaks into the glyph tweak sparp. */
+static void outenc_register_glyphtweaks(const glyphtweak_t tweaks[], int length);
+
+/* Remove registered tweak for glyph g. */
+static void outenc_unregister_glyphtweak(glyph_t g);
+
+/* Write something ('?' or the Unicode number) for unencodable glyphs */
+static void outenc_show_unknown(FILE * f, glyph_t g);
+
+
+/***********************************************************************
+ * "Generic" stuff (could - but need not - be used by any output encoding).
+ * In OO speak, this would belong to the base class from which specific
+ * output encoding classes are then derived.
+ ***********************************************************************/
+
+static const glyph_t genx_CATDVI_DoubleS[] = {GLYPH_S, GLYPH_S, 0};
+static const glyph_t genx_CATDVI_Ng[] = {GLYPH_N, GLYPH_G, 0};
+static const glyph_t genx_CATDVI_ng[] = {GLYPH_n, GLYPH_g, 0};
+static const glyph_t genx_CATDVI_negationslash[] = {GLYPH_slash, 0};
+static const glyph_t genx_CATDVI_vector[] = {GLYPH_arrowright, 0};
+static const glyph_t genx_ADOBE_zerooldstyle[] = {GLYPH_zero, 0};
+static const glyph_t genx_ADOBE_oneoldstyle[] = {GLYPH_one, 0};
+static const glyph_t genx_ADOBE_twooldstyle[] = {GLYPH_two, 0};
+static const glyph_t genx_ADOBE_threeoldstyle[] = {GLYPH_three, 0};
+static const glyph_t genx_ADOBE_fouroldstyle[] = {GLYPH_four, 0};
+static const glyph_t genx_ADOBE_fiveoldstyle[] = {GLYPH_five, 0};
+static const glyph_t genx_ADOBE_sixoldstyle[] = {GLYPH_six, 0};
+static const glyph_t genx_ADOBE_sevenoldstyle[] = {GLYPH_seven, 0};
+static const glyph_t genx_ADOBE_eightoldstyle[] = {GLYPH_eight, 0};
+static const glyph_t genx_ADOBE_nineoldstyle[] = {GLYPH_nine, 0};
+static const glyph_t genx_ADOBE_dotlessj[] = {GLYPH_j, 0};
+
+/* for the TEX math extension stuff */
+static const glyph_t genx_2parenleft[] = {GLYPH_parenleft, 0};
+static const glyph_t genx_2parenright[] = {GLYPH_parenright, 0};
+static const glyph_t genx_2bracketleft[] = {GLYPH_bracketleft, 0};
+static const glyph_t genx_2bracketright[] = {GLYPH_bracketright, 0};
+static const glyph_t genx_2braceleft[] = {GLYPH_braceleft, 0};
+static const glyph_t genx_2braceright[] = {GLYPH_braceright, 0};
+static const glyph_t genx_2angleleftmath[] = {GLYPH_UNI_angleleftmath, 0};
+static const glyph_t genx_2anglerightmath[] = {GLYPH_UNI_anglerightmath, 0};
+static const glyph_t genx_2UNI_floorleft[] = {GLYPH_UNI_floorleft, 0};
+static const glyph_t genx_2UNI_floorright[] = {GLYPH_UNI_floorright, 0};
+static const glyph_t genx_2UNI_ceilingleft[] = {GLYPH_UNI_ceilingleft, 0};
+static const glyph_t genx_2UNI_ceilingright[] = {GLYPH_UNI_ceilingright, 0};
+static const glyph_t genx_2slash[] = {GLYPH_slash, 0};
+static const glyph_t genx_2backslash[] = {GLYPH_backslash, 0};
+
+static const glyph_t genx_2integral[] = {GLYPH_integral, 0};
+static const glyph_t genx_2UNI_contintegral[] = {GLYPH_UNI_contintegral, 0};
+static const glyph_t genx_2UNI_unionsq[] = {GLYPH_UNI_unionsq, 0};
+static const glyph_t genx_2UNI_circledot[] = {GLYPH_UNI_circledot, 0};
+static const glyph_t genx_2circleplus[] = {GLYPH_circleplus, 0};
+static const glyph_t genx_2circlemultiply[] = {GLYPH_circlemultiply, 0};
+static const glyph_t genx_2summation[] = {GLYPH_summation, 0};
+static const glyph_t genx_2product[] = {GLYPH_product, 0};
+static const glyph_t genx_2UNI_coproduct[] = {GLYPH_UNI_coproduct, 0};
+static const glyph_t genx_2union[] = {GLYPH_union, 0};
+static const glyph_t genx_2intersection[] = {GLYPH_intersection, 0};
+static const glyph_t genx_2UNI_unionmulti[] = {GLYPH_UNI_unionmulti, 0};
+static const glyph_t genx_2logicaland[] = {GLYPH_logicaland, 0};
+static const glyph_t genx_2logicalor[] = {GLYPH_logicalor, 0};
+static const glyph_t genx_2radical[] = {GLYPH_radical, 0};
+
+static const glyph_t genx_2asciicircum[] = {GLYPH_asciicircum, 0};
+static const glyph_t genx_2asciitilde[] = {GLYPH_asciitilde, 0};
+
+static const glyphtweak_t generic_glyphtweaks[] = {
+ {GLYPH_CATDVI_DoubleS, genx_CATDVI_DoubleS, WIDTH_AUTO},
+ {GLYPH_CATDVI_Ng, genx_CATDVI_Ng, WIDTH_AUTO},
+ {GLYPH_CATDVI_ng, genx_CATDVI_ng, WIDTH_AUTO},
+ {GLYPH_CATDVI_negationslash, genx_CATDVI_negationslash, WIDTH_AUTO},
+ {GLYPH_CATDVI_vector, genx_CATDVI_vector, WIDTH_AUTO},
+ {GLYPH_ADOBE_zerooldstyle, genx_ADOBE_zerooldstyle, WIDTH_AUTO},
+ {GLYPH_ADOBE_oneoldstyle, genx_ADOBE_oneoldstyle, WIDTH_AUTO},
+ {GLYPH_ADOBE_twooldstyle, genx_ADOBE_twooldstyle, WIDTH_AUTO},
+ {GLYPH_ADOBE_threeoldstyle, genx_ADOBE_threeoldstyle, WIDTH_AUTO},
+ {GLYPH_ADOBE_fouroldstyle, genx_ADOBE_fouroldstyle, WIDTH_AUTO},
+ {GLYPH_ADOBE_fiveoldstyle, genx_ADOBE_fiveoldstyle, WIDTH_AUTO},
+ {GLYPH_ADOBE_sixoldstyle, genx_ADOBE_sixoldstyle, WIDTH_AUTO},
+ {GLYPH_ADOBE_sevenoldstyle, genx_ADOBE_sevenoldstyle, WIDTH_AUTO},
+ {GLYPH_ADOBE_eightoldstyle, genx_ADOBE_eightoldstyle, WIDTH_AUTO},
+ {GLYPH_ADOBE_nineoldstyle, genx_ADOBE_nineoldstyle, WIDTH_AUTO},
+ {GLYPH_ADOBE_dotlessj, genx_ADOBE_dotlessj, WIDTH_AUTO},
+
+ /* TeX Math Extension */
+ {GLYPH_CATDVI_parenleftbig, genx_2parenleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_parenleftBig, genx_2parenleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_parenleftbigg, genx_2parenleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_parenleftBigg, genx_2parenleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_parenrightbig, genx_2parenright, WIDTH_AUTO},
+ {GLYPH_CATDVI_parenrightBig, genx_2parenright, WIDTH_AUTO},
+ {GLYPH_CATDVI_parenrightbigg, genx_2parenright, WIDTH_AUTO},
+ {GLYPH_CATDVI_parenrightBigg, genx_2parenright, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracketleftbig, genx_2bracketleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracketleftBig, genx_2bracketleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracketleftbigg, genx_2bracketleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracketleftBigg, genx_2bracketleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracketrightbig, genx_2bracketright, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracketrightBig, genx_2bracketright, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracketrightbigg, genx_2bracketright, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracketrightBigg, genx_2bracketright, WIDTH_AUTO},
+ {GLYPH_CATDVI_braceleftbig, genx_2braceleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_braceleftBig, genx_2braceleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_braceleftbigg, genx_2braceleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_braceleftBigg, genx_2braceleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracerightbig, genx_2braceright, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracerightBig, genx_2braceright, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracerightbigg, genx_2braceright, WIDTH_AUTO},
+ {GLYPH_CATDVI_bracerightBigg, genx_2braceright, WIDTH_AUTO},
+ {GLYPH_CATDVI_angbracketleftbig, genx_2angleleftmath, WIDTH_AUTO},
+ {GLYPH_CATDVI_angbracketleftBig, genx_2angleleftmath, WIDTH_AUTO},
+ {GLYPH_CATDVI_angbracketleftbigg, genx_2angleleftmath, WIDTH_AUTO},
+ {GLYPH_CATDVI_angbracketleftBigg, genx_2angleleftmath, WIDTH_AUTO},
+ {GLYPH_CATDVI_angbracketrightbig, genx_2anglerightmath, WIDTH_AUTO},
+ {GLYPH_CATDVI_angbracketrightBig, genx_2anglerightmath, WIDTH_AUTO},
+ {GLYPH_CATDVI_angbracketrightbigg, genx_2anglerightmath, WIDTH_AUTO},
+ {GLYPH_CATDVI_angbracketrightBigg, genx_2anglerightmath, WIDTH_AUTO},
+ {GLYPH_CATDVI_floorleftbig, genx_2UNI_floorleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_floorleftBig, genx_2UNI_floorleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_floorleftbigg, genx_2UNI_floorleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_floorleftBigg, genx_2UNI_floorleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_floorrightbig, genx_2UNI_floorright, WIDTH_AUTO},
+ {GLYPH_CATDVI_floorrightBig, genx_2UNI_floorright, WIDTH_AUTO},
+ {GLYPH_CATDVI_floorrightbigg, genx_2UNI_floorright, WIDTH_AUTO},
+ {GLYPH_CATDVI_floorrightBigg, genx_2UNI_floorright, WIDTH_AUTO},
+ {GLYPH_CATDVI_ceilingleftbig, genx_2UNI_ceilingleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_ceilingleftBig, genx_2UNI_ceilingleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_ceilingleftbigg, genx_2UNI_ceilingleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_ceilingleftBigg, genx_2UNI_ceilingleft, WIDTH_AUTO},
+ {GLYPH_CATDVI_ceilingrightbig, genx_2UNI_ceilingright, WIDTH_AUTO},
+ {GLYPH_CATDVI_ceilingrightBig, genx_2UNI_ceilingright, WIDTH_AUTO},
+ {GLYPH_CATDVI_ceilingrightbigg, genx_2UNI_ceilingright, WIDTH_AUTO},
+ {GLYPH_CATDVI_ceilingrightBigg, genx_2UNI_ceilingright, WIDTH_AUTO},
+ {GLYPH_CATDVI_slashbig, genx_2slash, WIDTH_AUTO},
+ {GLYPH_CATDVI_slashBig, genx_2slash, WIDTH_AUTO},
+ {GLYPH_CATDVI_slashbigg, genx_2slash, WIDTH_AUTO},
+ {GLYPH_CATDVI_slashBigg, genx_2slash, WIDTH_AUTO},
+ {GLYPH_CATDVI_backslashbig, genx_2backslash, WIDTH_AUTO},
+ {GLYPH_CATDVI_backslashBig, genx_2backslash, WIDTH_AUTO},
+ {GLYPH_CATDVI_backslashbigg, genx_2backslash, WIDTH_AUTO},
+ {GLYPH_CATDVI_backslashBigg, genx_2backslash, WIDTH_AUTO},
+ {GLYPH_CATDVI_radicalbig, genx_2radical, WIDTH_AUTO},
+ {GLYPH_CATDVI_radicalBig, genx_2radical, WIDTH_AUTO},
+ {GLYPH_CATDVI_radicalbigg, genx_2radical, WIDTH_AUTO},
+ {GLYPH_CATDVI_radicalBigg, genx_2radical, WIDTH_AUTO},
+
+ {GLYPH_CATDVI_integraltext, genx_2integral, WIDTH_AUTO},
+ {GLYPH_CATDVI_integraldisplay, genx_2integral, WIDTH_AUTO},
+ {GLYPH_CATDVI_contintegraltext, genx_2UNI_contintegral, WIDTH_AUTO},
+ {GLYPH_CATDVI_contintegraldisplay, genx_2UNI_contintegral, WIDTH_AUTO},
+ {GLYPH_CATDVI_unionsqtext, genx_2UNI_unionsq, WIDTH_AUTO},
+ {GLYPH_CATDVI_unionsqdisplay, genx_2UNI_unionsq, WIDTH_AUTO},
+ {GLYPH_CATDVI_circledottext, genx_2UNI_circledot, WIDTH_AUTO},
+ {GLYPH_CATDVI_circledotdisplay, genx_2UNI_circledot, WIDTH_AUTO},
+ {GLYPH_CATDVI_circleplustext, genx_2circleplus, WIDTH_AUTO},
+ {GLYPH_CATDVI_circleplusdisplay, genx_2circleplus, WIDTH_AUTO},
+ {GLYPH_CATDVI_circlemultiplytext, genx_2circlemultiply, WIDTH_AUTO},
+ {GLYPH_CATDVI_circlemultiplydisplay, genx_2circlemultiply, WIDTH_AUTO},
+ {GLYPH_CATDVI_summationtext, genx_2summation, WIDTH_AUTO},
+ {GLYPH_CATDVI_summationdisplay, genx_2summation, WIDTH_AUTO},
+ {GLYPH_CATDVI_producttext, genx_2product, WIDTH_AUTO},
+ {GLYPH_CATDVI_productdisplay, genx_2product, WIDTH_AUTO},
+ {GLYPH_CATDVI_uniontext, genx_2union, WIDTH_AUTO},
+ {GLYPH_CATDVI_uniondisplay, genx_2union, WIDTH_AUTO},
+ {GLYPH_CATDVI_intersectiontext, genx_2intersection, WIDTH_AUTO},
+ {GLYPH_CATDVI_intersectiondisplay, genx_2intersection, WIDTH_AUTO},
+ {GLYPH_CATDVI_unionmultitext, genx_2UNI_unionmulti, WIDTH_AUTO},
+ {GLYPH_CATDVI_unionmultidisplay, genx_2UNI_unionmulti, WIDTH_AUTO},
+ {GLYPH_CATDVI_logicalandtext, genx_2logicaland, WIDTH_AUTO},
+ {GLYPH_CATDVI_logicalanddisplay, genx_2logicaland, WIDTH_AUTO},
+ {GLYPH_CATDVI_logicalortext, genx_2logicalor, WIDTH_AUTO},
+ {GLYPH_CATDVI_logicalordisplay, genx_2logicalor, WIDTH_AUTO},
+ {GLYPH_CATDVI_producttext, genx_2product, WIDTH_AUTO},
+ {GLYPH_CATDVI_productdisplay, genx_2product, WIDTH_AUTO},
+ {GLYPH_CATDVI_coproducttext, genx_2UNI_coproduct, WIDTH_AUTO},
+ {GLYPH_CATDVI_coproductdisplay, genx_2UNI_coproduct, WIDTH_AUTO},
+
+ {GLYPH_CATDVI_hatwide, genx_2asciicircum, WIDTH_AUTO},
+ {GLYPH_CATDVI_hatwider, genx_2asciicircum, WIDTH_AUTO},
+ {GLYPH_CATDVI_hatwidest, genx_2asciicircum, WIDTH_AUTO},
+ {GLYPH_CATDVI_tildewide, genx_2asciitilde, WIDTH_AUTO},
+ {GLYPH_CATDVI_tildewider, genx_2asciitilde, WIDTH_AUTO},
+ {GLYPH_CATDVI_tildewidest, genx_2asciitilde, WIDTH_AUTO},
+ /* End TeX Math Extension */
+
+ {GLYPH_CATDVI_hatxwide, genx_2asciicircum, WIDTH_AUTO},
+ {GLYPH_CATDVI_tildexwide, genx_2asciitilde, WIDTH_AUTO}
+};
+
+/* How to combine a base glyph and a single diacritic */
+struct generic_accententry_t {
+ glyph_t base;
+ glyph_t combining_diacritic;
+ glyph_t accented;
+};
+
+/* If the combining diacritic lives in the private use area, we want
+ * to do away with in any imaginable output encoding.
+ * This happens when TeX builds glyphs by overlaying strange pieces
+ * and we emulate this with strange combining diacritics.
+ */
+static struct generic_accententry_t generic_accentings[] = {
+ {GLYPH_C, GLYPH_CATDVI_Eurodblstrokecomb, GLYPH_Euro},
+ {GLYPH_L, GLYPH_CATDVI_polishstrokecomb, GLYPH_Lslash},
+ {GLYPH_l, GLYPH_CATDVI_polishstrokecomb, GLYPH_lslash},
+ {0, 0, 0}
+};
+
+static struct sparp_t accenting_sparp;
+static struct vlist_t accenting_vlist;
+
+/* Insert the table pa of accenting entries into the accenting sparp.
+ * The table need not be sorted by base glyph. End of table = {0, 0, 0}.
+ * In the case of conflicting entries, the one registered last wins.
+ */
+static void generic_register_accentings(const struct generic_accententry_t pa[])
+{
+ /* We keep a single list of all registered accentings. Accentings
+ * with the same base glyph are consecutive, the latest registered
+ * first.
+ *
+ * The accentings sparp is indexed by the base glyph we want to accent
+ * and the value is a vitor to the first known accenting of the base glyph.
+ */
+ for( ; pa->base != 0; ++pa) {
+ vitor_t old_va, new_va;
+
+ old_va = sparp_read(&accenting_sparp, pa->base);
+ if(old_va == NULL) old_va = vlist_begin(&accenting_vlist);
+
+ new_va = vlist_insert_before(&accenting_vlist, old_va, pa);
+ sparp_write(&accenting_sparp, pa->base, new_va);
+ }
+
+}
+
+static glyph_t generic_accent(glyph_t base, glyph_t diacritic)
+{
+ vitor_t va;
+
+ va = sparp_read(&accenting_sparp, base);
+ if(va == NULL) return 0;
+
+ while(va != vlist_end(&accenting_vlist)) {
+ struct generic_accententry_t * p;
+
+ p = vitor2ptr(va, struct generic_accententry_t);
+ if(p->base != base) break;
+ if(p->combining_diacritic == diacritic) return(p->accented);
+
+ va = va->next;
+ }
+
+ return 0;
+}
+
+static int generic_composition_width(const glyph_t c[], int length)
+{
+ glyph_t acc, sd;
+ int i;
+ int w;
+
+ assert(length >= 2);
+
+ if(length == 2) {
+ /* Only a single diacritic. Try to accent. */
+ acc = generic_accent(c[0], c[1]);
+ if(acc != 0) return outenc_glyph_width(acc);
+ }
+
+ /* Accenting failed, or more than one diacritic. Strategy: the best
+ * we can do is print the base glyph and the spacing variant of all
+ * diacritics. */
+ w = outenc_glyph_width(c[0]);
+ for(i = 1; i < length; ++i) {
+ sd = diacritic_spacing_variant(c[i]);
+ if(sd == 0) sd = c[i];
+ /* Not even a spacing variant known. */
+ w += outenc_glyph_width(sd);
+ };
+
+ return w;
+}
+
+static void generic_xlat_composition(
+ const glyph_t c[],
+ int length,
+ linebuf_t * l
+)
+{
+ glyph_t acc, sd;
+ int i;
+
+ assert(length >= 2);
+
+ if(length == 2) {
+ /* Only a single diacritic. Try to accent. */
+ acc = generic_accent(c[0], c[1]);
+ if(acc != 0) {
+ outenc_xlat_glyph(acc, l);
+ return;
+ }
+ }
+
+ /* Accenting failed, or more than one diacritic. Strategy: the best
+ * we can do is print the base glyph and the spacing variant of all
+ * diacritics (but in customary TeX order, i.e. reverse to the
+ * Unicode convention).
+ */
+ for(i = length - 1; i > 0; --i) {
+ sd = diacritic_spacing_variant(c[i]);
+ if(sd == 0) sd = c[i];
+ /* Not even a spacing variant known. */
+ outenc_xlat_glyph(sd, l);
+ };
+ outenc_xlat_glyph(c[0], l);
+
+}
+
+
+/***********************************************************************
+ * Routines for "simple" output encodings, i.e. those where each
+ * character fits in one char and the character stream is stateless.
+ ***********************************************************************/
+struct simple_charmap_entry_t {
+ glyph_t unicode;
+ unsigned char output;
+};
+
+static spars32_t simple_charmap_spars32;
+static unsigned char simple_identity_range;
+
+/* implements outenc_write_raw_glyph for simple output encodings */
+static void simple_write_raw_glyph(FILE * f, glyph_t g)
+{
+ if(g <= simple_identity_range) putc((int) g, f);
+ else {
+ int c;
+ c = spars32_read(&simple_charmap_spars32, g);
+
+ if (c > 0) putc(c, f);
+ else outenc_show_unknown(f, g);
+ }
+}
+
+/* Has to be called exactly once before use. Defines the output encoding:
+ *
+ * glyph <= identity_range -> write as is
+ * glyph has charmap entry -> write entry.output
+ * otherwise -> outenc_show_unknown()
+ *
+ * charmap_tbl == NULL is OK if also tbl_length == 0
+ */
+static void simple_init_charmap(
+ unsigned char identity_range,
+ struct simple_charmap_entry_t charmap_tbl[],
+ size_t tbl_length
+)
+{
+ size_t i;
+
+ simple_identity_range = identity_range;
+ spars32_init(&simple_charmap_spars32, 0);
+ for(i = 0; i < tbl_length; ++i) {
+ spars32_write(
+ &simple_charmap_spars32,
+ charmap_tbl[i].unicode,
+ charmap_tbl[i].output
+ );
+ }
+
+}
+
+
+/***********************************************************************
+ * utf-8
+ ***********************************************************************/
+
+/* A few characters in AMSSymbolsB are not in Unicode, but can be represented
+ * in Unicode by use of combining characters.
+ * FIXME: these translations should really be generic, but our substitution
+ * mechanism is not up to it.
+ */
+static const glyph_t utf8x_2not_lessequalslanted[] = {
+ GLYPH_UNI_lessequalslanted, GLYPH_UNI_slashlongcomb, 0
+};
+static const glyph_t utf8x_2not_greaterequalslanted[] = {
+ GLYPH_UNI_greaterequalslanted, GLYPH_UNI_slashlongcomb, 0
+};
+static const glyph_t utf8x_2not_lessequal2[] = {
+ GLYPH_UNI_lessequal2, GLYPH_UNI_slashlongcomb, 0
+};
+static const glyph_t utf8x_2not_greaterequal2[] = {
+ GLYPH_UNI_greaterequal2, GLYPH_UNI_slashlongcomb, 0
+};
+static const glyph_t utf8x_2not_subsetequal2[] = {
+ GLYPH_UNI_subsetequal2, GLYPH_UNI_slashlongcomb, 0
+};
+static const glyph_t utf8x_2not_supersetequal2[] = {
+ GLYPH_UNI_supersetequal2, GLYPH_UNI_slashlongcomb, 0
+};
+
+static const glyphtweak_t utf8_glyphtweaks[] = {
+ {GLYPH_CATDVI_notlessequalslanted, utf8x_2not_lessequalslanted, 1},
+ {GLYPH_CATDVI_notgreaterequalslanted, utf8x_2not_greaterequalslanted, 1},
+ {GLYPH_CATDVI_notlessequal2, utf8x_2not_lessequal2, 1},
+ {GLYPH_CATDVI_notgreaterequal2, utf8x_2not_greaterequal2, 1},
+ {GLYPH_CATDVI_notsubsetequal2, utf8x_2not_subsetequal2, 1},
+ {GLYPH_CATDVI_notsupersetequal2, utf8x_2not_supersetequal2, 1}
+};
+
+
+/* UCS-4 to UTF-8 translation control tables. */
+
+#define UTFVEC_MAXLEN (6+1) /* UTF-8 takes max 6 bytes + null terminator */
+
+struct ucs2utf_elem {
+ int numbits; /* number of variable bits, 1-8 */
+ unsigned char octet; /* template for this octet */
+};
+
+struct ucs2utf_ctbl {
+ uint32 maxval; /* maximum UC-4 value encodable */
+ int len; /* length of the UTF-8 bit stream in octets */
+ struct ucs2utf_elem template[UTFVEC_MAXLEN]; /* the vector containing
+ info on each octet */
+};
+
+static struct ucs2utf_ctbl utfcnv_ctbl[] = {
+ /* maximum, num entries, template vector */
+ /* num bits, initial value */
+ { 0x7f, 1, { { 7, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 } } },
+ { 0x7ff, 2, { { 5, 0xc0 },
+ { 6, 0x80 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 }, } },
+ { 0xffff, 3, { { 4, 0xe0 },
+ { 6, 0x80 },
+ { 6, 0x80 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 } } },
+ { 0x1fffff, 4, { { 3, 0xf0 },
+ { 6, 0x80 },
+ { 6, 0x80 },
+ { 6, 0x80 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 } } },
+ { 0x3ffffff, 5, { { 2, 0xf4 },
+ { 6, 0x80 },
+ { 6, 0x80 },
+ { 6, 0x80 },
+ { 6, 0x80 },
+ { 0, 0 },
+ { 0, 0 } } },
+ { 0x7fffffff, 6, { { 1, 0xfc },
+ { 6, 0x80 },
+ { 6, 0x80 },
+ { 6, 0x80 },
+ { 6, 0x80 },
+ { 6, 0x80 },
+ { 0, 0 } } }
+};
+
+static void utf8_write_raw_glyph(FILE * f, glyph_t g)
+{
+ size_t tblinx; /* index to conversion control table */
+ unsigned char outv[UTFVEC_MAXLEN];
+ int i;
+
+ /* Unicode -> UTF-8, see RFC 2279 */
+
+ /* 1. Determine the row in the translation table. */
+ for (tblinx = 0; tblinx < lengthof(utfcnv_ctbl); tblinx++) {
+ if (g <= utfcnv_ctbl[tblinx].maxval) {
+ break;
+ }
+ }
+ if (tblinx >= lengthof(utfcnv_ctbl)) {
+ pmesg(60, "character code too big");
+ return;
+ }
+
+ /* 2. Do the conversion from right to left. */
+ for (i = UTFVEC_MAXLEN - 1; i >= 0; i--) {
+ /* At each iteration we first apply the initial bit
+ pattern and then patch the rest with the indicated
+ number of lower-order bits in g. When we are
+ done, we shift these out. Zero-bit codes are
+ exceptional, we just leave the initial bit pattern
+ and move on.*/
+
+ int numbits = utfcnv_ctbl[tblinx].template[i].numbits;
+
+ outv[i] = utfcnv_ctbl[tblinx].template[i].octet;
+
+ if (numbits == 0) continue;
+
+ outv[i] |= ((1 << numbits) - 1) & g;
+
+ g = g >> numbits;
+ }
+
+ /* Output it. */
+ fputs((char *) outv, f);
+}
+
+static int utf8_composition_width(const glyph_t c[], int length)
+{
+ glyph_t a;
+
+
+ assert(length >= 2);
+
+ if(length == 2 && (a = generic_accent(c[0], c[1])) != 0) {
+ return outenc_glyph_width(a);
+ }
+ else {
+ return outenc_glyph_width(c[0]);
+ }
+}
+
+static void utf8_xlat_composition(
+ const glyph_t c[],
+ int length,
+ linebuf_t * l
+)
+{
+ int i;
+ glyph_t a;
+
+ if(length == 2 && (a = generic_accent(c[0], c[1])) != 0) {
+ linebuf_putg(l, a);
+ }
+ else {
+ for(i = 0; i < length; ++i) linebuf_putg(l, c[i]);
+ }
+}
+
+static void utf8_init(void)
+{
+ outenc_register_glyphtweaks(
+ utf8_glyphtweaks,
+ lengthof(utf8_glyphtweaks)
+ );
+ outenc_write_raw_glyph = utf8_write_raw_glyph;
+ outenc_composition_width = utf8_composition_width;
+ outenc_xlat_composition = utf8_xlat_composition;
+}
+
+
+/***********************************************************************
+ * ascii
+ ***********************************************************************/
+
+static const glyph_t a2l1x_IJ[] = {GLYPH_I, GLYPH_J, 0};
+static const glyph_t a2l1x_ij[] = {GLYPH_i, GLYPH_j, 0};
+static const glyph_t a2l1x_OE[] = {GLYPH_O, GLYPH_E, 0};
+static const glyph_t a2l1x_oe[] = {GLYPH_o, GLYPH_e, 0};
+static const glyph_t a2l1x_Eng[] = {GLYPH_N, GLYPH_g, 0};
+static const glyph_t a2l1x_eng[] = {GLYPH_n, GLYPH_g, 0};
+static const glyph_t a2l1x_endash[] = {GLYPH_UNI_hyphen, GLYPH_UNI_hyphen, 0};
+static const glyph_t a2l1x_emdash[] = {GLYPH_UNI_hyphen, GLYPH_UNI_hyphen, GLYPH_UNI_hyphen, 0};
+static const glyph_t a2l1x_quoteleft[] = {GLYPH_quotesingle, 0};
+static const glyph_t a2l1x_quoteright[] = {GLYPH_quotesingle, 0};
+static const glyph_t a2l1x_quotereversed[] = {GLYPH_quotesingle, 0};
+static const glyph_t a2l1x_quotedblleft[] = {GLYPH_quotedbl, 0};
+static const glyph_t a2l1x_quotedblright[] = {GLYPH_quotedbl, 0};
+static const glyph_t a2l1x_UNI_quotedblreversed[] = {GLYPH_quotedbl, 0};
+static const glyph_t a2l1x_ff[] = {GLYPH_f, GLYPH_f, 0};
+static const glyph_t a2l1x_fi[] = {GLYPH_f, GLYPH_i, 0};
+static const glyph_t a2l1x_fl[] = {GLYPH_f, GLYPH_l, 0};
+static const glyph_t a2l1x_ffi[] = {GLYPH_f, GLYPH_f, GLYPH_i, 0};
+static const glyph_t a2l1x_ffl[] = {GLYPH_f, GLYPH_f, GLYPH_l, 0};
+static const glyph_t a2l1x_UNI_st[] = {GLYPH_s, GLYPH_t, 0};
+static const glyph_t a2l1x_UNI_longst[] = {GLYPH_s, GLYPH_t, 0};
+static const glyph_t a2l1x_minus[] = {GLYPH_UNI_hyphen, 0};
+static const glyph_t a2l1x_asteriskmath[] = {GLYPH_asterisk, 0};
+static const glyph_t a2l1x_2emptystring[] = {0};
+static const glyph_t a2l1x_2asciitilde[] = {GLYPH_asciitilde, 0};
+static const glyph_t a2l1x_lessequal[] = {GLYPH_equal, GLYPH_less, 0};
+static const glyph_t a2l1x_greaterequal[] = {GLYPH_greater, GLYPH_equal, 0};
+
+static const glyph_t a2l1x_2A[] = {GLYPH_A, 0};
+static const glyph_t a2l1x_2B[] = {GLYPH_B, 0};
+static const glyph_t a2l1x_2C[] = {GLYPH_C, 0};
+static const glyph_t a2l1x_2D[] = {GLYPH_D, 0};
+static const glyph_t a2l1x_2E[] = {GLYPH_E, 0};
+static const glyph_t a2l1x_2F[] = {GLYPH_F, 0};
+static const glyph_t a2l1x_2G[] = {GLYPH_G, 0};
+static const glyph_t a2l1x_2H[] = {GLYPH_H, 0};
+static const glyph_t a2l1x_2I[] = {GLYPH_I, 0};
+static const glyph_t a2l1x_2J[] = {GLYPH_J, 0};
+static const glyph_t a2l1x_2K[] = {GLYPH_K, 0};
+static const glyph_t a2l1x_2L[] = {GLYPH_L, 0};
+static const glyph_t a2l1x_2M[] = {GLYPH_M, 0};
+static const glyph_t a2l1x_2N[] = {GLYPH_N, 0};
+static const glyph_t a2l1x_2O[] = {GLYPH_O, 0};
+static const glyph_t a2l1x_2P[] = {GLYPH_P, 0};
+static const glyph_t a2l1x_2Q[] = {GLYPH_Q, 0};
+static const glyph_t a2l1x_2R[] = {GLYPH_R, 0};
+static const glyph_t a2l1x_2S[] = {GLYPH_S, 0};
+static const glyph_t a2l1x_2T[] = {GLYPH_T, 0};
+static const glyph_t a2l1x_2U[] = {GLYPH_U, 0};
+static const glyph_t a2l1x_2V[] = {GLYPH_V, 0};
+static const glyph_t a2l1x_2W[] = {GLYPH_W, 0};
+static const glyph_t a2l1x_2X[] = {GLYPH_X, 0};
+static const glyph_t a2l1x_2Y[] = {GLYPH_Y, 0};
+static const glyph_t a2l1x_2Z[] = {GLYPH_Z, 0};
+
+static const glyph_t a2l1x_2a[] = {GLYPH_a, 0};
+static const glyph_t a2l1x_2b[] = {GLYPH_b, 0};
+static const glyph_t a2l1x_2c[] = {GLYPH_c, 0};
+static const glyph_t a2l1x_2d[] = {GLYPH_d, 0};
+static const glyph_t a2l1x_2e[] = {GLYPH_e, 0};
+static const glyph_t a2l1x_2f[] = {GLYPH_f, 0};
+static const glyph_t a2l1x_2g[] = {GLYPH_g, 0};
+static const glyph_t a2l1x_2h[] = {GLYPH_h, 0};
+static const glyph_t a2l1x_2i[] = {GLYPH_i, 0};
+static const glyph_t a2l1x_2j[] = {GLYPH_j, 0};
+static const glyph_t a2l1x_2k[] = {GLYPH_k, 0};
+static const glyph_t a2l1x_2l[] = {GLYPH_l, 0};
+static const glyph_t a2l1x_2m[] = {GLYPH_m, 0};
+static const glyph_t a2l1x_2n[] = {GLYPH_n, 0};
+static const glyph_t a2l1x_2o[] = {GLYPH_o, 0};
+static const glyph_t a2l1x_2p[] = {GLYPH_p, 0};
+static const glyph_t a2l1x_2q[] = {GLYPH_q, 0};
+static const glyph_t a2l1x_2r[] = {GLYPH_r, 0};
+static const glyph_t a2l1x_2s[] = {GLYPH_s, 0};
+static const glyph_t a2l1x_2t[] = {GLYPH_t, 0};
+static const glyph_t a2l1x_2u[] = {GLYPH_u, 0};
+static const glyph_t a2l1x_2v[] = {GLYPH_v, 0};
+static const glyph_t a2l1x_2w[] = {GLYPH_w, 0};
+static const glyph_t a2l1x_2x[] = {GLYPH_x, 0};
+static const glyph_t a2l1x_2y[] = {GLYPH_y, 0};
+static const glyph_t a2l1x_2z[] = {GLYPH_z, 0};
+
+static const glyph_t a2l1x_2zero[] = {GLYPH_zero, 0};
+static const glyph_t a2l1x_2one[] = {GLYPH_one, 0};
+static const glyph_t a2l1x_2two[] = {GLYPH_two, 0};
+static const glyph_t a2l1x_2three[] = {GLYPH_three, 0};
+static const glyph_t a2l1x_2four[] = {GLYPH_four, 0};
+static const glyph_t a2l1x_2five[] = {GLYPH_five, 0};
+static const glyph_t a2l1x_2six[] = {GLYPH_six, 0};
+static const glyph_t a2l1x_2seven[] = {GLYPH_seven, 0};
+static const glyph_t a2l1x_2eight[] = {GLYPH_eight, 0};
+static const glyph_t a2l1x_2nine[] = {GLYPH_nine, 0};
+
+/* These are shared between ascii and latin1. Latin9 uses them as well,
+ * but discards the GLYPH_oe and GLYPH_OE tweaks. */
+static const glyphtweak_t a2l1_glyphtweaks[] = {
+ { GLYPH_IJ, a2l1x_IJ, WIDTH_AUTO },
+ { GLYPH_ij, a2l1x_ij, WIDTH_AUTO },
+ { GLYPH_OE, a2l1x_OE, WIDTH_AUTO },
+ { GLYPH_oe, a2l1x_oe, WIDTH_AUTO },
+ { GLYPH_Eng, a2l1x_Eng, WIDTH_AUTO},
+ { GLYPH_eng, a2l1x_eng, WIDTH_AUTO},
+ { GLYPH_endash, a2l1x_endash, WIDTH_AUTO },
+ { GLYPH_emdash, a2l1x_emdash, WIDTH_AUTO },
+ { GLYPH_quoteleft, a2l1x_quoteleft, WIDTH_AUTO },
+ { GLYPH_quoteright, a2l1x_quoteright, WIDTH_AUTO },
+ { GLYPH_quotereversed, a2l1x_quotereversed, WIDTH_AUTO },
+ { GLYPH_quotedblleft, a2l1x_quotedblleft, WIDTH_AUTO },
+ { GLYPH_quotedblright, a2l1x_quotedblright, WIDTH_AUTO },
+ { GLYPH_UNI_quotedblreversed, a2l1x_UNI_quotedblreversed, WIDTH_AUTO },
+ { GLYPH_ff, a2l1x_ff, WIDTH_AUTO },
+ { GLYPH_fi, a2l1x_fi, WIDTH_AUTO },
+ { GLYPH_fl, a2l1x_fl, WIDTH_AUTO },
+ { GLYPH_ffi, a2l1x_ffi, WIDTH_AUTO },
+ { GLYPH_ffl, a2l1x_ffl, WIDTH_AUTO },
+ { GLYPH_UNI_st, a2l1x_UNI_st, WIDTH_AUTO },
+ { GLYPH_UNI_longst, a2l1x_UNI_longst, WIDTH_AUTO },
+ { GLYPH_minus, a2l1x_minus, WIDTH_AUTO },
+ { GLYPH_asteriskmath, a2l1x_asteriskmath, WIDTH_AUTO},
+ { GLYPH_UNI_ZWNJ, a2l1x_2emptystring, WIDTH_AUTO},
+ { GLYPH_tilde, a2l1x_2asciitilde, WIDTH_AUTO},
+ { GLYPH_similar, a2l1x_2asciitilde, WIDTH_AUTO},
+ { GLYPH_lessequal, a2l1x_lessequal, WIDTH_AUTO},
+ { GLYPH_greaterequal, a2l1x_greaterequal, WIDTH_AUTO},
+
+ { GLYPH_UNI_Amathscript, a2l1x_2A, WIDTH_AUTO },
+ { GLYPH_UNI_Bscript, a2l1x_2B, WIDTH_AUTO },
+ { GLYPH_UNI_Cmathscript, a2l1x_2C, WIDTH_AUTO },
+ { GLYPH_UNI_Dmathscript, a2l1x_2D, WIDTH_AUTO },
+ { GLYPH_UNI_Escript, a2l1x_2E, WIDTH_AUTO },
+ { GLYPH_UNI_Fscript, a2l1x_2F, WIDTH_AUTO },
+ { GLYPH_UNI_Gmathscript, a2l1x_2G, WIDTH_AUTO },
+ { GLYPH_UNI_Hscript, a2l1x_2H, WIDTH_AUTO },
+ { GLYPH_UNI_Iscript, a2l1x_2I, WIDTH_AUTO },
+ { GLYPH_UNI_Jmathscript, a2l1x_2J, WIDTH_AUTO },
+ { GLYPH_UNI_Kmathscript, a2l1x_2K, WIDTH_AUTO },
+ { GLYPH_UNI_Lscript, a2l1x_2L, WIDTH_AUTO },
+ { GLYPH_UNI_Mscript, a2l1x_2M, WIDTH_AUTO },
+ { GLYPH_UNI_Nmathscript, a2l1x_2N, WIDTH_AUTO },
+ { GLYPH_UNI_Omathscript, a2l1x_2O, WIDTH_AUTO },
+ { GLYPH_UNI_Pmathscript, a2l1x_2P, WIDTH_AUTO },
+ { GLYPH_UNI_Qmathscript, a2l1x_2Q, WIDTH_AUTO },
+ { GLYPH_UNI_Rscript, a2l1x_2R, WIDTH_AUTO },
+ { GLYPH_UNI_Smathscript, a2l1x_2S, WIDTH_AUTO },
+ { GLYPH_UNI_Tmathscript, a2l1x_2T, WIDTH_AUTO },
+ { GLYPH_UNI_Umathscript, a2l1x_2U, WIDTH_AUTO },
+ { GLYPH_UNI_Vmathscript, a2l1x_2V, WIDTH_AUTO },
+ { GLYPH_UNI_Wmathscript, a2l1x_2W, WIDTH_AUTO },
+ { GLYPH_UNI_Xmathscript, a2l1x_2X, WIDTH_AUTO },
+ { GLYPH_UNI_Ymathscript, a2l1x_2Y, WIDTH_AUTO },
+ { GLYPH_UNI_Zmathscript, a2l1x_2Z, WIDTH_AUTO },
+
+ { GLYPH_UNI_lscript, a2l1x_2l, WIDTH_AUTO },
+
+ { GLYPH_UNI_Amathbb, a2l1x_2A, WIDTH_AUTO },
+ { GLYPH_UNI_Bmathbb, a2l1x_2B, WIDTH_AUTO },
+ { GLYPH_UNI_Cdblstruck, a2l1x_2C, WIDTH_AUTO },
+ { GLYPH_UNI_Dmathbb, a2l1x_2D, WIDTH_AUTO },
+ { GLYPH_UNI_Emathbb, a2l1x_2E, WIDTH_AUTO },
+ { GLYPH_UNI_Fmathbb, a2l1x_2F, WIDTH_AUTO },
+ { GLYPH_UNI_Gmathbb, a2l1x_2G, WIDTH_AUTO },
+ { GLYPH_UNI_Hdblstruck, a2l1x_2H, WIDTH_AUTO },
+ { GLYPH_UNI_Imathbb, a2l1x_2I, WIDTH_AUTO },
+ { GLYPH_UNI_Jmathbb, a2l1x_2J, WIDTH_AUTO },
+ { GLYPH_UNI_Kmathbb, a2l1x_2K, WIDTH_AUTO },
+ { GLYPH_UNI_Lmathbb, a2l1x_2L, WIDTH_AUTO },
+ { GLYPH_UNI_Mmathbb, a2l1x_2M, WIDTH_AUTO },
+ { GLYPH_UNI_Ndblstruck, a2l1x_2N, WIDTH_AUTO },
+ { GLYPH_UNI_Omathbb, a2l1x_2O, WIDTH_AUTO },
+ { GLYPH_UNI_Pdblstruck, a2l1x_2P, WIDTH_AUTO },
+ { GLYPH_UNI_Qdblstruck, a2l1x_2Q, WIDTH_AUTO },
+ { GLYPH_UNI_Rdblstruck, a2l1x_2R, WIDTH_AUTO },
+ { GLYPH_UNI_Smathbb, a2l1x_2S, WIDTH_AUTO },
+ { GLYPH_UNI_Tmathbb, a2l1x_2T, WIDTH_AUTO },
+ { GLYPH_UNI_Umathbb, a2l1x_2U, WIDTH_AUTO },
+ { GLYPH_UNI_Vmathbb, a2l1x_2V, WIDTH_AUTO },
+ { GLYPH_UNI_Wmathbb, a2l1x_2W, WIDTH_AUTO },
+ { GLYPH_UNI_Xmathbb, a2l1x_2X, WIDTH_AUTO },
+ { GLYPH_UNI_Ymathbb, a2l1x_2Y, WIDTH_AUTO },
+ { GLYPH_UNI_Zdblstruck, a2l1x_2Z, WIDTH_AUTO },
+
+ { GLYPH_UNI_amathbb, a2l1x_2a, WIDTH_AUTO },
+ { GLYPH_UNI_bmathbb, a2l1x_2b, WIDTH_AUTO },
+ { GLYPH_UNI_cmathbb, a2l1x_2c, WIDTH_AUTO },
+ { GLYPH_UNI_dmathbb, a2l1x_2d, WIDTH_AUTO },
+ { GLYPH_UNI_emathbb, a2l1x_2e, WIDTH_AUTO },
+ { GLYPH_UNI_fmathbb, a2l1x_2f, WIDTH_AUTO },
+ { GLYPH_UNI_gmathbb, a2l1x_2g, WIDTH_AUTO },
+ { GLYPH_UNI_hmathbb, a2l1x_2h, WIDTH_AUTO },
+ { GLYPH_UNI_imathbb, a2l1x_2i, WIDTH_AUTO },
+ { GLYPH_UNI_jmathbb, a2l1x_2j, WIDTH_AUTO },
+ { GLYPH_UNI_kmathbb, a2l1x_2k, WIDTH_AUTO },
+ { GLYPH_UNI_lmathbb, a2l1x_2l, WIDTH_AUTO },
+ { GLYPH_UNI_mmathbb, a2l1x_2m, WIDTH_AUTO },
+ { GLYPH_UNI_nmathbb, a2l1x_2n, WIDTH_AUTO },
+ { GLYPH_UNI_omathbb, a2l1x_2o, WIDTH_AUTO },
+ { GLYPH_UNI_pmathbb, a2l1x_2p, WIDTH_AUTO },
+ { GLYPH_UNI_qmathbb, a2l1x_2q, WIDTH_AUTO },
+ { GLYPH_UNI_rmathbb, a2l1x_2r, WIDTH_AUTO },
+ { GLYPH_UNI_smathbb, a2l1x_2s, WIDTH_AUTO },
+ { GLYPH_UNI_tmathbb, a2l1x_2t, WIDTH_AUTO },
+ { GLYPH_UNI_umathbb, a2l1x_2u, WIDTH_AUTO },
+ { GLYPH_UNI_vmathbb, a2l1x_2v, WIDTH_AUTO },
+ { GLYPH_UNI_wmathbb, a2l1x_2w, WIDTH_AUTO },
+ { GLYPH_UNI_xmathbb, a2l1x_2x, WIDTH_AUTO },
+ { GLYPH_UNI_ymathbb, a2l1x_2y, WIDTH_AUTO },
+ { GLYPH_UNI_zmathbb, a2l1x_2z, WIDTH_AUTO },
+
+ { GLYPH_UNI_zeromathbb, a2l1x_2zero, WIDTH_AUTO },
+ { GLYPH_UNI_onemathbb, a2l1x_2one, WIDTH_AUTO },
+ { GLYPH_UNI_twomathbb, a2l1x_2two, WIDTH_AUTO },
+ { GLYPH_UNI_threemathbb, a2l1x_2three, WIDTH_AUTO },
+ { GLYPH_UNI_fourmathbb, a2l1x_2four, WIDTH_AUTO },
+ { GLYPH_UNI_fivemathbb, a2l1x_2five, WIDTH_AUTO },
+ { GLYPH_UNI_sixmathbb, a2l1x_2six, WIDTH_AUTO },
+ { GLYPH_UNI_sevenmathbb, a2l1x_2seven, WIDTH_AUTO },
+ { GLYPH_UNI_eightmathbb, a2l1x_2eight, WIDTH_AUTO },
+ { GLYPH_UNI_ninemathbb, a2l1x_2nine, WIDTH_AUTO },
+
+ { GLYPH_UNI_Amathfrak, a2l1x_2A, WIDTH_AUTO },
+ { GLYPH_UNI_Bmathfrak, a2l1x_2B, WIDTH_AUTO },
+ { GLYPH_UNI_Cfraktur, a2l1x_2C, WIDTH_AUTO },
+ { GLYPH_UNI_Dmathfrak, a2l1x_2D, WIDTH_AUTO },
+ { GLYPH_UNI_Emathfrak, a2l1x_2E, WIDTH_AUTO },
+ { GLYPH_UNI_Fmathfrak, a2l1x_2F, WIDTH_AUTO },
+ { GLYPH_UNI_Gmathfrak, a2l1x_2G, WIDTH_AUTO },
+ { GLYPH_UNI_Hfraktur, a2l1x_2H, WIDTH_AUTO },
+ { GLYPH_Ifraktur, a2l1x_2I, WIDTH_AUTO },
+ { GLYPH_UNI_Jmathfrak, a2l1x_2J, WIDTH_AUTO },
+ { GLYPH_UNI_Kmathfrak, a2l1x_2K, WIDTH_AUTO },
+ { GLYPH_UNI_Lmathfrak, a2l1x_2L, WIDTH_AUTO },
+ { GLYPH_UNI_Mmathfrak, a2l1x_2M, WIDTH_AUTO },
+ { GLYPH_UNI_Nmathfrak, a2l1x_2N, WIDTH_AUTO },
+ { GLYPH_UNI_Omathfrak, a2l1x_2O, WIDTH_AUTO },
+ { GLYPH_UNI_Pmathfrak, a2l1x_2P, WIDTH_AUTO },
+ { GLYPH_UNI_Qmathfrak, a2l1x_2Q, WIDTH_AUTO },
+ { GLYPH_Rfraktur, a2l1x_2R, WIDTH_AUTO },
+ { GLYPH_UNI_Smathfrak, a2l1x_2S, WIDTH_AUTO },
+ { GLYPH_UNI_Tmathfrak, a2l1x_2T, WIDTH_AUTO },
+ { GLYPH_UNI_Umathfrak, a2l1x_2U, WIDTH_AUTO },
+ { GLYPH_UNI_Vmathfrak, a2l1x_2V, WIDTH_AUTO },
+ { GLYPH_UNI_Wmathfrak, a2l1x_2W, WIDTH_AUTO },
+ { GLYPH_UNI_Xmathfrak, a2l1x_2X, WIDTH_AUTO },
+ { GLYPH_UNI_Ymathfrak, a2l1x_2Y, WIDTH_AUTO },
+ { GLYPH_UNI_Zfraktur, a2l1x_2Z, WIDTH_AUTO },
+
+ { GLYPH_UNI_amathfrak, a2l1x_2a, WIDTH_AUTO },
+ { GLYPH_UNI_bmathfrak, a2l1x_2b, WIDTH_AUTO },
+ { GLYPH_UNI_cmathfrak, a2l1x_2c, WIDTH_AUTO },
+ { GLYPH_UNI_dmathfrak, a2l1x_2d, WIDTH_AUTO },
+ { GLYPH_UNI_emathfrak, a2l1x_2e, WIDTH_AUTO },
+ { GLYPH_UNI_fmathfrak, a2l1x_2f, WIDTH_AUTO },
+ { GLYPH_UNI_gmathfrak, a2l1x_2g, WIDTH_AUTO },
+ { GLYPH_UNI_hmathfrak, a2l1x_2h, WIDTH_AUTO },
+ { GLYPH_UNI_imathfrak, a2l1x_2i, WIDTH_AUTO },
+ { GLYPH_UNI_jmathfrak, a2l1x_2j, WIDTH_AUTO },
+ { GLYPH_UNI_kmathfrak, a2l1x_2k, WIDTH_AUTO },
+ { GLYPH_UNI_lmathfrak, a2l1x_2l, WIDTH_AUTO },
+ { GLYPH_UNI_mmathfrak, a2l1x_2m, WIDTH_AUTO },
+ { GLYPH_UNI_nmathfrak, a2l1x_2n, WIDTH_AUTO },
+ { GLYPH_UNI_omathfrak, a2l1x_2o, WIDTH_AUTO },
+ { GLYPH_UNI_pmathfrak, a2l1x_2p, WIDTH_AUTO },
+ { GLYPH_UNI_qmathfrak, a2l1x_2q, WIDTH_AUTO },
+ { GLYPH_UNI_rmathfrak, a2l1x_2r, WIDTH_AUTO },
+ { GLYPH_UNI_smathfrak, a2l1x_2s, WIDTH_AUTO },
+ { GLYPH_UNI_tmathfrak, a2l1x_2t, WIDTH_AUTO },
+ { GLYPH_UNI_umathfrak, a2l1x_2u, WIDTH_AUTO },
+ { GLYPH_UNI_vmathfrak, a2l1x_2v, WIDTH_AUTO },
+ { GLYPH_UNI_wmathfrak, a2l1x_2w, WIDTH_AUTO },
+ { GLYPH_UNI_xmathfrak, a2l1x_2x, WIDTH_AUTO },
+ { GLYPH_UNI_ymathfrak, a2l1x_2y, WIDTH_AUTO },
+ { GLYPH_UNI_zmathfrak, a2l1x_2z, WIDTH_AUTO }
+};
+
+static void ascii_init(void)
+{
+ outenc_register_glyphtweaks(
+ a2l1_glyphtweaks,
+ lengthof(a2l1_glyphtweaks)
+ );
+ simple_init_charmap(127, NULL, 0);
+
+ outenc_write_raw_glyph = simple_write_raw_glyph;
+ outenc_composition_width = generic_composition_width;
+ outenc_xlat_composition = generic_xlat_composition;
+
+ /* FIXME: we don't register any accentings, but we should register some
+ * translations for the most common non-spacing diacritics instead.
+ */
+}
+
+
+/***********************************************************************
+ * latin1
+ ***********************************************************************/
+
+/* How to combine a base glyph and a diacritic - ISO 8859-1 cases */
+static struct generic_accententry_t latin1_accentings[] = {
+ {GLYPH_A, GLYPH_gravecomb, GLYPH_Agrave},
+ {GLYPH_A, GLYPH_acutecomb, GLYPH_Aacute},
+ {GLYPH_A, GLYPH_UNI_circumflexcomb, GLYPH_Acircumflex},
+ {GLYPH_A, GLYPH_tildecomb, GLYPH_Atilde},
+ {GLYPH_A, GLYPH_UNI_dieresiscomb, GLYPH_Adieresis},
+ {GLYPH_A, GLYPH_UNI_ringcomb, GLYPH_Aring},
+ {GLYPH_C, GLYPH_UNI_cedillacomb, GLYPH_Ccedilla},
+ {GLYPH_C, GLYPH_UNI_circlecomb, GLYPH_copyright},
+ {GLYPH_E, GLYPH_gravecomb, GLYPH_Egrave},
+ {GLYPH_E, GLYPH_acutecomb, GLYPH_Eacute},
+ {GLYPH_E, GLYPH_UNI_circumflexcomb, GLYPH_Ecircumflex},
+ {GLYPH_E, GLYPH_UNI_dieresiscomb, GLYPH_Edieresis},
+ {GLYPH_I, GLYPH_gravecomb, GLYPH_Igrave},
+ {GLYPH_I, GLYPH_acutecomb, GLYPH_Iacute},
+ {GLYPH_I, GLYPH_UNI_circumflexcomb, GLYPH_Icircumflex},
+ {GLYPH_I, GLYPH_UNI_dieresiscomb, GLYPH_Idieresis},
+ {GLYPH_N, GLYPH_tildecomb, GLYPH_Ntilde},
+ {GLYPH_O, GLYPH_gravecomb, GLYPH_Ograve},
+ {GLYPH_O, GLYPH_acutecomb, GLYPH_Oacute},
+ {GLYPH_O, GLYPH_UNI_circumflexcomb, GLYPH_Ocircumflex},
+ {GLYPH_O, GLYPH_tildecomb, GLYPH_Otilde},
+ {GLYPH_O, GLYPH_UNI_dieresiscomb, GLYPH_Odieresis},
+ {GLYPH_R, GLYPH_UNI_circlecomb, GLYPH_registered},
+ {GLYPH_U, GLYPH_gravecomb, GLYPH_Ugrave},
+ {GLYPH_U, GLYPH_acutecomb, GLYPH_Uacute},
+ {GLYPH_U, GLYPH_UNI_circumflexcomb, GLYPH_Ucircumflex},
+ {GLYPH_U, GLYPH_UNI_dieresiscomb, GLYPH_Udieresis},
+ {GLYPH_Y, GLYPH_acutecomb, GLYPH_Yacute},
+ {GLYPH_a, GLYPH_gravecomb, GLYPH_agrave},
+ {GLYPH_a, GLYPH_acutecomb, GLYPH_aacute},
+ {GLYPH_a, GLYPH_UNI_circumflexcomb, GLYPH_acircumflex},
+ {GLYPH_a, GLYPH_tildecomb, GLYPH_atilde},
+ {GLYPH_a, GLYPH_UNI_dieresiscomb, GLYPH_adieresis},
+ {GLYPH_a, GLYPH_UNI_ringcomb, GLYPH_aring},
+ {GLYPH_c, GLYPH_UNI_cedillacomb, GLYPH_ccedilla},
+ {GLYPH_c, GLYPH_UNI_circlecomb, GLYPH_copyright},
+ {GLYPH_e, GLYPH_gravecomb, GLYPH_egrave},
+ {GLYPH_e, GLYPH_acutecomb, GLYPH_eacute},
+ {GLYPH_e, GLYPH_UNI_circumflexcomb, GLYPH_ecircumflex},
+ {GLYPH_e, GLYPH_UNI_dieresiscomb, GLYPH_edieresis},
+ {GLYPH_i, GLYPH_gravecomb, GLYPH_igrave},
+ {GLYPH_i, GLYPH_acutecomb, GLYPH_iacute},
+ {GLYPH_i, GLYPH_UNI_circumflexcomb, GLYPH_icircumflex},
+ {GLYPH_i, GLYPH_UNI_dieresiscomb, GLYPH_idieresis},
+ {GLYPH_dotlessi, GLYPH_gravecomb, GLYPH_igrave},
+ {GLYPH_dotlessi, GLYPH_acutecomb, GLYPH_iacute},
+ {GLYPH_dotlessi, GLYPH_UNI_circumflexcomb, GLYPH_icircumflex},
+ {GLYPH_dotlessi, GLYPH_UNI_dieresiscomb, GLYPH_idieresis},
+ {GLYPH_n, GLYPH_tildecomb, GLYPH_ntilde},
+ {GLYPH_o, GLYPH_gravecomb, GLYPH_ograve},
+ {GLYPH_o, GLYPH_acutecomb, GLYPH_oacute},
+ {GLYPH_o, GLYPH_UNI_circumflexcomb, GLYPH_ocircumflex},
+ {GLYPH_o, GLYPH_tildecomb, GLYPH_otilde},
+ {GLYPH_o, GLYPH_UNI_dieresiscomb, GLYPH_odieresis},
+ {GLYPH_u, GLYPH_gravecomb, GLYPH_ugrave},
+ {GLYPH_u, GLYPH_acutecomb, GLYPH_uacute},
+ {GLYPH_u, GLYPH_UNI_circumflexcomb, GLYPH_ucircumflex},
+ {GLYPH_u, GLYPH_UNI_dieresiscomb, GLYPH_udieresis},
+ {GLYPH_y, GLYPH_acutecomb, GLYPH_yacute},
+ {GLYPH_y, GLYPH_UNI_dieresiscomb, GLYPH_ydieresis},
+ /* end of table */
+ {0, 0, 0}
+};
+
+static void latin1_init(void)
+{
+ outenc_register_glyphtweaks(
+ a2l1_glyphtweaks,
+ lengthof(a2l1_glyphtweaks)
+ );
+
+ simple_init_charmap(255, NULL, 0);
+ outenc_write_raw_glyph = simple_write_raw_glyph;
+
+ outenc_composition_width = generic_composition_width;
+ outenc_xlat_composition = generic_xlat_composition;
+
+ generic_register_accentings(latin1_accentings);
+}
+
+
+/***********************************************************************
+ * latin9
+ ***********************************************************************/
+/* How to combine a base glyph and a diacritic -- ISO 8859-15 cases not
+ * already covered by ISO 8859-1
+ */
+static struct generic_accententry_t latin9_accentings[] = {
+ {GLYPH_S, GLYPH_UNI_caroncomb, GLYPH_Scaron},
+ {GLYPH_s, GLYPH_UNI_caroncomb, GLYPH_scaron},
+ {GLYPH_Z, GLYPH_UNI_caroncomb, GLYPH_Zcaron},
+ {GLYPH_z, GLYPH_UNI_caroncomb, GLYPH_zcaron},
+ {GLYPH_Y, GLYPH_UNI_dieresiscomb, GLYPH_Ydieresis},
+ /* end of table */
+ {0, 0, 0}
+};
+
+static struct simple_charmap_entry_t latin9_charmap[] = {
+ {GLYPH_Euro, 0xa4},
+ {0x00a5, 0xa5},
+ {GLYPH_Scaron, 0xa6},
+ {0x00a7, 0xa7},
+ {GLYPH_scaron, 0xa8},
+ {0x00a9, 0xa9},
+ {0x00aa, 0xaa},
+ {0x00ab, 0xab},
+ {0x00ac, 0xac},
+ {0x00ad, 0xad},
+ {0x00ae, 0xae},
+ {0x00af, 0xaf},
+ {0x00b0, 0xb0},
+ {0x00b1, 0xb1},
+ {0x00b2, 0xb2},
+ {0x00b3, 0xb3},
+ {GLYPH_Zcaron, 0xb4},
+ {0x00b5, 0xb5},
+ {0x00b6, 0xb6},
+ {0x00b7, 0xb7},
+ {GLYPH_zcaron, 0xb8},
+ {0x00b9, 0xb9},
+ {0x00ba, 0xba},
+ {0x00bb, 0xbb},
+ {GLYPH_OE, 0xbc},
+ {GLYPH_oe, 0xbd},
+ {GLYPH_Ydieresis, 0xbe},
+ {0x00bf, 0xbf},
+ {0x00c0, 0xc0},
+ {0x00c1, 0xc1},
+ {0x00c2, 0xc2},
+ {0x00c3, 0xc3},
+ {0x00c4, 0xc4},
+ {0x00c5, 0xc5},
+ {0x00c6, 0xc6},
+ {0x00c7, 0xc7},
+ {0x00c8, 0xc8},
+ {0x00c9, 0xc9},
+ {0x00ca, 0xca},
+ {0x00cb, 0xcb},
+ {0x00cc, 0xcc},
+ {0x00cd, 0xcd},
+ {0x00ce, 0xce},
+ {0x00cf, 0xcf},
+ {0x00d0, 0xd0},
+ {0x00d1, 0xd1},
+ {0x00d2, 0xd2},
+ {0x00d3, 0xd3},
+ {0x00d4, 0xd4},
+ {0x00d5, 0xd5},
+ {0x00d6, 0xd6},
+ {0x00d7, 0xd7},
+ {0x00d8, 0xd8},
+ {0x00d9, 0xd9},
+ {0x00da, 0xda},
+ {0x00db, 0xdb},
+ {0x00dc, 0xdc},
+ {0x00dd, 0xdd},
+ {0x00de, 0xde},
+ {0x00df, 0xdf},
+ {0x00e0, 0xe0},
+ {0x00e1, 0xe1},
+ {0x00e2, 0xe2},
+ {0x00e3, 0xe3},
+ {0x00e4, 0xe4},
+ {0x00e5, 0xe5},
+ {0x00e6, 0xe6},
+ {0x00e7, 0xe7},
+ {0x00e8, 0xe8},
+ {0x00e9, 0xe9},
+ {0x00ea, 0xea},
+ {0x00eb, 0xeb},
+ {0x00ec, 0xec},
+ {0x00ed, 0xed},
+ {0x00ee, 0xee},
+ {0x00ef, 0xef},
+ {0x00f0, 0xf0},
+ {0x00f1, 0xf1},
+ {0x00f2, 0xf2},
+ {0x00f3, 0xf3},
+ {0x00f4, 0xf4},
+ {0x00f5, 0xf5},
+ {0x00f6, 0xf6},
+ {0x00f7, 0xf7},
+ {0x00f8, 0xf8},
+ {0x00f9, 0xf9},
+ {0x00fa, 0xfa},
+ {0x00fb, 0xfb},
+ {0x00fc, 0xfc},
+ {0x00fd, 0xfd},
+ {0x00fe, 0xfe},
+ {0x00ff, 0xff}
+};
+
+static void latin9_init(void)
+{
+ outenc_register_glyphtweaks(
+ a2l1_glyphtweaks,
+ lengthof(a2l1_glyphtweaks)
+ );
+ outenc_unregister_glyphtweak(GLYPH_OE);
+ outenc_unregister_glyphtweak(GLYPH_oe);
+ /* We are parasitic and simply tune the latin1 tweaks to our needs. */
+
+ simple_init_charmap(163, latin9_charmap, lengthof(latin9_charmap));
+ outenc_write_raw_glyph = simple_write_raw_glyph;
+
+ outenc_composition_width = generic_composition_width;
+ outenc_xlat_composition = generic_xlat_composition;
+
+ generic_register_accentings(latin1_accentings);
+ generic_register_accentings(latin9_accentings);
+}
+
+
+/***********************************************************************
+ * implementations of encoding independent stuff
+ ***********************************************************************/
+
+static spars32_t glyphwidth_spars32;
+static sparp_t glyphxlat_sparp;
+
+void outenc_init(void)
+{
+ assert(outenc_num < OE_TOOBIG);
+
+ pmesg(50, "BEGIN outenc_init\n");
+
+ sparp_init(&accenting_sparp);
+ vlist_init(&accenting_vlist);
+ spars32_init(&glyphwidth_spars32, 1);
+ sparp_init(&glyphxlat_sparp);
+
+ outenc_register_glyphtweaks(
+ generic_glyphtweaks,
+ lengthof(generic_glyphtweaks)
+ );
+ /* The encoding-specific inits can override these if required */
+
+ generic_register_accentings(generic_accentings);
+ /* Ditto. But any encoding wants them anyway. */
+
+ switch(outenc_num) {
+ case OE_UTF8:
+ utf8_init();
+ break;
+ case OE_ASCII:
+ ascii_init();
+ break;
+ case OE_LATIN1:
+ latin1_init();
+ break;
+ case OE_LATIN9:
+ latin9_init();
+ break;
+ default:
+ NOTREACHED;
+ }
+ /* check we didn't forget to set the virtual methods */
+ assert(outenc_composition_width != NULL);
+ assert(outenc_xlat_composition != NULL);
+ assert(outenc_write_raw_glyph != NULL);
+
+ pmesg(50, "END outenc_init\n");
+}
+
+
+int outenc_get_width(const linebuf_t * l)
+{
+ glyph_t * p;
+ int w = 0;
+
+ pmesg(50, "BEGIN outenc_get_width\n");
+
+ p = l->gstring;
+ while(*p != 0) {
+ if(glyph_get_hint(*(p + 1)) & GH_COMBINING) {
+ /* grok the sequence of combining diacritics after *p */
+ glyph_t * q = p + 2;
+ while(glyph_get_hint(*q) & GH_COMBINING) ++q;
+ /* will stop by itself on 0 termination */
+ w += outenc_composition_width(p, q - p);
+ p = q;
+ }
+ else {
+ w += outenc_glyph_width(*p);
+ ++p;
+ }
+ }
+
+ pmesg(50, "END outenc_get_width\n");
+ return w;
+}
+
+
+void outenc_write(FILE * f, const linebuf_t * l)
+{
+ linebuf_t xl;
+ glyph_t * p;
+
+ pmesg(50, "BEGIN outenc_write\n");
+
+ linebuf_init(&xl, 2*l->size_curr);
+
+ p = l->gstring;
+ while(*p != 0) {
+ if(glyph_get_hint(*(p + 1)) & GH_COMBINING) {
+ /* grok the sequence of combining diacritics after *p */
+ glyph_t * q = p + 2;
+ while(glyph_get_hint(*q) & GH_COMBINING) ++q;
+ /* will stop by itself on 0 termination */
+ outenc_xlat_composition(p, q - p, &xl);
+ p = q;
+ }
+ else {
+ outenc_xlat_glyph(*p, &xl);
+ ++p;
+ }
+ }
+
+ p = xl.gstring;
+ while(*p != 0) outenc_write_raw_glyph(f, *p++);
+
+ linebuf_done(&xl);
+
+ pmesg(50, "END outenc_write\n");
+}
+
+static int outenc_glyph_width(glyph_t g)
+{
+ return (int) spars32_read(&glyphwidth_spars32, g);
+}
+
+static void outenc_xlat_glyph(glyph_t g, linebuf_t * l)
+{
+ linebuf_t * px;
+
+ px = sparp_read(&glyphxlat_sparp, g);
+ if(px == NULL) linebuf_putg(l, g);
+ else linebuf_append(l, px);
+
+}
+
+static void outenc_register_glyphtweaks(const glyphtweak_t tweaks[], int length)
+{
+ int i;
+ linebuf_t * px;
+ glyphtweak_t tweak;
+
+ px = malloc(length * sizeof(linebuf_t));
+ if(px == NULL) enomem();
+ /* Note we "leak memory" here since we leave px allocated but
+ * forget them on returning from this function. This is OK since
+ * the allocated memory is used throughout the whole lifetime of
+ * the process.
+ *
+ * FIXME: this has to stop if we want to become a library.
+ */
+
+ for(i=0; i < length; ++i) {
+ tweak = tweaks[i];
+ assert(tweak.width != WIDTH_AUTO || tweak.xlat != NULL);
+ /* We can't calculate width without translation string */
+ if(tweak.xlat != NULL) {
+ linebuf_garray0_init(px+i, tweak.xlat);
+ sparp_write(&glyphxlat_sparp, tweak.glyph, px+i);
+ if(tweak.width == WIDTH_AUTO) tweak.width = px[i].size_curr;
+ }
+ spars32_write(&glyphwidth_spars32, tweak.glyph, tweak.width);
+ }
+
+}
+
+static void outenc_unregister_glyphtweak(glyph_t g)
+{
+ if(sparp_read(&glyphxlat_sparp, g) != NULL) {
+ sparp_write(&glyphxlat_sparp, g, NULL);
+ }
+ if(spars32_read(&glyphwidth_spars32, g) != 1) {
+ spars32_write(&glyphwidth_spars32, g, 1);
+ }
+}
+
+static void outenc_show_unknown(FILE * f, glyph_t g)
+/* FIXME: prints always in the execution character set, even if that
+ * is not a superset of ASCII. Is this good or bad?
+ */
+{
+ if (outenc_show_unicode_number) {
+ if(g <= 0xffff) fprintf(f, "[U+%04lX]", g);
+ else fprintf(f, "[U+%08lX]", g);
+ } else {
+ putc('?', f);
+ }
+}
+
diff --git a/dviware/catdvi/outenc.d b/dviware/catdvi/outenc.d
new file mode 100644
index 0000000000..edc1446974
--- /dev/null
+++ b/dviware/catdvi/outenc.d
@@ -0,0 +1,2 @@
+outenc.o outenc.d : outenc.c outenc.h linebuf.h page.h bytesex.h pageref.h \
+ util.h sparse.h vlist.h glyphenm.h glyphops.h
diff --git a/dviware/catdvi/outenc.h b/dviware/catdvi/outenc.h
new file mode 100644
index 0000000000..75579c251d
--- /dev/null
+++ b/dviware/catdvi/outenc.h
@@ -0,0 +1,60 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2001 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef OUTENC_H
+#define OUTENC_H
+
+#include "linebuf.h"
+
+/* The available encoding numbers. */
+enum outenc_num_t {
+ OE_UTF8,
+ OE_ASCII,
+ OE_LATIN1,
+ OE_LATIN9,
+ OE_TOOBIG /* do not use! */
+};
+
+/* The encoding we use. Initialized to OE_ASCII. Changes after calling
+ * outenc_init() have no effect.
+ */
+extern enum outenc_num_t outenc_num;
+
+/* Array of encoding names, indexed by encoding number */
+extern char const * const * const outenc_names;
+
+/* Flag: show unicode number instead of `?' for unencodeable glyphs.
+ * Initialized to 0.
+ */
+extern int outenc_show_unicode_number;
+
+/* constructor */
+void outenc_init(void);
+
+/* How many columns would that string of glyphs use in printout.
+ * Mostly 1 per glyph of course, but more than one for e.g. $ng, hyphen
+ * (in ascii and latin1 encodings) and less in the case of combining
+ * diacritics.
+ */
+int outenc_get_width(const linebuf_t * l);
+
+/* guess */
+void outenc_write(FILE * f, const linebuf_t * l);
+
+#endif /* OUTENC_H */
diff --git a/dviware/catdvi/page.c b/dviware/catdvi/page.c
new file mode 100644
index 0000000000..387540f750
--- /dev/null
+++ b/dviware/catdvi/page.c
@@ -0,0 +1,1038 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2000-02 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include "page2.h"
+#include "util.h"
+#include "glyphops.h"
+#include "layout.h"
+
+/* Return value like with strcmp and friends. */
+static int compare_boxes(struct box_t a, struct box_t b)
+{
+ if (a.y > b.y) return 1;
+ if (a.y < b.y) return -1;
+ assert(a.y == b.y);
+ if (a.x > b.x) return 1;
+ if (a.x < b.x) return -1;
+ assert(a.x == b.x);
+ return 0;
+}
+
+struct point_t {
+ sint32 x;
+ sint32 y;
+};
+
+static int point_in_box(const struct point_t * point, const struct box_t * box)
+{
+ assert(box);
+ assert(point);
+ return(
+ box->x <= point->x &&
+ (box->x + box->width) >= point->x &&
+ (box->y - box->height) <= point->y &&
+ box->y >= point->y
+ );
+}
+
+/* Set to 1 when catdvi is invoked with the --sequential option */
+int page_sequential = 0;
+
+/* Set to 1 when catdvi is invoked with the --list-page-numbers option */
+int page_list_numbers = 0;
+
+/* List support variables. Note that most insertions happen near the
+ previous insertion, so it's beneficial to keep a pointer to the
+ last inserted node. */
+struct list_node_t * list_head;
+struct list_node_t * list_tail;
+struct list_node_t * list_latest; /* Node that was inserted last. */
+
+/* flags to avoid the page_adjust_*() loops over the whole page when
+ * there's nothing to adjust.
+ */
+static int page_has_diacritics;
+static int page_has_texmext;
+static int page_has_radicals;
+
+static void swap_nodes(struct list_node_t * one, struct list_node_t * other)
+{
+ assert(one != 0);
+ assert(other != 0);
+ assert(one->next == other);
+ assert(one == other->prev);
+
+ one->next = other->next;
+ other->prev = one->prev;
+ other->next = one;
+ one->prev = other;
+ if (one->next == 0) {
+ list_tail = one;
+ } else {
+ one->next->prev = one;
+ }
+ if (other->prev == 0) {
+ list_head = other;
+ } else {
+ other->prev->next = other;
+ }
+
+ assert(other->next == one);
+ assert(other == one->prev);
+}
+
+/* move list_latest into its correct position in the list */
+static void bubble(void)
+{
+ while (1) {
+ assert(list_latest != 0);
+
+ /* If it is in correct position now, end here. */
+ if ((list_latest->prev == 0
+ || compare_boxes(list_latest->prev->b, list_latest->b) <= 0)
+ && (list_latest->next == 0
+ || compare_boxes(list_latest->b, list_latest->next->b) <= 0)) {
+ return;
+ }
+
+ /* If it is too left, we must bubble it one position to the right. */
+ if (list_latest->next != 0
+ && compare_boxes(list_latest->b, list_latest->next->b) > 0) {
+ swap_nodes(list_latest, list_latest->next);
+ continue;
+ }
+
+ /* If it is too right, we must bubble it one position to the left. */
+ if (list_latest->prev != 0
+ && compare_boxes(list_latest->prev->b, list_latest->b) > 0) {
+ assert(list_latest->prev->next == list_latest);
+ swap_nodes(list_latest->prev, list_latest);
+ continue;
+ }
+ NOTREACHED;
+ }
+ NOTREACHED;
+}
+
+
+/* move some random node into its correct position in the list */
+static void bubble_node(struct list_node_t * p)
+{
+ list_latest = p;
+ bubble();
+}
+
+
+static void insert_list(struct box_t box)
+{
+ struct list_node_t * new;
+
+ new = malloc(sizeof(struct list_node_t));
+ if (new == 0) enomem();
+ new->b = box;
+
+ if (list_head == 0 || list_tail == 0 || list_latest == 0) {
+ assert(list_head == 0);
+ assert(list_tail == 0);
+ assert(list_latest == 0);
+
+ new->next = new->prev = 0;
+
+ list_head = list_tail = list_latest = new;
+ return;
+ }
+
+ /* The list is nonempty. */
+
+ assert(list_head != 0);
+ assert(list_tail != 0);
+ assert(list_latest != 0);
+
+ /* The insertion algorithm is this: insert the node after the
+ latest insertion, and then bubble it into its correct
+ position. */
+
+ new->next = list_latest->next;
+ list_latest->next = new;
+ new->prev = list_latest;
+ list_latest = new;
+ if (new->next == 0) {
+ list_tail = new;
+ } else {
+ new->next->prev = new;
+ }
+
+ assert(list_latest->prev->next == list_latest);
+ assert(list_latest->next == 0 || list_latest->next->prev == list_latest);
+
+ /* sort by position except in sequential mode */
+ if (!page_sequential) bubble();
+}
+
+
+/* These two are set by command line options */
+struct pageref_t page_start_output = {0, 0, 0, PRF_PHYSICAL};
+struct pageref_t page_last_output = {SINT32_MAX, 0, 0, PRF_PHYSICAL};
+
+static struct pageref_t current_page = {0, 0, 0, PRF_INVALID};
+
+
+void page_begin(sint32 count0)
+{
+ /* If necessary, delete the previous page's data structure. */
+ if (list_head != 0 || list_tail != 0 || list_latest != 0) {
+ struct list_node_t * p;
+
+ assert(list_head != 0);
+ assert(list_tail != 0);
+ assert(list_latest != 0);
+
+ p = list_head;
+ while (p != 0) {
+ struct list_node_t * next;
+
+ if (p == list_head) list_head = 0;
+ if (p == list_latest) list_latest = 0;
+ if (p == list_tail) list_tail = 0;
+
+ next = p->next;
+ free(p);
+ p = next;
+ }
+ }
+ assert(list_head == 0);
+ assert(list_tail == 0);
+ assert(list_latest == 0);
+
+ /* reset per page flags */
+ page_has_diacritics = 0;
+ page_has_texmext = 0;
+ page_has_radicals = 0;
+
+ /* keep track of page numbering */
+ if(current_page.flavour == PRF_INVALID) {
+ /* here comes the very first page of the document */
+ current_page.physical = 1;
+ current_page.count0 = count0;
+ if (count0 < 0) current_page.chapter = 1;
+ else current_page.chapter = 0;
+ /* number chapters from 0 to accomodate frontmatter */
+ current_page.flavour = PRF_COMPLETE;
+ }
+ else {
+ /* just another ordinary page */
+ current_page.physical += 1;
+ if (pageref_count0_cmp(current_page.count0, count0) >= 0) {
+ /* count0 has not increased, so start new chapter */
+ current_page.chapter += 1;
+ }
+ current_page.count0 = count0;
+ }
+}
+
+
+void page_set_glyph(
+ font_t font, glyph_t glyph,
+ sint32 width, sint32 height, sint32 depth, sint32 axis_height,
+ sint32 x, sint32 y
+)
+{
+ struct box_t b;
+ enum glyph_hint_t hint;
+
+ b.x = x;
+ b.y = y;
+ b.width = width;
+ b.height = height;
+ b.depth = depth;
+ b.glyph = glyph;
+ b.font = font;
+ b.axis_height = axis_height;
+ b.flags = 0;
+ b.axis = 0;
+
+ hint = glyph_get_hint(glyph);
+
+ if(hint & GH_DIACRITIC) {
+ b.flags |= BF_SWIMMING | BF_DIACRITIC ;
+ page_has_diacritics = 1;
+ }
+
+ if(hint & GH_EXTENSIBLE_RECIPE) {
+ b.flags |= BF_SWIMMING;
+ page_has_texmext = 1;
+ }
+ else if(hint & GH_ON_AXIS) {
+ b.flags |= BF_SWIMMING | BF_ON_AXIS | BF_HAS_AXIS ;
+ b.axis = y + (-height + depth)/2;
+ page_has_texmext = 1;
+ }
+ else if(hint & GH_RADICAL) {
+ b.flags |= BF_SWIMMING | BF_RADICAL ;
+ page_has_radicals = 1;
+ }
+ else if(axis_height > 0) {
+ b.flags |= BF_HAS_AXIS;
+ b.axis = y - axis_height;
+ }
+
+ insert_list(b);
+}
+
+
+static void page_pair_accenting(
+ struct list_node_t * pbase,
+ struct list_node_t * pdiacritic,
+ int direction
+);
+
+void page_end(void)
+{
+ pmesg(50, "BEGIN page_end\n");
+
+ if (
+ pageref_cmp(&page_start_output, &current_page) > 0 ||
+ pageref_cmp(&page_last_output, &current_page) < 0
+ ) {
+ if(msglevel >= 80) {
+ pmesg(80, "skipping page by user request:\n ");
+ pageref_print(&current_page, stderr);
+ }
+ pmesg(50, "END page_end\n");
+ return;
+ }
+
+ if(page_list_numbers) {
+ pageref_print(&current_page, stdout);
+ pmesg(50, "END page_end\n");
+ return;
+ }
+
+ if(page_sequential) page_print_sequential();
+ else page_print_formatted();
+
+ pmesg(50, "END page_end\n");
+ return;
+
+}
+
+void page_adjust_diacritics(void)
+{
+ int trouble = 0;
+ int direction = 0;
+
+ struct list_node_t *p, *s, *q, *pb;
+ struct box_t dia_box;
+ struct point_t dia_center;
+
+ pmesg(50, "BEGIN page_adjust_diacritics\n");
+
+ if(!page_has_diacritics) {
+ pmesg(80, "nothing to do\n");
+ pmesg(50, "END page_adjust_diacritics\n");
+ return;
+ }
+
+ for (p = list_head; p != 0; p = s) {
+ s = p->next;
+ /* p-> is a moving target */
+
+ if (!(p->b.flags & BF_DIACRITIC)) continue;
+
+ trouble = 0;
+ pb = 0;
+
+ dia_box = p->b;
+ dia_center.x = dia_box.x + dia_box.width / 2;
+ dia_center.y = dia_box.y - dia_box.height / 2;
+
+ /* Search corresponding base box. There are complex overlayed
+ * constructions we can't handle. Therefore, we try to find all
+ * possible candidates and abort when more than one is found.
+ */
+
+ /* search backwards */
+ for(q = p->prev; q != 0; q = q->prev) {
+ if (abs(dia_box.y - q->b.y) > 3*(dia_box.height + q->b.height))
+ /* too far off to find anything useful */
+ break;
+
+ if (point_in_box(&dia_center, &q->b)) {
+ /* I got you babe */
+ if(pb != 0) {
+ /* we are not alone...too bad */
+ trouble = 1;
+ break;
+ }
+ pb = q;
+ direction = -1;
+ }
+ }
+
+ if(trouble) {
+ pmesg(
+ 80,
+ "page_adjust_diacritics: trouble with diacritic %#lx\n",
+ dia_box.glyph
+ );
+ continue;
+ }
+
+ /* search forward */
+ for(q = p->next; q != 0; q = q->next) {
+ if (abs(dia_box.y - q->b.y) > 3*(dia_box.height + q->b.height))
+ /* too far off to find anything useful */
+ break;
+
+ if (point_in_box(&dia_center, &q->b)) {
+ /* I got you babe */
+ if(pb != 0) {
+ /* we are not alone...too bad */
+ trouble = 1;
+ break;
+ }
+ pb = q;
+ direction = 1;
+ }
+ }
+
+ if(trouble) {
+ pmesg(
+ 80,
+ "page_adjust_diacritics: trouble with diacritic %#lx\n",
+ dia_box.glyph
+ );
+ continue;
+ }
+ if(pb == 0) {
+ pmesg(
+ 80,
+ "page_adjust_diacritics: no base glyph for diacritic %#lx\n",
+ dia_box.glyph
+ );
+ /* a lone diacritic. assume it just belongs where it is */
+ p->b.flags &= ~(BF_SWIMMING | BF_DIACRITIC);
+ continue;
+ }
+
+ /* Found the one and only one. Let's get closer. */
+ page_pair_accenting(pb, p, direction);
+ }
+
+ pmesg(50, "END page_adjust_diacritics\n");
+}
+
+
+static void page_pair_accenting(
+ struct list_node_t * pbase,
+ struct list_node_t * pdiacritic,
+ int direction
+)
+{
+ glyph_t dcv;
+
+ assert(pdiacritic->b.flags & BF_DIACRITIC);
+ assert(abs(direction) == 1);
+
+ pmesg(
+ 80,
+ "detected accenting: base=%#lx, diacritic=%#lx\n",
+ pbase->b.glyph,
+ pdiacritic->b.glyph
+ );
+
+ dcv = diacritic_combining_variant(pdiacritic->b.glyph);
+
+ if(dcv) {
+ /* OK this one can be handeled within the unicode framework */
+
+ /* move diacritic right after base glyph */
+ if(direction == -1) {
+ /* base before diacritic */
+ while(pdiacritic->prev != pbase) {
+ swap_nodes(pdiacritic->prev, pdiacritic);
+ }
+ }
+ else {
+ /* base after diacritic */
+ while(pdiacritic->prev != pbase) {
+ swap_nodes(pdiacritic, pdiacritic->next);
+ /* note swap_nodes() is order sensitive */
+ }
+ }
+
+ /* Make the combining diacritic occupy the same space as the
+ * accented glyph would. That's the only way to statisfy all
+ * ordering and spacing assumptions in this program. And nearly
+ * consequent.
+ */
+ pdiacritic->b.width = pbase->b.width;
+ pdiacritic->b.height = max(
+ pbase->b.height,
+ pdiacritic->b.height + pbase->b.y - pdiacritic->b.y
+ );
+ pdiacritic->b.x = pbase->b.x;
+ pdiacritic->b.y = pbase->b.y;
+ pdiacritic->b.glyph = dcv;
+ pdiacritic->b.flags &= ~(BF_SWIMMING | BF_DIACRITIC);
+ }
+ else {
+ /* A strange guy. Won't combine. Just put him in line so he can't
+ * clobber up things. Like in real life.
+ */
+ pdiacritic->b.height =
+ pdiacritic->b.height + pbase->b.y - pdiacritic->b.y;
+ pdiacritic->b.y = pbase->b.y;
+ pdiacritic->b.flags &= ~(BF_SWIMMING | BF_DIACRITIC);
+
+ /* keep the list ordered */
+ if(!page_sequential) bubble_node(pdiacritic);
+ }
+
+}
+
+
+/************************************************************************
+ * the hairy texmext stuff
+ ************************************************************************/
+
+typedef struct interval32_t interval32_t;
+struct interval32_t {
+ sint32 a;
+ sint32 b;
+};
+
+static int interval32_contains(const interval32_t * this, sint32 x)
+{
+ int res;
+
+ res = (this->a <= x) && (x <= this->b);
+
+ pmesg(
+ 150,
+ "interval32_contains: %ld %s [%ld, %ld]\n",
+ x,
+ res ? "in" : "not in",
+ this->a,
+ this->b
+ );
+
+ return res;
+}
+
+
+typedef struct searchinfo_t searchinfo_t;
+struct searchinfo_t {
+ interval32_t searched_y;
+ interval32_t x;
+ interval32_t y;
+ interval32_t top;
+ interval32_t axis;
+ int require_axis;
+ int test_start;
+ struct list_node_t * start;
+ struct list_node_t * first_found;
+};
+
+static int page_match_box(
+ const struct searchinfo_t * quest,
+ const struct list_node_t * candidate
+)
+{
+ int matches;
+ const struct box_t * cb;
+
+ cb = &(candidate->b);
+
+ /* The candidate's x, y and top ( == y - height) values must match the ones
+ * we're searching for. If candidate has a known math axis, it must match.
+ * require_axis says whether we require it to have a known math axis.
+ */
+ matches =
+ interval32_contains(&(quest->x), cb->x) &&
+ interval32_contains(&(quest->y), cb->y) &&
+ interval32_contains(&(quest->top), cb->y - cb->height) &&
+ (
+ (cb->flags & BF_HAS_AXIS) ?
+ interval32_contains(&(quest->axis), cb->axis) :
+ !quest->require_axis
+ ); /* yes these parentheses _are_ neccessary */
+
+ return(matches);
+}
+
+/* Return values:
+ * 0 - no box matches the given criteria
+ * 1 - some boxes match the given criteria, and all of them have the same y
+ * 2 - some boxes match the given criteria, but different y values occur.
+ *
+ * If some boxes match, quest->first_found will point to guess what.
+ */
+static int page_grb_unique_y(
+ struct searchinfo_t * quest
+)
+{
+ interval32_t * range;
+ struct list_node_t * p;
+ struct list_node_t * start_up, * start_down;
+ sint32 y;
+ int have_y = 0;
+
+
+ range = &(quest->searched_y);
+ assert(interval32_contains(range, quest->start->b.y));
+ start_up = quest->test_start ? quest->start : quest->start->prev;
+ start_down = quest->start->next;
+
+ quest->first_found = NULL;
+
+ for(p = start_up; p != NULL; p = p->prev) {
+ if(!interval32_contains(range, p->b.y)) break;
+ if(p->b.flags & BF_SWIMMING) continue;
+ if(page_match_box(quest, p)) {
+ if(have_y) {
+ if(p->b.y != y) {
+ return 2;
+ }
+ }
+ else {
+ quest->first_found = p;
+ y = p->b.y;
+ have_y = 1;
+ }
+ }
+ }
+
+ for(p = start_down; p != NULL; p = p->next) {
+ if(!interval32_contains(range, p->b.y)) break;
+ if(p->b.flags & BF_SWIMMING) continue;
+ if(page_match_box(quest, p)) {
+ if(have_y) {
+ if(p->b.y != y) {
+ return 2;
+ }
+ }
+ else {
+ quest->first_found = p;
+ y = p->b.y;
+ have_y = 1;
+ }
+ }
+ }
+
+ return have_y;
+}
+
+
+enum srestrict_t {
+ SRS_MIN_VAL = -1, /* always first */
+ SRS_REQUIRE_AXIS,
+ SRS_NARROW,
+ SRS_VERY_NARROW,
+ SRS_MOREMATH_SIDE,
+ SRS_LESSMATH_SIDE,
+ SRS_MAX_VAL /* always last */
+};
+
+static int srestrict_conflicts[SRS_MAX_VAL] = {
+ 0, /* SRS_REQUIRE_AXIS */
+ 1 << SRS_VERY_NARROW, /* SRS_NARROW */
+ 1 << SRS_NARROW, /* SRS_VERY_NARROW */
+ 1 << SRS_MOREMATH_SIDE, /* SRS_MOREMATH_SIDE */
+ 1 << SRS_LESSMATH_SIDE /* SRS_LESSMATH_SIDE */
+};
+
+
+/* Recurse through all subsets of the set of search restrictions.
+ * Return values:
+ * 0 - No box conforms to the given set of restrictions. Cut that branch.
+ * 1 - The given restrictions or a further refinement have lead to a unique
+ * y value.
+ * 2 - There were boxes conforming to the given set of restrictions, but
+ * the refinements I've tried haven't lead to a unique y value.
+ */
+static int page_grb_recursion(
+ struct searchinfo_t * quest,
+ struct list_node_t * swimmer,
+ enum srestrict_t try_restrict,
+ int srestricts
+)
+{
+ struct searchinfo_t newquest;
+ int res;
+ struct box_t * pb;
+ sint32 d;
+
+ static char indents[] = " ";
+ char * indent;
+
+ indent = indents + lengthof(indents) + try_restrict - SRS_MAX_VAL;
+
+ pmesg(130, "%sBEGIN page_grb_recursion\n", indent);
+ pmesg(150, "%spage_grb_recursion: try_restrict=%d\n", indent, try_restrict);
+
+ if(try_restrict < 0) {
+ /* The set of applicable search restrictions is already settled.
+ * Really DO something.
+ */
+ res = page_grb_unique_y(quest);
+ pmesg(
+ 150,
+ "%spage_grb_recursion: srestricts=%#4x, unique_y result %d\n",
+ indent,
+ srestricts,
+ res
+ );
+ pmesg(130, "%sEND page_grb_recursion\n", indent);
+ return res;
+ }
+
+ /* Try without imposing a new restriction first */
+ res = page_grb_recursion(quest, swimmer, try_restrict - 1, srestricts);
+ if(res <= 1) {
+ pmesg(130, "%sEND page_grb_recursion\n", indent);
+ return res;
+ }
+
+ /* This hasn't been restrictive enough, try adding "our" restriction. */
+
+ if(srestrict_conflicts[try_restrict] & srestricts) {
+ /* We can't add "our" restriction - conflict. But our caller could
+ * try others.
+ */
+ pmesg(150, "%spage_grb_recursion: tried conflicting restrictions\n", indent);
+ pmesg(130, "%sEND page_grb_recursion\n", indent);
+ return(2);
+ }
+
+ pb = &(swimmer->b);
+ d = ((pb->height + pb->depth) + pb->width) / 20;
+ /* (arithmetic mean of total height and width of swimmer)/10 */
+ newquest = *quest;
+ switch(try_restrict) {
+ case SRS_REQUIRE_AXIS:
+ newquest.require_axis = 1;
+ break;
+ case SRS_NARROW:
+ newquest.x.a = max(newquest.x.a, pb->x - 30*d);
+ newquest.x.b = min(newquest.x.b, pb->x + 40*d);
+ /* 10 for the swimmer itself */
+ break;
+ case SRS_MOREMATH_SIDE:
+ if(glyph_get_hint(pb->glyph) & GH_MOREMATH_LEFT) {
+ newquest.x.b = pb->x + pb->width;
+ }
+ else {
+ newquest.x.a = pb->x;
+ }
+ break;
+ case SRS_LESSMATH_SIDE:
+ if(glyph_get_hint(pb->glyph) & GH_MOREMATH_LEFT) {
+ newquest.x.a = pb->x;
+ }
+ else {
+ newquest.x.b = pb->x + pb->width;
+ }
+ break;
+ case SRS_VERY_NARROW:
+ newquest.x.a = max(newquest.x.a, pb->x - 15*d);
+ newquest.x.b = min(newquest.x.b, pb->x + 25*d);
+ /* 10 for the swimmer itself */
+ break;
+ default:
+ NOTREACHED;
+ }
+
+ res = page_grb_recursion(
+ &newquest,
+ swimmer,
+ try_restrict - 1,
+ srestricts | (1 << try_restrict)
+ );
+
+ quest->first_found = newquest.first_found;
+ pmesg(130, "%sEND page_grb_recursion\n", indent);
+ if(res == 1) return 1;
+ else return 2;
+
+}
+
+
+/* The fonts in "TeX math extension" encoding are somewhat different from
+ * the others. The glyphs are centered on the "math axis" (about the height
+ * of a minus sign above the baseline of the surrounding text/formula). The
+ * y coordinate of the glyphs reference point is mostly meaningless (and in
+ * Knuths cmex fonts the glyphs are "hanging down" from the reference
+ * point). We know the math axis: its the arithmethic mean of (y - height)
+ * and (y + depth). But we have to move the glyph to the _baseline_ for
+ * proper text formatting, hence we need to deduce the baseline somehow.
+ *
+ * TeX gets the height of the math axis above the baseline from a parameter
+ * named axis_height in the font metrics of the currently used math symbol
+ * font. This parameter is only present in TFM files for fonts with "TeX math
+ * symbols" encoding and it is not easy to be sure which axis height was
+ * in effect when the math extension glyph was set, given only the DVI file.
+ *
+ * Therefore, we try another approach first: we look at the surrounding
+ * boxes. If every box in some reasonable neighbourhood that is dissected
+ * by the math axis has the same baseline, this must be the baseline of
+ * the formula. Only if this approach fails we resort to guessing
+ * axis_height by looking at the loaded math symbol fonts.
+ */
+static struct list_node_t * page_guess_reference_box(
+ struct list_node_t * swimmer
+)
+{
+ struct searchinfo_t quest;
+ struct box_t * pb;
+
+ pmesg(50, "BEGIN page_guess_reference_box\n");
+ pmesg(
+ 80,
+ "page_guess_reference_box: y=%ld, axis=%ld\n",
+ swimmer->b.y,
+ swimmer->b.axis
+ );
+
+ pb = &(swimmer->b);
+
+ assert(pb->flags & BF_SWIMMING);
+ assert(pb->flags & BF_HAS_AXIS);
+
+ quest.x.a = SINT32_MIN;
+ quest.x.b = SINT32_MAX;
+ quest.y.a = pb->axis;
+ quest.y.b = pb->y + pb->depth;
+ quest.top.a = SINT32_MIN;
+ quest.top.b = pb->axis;
+ quest.axis.a = pb->axis - 2;
+ quest.axis.b = pb->axis + 2; /* allow small rounding errors */
+ quest.require_axis = 0;
+ quest.test_start = 0;
+ quest.start = swimmer;
+
+
+ if(page_sequential) {
+ sint32 h;
+
+ h = pb->height + pb->depth;
+ quest.searched_y.a = pb->axis - 3*h;
+ quest.searched_y.b = pb->axis + 3*h;
+ }
+ else {
+ quest.searched_y.a = min(pb->axis, pb->y);
+ quest.searched_y.b = pb->y + pb->depth;
+ }
+
+ if(page_grb_recursion(&quest, swimmer, SRS_MAX_VAL - 1, 0) == 1) {
+ pmesg(50, "END page_guess_reference_box\n");
+ return quest.first_found;
+ }
+ else {
+ pmesg(50, "END page_guess_reference_box\n");
+ return NULL;
+ }
+
+}
+
+
+void page_adjust_texmext(void)
+{
+ struct list_node_t * p, * s, * ref;
+ sint32 new_y, delta;
+
+ pmesg(50, "BEGIN page_adjust_texmext\n");
+
+ if(!page_has_texmext) {
+ pmesg(80, "nothing to do\n");
+ pmesg(50, "END page_adjust_texmext\n");
+ return;
+ }
+
+ for (p = list_head; p != 0; p = s) {
+ s = p->next;
+ /* p-> is a moving target */
+
+ if (!(p->b.flags & BF_ON_AXIS)) continue;
+ assert(p->b.flags & BF_HAS_AXIS);
+ assert(p->b.flags & BF_SWIMMING);
+
+ pmesg(
+ 80,
+ "page_adjust_texmext: glyph=%#6lx, y=%ld\n",
+ p->b.glyph,
+ p->b.y
+ );
+
+ if(p->b.axis_height > 0) {
+ ref = NULL;
+ pmesg(
+ 80,
+ "page_adjust_texmext: known axis_height=%ld\n",
+ p->b.axis_height
+ );
+ }
+ else {
+ ref = page_guess_reference_box(p);
+ pmesg(
+ 80,
+ "page_adjust_texmext:%s reference box found\n",
+ ref ? "" : " no"
+ );
+ }
+
+ if(ref != NULL) new_y = ref->b.y;
+ else new_y = p->b.axis + abs(p->b.axis_height);
+ pmesg(80, "page_adjust_texmext: new_y=%ld\n", new_y);
+
+ delta = new_y - p->b.y;
+ p->b.y = new_y;
+ p->b.height += delta;
+ p->b.depth -= delta;
+ p->b.axis_height = p->b.y - p->b.axis;
+ p->b.flags &= ~(BF_SWIMMING | BF_ON_AXIS);
+
+ if(!page_sequential) bubble_node(p);
+
+ }
+
+ pmesg(50, "END page_adjust_texmext\n");
+}
+
+
+static struct list_node_t * page_find_lowest_box(struct searchinfo_t * quest)
+{
+ interval32_t * range;
+ struct list_node_t * p, * low;
+ struct list_node_t * start_up, * start_down;
+
+ range = &(quest->searched_y);
+ assert(interval32_contains(range, quest->start->b.y));
+ start_up = quest->test_start ? quest->start : quest->start->prev;
+ start_down = quest->start->next;
+
+ quest->first_found = NULL;
+ low = NULL;
+
+ for(p = start_up; p != NULL; p = p->prev) {
+ if(!interval32_contains(range, p->b.y)) break;
+ if(p->b.flags & BF_SWIMMING) continue;
+ if(page_match_box(quest, p)) {
+ if(low == NULL || p->b.y > low->b.y) low = p;
+ }
+ }
+
+ for(p = start_down; p != NULL; p = p->next) {
+ if(!interval32_contains(range, p->b.y)) break;
+ if(p->b.flags & BF_SWIMMING) continue;
+ if(page_match_box(quest, p)) {
+ if(low == NULL || p->b.y > low->b.y) low = p;
+ }
+ }
+
+ quest->first_found = low;
+ return low;
+}
+
+
+/* TeX's radical signs are hanging down from their reference point. We move
+ * them to the baseline of the lowest glyph in the radicant (that's where
+ * the bottom tip ought to be) or, if there's no radicant, to the y position
+ * of the bottom tip.
+ */
+void page_adjust_radicals(void)
+{
+ struct list_node_t * p, * s, * lowest;
+ sint32 new_y, delta;
+ struct searchinfo_t quest;
+
+ pmesg(50, "BEGIN page_adjust_radicals\n");
+
+ if(!page_has_radicals) {
+ pmesg(80, "nothing to do\n");
+ pmesg(50, "END page_adjust_radicals\n");
+ return;
+ }
+
+ for (p = list_head; p != 0; p = s) {
+ s = p->next;
+ /* p-> is a moving target */
+
+ if (!(p->b.flags & BF_RADICAL)) continue;
+ assert(p->b.flags & BF_SWIMMING);
+
+ pmesg(
+ 80,
+ "page_adjust_radicals: glyph=%#6lx, y=%ld\n",
+ p->b.glyph,
+ p->b.y
+ );
+
+ /* put the radical on the baseline of the lowest box in the radicant */
+ quest.x.a = p->b.x;
+ quest.x.b = SINT32_MAX;
+ /* FIXME: Once we have rudimentary rules support, we can search
+ * for the rule forming the radicals top and take its length as
+ * the width of the radicant.
+ */
+ quest.y.a = p->b.y - p->b.height;
+ quest.y.b = p->b.y + p->b.depth;
+ quest.top = quest.y;
+ quest.axis.a = SINT32_MIN;
+ quest.axis.b = SINT32_MAX;
+ quest.require_axis = 0;
+ quest.test_start = 0;
+ quest.start = p;
+
+ if(page_sequential) {
+ sint32 h;
+
+ h = p->b.height + p->b.depth;
+ quest.searched_y.a = p->b.y - h;
+ quest.searched_y.b = p->b.y + 2*h;
+ }
+ else {
+ quest.searched_y = quest.y;
+ }
+
+ lowest = page_find_lowest_box(&quest);
+ pmesg(
+ 80,
+ "page_adjust_radicals:%s lowest box found\n",
+ lowest ? "" : " no"
+ );
+
+ if(lowest != NULL) new_y = lowest->b.y;
+ else new_y = p->b.y + p->b.depth;
+ pmesg(80, "page_adjust_radicals: new_y=%ld\n", new_y);
+
+ delta = new_y - p->b.y;
+ p->b.y = new_y;
+ p->b.height += delta;
+ p->b.depth -= delta;
+ p->b.flags &= ~(BF_SWIMMING | BF_RADICAL);
+
+ if(!page_sequential) bubble_node(p);
+
+ }
+
+ pmesg(50, "END page_adjust_radicals\n");
+}
diff --git a/dviware/catdvi/page.d b/dviware/catdvi/page.d
new file mode 100644
index 0000000000..e6aa050036
--- /dev/null
+++ b/dviware/catdvi/page.d
@@ -0,0 +1,2 @@
+page.o page.d : page.c page2.h page.h bytesex.h pageref.h util.h glyphops.h \
+ layout.h
diff --git a/dviware/catdvi/page.h b/dviware/catdvi/page.h
new file mode 100644
index 0000000000..15626af569
--- /dev/null
+++ b/dviware/catdvi/page.h
@@ -0,0 +1,44 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2001 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef PAGE_H
+#define PAGE_H
+
+#include "bytesex.h"
+#include "pageref.h"
+
+typedef sint32 glyph_t, font_t;
+
+extern int page_sequential;
+extern int page_list_numbers;
+extern struct pageref_t page_start_output, page_last_output;
+
+void page_begin(sint32 count0);
+
+/* glyph is Unicode value */
+void page_set_glyph(
+ font_t font, glyph_t glyph,
+ sint32 width, sint32 height, sint32 depth, sint32 axis_height,
+ sint32 x, sint32 y
+);
+
+/* page_end will output the resulting page */
+void page_end(void);
+
+#endif /* PAGE_H */
diff --git a/dviware/catdvi/page2.h b/dviware/catdvi/page2.h
new file mode 100644
index 0000000000..deb39c6c72
--- /dev/null
+++ b/dviware/catdvi/page2.h
@@ -0,0 +1,96 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2000-02 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Files that need some of the internals of page.c exposed should include
+ * this header rather than page.h
+ */
+
+#ifndef PAGE2_H
+#define PAGE2_H
+
+#include "page.h"
+
+/* A page is modeled as an ordered doubly-linked list of boxes (x, y,
+ glyph), where the ordering is left-to-right top-to-bottom. */
+
+enum box_flag_t {
+ BF_SWIMMING = 1 << 0,
+ /* (x, y) != (left border, baseline). We need to
+ * move this one to the "logically right" place.
+ */
+ BF_HAS_AXIS = 1 << 1,
+ /* box_t.axis is valid, i.e. we know where the math
+ * axis passes through this box.
+ */
+ BF_ON_AXIS = 1 << 2,
+ /* This box is centered on the math axis (e.g. the
+ * big operators). Implies BF_SWIMMING.
+ */
+ BF_RADICAL = 1 << 3,
+ /* This is a radical sign (and hence "hanging down"
+ * from the y coordinate). Implies BF_SWIMMING.
+ */
+ BF_DIACRITIC = 1 << 4
+ /* This is a diacritical mark. Often its baseline is vertically
+ * displaced against the baseline of the glyph it should accent
+ * because the combination looks better this way).
+ * Implies BF_SWIMMING.
+ */
+};
+
+struct box_t {
+ sint32 x;
+ sint32 y;
+ sint32 axis;
+
+ sint32 width;
+ sint32 height;
+ sint32 depth;
+ sint32 axis_height; /* The TeX font parameter. <= 0 if unknown. */
+
+ glyph_t glyph;
+ font_t font;
+ enum box_flag_t flags;
+};
+
+typedef struct list_node_t list_node_t;
+struct list_node_t {
+ struct box_t b;
+ struct list_node_t * prev;
+ struct list_node_t * next;
+};
+
+/* List support variables. Note that most insertions happen near the
+ previous insertion, so it's beneficial to keep a pointer to the
+ last inserted node. */
+extern struct list_node_t * list_head;
+extern struct list_node_t * list_tail;
+extern struct list_node_t * list_latest; /* Node that was inserted last. */
+
+
+/* normalize placement of combining diacritics */
+void page_adjust_diacritics(void);
+
+/* normalize placement of big operators etc. */
+void page_adjust_texmext(void);
+
+/* normalize placement of radicals */
+void page_adjust_radicals(void);
+
+#endif /* PAGE2_H */
diff --git a/dviware/catdvi/pageref.c b/dviware/catdvi/pageref.c
new file mode 100644
index 0000000000..33358ddb5a
--- /dev/null
+++ b/dviware/catdvi/pageref.c
@@ -0,0 +1,161 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2001 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "pageref.h"
+#include "util.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+pageref_flavour_t pageref_parse(pageref_t * this, const char * pagespec)
+{
+ char * tail, * colon;
+ pageref_t r = {0, 0, 0, PRF_INVALID};
+ sint32 * field;
+
+ colon = strchr(pagespec, ':');
+
+ if(pagespec[0] == '=' || pagespec[0] == '@') {
+ /* physical page */
+ ++pagespec;
+ r.flavour = PRF_PHYSICAL;
+ field = &r.physical;
+ }
+ else if(colon != NULL) {
+ /* chapter:count0 */
+ if(pagespec[0] == ':') return PRF_INVALID;
+ r.chapter = strtol(pagespec, &tail, 10);
+ if(tail != colon) return PRF_INVALID;
+ pagespec = colon + 1;
+ r.flavour = PRF_COUNT0_CHAPTER;
+ field = &r.count0;
+ }
+ else {
+ /* count0 without chapter */
+ r.flavour = PRF_COUNT0;
+ field = &r.count0;
+ }
+
+ if(*pagespec == 0) return PRF_INVALID;
+ *field = strtol(pagespec, &tail, 10);
+ if(*tail != 0) return PRF_INVALID;
+ *this = r;
+ return r.flavour;
+}
+
+
+/* Return value like strcmp */
+static int sint32_cmp(sint32 a, sint32 b)
+{
+ if (a > b) return 1;
+ else if (a < b) return -1;
+ else return 0;
+}
+
+int pageref_count0_cmp(sint32 a, sint32 b)
+{
+ if ((a < 0) && (b < 0)) return sint32_cmp(-a, -b);
+ else return sint32_cmp(a, b);
+ /* if only one of them is negative we get it right the usual way */
+}
+
+int pageref_cmp(const struct pageref_t * a, const struct pageref_t * b)
+{
+ enum pageref_flavour_t fa, fb;
+ int r;
+
+ fa = a->flavour;
+ fb = b->flavour;
+
+ /* flavour PRF_COMPLETE is compatible with everything */
+ if (fa == PRF_COMPLETE) {
+ if (fb == PRF_COMPLETE) {
+ /* OK, we choose physical pages then */
+ fa = PRF_PHYSICAL;
+ fb = PRF_PHYSICAL;
+ }
+ else fa = fb;
+ }
+ else if (fb == PRF_COMPLETE) fb = fa;
+
+ if (fa != fb)
+ panic("pageref_cmp: incompatible page reference flavours\n");
+
+ switch(fa) {
+ case PRF_INVALID:
+ panic("pageref_cmp: invalid page reference\n");
+ break;
+ case PRF_PHYSICAL:
+ return sint32_cmp(a->physical, b->physical);
+ break;
+ case PRF_COUNT0:
+ return pageref_count0_cmp(a->count0, b->count0);
+ break;
+ case PRF_COUNT0_CHAPTER:
+ r = sint32_cmp(a->chapter, b->chapter);
+ if (r != 0) return r;
+ else return pageref_count0_cmp(a->count0, b->count0);
+ break;
+ default:
+ panic("pageref_cmp: unknown page reference flavour\n");
+ }
+ NOTREACHED;
+ return 0; /* get rid of pointless compiler warning */
+}
+
+void pageref_print(pageref_t * this, FILE * f)
+{
+ switch(this->flavour) {
+ case PRF_INVALID:
+ fputs("INVALID\n", f);
+ break;
+ case PRF_PHYSICAL:
+ fprintf(
+ f,
+ "physical=%5ld\n",
+ this->physical
+ );
+ break;
+ case PRF_COUNT0:
+ fprintf(
+ f,
+ "count0=%5ld\n",
+ this->count0
+ );
+ break;
+ case PRF_COUNT0_CHAPTER:
+ fprintf(
+ f,
+ "count0=%5ld, chapter=%5ld\n",
+ this->count0,
+ this->chapter
+ );
+ break;
+ case PRF_COMPLETE:
+ fprintf(
+ f,
+ "physical=%5ld, count0=%5ld, chapter=%5ld\n",
+ this->physical,
+ this->count0,
+ this->chapter
+ );
+ break;
+ default:
+ fputs("UNKNOWN\n", f);
+ }
+}
diff --git a/dviware/catdvi/pageref.d b/dviware/catdvi/pageref.d
new file mode 100644
index 0000000000..8f6fdee845
--- /dev/null
+++ b/dviware/catdvi/pageref.d
@@ -0,0 +1 @@
+pageref.o pageref.d : pageref.c pageref.h bytesex.h util.h
diff --git a/dviware/catdvi/pageref.h b/dviware/catdvi/pageref.h
new file mode 100644
index 0000000000..0d912e5e9f
--- /dev/null
+++ b/dviware/catdvi/pageref.h
@@ -0,0 +1,62 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2001 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef PAGEREF_H
+#define PAGEREF_H
+
+#include "bytesex.h"
+
+enum pageref_flavour_t {
+ PRF_INVALID = 0,
+ PRF_PHYSICAL,
+ PRF_COUNT0,
+ PRF_COUNT0_CHAPTER,
+ PRF_COMPLETE
+};
+typedef enum pageref_flavour_t pageref_flavour_t;
+
+typedef struct pageref_t {
+ sint32 physical;
+ sint32 count0;
+ sint32 chapter;
+ enum pageref_flavour_t flavour;
+} pageref_t;
+
+/* Make up a pageref_t from a string (syntax documented in catdvi manpage).
+ * Return flavour (!= 0 if no error).
+ * If an error occurs, we return PRF_INVALID (== 0) and do NOT modify *this.
+ */
+pageref_flavour_t pageref_parse(pageref_t * this, const char * pagespec);
+
+/* \count0 usually holds the TeX page number. Plain TeX uses negative count0
+ * values for roman-numbered frontmatter (preface, toc, etc.) so we have
+ * the integers ordered like -1 < -2 < -3 < ... < 0 < 1 < 2 < 3 < ...
+ * (0 shouldn't appear as page number though).
+ *
+ * Compare two count0 values wrt this ordering. Return value like strcmp.
+ */
+int pageref_count0_cmp(sint32 a, sint32 b);
+
+/* Compare two page references, given their flavours are compatible.
+ * Return value like strcmp.
+ */
+int pageref_cmp(const struct pageref_t * a, const struct pageref_t * b);
+
+void pageref_print(pageref_t * this, FILE * f);
+
+#endif /* PAGEREF_H */
diff --git a/dviware/catdvi/pse2unic.c b/dviware/catdvi/pse2unic.c
new file mode 100644
index 0000000000..05d6691e8a
--- /dev/null
+++ b/dviware/catdvi/pse2unic.c
@@ -0,0 +1,428 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999, 2000 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2001-2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "util.h"
+
+#define TOK_MAXLEN 256
+#define TBL_LEN 256
+
+static int lineno = 1;
+static int lpp; /* table rows per page in the report */
+
+typedef unsigned long uint32;
+
+struct adobe2unicode_t {
+ char const * adobe;
+ uint32 unicode;
+};
+#include "adobetbl.h"
+
+/* For each encoding, we want to present a sample font with the respective
+ * encoding in the report. Therefore, we have to know:
+ * - what we have to put into the preamble to use the sample font
+ * - a LaTeX command to activate the sample font
+ * - an appropriate number of lines per page for the report (some fonts tend
+ * to be large).
+ * We have reasonable defaults for unlisted encodings.
+ */
+static struct enc_sample_t {
+ char * enc_name;
+ char * preamble_cmd;
+ char * latex_cmd;
+ int lpp;
+} enc_samples[] = {
+ {"OT1Encoding", "", "\\usefont{OT1}{cmr}{m}{n}", 32},
+ {"OT1woflEncoding", "", "\\usefont{OT1}{cmr}{m}{sc}", 32},
+ {"CorkEncoding", "", "\\usefont{T1}{cmr}{m}{n}", 32},
+ {"TeXMathItalicEncoding", "", "\\usefont{OML}{cmm}{m}{it}", 32},
+ {"TeXMathSymbolEncoding", "", "\\usefont{OMS}{cmsy}{m}{n}", 32},
+ {"TeXMathExtensionEncoding", "", "\\usefont{OMX}{cmex}{m}{n}", 16},
+ {"TeXTypewriterTextEncoding", "", "\\usefont{OT1}{cmtt}{m}{n}", 32},
+ {
+ "EurosymEncoding",
+ "\\usepackage{eurosym}",
+ "\\usefont{U}{eurosym}{m}{n}",
+ 32
+ },
+ {
+ "TextCompanionEncoding",
+ "\\usepackage{textcomp}",
+ "\\usefont{TS1}{cmr}{m}{n}",
+ 32
+ },
+ {
+ "Marvosym1998Encoding",
+ "\\usepackage{marvosym}",
+ "\\usefont{OT1}{mvs}{m}{n}",
+ 32
+ },
+ {
+ "Marvosym2000Encoding",
+ "\\usepackage{marvosym}",
+ "\\usefont{OT1}{mvs}{m}{n}",
+ 32
+ },
+ {
+ "LaTeXSymbolsEncoding",
+ "\\usepackage{latexsym}",
+ "\\usefont{U}{lasy}{m}{n}",
+ 32
+ },
+ {
+ "BlackboardEncoding",
+ "\\usepackage{bbm}",
+ "\\usefont{U}{bbm}{m}{n}",
+ 32
+ },
+ {
+ "EulerFrakturEncoding",
+ "\\usepackage{amssymb}",
+ "\\usefont{U}{euf}{m}{n}",
+ 32
+ },
+ {
+ "AMSSymbolsAEncoding",
+ "\\usepackage{amssymb}",
+ "\\usefont{U}{msa}{m}{n}",
+ 32
+ },
+ {
+ "AMSSymbolsBEncoding",
+ "\\usepackage{amssymb}",
+ "\\usefont{U}{msb}{m}{n}",
+ 32
+ },
+ {
+ "EulerExtensionEncoding",
+ "\\usepackage{amssymb}",
+ "\\usefont{U}{euex}{m}{n}",
+ 32
+ },
+ /* END OF TABLE */
+ {NULL, NULL, NULL, 32}
+};
+
+/* Make extensive mixture of fputs and fprintf slightly more readable */
+#define froputs(f, s) fputs(s, f)
+
+
+static char enc_name[TOK_MAXLEN]; /* name of the current encoding */
+
+static int my_getc(FILE * fp)
+{
+ int c;
+
+ c = getc(fp);
+
+ if (c == '\n') lineno++;
+
+ return c;
+}
+
+static void my_ungetc(int c, FILE * fp)
+{
+ if (c == '\n') lineno--;
+
+ ungetc(c, fp);
+}
+
+/* Read a token from a PS ENC file */
+static unsigned char const * get_token(FILE * fp, char const * fname)
+{
+ int c;
+ unsigned char ch;
+ static unsigned char tok[TOK_MAXLEN];
+ size_t i = 0;
+
+ /* Ignore leading whitespace & comments. */
+ do {
+ c = my_getc(fp); ch = c;
+ if (c == EOF) return (unsigned char const *) "";
+
+ /* Ignore comment. */
+ if (ch == '%') {
+ do {
+ c = my_getc(fp); ch = c;
+ if (c == EOF) return (unsigned char const *) "";
+ } while (ch != '\n');
+ }
+
+ } while (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n');
+
+ my_ungetc(c, fp);
+
+ while (1) {
+ c = my_getc(fp); ch = c;
+
+ if (ch == ' ' || ch == '\t' || ch == '\r'
+ || ch == '\n' || c == EOF) {
+ tok[i] = 0;
+ return tok;
+ }
+
+ if (i == TOK_MAXLEN) {
+ panic("token too long while reading %s\n", fname);
+ }
+
+ tok[i++] = c;
+ }
+ NOTREACHED;
+}
+
+static int a2u_cmp(void const * av, void const * bv)
+{
+ struct adobe2unicode_t const * a = av;
+ struct adobe2unicode_t const * b = bv;
+
+ return strcmp(a->adobe, b->adobe);
+}
+
+/* Warn about some easily made mistakes in adobetbl.h */
+static void check_adobetbl(void)
+{
+ struct adobe2unicode_t * p, * last;
+ int cmp;
+
+ last = adobe2unicode + lengthof(adobe2unicode) - 1;
+ for(p = adobe2unicode; p < last; ++p) {
+
+ cmp = a2u_cmp(p, p+1);
+ if(cmp == 0) {
+ warning("duplicate entry `%s' in adobetbl.h\n", p->adobe);
+ }
+ else if(cmp > 0) {
+ warning(
+ "adobetbl.h not sorted: `%s' before `%s'\n",
+ p->adobe,
+ (p+1)->adobe
+ );
+ }
+
+ }
+}
+
+
+/* Look a name up in the translation table. */
+static uint32 lookup(unsigned char const * name, char const * fname)
+{
+ struct adobe2unicode_t key;
+ struct adobe2unicode_t * datum;
+
+ key.adobe = (char const *) name;
+
+ datum = bsearch(&key, adobe2unicode,
+ sizeof(adobe2unicode) / sizeof(adobe2unicode[0]),
+ sizeof(adobe2unicode[0]),
+ a2u_cmp);
+
+ if (datum == 0) {
+ warning("%s:%i: Unknown Adobe glyph name `%s'\n",
+ fname, lineno, name);
+ return 0;
+ }
+
+ return datum->unicode;
+}
+
+/* Write the conversion report header */
+static void report_header(FILE * rp)
+{
+ time_t now;
+ struct enc_sample_t * p;
+ char * cmd;
+
+ time(&now);
+
+ /* find the LaTeX command for the right sample font */
+ for(p = enc_samples; p->enc_name != NULL; ++p) {
+ if(strcmp(p->enc_name, enc_name) == 0) break;
+ }
+ cmd = p->latex_cmd;
+ lpp = p->lpp;
+
+ froputs(rp, "% AUTOMATICALLY GENERATED - DO NOT EDIT.\n");
+ froputs(rp, "\n");
+ froputs(rp, "\\documentclass{article}\n");
+ froputs(rp, "\n");
+ froputs(rp, "\\title{\n");
+ froputs(rp, " \\texttt{catdvi}'s Mapping of the\n");
+ fprintf(rp, " `%s' Font~Encoding to Unicode\n", enc_name);
+ froputs(rp, "}\n");
+ froputs(rp, "\\author{\\texttt{pse2unic}}\n");
+ fprintf(rp, "\\date{%s}\n", ctime(&now));
+ froputs(rp, "\n");
+ if(p->preamble_cmd != NULL) fprintf(rp, "%s\n", p->preamble_cmd);
+ froputs(rp, "\n");
+ if(cmd != NULL) fprintf(
+ rp,
+ "\\newcommand{\\sample}[1]{{%s\\symbol{#1}}}\n",
+ cmd
+ );
+ else froputs(rp, "\\newcommand{\\sample}[1]{N/A}\n");
+ froputs(rp, "\n");
+ froputs(rp, "\\begin{document}\n");
+ froputs(rp, "\n");
+ froputs(rp, "\\maketitle\n");
+ froputs(rp, "\n");
+}
+
+/* Print one conversion table line in the report */
+static void report_line(
+ FILE * rp,
+ int code,
+ unsigned char const * name,
+ uint32 unicode
+)
+{
+ if(code % lpp == 0) {
+ froputs(rp, "\\begin{tabular}{r|l|l|r}\n");
+ froputs(rp, "code point & sample shape & internal name & Unicode\\\\\n");
+ froputs(rp, "\\hline\n");
+ }
+
+ fprintf(
+ rp,
+ "\\texttt{%#04x} & \\sample{%d} & \\verb/%s/ & ",
+ code,
+ code,
+ name
+ );
+ if(unicode != 0) {
+ fprintf(rp, "\\texttt{U+%04lX}\\\\\n", unicode);
+ }
+ else {
+ froputs(rp, "N/A\\\\\n");
+ }
+ froputs(rp, "\\hline\n");
+
+ if((code % lpp == lpp - 1) || (code == TBL_LEN - 1)) {
+ froputs(rp, "\\end{tabular}\n");
+ froputs(rp, "\n\\newpage\n");
+ }
+}
+
+/* Dump the conversion report footer */
+static void report_footer(FILE * rp)
+{
+ froputs(rp, "\n");
+ froputs(rp, "\\end{document}\n");
+}
+
+/* Parse a PS ENC file named fname.
+ * Return a statically allocated table of
+ * TBL_LEN uint32's indexed by input octets.
+ * As a byproduct, write a (LaTeX format) report about the PS ENC file
+ * to a file named rname.
+ */
+static uint32 * parse_enc(char const * fname, char const * rname)
+{
+ FILE * fp, * rp;
+ unsigned char const * tok;
+ static uint32 tbl[TBL_LEN];
+ int i;
+ uint32 u;
+
+ fp = fopen(fname, "r");
+ if (fp == 0) panic("unable to open %s: %s\n", fname, strerror(errno));
+ rp = fopen(rname, "w");
+ if (rp == 0) panic("Unable to open `%s' for writing: %s.\n",
+ rname, strerror(errno));
+
+ lineno = 1;
+
+ tok = get_token(fp, fname);
+ if (tok[0] != '/') panic("expected a literal, got `%s'\n", tok);
+
+ strcpy(enc_name, (char const *) (tok+1));
+
+ tok = get_token(fp, fname);
+ if (! (tok[0] == '[' && tok[1] == 0)) {
+ panic("expected `[', got `%s'\n", tok);
+ }
+ report_header(rp);
+
+ for (i = 0; i < TBL_LEN; i++) {
+ tok = get_token(fp, fname);
+
+ if (tok[0] != '/') panic("expected a literal, got `%s'\n", tok);
+
+ u = lookup(tok+1, fname);
+ tbl[i] = u ? u : 0x003f; /* QUESTION MARK */
+ report_line(rp, i, tok+1, u);
+ }
+
+ tok = get_token(fp, fname);
+ if (! (tok[0] == ']' && tok[1] == 0)) {
+ panic("expected `]', got `%s'\n", tok);
+ }
+
+ report_footer(rp);
+ if (fclose(rp) != 0) panic("Unable to write `%s': %s.\n",
+ rname, strerror(errno));
+ fclose(fp);
+ return tbl;
+}
+
+int main(int argc, char * argv[])
+{
+ FILE * fp;
+ uint32 * tbl;
+ int i;
+ char * progname = argv[0];
+
+ msglevel = 10;
+
+ if (argc == 5 && strcmp(argv[1], "-w") == 0) {
+ suppress_warnings = 1;
+ --argc;
+ ++argv;
+ }
+
+ if (argc != 4) panic("Usage error!\n");
+
+ check_adobetbl();
+
+ tbl = parse_enc(argv[1], argv[3]);
+
+
+ fp = fopen(argv[2], "w");
+ if (fp == 0) panic("Unable to open `%s' for writing: %s.\n",
+ argv[2], strerror(errno));
+ fprintf(fp, "static sint32 %s[%i] = {\n", enc_name, TBL_LEN);
+ for (i = 0; i < TBL_LEN; i++) {
+ fprintf(fp, " 0x%04lx,\n", tbl[i]);
+ }
+ fputs("};\n", fp);
+
+ if (fclose(fp) != 0) panic("Unable to write `%s': %s.\n",
+ argv[2], strerror(errno));
+
+ if (suppress_warnings && num_warnings > 0) {
+ fprintf(stderr, "%s: suppressed %i warnings\n",
+ progname, num_warnings);
+ }
+
+ return 0;
+}
diff --git a/dviware/catdvi/pse2unic.d b/dviware/catdvi/pse2unic.d
new file mode 100644
index 0000000000..2f6abbad8d
--- /dev/null
+++ b/dviware/catdvi/pse2unic.d
@@ -0,0 +1 @@
+pse2unic.o pse2unic.d : pse2unic.c util.h adobetbl.h
diff --git a/dviware/catdvi/readdvi.c b/dviware/catdvi/readdvi.c
new file mode 100644
index 0000000000..0e47f22565
--- /dev/null
+++ b/dviware/catdvi/readdvi.c
@@ -0,0 +1,444 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl>
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * For a thorough description of the DVI file format, see the dvitype literate
+ * program as distributed e.g. with teTeX and
+ * "The DVI Driver Standard, Level 0" available from your neighbourhood CTAN
+ * site.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include "fntenc.h"
+#include "fontinfo.h"
+#include "outenc.h"
+#include "page.h"
+#include "readdvi.h"
+#include "regsta.h"
+#include "util.h"
+
+uint32 magnification = 1000;
+
+#define COMMENT_MAXLEN 16384
+
+
+#define DVI_set_char_0 0
+#define DVI_set_char_127 127
+#define DVI_set1 128
+#define DVI_set2 129
+#define DVI_set3 130
+#define DVI_set4 131
+#define DVI_set_rule 132
+#define DVI_put1 133
+#define DVI_put2 134
+#define DVI_put3 135
+#define DVI_put4 136
+#define DVI_put_rule 137
+#define DVI_nop 138
+#define DVI_bop 139
+#define DVI_eop 140
+#define DVI_push 141
+#define DVI_pop 142
+#define DVI_right1 143
+#define DVI_right2 144
+#define DVI_right3 145
+#define DVI_right4 146
+#define DVI_w0 147
+#define DVI_w1 148
+#define DVI_w2 149
+#define DVI_w3 150
+#define DVI_w4 151
+#define DVI_x0 152
+#define DVI_x1 153
+#define DVI_x2 154
+#define DVI_x3 155
+#define DVI_x4 156
+#define DVI_down1 157
+#define DVI_down2 158
+#define DVI_down3 159
+#define DVI_down4 160
+#define DVI_y0 161
+#define DVI_y1 162
+#define DVI_y2 163
+#define DVI_y3 164
+#define DVI_y4 165
+#define DVI_z0 166
+#define DVI_z1 167
+#define DVI_z2 168
+#define DVI_z3 169
+#define DVI_z4 170
+#define DVI_fnt_num_0 171
+#define DVI_fnt_num_1 172
+#define DVI_fnt_num_63 234
+#define DVI_fnt1 235
+#define DVI_fnt2 236
+#define DVI_fnt3 237
+#define DVI_fnt4 238
+#define DVI_xxx1 239
+#define DVI_xxx2 240
+#define DVI_xxx3 241
+#define DVI_xxx4 242
+#define DVI_fnt_def1 243
+#define DVI_fnt_def2 244
+#define DVI_fnt_def3 245
+#define DVI_fnt_def4 246
+#define DVI_pre 247
+#define DVI_post 248
+#define DVI_post_post 249
+
+
+static double conversion = 1; /* conversion factor DVI units --> 10^-7 m */
+
+static void output_glyph(sint32 font, sint32 glyph)
+{
+ static sint32 currfont = -1;
+ static int currfenc = -1;
+ static fix_word_t last_axis_height = double2fw(0.25);
+ static sint32 curr_math_axis;
+
+ if (font != currfont) {
+ fix_word_t new_axis_height;
+
+ currfont = font;
+ currfenc = find_fntenc(font_enc(font), font_family(font));
+ new_axis_height = font_axis_height(font);
+
+ if(new_axis_height > 0) {
+ /* This font really has axis_height defined */
+ last_axis_height = new_axis_height;
+ curr_math_axis = font_scale_fw(font, new_axis_height);
+ }
+ else {
+ /* Since the axis height is usually about constant in a
+ * whole family of fonts, we have a good chance that
+ * scaling up the last known one to the current font
+ * size works. But we make the value negative to mark
+ * it as bogus.
+ */
+ curr_math_axis = - font_scale_fw(font, last_axis_height);
+ }
+ }
+
+ dump_regs(86);
+ pmesg(85, "OUTPUT_GLYPH: font %li, glyph %li, H %li, V %li\n",
+ font, glyph, get_reg(REGISTER_H), get_reg(REGISTER_V));
+
+ page_set_glyph(font, fnt_convert(currfenc, glyph),
+ font_char_width(currfont, glyph),
+ font_char_height(currfont, glyph),
+ font_char_depth(currfont, glyph),
+ curr_math_axis,
+ get_reg(REGISTER_H), get_reg(REGISTER_V));
+}
+
+void process_file(FILE *f) {
+ byte b;
+ sint32 sc;
+ uint32 num, den, c;
+ sint32 currfont = 0;
+ char comment[COMMENT_MAXLEN+1];
+
+ /* Process the preamble */
+ efread(&b, 1, 1, f, "Could not read initial byte\n");
+ if (b != DVI_pre)
+ panic("Does not start with preamble\n");
+ pmesg(100, "Read preamble byte\n");
+
+ efread(&b, 1, 1, f, "Could not read second byte\n");
+ if (b != 2)
+ panic("Identification byte wrong\n");
+ pmesg(100, "Read identification byte\n");
+
+ num = u_readbigendiannumber(4, f);
+ pmesg(80, "Read numerator: %li\n", num);
+
+ den = u_readbigendiannumber(4, f);
+ pmesg(80, "Read denominator: %li\n", den);
+
+ conversion = ((double) num) / ((double) den);
+
+ magnification = s_readbigendiannumber(4, f);
+ pmesg(80, "Read magnification: %li\n", magnification);
+
+ efread(&b, 1, 1, f, "Could not read comment length\n");
+ pmesg(100, "Read comment length: %i\n", b);
+ efread(comment, 1, b, f, "Could not read comment\n");
+ comment[b+1] = '\0';
+ pmesg(80, "Read comment: `%s'\n", comment);
+
+ /* Core processing loop: read an opcode byte, and process its
+ * arguments (if any) */
+ while(1) {
+ efread(&b, 1, 1, f, "Failed to read opcode byte\n");
+
+ if (b == DVI_post)
+ break;
+
+ if ((b >= DVI_set_char_0) && (b <= DVI_set_char_127)) {
+ c = b;
+ pmesg(80, "[set char %i: %c]\n", b-DVI_set_char_0, (unsigned char) (b-DVI_set_char_0));
+ output_glyph(currfont, b-DVI_set_char_0);
+ add_reg(REGISTER_H, font_char_width(currfont, b-DVI_set_char_0));
+ continue;
+ }
+
+ if ((b >= DVI_set1) && (b <= DVI_set3)) {
+ sc = u_readbigendiannumber(b-DVI_set1+1, f);
+ output_glyph(currfont, sc);
+ add_reg(REGISTER_H, font_char_width(currfont, sc));
+ pmesg(80, "[set char%i: %lX]\n", b-DVI_set1+1, c);
+ continue;
+ }
+
+ if (b == DVI_set4) {
+ sc = u_readbigendiannumber(b-DVI_set1+1, f);
+ output_glyph(currfont, sc);
+ add_reg(REGISTER_H, font_char_width(currfont, sc));
+ pmesg(80, "[set char%i: %lX]\n", b-DVI_set1+1, sc);
+ continue;
+ }
+
+ if (b == DVI_set_rule) {
+ sint32 rule_width, rule_height;
+ rule_height = s_readbigendiannumber(4, f);
+ rule_width = s_readbigendiannumber(4, f);
+ add_reg(REGISTER_H, rule_width);
+ pmesg(
+ 80,
+ "[setrule: height=%li, width=%li]\n",
+ rule_height,
+ rule_width
+ );
+ continue;
+ }
+
+ if ((b >= DVI_put1) && (b <= DVI_put4)) {
+ c = u_readbigendiannumber(b-DVI_put1+1, f);
+ pmesg(80, "[put char%i: %lX]\n", b-DVI_put1+1, c);
+ continue;
+ }
+
+ if (b == DVI_put_rule) {
+ sint32 rule_width, rule_height;
+ rule_height = s_readbigendiannumber(4, f);
+ rule_width = s_readbigendiannumber(4, f);
+ pmesg(
+ 80,
+ "[putrule: height=%li, width=%li]\n",
+ rule_height,
+ rule_width
+ );
+ continue;
+ }
+
+ if (b == DVI_nop) {
+ pmesg(80, "[nop]\n");
+ continue;
+ }
+
+ if (b == DVI_bop) {
+ sint32 count0;
+
+ count0 = s_readbigendiannumber(4, f);
+ skipbytes(9*4+4, f);
+ pmesg(80, "[bop]\n");
+ init_regs_stack(100);
+ page_begin(count0);
+ continue;
+ }
+
+ if (b == DVI_eop) {
+ pmesg(80, "[eop]\n");
+ page_end();
+ continue;
+ }
+
+ if (b == DVI_push) {
+ pmesg(80, "[push]\n");
+ push_regs();
+ continue;
+ }
+
+ if (b == DVI_pop) {
+ pmesg(80, "[pop]\n");
+ pop_regs();
+ continue;
+ }
+
+ if ((b >= DVI_right1) && (b <= DVI_right4)) {
+ sint32 qwerty;
+ qwerty = s_readbigendiannumber(b-DVI_right1+1, f);
+ pmesg(80, "[right%i: %li]\n", b-DVI_right1+1, qwerty);
+ add_reg(REGISTER_H, qwerty);
+ continue;
+ }
+
+ if (b == DVI_w0) {
+ add_reg(REGISTER_H, get_reg(REGISTER_W));
+ pmesg(80, "[w0]\n");
+ continue;
+ }
+
+ if ((b >= DVI_w1) && (b <= DVI_w4)) {
+ set_reg(REGISTER_W,
+ s_readbigendiannumber(b-DVI_w1+1, f));
+ pmesg(80, "[w%i: w=%li]\n",
+ b-DVI_w1+1, get_reg(REGISTER_W));
+ add_reg(REGISTER_H, get_reg(REGISTER_W));
+ continue;
+ }
+
+ if (b == DVI_x0) {
+ pmesg(80, "[x0]\n");
+ add_reg(REGISTER_H, get_reg(REGISTER_X));
+ continue;
+ }
+
+ if ((b >= DVI_x1) && (b <= DVI_x4)) {
+ set_reg(REGISTER_X,
+ s_readbigendiannumber(b-DVI_x1+1, f));
+ pmesg(80, "[x%i: x=%li]\n",
+ b-DVI_x1+1, get_reg(REGISTER_X));
+ add_reg(REGISTER_H, get_reg(REGISTER_X));
+ continue;
+ }
+
+ if ((b >= DVI_down1) && (b <= DVI_down4)) {
+ sint32 qwerty;
+ qwerty = s_readbigendiannumber(b-DVI_down1+1, f);
+ pmesg(80, "[down%i, %li]\n", b-DVI_down1+1, qwerty);
+ add_reg(REGISTER_V, qwerty);
+ continue;
+ }
+
+ if (b == DVI_y0) {
+ pmesg(80, "[y0]\n");
+ add_reg(REGISTER_V, get_reg(REGISTER_Y));
+ continue;
+ }
+
+ if ((b >= DVI_y1) && (b <= DVI_y4)) {
+ set_reg(REGISTER_Y,
+ s_readbigendiannumber(b-DVI_y1+1, f));
+ pmesg(80, "[y%i: y=%li]\n",
+ b-DVI_y1+1, get_reg(REGISTER_Y));
+ add_reg(REGISTER_V, get_reg(REGISTER_Y));
+ continue;
+ }
+
+ if (b == DVI_z0) {
+ add_reg(REGISTER_V, get_reg(REGISTER_Z));
+ pmesg(80, "[z0]\n");
+ continue;
+ }
+
+ if ((b >= DVI_z1) && (b <= DVI_z4)) {
+ set_reg(REGISTER_Z,
+ s_readbigendiannumber(b-DVI_z1+1, f));
+ pmesg(80, "[z%i: z=%li]\n",
+ b-DVI_z1+1, get_reg(REGISTER_Z));
+ add_reg(REGISTER_V, get_reg(REGISTER_Z));
+ continue;
+ }
+
+ if ((b >= DVI_fnt_num_0) && (b <= DVI_fnt_num_63)) {
+ pmesg(80, "[fnt_num_%i]\n", b-DVI_fnt_num_0);
+ currfont = b-DVI_fnt_num_0;
+ continue;
+ }
+
+ if ((b >= DVI_fnt1) && (b <= DVI_fnt3)) {
+ pmesg(80, "[fnt%i]\n", b-DVI_fnt1+1);
+ currfont = u_readbigendiannumber(b-DVI_fnt1+1, f);
+ continue;
+ }
+
+ if (b == DVI_fnt4) {
+ pmesg(80, "[fnt4]\n");
+ currfont = s_readbigendiannumber(4, f);
+ continue;
+ }
+
+ if ((b >= DVI_xxx1) && (b <= DVI_xxx4)) {
+ pmesg(80, "[xxx%i]\n", b-DVI_xxx1+1);
+ c = u_readbigendiannumber(b-DVI_xxx1+1, f);
+ if (c > COMMENT_MAXLEN) {
+ panic("too long comment\n");
+ }
+ efread(comment, 1, c, f, "Could not read comment\n");
+ comment[c+1] = '\0';
+ pmesg(50, "[Comment: `%s']\n", comment);
+#if 0
+ skipbytes(c, f);
+#endif
+ continue;
+ }
+
+ if ((b >= DVI_fnt_def1) && (b <= DVI_fnt_def4)) {
+ sint32 k;
+ uint32 cs, s, d;
+ byte a, l;
+ char * n;
+
+ if (b == DVI_fnt_def4) {
+ k = s_readbigendiannumber(4, f);
+ } else {
+ k = u_readbigendiannumber(b-DVI_fnt_def1+1, f);
+ }
+ cs = u_readbigendiannumber(4, f);
+ s = u_readbigendiannumber(4, f);
+ d = u_readbigendiannumber(4, f);
+ a = u_readbigendiannumber(1, f);
+ l = u_readbigendiannumber(1, f);
+
+ n = malloc(a + l + 1);
+ if (n == 0) enomem();
+
+ efread(n, a + l, 1, f, "Failed to read font name");
+ n[a+l] = 0;
+
+ pmesg(80, "[fnt_def%i: %s]\n", b-DVI_fnt_def1+1, n);
+ font_def(k, cs, s, d, a, l, n);
+ free(n);
+ continue;
+ }
+
+ if (b == DVI_pre)
+ panic("Unexpected preamble start marker\n");
+
+ if (b == DVI_post)
+ break;
+
+ if (b == DVI_post_post)
+ panic("Unexpected postamble end marker\n");
+
+ if (b > DVI_post_post)
+ panic("Unimplemented opcode %i\n", b);
+ }
+
+ /* FIXME: process postamble */
+}
+
diff --git a/dviware/catdvi/readdvi.d b/dviware/catdvi/readdvi.d
new file mode 100644
index 0000000000..66eb5843af
--- /dev/null
+++ b/dviware/catdvi/readdvi.d
@@ -0,0 +1,2 @@
+readdvi.o readdvi.d : readdvi.c fntenc.h bytesex.h fontinfo.h fixword.h outenc.h \
+ linebuf.h page.h pageref.h readdvi.h regsta.h util.h
diff --git a/dviware/catdvi/readdvi.h b/dviware/catdvi/readdvi.h
new file mode 100644
index 0000000000..d6e317fed0
--- /dev/null
+++ b/dviware/catdvi/readdvi.h
@@ -0,0 +1,29 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef READDVI_H
+#define READDVI_H
+
+#include <stdio.h>
+#include "bytesex.h"
+
+extern uint32 magnification;
+
+void process_file(FILE *);
+
+#endif /* READDVI_H */
diff --git a/dviware/catdvi/regsta.c b/dviware/catdvi/regsta.c
new file mode 100644
index 0000000000..da000c2771
--- /dev/null
+++ b/dviware/catdvi/regsta.c
@@ -0,0 +1,109 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include "regsta.h"
+#include "util.h"
+
+#define NUM_REGS ((REGISTER_Z) + 1)
+
+static size_t SP = 0; /* top of stack (index of first available slot) */
+static size_t sdepth = 0; /* stack depth */
+static sint32 * stack = 0;
+static sint32 registers[NUM_REGS] = {0};
+char const * regnames[NUM_REGS] = { "H", "V", "W", "X", "Y", "Z" };
+
+void init_regs_stack(int depth)
+{
+ int i;
+ assert(depth > 0);
+
+ if (stack != 0) free(stack);
+
+ for (i = 0; i < NUM_REGS; i++) registers[i] = 0;
+
+ stack = malloc(depth * NUM_REGS * sizeof(sint32));
+ if (stack == 0) panic("Out of memory!");
+ SP = 0;
+ sdepth = depth;
+}
+
+void push_regs(void)
+{
+ int i;
+ assert(SP <= sdepth);
+ if (SP == sdepth) panic("Stack overflow!");
+ for (i = 0; i < NUM_REGS; i++) {
+ stack[NUM_REGS * SP + i] = registers[i];
+ }
+ ++SP;
+ dump_regs(90);
+}
+
+void pop_regs(void)
+{
+ int i;
+ assert(SP <= sdepth);
+ if (SP == 0) panic("Stack underflow!");
+ --SP;
+ for (i = 0; i < NUM_REGS; i++) {
+ registers[i] = stack[NUM_REGS * SP + i];
+ }
+ dump_regs(90);
+}
+
+sint32 get_reg(int reg)
+{
+ assert(reg >= 0);
+ assert(reg < NUM_REGS);
+ pmesg(150, "GET_REG %s -> %li\n", regnames[reg], registers[reg]);
+ return registers[reg];
+}
+
+void set_reg(int reg, sint32 a)
+{
+ assert(reg >= 0);
+ assert(reg < NUM_REGS);
+ pmesg(95, "SET_REG %s <- %li\n", regnames[reg], a);
+ registers[reg] = a;
+ dump_regs(90);
+}
+
+void add_reg(int reg, sint32 a)
+{
+ assert(reg >= 0);
+ assert(reg < NUM_REGS);
+ pmesg(95, "REGISTER %s <- %li + %li = ",
+ regnames[reg], registers[reg], a);
+ registers[reg] += a;
+ pmesg(95, "%li\n", registers[reg]);
+ dump_regs(90);
+}
+
+void dump_regs(int level)
+{
+ int i;
+
+ if(level > msglevel) return;
+ pmesg(level, "REGISTER DUMP: ");
+ for (i = 0; i < NUM_REGS; i++) {
+ pmesg(level, "(%s %01li) ", regnames[i], registers[i]);
+ }
+ pmesg(level, "\n");
+}
diff --git a/dviware/catdvi/regsta.d b/dviware/catdvi/regsta.d
new file mode 100644
index 0000000000..db1ba8a4c2
--- /dev/null
+++ b/dviware/catdvi/regsta.d
@@ -0,0 +1 @@
+regsta.o regsta.d : regsta.c regsta.h bytesex.h util.h
diff --git a/dviware/catdvi/regsta.h b/dviware/catdvi/regsta.h
new file mode 100644
index 0000000000..70d9089f7d
--- /dev/null
+++ b/dviware/catdvi/regsta.h
@@ -0,0 +1,57 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef REGSTA_H
+#define REGSTA_H
+
+#include "bytesex.h"
+
+/* Handle the registers and the stack. */
+
+#define REGISTER_H 0
+#define REGISTER_V 1
+#define REGISTER_W 2
+#define REGISTER_X 3
+#define REGISTER_Y 4
+#define REGISTER_Z 5
+
+/* Set registers to zero and initialize an empty stack with the given
+ maximum depth. */
+void init_regs_stack(int depth);
+
+/* Get the value of one of the registers (h, v, w, x, y, z). */
+
+sint32 get_reg(int reg);
+
+/* Set the value of one of the registers (h, v, w, x, y, z). */
+void set_reg(int reg, sint32);
+
+/* Add to the value of one of the registers. */
+void add_reg(int reg, sint32 a);
+
+/* Push the registers on the stack. */
+void push_regs(void);
+
+/* Pop the registers off the stack. */
+void pop_regs(void);
+
+/* For debug purposes, dump registers to the standard error stream, if
+ level is right. */
+void dump_regs(int level);
+
+#endif /* REGSTA_H */
diff --git a/dviware/catdvi/sparse.c b/dviware/catdvi/sparse.c
new file mode 100644
index 0000000000..7e324c18d7
--- /dev/null
+++ b/dviware/catdvi/sparse.c
@@ -0,0 +1,202 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2001, 2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdlib.h>
+#include "sparse.h"
+#include "util.h"
+
+
+/******************************* spar_t *******************************/
+#define SPAR_NODES_PER_BLOCK (1 << SPAR_BITS_PER_STAGE)
+#define SPAR_STAGE_MASK ((1 << SPAR_BITS_PER_STAGE) - 1)
+
+
+/* Readability notes:
+ * - stage(node) := this->height - distance(root, node)
+ * = distance(node, nearest leaf)
+ *
+ * - invariant: this->max_shift = (this->height - 1) * SPAR_BITS_PER_STAGE
+ */
+
+
+/* Allocate a block of SPAR_NODES_PER_STAGE nodes and initialize them
+ * with fill_with.
+ */
+static spar_node_t * spar_new_block(spar_node_t fill_with);
+
+/* Free block block of nodes at stage stage and recursively all of its
+ * children.
+ */
+static void spar_free_block(spar_node_t * block, int stage);
+
+/* Create a new tree root and make the old one the 0-th child of the new,
+ * thus increasing the height of the tree by 1.
+ */
+static void spar_grow(spar_t * this);
+
+/* the default non-leaf node */
+static const spar_node_t default_branch = {NULL};
+
+
+void spar_init(spar_t * this, spar_node_t default_entry)
+{
+ this->height = 0;
+ this->max_shift = - SPAR_BITS_PER_STAGE;
+ this->max_index = 0;
+ this->default_leaf = default_entry;
+
+ /* we start with a single entry (index 0) with default value */
+ this->root = default_entry;
+}
+
+void spar_done(spar_t * this)
+{
+ if(this->height > 0) {
+ spar_free_block(this->root.children, this->height - 1);
+ }
+
+ this->root.children = NULL;
+ /* block erroneous access to now freed memory */
+}
+
+
+const spar_node_t * spar_const_entry(const spar_t * this, spar_index_t i)
+{
+ int shift;
+ const spar_node_t * p;
+
+ if(i > this->max_index) return &(this->default_leaf);
+
+ p = &(this->root);
+ for(shift = this->max_shift; shift >= 0; shift -= SPAR_BITS_PER_STAGE) {
+ if(p->children == NULL) return &(this->default_leaf);
+ p = p->children + ((i >> shift) & SPAR_STAGE_MASK);
+ }
+
+ return p;
+}
+
+
+spar_node_t * spar_assignable_entry(spar_t * this, spar_index_t i)
+{
+ int shift;
+ spar_node_t * p;
+
+ while(i > this->max_index) spar_grow(this);
+
+ p = &(this->root);
+ for(shift = this->max_shift; shift >= 0; shift -= SPAR_BITS_PER_STAGE) {
+ if(p->children == NULL) {
+ /* The path from root to requested leaf exists only until here.
+ * Create the rest and return address of new leaf.
+ */
+ for( ; shift > 0; shift -= SPAR_BITS_PER_STAGE) {
+ p->children = spar_new_block(default_branch);
+ p = p->children + ((i >> shift) & SPAR_STAGE_MASK);
+ }
+ /* shift == 0 is different because the new children are leaves */
+ p->children = spar_new_block(this->default_leaf);
+ p = p->children + (i & SPAR_STAGE_MASK);
+
+ return p;
+ }
+ p = p->children + ((i >> shift) & SPAR_STAGE_MASK);
+ }
+
+ return p;
+}
+
+
+static spar_node_t * spar_new_block(spar_node_t fill_with)
+{
+ spar_node_t * p, * q;
+
+ p = xmalloc(SPAR_NODES_PER_BLOCK * sizeof(spar_node_t));
+ for(q = p; q < p + SPAR_NODES_PER_BLOCK; ++q) *q = fill_with;
+ return p;
+}
+
+
+static void spar_free_block(spar_node_t * block, int stage)
+{
+ int i;
+
+ if(stage > 0) {
+ for(i = 0; i < SPAR_NODES_PER_BLOCK; ++i) {
+ if(block[i].children != NULL) {
+ spar_free_block(block[i].children, stage - 1);
+ }
+ }
+ }
+ free(block);
+}
+
+
+static void spar_grow(spar_t * this)
+{
+ spar_node_t * p;
+
+ /* We grow at the root, i.e. we have a new root node, and the old one
+ * becomes the new roots zeroth child.
+ */
+ if(this->height == 0) {
+ p = spar_new_block(this->default_leaf);
+ }
+ else {
+ p = spar_new_block(default_branch);
+ }
+ p[0] = this->root;
+ this->root.children = p;
+
+ /* tell the world */
+ this->height += 1;
+ this->max_shift += SPAR_BITS_PER_STAGE;
+ this->max_index = (this->max_index << SPAR_BITS_PER_STAGE)
+ | SPAR_STAGE_MASK;
+
+}
+
+
+/******************************* sparp_t *******************************/
+
+void sparp_init(sparp_t * this) {
+ spar_node_t default_leaf;
+
+ default_leaf.p = NULL;
+ spar_init(&this->p_spar, default_leaf);
+}
+
+
+void sparp_done(sparp_t * this) {
+ spar_done(&this->p_spar);
+}
+
+
+/******************************* spars32_t *******************************/
+
+void spars32_init(spars32_t * this, sint32 default_value) {
+ spar_node_t default_leaf;
+
+ default_leaf.s32 = default_value;
+ spar_init(&this->s32_spar, default_leaf);
+}
+
+
+void spars32_done(spars32_t * this) {
+ spar_done(&this->s32_spar);
+}
diff --git a/dviware/catdvi/sparse.d b/dviware/catdvi/sparse.d
new file mode 100644
index 0000000000..add48a1e1d
--- /dev/null
+++ b/dviware/catdvi/sparse.d
@@ -0,0 +1 @@
+sparse.o sparse.d : sparse.c sparse.h bytesex.h util.h
diff --git a/dviware/catdvi/sparse.h b/dviware/catdvi/sparse.h
new file mode 100644
index 0000000000..4d924de6cd
--- /dev/null
+++ b/dviware/catdvi/sparse.h
@@ -0,0 +1,161 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2001, 2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef SPARSE_H
+#define SPARSE_H
+
+/* Implements "sparse arrays" of void * and sint32.
+ *
+ * The assigned entries are stored as the leaves of a dynamically growing
+ * (2^SPAR_BITS_PER_STAGE)-ary tree. Branches not leading to an assigned
+ * entry are not created, and looking them up returns a default value.
+ *
+ * Two structures with accompanying methods are defined,
+ * sparp_t (for void *) and spars32_t (for sint32). Almost all of the code
+ * is shared and factored out into a common "base class" spar_t.
+ *
+ * Note sparp_t is not at all interested in what the void *'s it holds
+ * may point to.
+ *
+ * The default value is NULL in the case of void * and settable in the
+ * constructor call in the case of sint32.
+ */
+
+#include "bytesex.h" /* for sint32, uint32 */
+
+/******************************* spar_t *******************************/
+typedef uint32 spar_index_t;
+ /* Could be changed to any unsigned integral type */
+
+#define SPAR_BITS_PER_STAGE 8
+ /* Configurable. Need not divide (bits per spar_index_t) */
+
+typedef union spar_node_t {
+ union spar_node_t * children;
+ /* payload */
+ void * p;
+ sint32 s32;
+} spar_node_t;
+
+typedef struct spar_t {
+ int height;
+ int max_shift;
+ spar_index_t max_index;
+ spar_node_t root;
+ spar_node_t default_leaf;
+} spar_t;
+
+/* constructor */
+void spar_init(spar_t * this, spar_node_t default_entry);
+
+/* destructor */
+void spar_done(spar_t * this);
+
+/* Get pointer to const leaf node (array entry) with index i.
+ * Returns pointer to some node with default value if unassigned.
+ */
+const spar_node_t * spar_const_entry(const spar_t * this, spar_index_t i);
+
+/* Get pointer to leaf node (array entry) with index i, creating it
+ * if necessary. Newly created nodes have the default value. The pointer
+ * target is assignable.
+ *
+ * Consecutive calls to this function (and to spar_const_entry()) with
+ * the same arguments will always return the same address.
+ */
+spar_node_t * spar_assignable_entry(spar_t * this, spar_index_t i);
+
+/******************************* sparp_t *******************************/
+typedef spar_index_t sparp_index_t;
+
+typedef struct sparp_t {
+ spar_t p_spar;
+} sparp_t;
+
+/* constructor */
+void sparp_init(sparp_t * this);
+
+/* destructor */
+void sparp_done(sparp_t * this);
+
+/* Read array entry with index i.
+ * This behaves like a function with prototype
+ * void * sparp_read(sparp_t * this, sparp_index_t i);
+ */
+#define sparp_read(this, i) (spar_const_entry(&((this)->p_spar), i)->p)
+
+/* Write array entry with index i.
+ * This behaves like a function with prototype
+ * void sparp_write(sparp_t * this, sparp_index_t i, void * v);
+ */
+#define sparp_write(this, i, v) \
+ ((void) (spar_assignable_entry(&((this)->p_spar), i)->p = v))
+
+/* Get pointer to array entry with index i, creating it
+ * if necessary. Newly created entries have value NULL. The pointer
+ * target is assignable.
+ *
+ * Consecutive calls to this function with
+ * the same arguments will always return the same address.
+ *
+ * This behaves like a function with prototype
+ * void ** sparp_assignable_entry(sparp_t * this, sparp_index_t i);
+ */
+#define sparp_assignable_entry(this, i) \
+ (&(spar_assignable_entry(&((this)->p_spar), i)->p))
+
+/******************************* spars32_t *******************************/
+typedef spar_index_t spars32_index_t;
+
+typedef struct spars32_t {
+ spar_t s32_spar;
+} spars32_t;
+
+/* constructor */
+void spars32_init(spars32_t * this, sint32 default_value);
+
+/* destructor */
+void spars32_done(spars32_t * this);
+
+/* Read array entry with index i.
+ * This behaves like a function with prototype
+ * sint32 spars32_read(spars32_t * this, spars32_index_t i);
+ */
+#define spars32_read(this, i) (spar_const_entry(&((this)->s32_spar), i)->s32)
+
+/* Write array entry with index i.
+ * This behaves like a function with prototype
+ * void spars32_write(spars32_t * this, spars32_index_t i, sint32 v);
+ */
+#define spars32_write(this, i, v) \
+ ((void) (spar_assignable_entry(&((this)->s32_spar), i)->s32 = v))
+
+/* Get pointer to array entry with index i, creating it
+ * if necessary. Newly created entries have default value. The pointer
+ * target is assignable.
+ *
+ * Consecutive calls to this function with
+ * the same arguments will always return the same address.
+ *
+ * This behaves like a function with prototype
+ * sint32* spars32_assignable_entry(spars32_t * this, spars32_index_t i);
+ */
+#define spars32_assignable_entry(this, i) \
+ (&(spar_assignable_entry(&((this)->s32_spar), i)->s32))
+
+#endif
diff --git a/dviware/catdvi/test/box.tex b/dviware/catdvi/test/box.tex
new file mode 100644
index 0000000000..865ad8fc64
--- /dev/null
+++ b/dviware/catdvi/test/box.tex
@@ -0,0 +1,7 @@
+\documentclass{article}
+
+\begin{document}
+
+\mbox{ABC}def
+
+\end{document}
diff --git a/dviware/catdvi/test/finnish.tex b/dviware/catdvi/test/finnish.tex
new file mode 100644
index 0000000000..7079ed84b6
--- /dev/null
+++ b/dviware/catdvi/test/finnish.tex
@@ -0,0 +1,12 @@
+\documentclass{article}
+
+\usepackage[latin1]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage[finnish]{babel}
+
+\begin{document}
+
+Äijän ämmän äkkiä äkättyä öylätin lattialta öljylätäkön ärjyi tämä
+höyryisästi.
+
+\end{document}
diff --git a/dviware/catdvi/test/ligatures.tex b/dviware/catdvi/test/ligatures.tex
new file mode 100644
index 0000000000..e454986526
--- /dev/null
+++ b/dviware/catdvi/test/ligatures.tex
@@ -0,0 +1,7 @@
+\documentclass{article}
+
+\begin{document}
+
+Affine transformation affords authenticity. T\ss\"u\ss
+
+\end{document}
diff --git a/dviware/catdvi/test/math.tex b/dviware/catdvi/test/math.tex
new file mode 100644
index 0000000000..34609cf32f
--- /dev/null
+++ b/dviware/catdvi/test/math.tex
@@ -0,0 +1,18 @@
+\documentclass{article}
+
+\usepackage{bbm}
+
+\begin{document}
+
+$A = B$
+
+$\mathbbm{N} = \{ 0, 1, 2, 3, \ldots \}$
+
+$\mathbbm{Z} = \{ \, n \mid n \in \mathbbm{N} \wedge -n \in \mathbbm{N} \,\}$
+
+$x^y$
+
+$x + \sum_x^y$
+\[x + \sum_x^y\]
+
+\end{document}
diff --git a/dviware/catdvi/test/ot1umlauts.tex b/dviware/catdvi/test/ot1umlauts.tex
new file mode 100644
index 0000000000..0caa27a3d6
--- /dev/null
+++ b/dviware/catdvi/test/ot1umlauts.tex
@@ -0,0 +1,12 @@
+\documentclass{article}
+
+\usepackage[latin1]{inputenc}
+\usepackage[OT1]{fontenc}
+\usepackage[finnish]{babel}
+
+\begin{document}
+
+Äijän ämmän äkkiä äkättyä öylätin lattialta öljylätäkön ärjyi tämä
+höyryisästi.
+
+\end{document} \ No newline at end of file
diff --git a/dviware/catdvi/test/private.tex b/dviware/catdvi/test/private.tex
new file mode 100644
index 0000000000..d6438eb6bd
--- /dev/null
+++ b/dviware/catdvi/test/private.tex
@@ -0,0 +1,8 @@
+\documentclass{article}
+\usepackage[T1]{fontenc}
+\begin{document}
+\symbol{"AD} % ng
+\symbol{"DF} % SS
+\symbol{"8D} % NG
+\end{document}
+
diff --git a/dviware/catdvi/test/testfont.tex b/dviware/catdvi/test/testfont.tex
new file mode 100644
index 0000000000..53c5207723
--- /dev/null
+++ b/dviware/catdvi/test/testfont.tex
@@ -0,0 +1,517 @@
+\documentclass{article}
+\begin{document}
+\font\cm=cmr10
+\font\bb=bbm10
+\cm 0 \bb \symbol{0}
+
+\cm 1 \bb \symbol{1}
+
+\cm 2 \bb \symbol{2}
+
+\cm 3 \bb \symbol{3}
+
+\cm 4 \bb \symbol{4}
+
+\cm 5 \bb \symbol{5}
+
+\cm 6 \bb \symbol{6}
+
+\cm 7 \bb \symbol{7}
+
+\cm 8 \bb \symbol{8}
+
+\cm 9 \bb \symbol{9}
+
+\cm 10 \bb \symbol{10}
+
+\cm 11 \bb \symbol{11}
+
+\cm 12 \bb \symbol{12}
+
+\cm 13 \bb \symbol{13}
+
+\cm 14 \bb \symbol{14}
+
+\cm 15 \bb \symbol{15}
+
+\cm 16 \bb \symbol{16}
+
+\cm 17 \bb \symbol{17}
+
+\cm 18 \bb \symbol{18}
+
+\cm 19 \bb \symbol{19}
+
+\cm 20 \bb \symbol{20}
+
+\cm 21 \bb \symbol{21}
+
+\cm 22 \bb \symbol{22}
+
+\cm 23 \bb \symbol{23}
+
+\cm 24 \bb \symbol{24}
+
+\cm 25 \bb \symbol{25}
+
+\cm 26 \bb \symbol{26}
+
+\cm 27 \bb \symbol{27}
+
+\cm 28 \bb \symbol{28}
+
+\cm 29 \bb \symbol{29}
+
+\cm 30 \bb \symbol{30}
+
+\cm 31 \bb \symbol{31}
+
+\cm 32 \bb \symbol{32}
+
+\cm 33 \bb \symbol{33}
+
+\cm 34 \bb \symbol{34}
+
+\cm 35 \bb \symbol{35}
+
+\cm 36 \bb \symbol{36}
+
+\cm 37 \bb \symbol{37}
+
+\cm 38 \bb \symbol{38}
+
+\cm 39 \bb \symbol{39}
+
+\cm 40 \bb \symbol{40}
+
+\cm 41 \bb \symbol{41}
+
+\cm 42 \bb \symbol{42}
+
+\cm 43 \bb \symbol{43}
+
+\cm 44 \bb \symbol{44}
+
+\cm 45 \bb \symbol{45}
+
+\cm 46 \bb \symbol{46}
+
+\cm 47 \bb \symbol{47}
+
+\cm 48 \bb \symbol{48}
+
+\cm 49 \bb \symbol{49}
+
+\cm 50 \bb \symbol{50}
+
+\cm 51 \bb \symbol{51}
+
+\cm 52 \bb \symbol{52}
+
+\cm 53 \bb \symbol{53}
+
+\cm 54 \bb \symbol{54}
+
+\cm 55 \bb \symbol{55}
+
+\cm 56 \bb \symbol{56}
+
+\cm 57 \bb \symbol{57}
+
+\cm 58 \bb \symbol{58}
+
+\cm 59 \bb \symbol{59}
+
+\cm 60 \bb \symbol{60}
+
+\cm 61 \bb \symbol{61}
+
+\cm 62 \bb \symbol{62}
+
+\cm 63 \bb \symbol{63}
+
+\cm 64 \bb \symbol{64}
+
+\cm 65 \bb \symbol{65}
+
+\cm 66 \bb \symbol{66}
+
+\cm 67 \bb \symbol{67}
+
+\cm 68 \bb \symbol{68}
+
+\cm 69 \bb \symbol{69}
+
+\cm 70 \bb \symbol{70}
+
+\cm 71 \bb \symbol{71}
+
+\cm 72 \bb \symbol{72}
+
+\cm 73 \bb \symbol{73}
+
+\cm 74 \bb \symbol{74}
+
+\cm 75 \bb \symbol{75}
+
+\cm 76 \bb \symbol{76}
+
+\cm 77 \bb \symbol{77}
+
+\cm 78 \bb \symbol{78}
+
+\cm 79 \bb \symbol{79}
+
+\cm 80 \bb \symbol{80}
+
+\cm 81 \bb \symbol{81}
+
+\cm 82 \bb \symbol{82}
+
+\cm 83 \bb \symbol{83}
+
+\cm 84 \bb \symbol{84}
+
+\cm 85 \bb \symbol{85}
+
+\cm 86 \bb \symbol{86}
+
+\cm 87 \bb \symbol{87}
+
+\cm 88 \bb \symbol{88}
+
+\cm 89 \bb \symbol{89}
+
+\cm 90 \bb \symbol{90}
+
+\cm 91 \bb \symbol{91}
+
+\cm 92 \bb \symbol{92}
+
+\cm 93 \bb \symbol{93}
+
+\cm 94 \bb \symbol{94}
+
+\cm 95 \bb \symbol{95}
+
+\cm 96 \bb \symbol{96}
+
+\cm 97 \bb \symbol{97}
+
+\cm 98 \bb \symbol{98}
+
+\cm 99 \bb \symbol{99}
+
+\cm 100 \bb \symbol{100}
+
+\cm 101 \bb \symbol{101}
+
+\cm 102 \bb \symbol{102}
+
+\cm 103 \bb \symbol{103}
+
+\cm 104 \bb \symbol{104}
+
+\cm 105 \bb \symbol{105}
+
+\cm 106 \bb \symbol{106}
+
+\cm 107 \bb \symbol{107}
+
+\cm 108 \bb \symbol{108}
+
+\cm 109 \bb \symbol{109}
+
+\cm 110 \bb \symbol{110}
+
+\cm 111 \bb \symbol{111}
+
+\cm 112 \bb \symbol{112}
+
+\cm 113 \bb \symbol{113}
+
+\cm 114 \bb \symbol{114}
+
+\cm 115 \bb \symbol{115}
+
+\cm 116 \bb \symbol{116}
+
+\cm 117 \bb \symbol{117}
+
+\cm 118 \bb \symbol{118}
+
+\cm 119 \bb \symbol{119}
+
+\cm 120 \bb \symbol{120}
+
+\cm 121 \bb \symbol{121}
+
+\cm 122 \bb \symbol{122}
+
+\cm 123 \bb \symbol{123}
+
+\cm 124 \bb \symbol{124}
+
+\cm 125 \bb \symbol{125}
+
+\cm 126 \bb \symbol{126}
+
+\cm 127 \bb \symbol{127}
+
+\cm 128 \bb \symbol{128}
+
+\cm 129 \bb \symbol{129}
+
+\cm 130 \bb \symbol{130}
+
+\cm 131 \bb \symbol{131}
+
+\cm 132 \bb \symbol{132}
+
+\cm 133 \bb \symbol{133}
+
+\cm 134 \bb \symbol{134}
+
+\cm 135 \bb \symbol{135}
+
+\cm 136 \bb \symbol{136}
+
+\cm 137 \bb \symbol{137}
+
+\cm 138 \bb \symbol{138}
+
+\cm 139 \bb \symbol{139}
+
+\cm 140 \bb \symbol{140}
+
+\cm 141 \bb \symbol{141}
+
+\cm 142 \bb \symbol{142}
+
+\cm 143 \bb \symbol{143}
+
+\cm 144 \bb \symbol{144}
+
+\cm 145 \bb \symbol{145}
+
+\cm 146 \bb \symbol{146}
+
+\cm 147 \bb \symbol{147}
+
+\cm 148 \bb \symbol{148}
+
+\cm 149 \bb \symbol{149}
+
+\cm 150 \bb \symbol{150}
+
+\cm 151 \bb \symbol{151}
+
+\cm 152 \bb \symbol{152}
+
+\cm 153 \bb \symbol{153}
+
+\cm 154 \bb \symbol{154}
+
+\cm 155 \bb \symbol{155}
+
+\cm 156 \bb \symbol{156}
+
+\cm 157 \bb \symbol{157}
+
+\cm 158 \bb \symbol{158}
+
+\cm 159 \bb \symbol{159}
+
+\cm 160 \bb \symbol{160}
+
+\cm 161 \bb \symbol{161}
+
+\cm 162 \bb \symbol{162}
+
+\cm 163 \bb \symbol{163}
+
+\cm 164 \bb \symbol{164}
+
+\cm 165 \bb \symbol{165}
+
+\cm 166 \bb \symbol{166}
+
+\cm 167 \bb \symbol{167}
+
+\cm 168 \bb \symbol{168}
+
+\cm 169 \bb \symbol{169}
+
+\cm 170 \bb \symbol{170}
+
+\cm 171 \bb \symbol{171}
+
+\cm 172 \bb \symbol{172}
+
+\cm 173 \bb \symbol{173}
+
+\cm 174 \bb \symbol{174}
+
+\cm 175 \bb \symbol{175}
+
+\cm 176 \bb \symbol{176}
+
+\cm 177 \bb \symbol{177}
+
+\cm 178 \bb \symbol{178}
+
+\cm 179 \bb \symbol{179}
+
+\cm 180 \bb \symbol{180}
+
+\cm 181 \bb \symbol{181}
+
+\cm 182 \bb \symbol{182}
+
+\cm 183 \bb \symbol{183}
+
+\cm 184 \bb \symbol{184}
+
+\cm 185 \bb \symbol{185}
+
+\cm 186 \bb \symbol{186}
+
+\cm 187 \bb \symbol{187}
+
+\cm 188 \bb \symbol{188}
+
+\cm 189 \bb \symbol{189}
+
+\cm 190 \bb \symbol{190}
+
+\cm 191 \bb \symbol{191}
+
+\cm 192 \bb \symbol{192}
+
+\cm 193 \bb \symbol{193}
+
+\cm 194 \bb \symbol{194}
+
+\cm 195 \bb \symbol{195}
+
+\cm 196 \bb \symbol{196}
+
+\cm 197 \bb \symbol{197}
+
+\cm 198 \bb \symbol{198}
+
+\cm 199 \bb \symbol{199}
+
+\cm 200 \bb \symbol{200}
+
+\cm 201 \bb \symbol{201}
+
+\cm 202 \bb \symbol{202}
+
+\cm 203 \bb \symbol{203}
+
+\cm 204 \bb \symbol{204}
+
+\cm 205 \bb \symbol{205}
+
+\cm 206 \bb \symbol{206}
+
+\cm 207 \bb \symbol{207}
+
+\cm 208 \bb \symbol{208}
+
+\cm 209 \bb \symbol{209}
+
+\cm 210 \bb \symbol{210}
+
+\cm 211 \bb \symbol{211}
+
+\cm 212 \bb \symbol{212}
+
+\cm 213 \bb \symbol{213}
+
+\cm 214 \bb \symbol{214}
+
+\cm 215 \bb \symbol{215}
+
+\cm 216 \bb \symbol{216}
+
+\cm 217 \bb \symbol{217}
+
+\cm 218 \bb \symbol{218}
+
+\cm 219 \bb \symbol{219}
+
+\cm 220 \bb \symbol{220}
+
+\cm 221 \bb \symbol{221}
+
+\cm 222 \bb \symbol{222}
+
+\cm 223 \bb \symbol{223}
+
+\cm 224 \bb \symbol{224}
+
+\cm 225 \bb \symbol{225}
+
+\cm 226 \bb \symbol{226}
+
+\cm 227 \bb \symbol{227}
+
+\cm 228 \bb \symbol{228}
+
+\cm 229 \bb \symbol{229}
+
+\cm 230 \bb \symbol{230}
+
+\cm 231 \bb \symbol{231}
+
+\cm 232 \bb \symbol{232}
+
+\cm 233 \bb \symbol{233}
+
+\cm 234 \bb \symbol{234}
+
+\cm 235 \bb \symbol{235}
+
+\cm 236 \bb \symbol{236}
+
+\cm 237 \bb \symbol{237}
+
+\cm 238 \bb \symbol{238}
+
+\cm 239 \bb \symbol{239}
+
+\cm 240 \bb \symbol{240}
+
+\cm 241 \bb \symbol{241}
+
+\cm 242 \bb \symbol{242}
+
+\cm 243 \bb \symbol{243}
+
+\cm 244 \bb \symbol{244}
+
+\cm 245 \bb \symbol{245}
+
+\cm 246 \bb \symbol{246}
+
+\cm 247 \bb \symbol{247}
+
+\cm 248 \bb \symbol{248}
+
+\cm 249 \bb \symbol{249}
+
+\cm 250 \bb \symbol{250}
+
+\cm 251 \bb \symbol{251}
+
+\cm 252 \bb \symbol{252}
+
+\cm 253 \bb \symbol{253}
+
+\cm 254 \bb \symbol{254}
+
+\cm 255 \bb \symbol{255}
+
+\end{document}
diff --git a/dviware/catdvi/test/texlogo.tex b/dviware/catdvi/test/texlogo.tex
new file mode 100644
index 0000000000..7949cb6834
--- /dev/null
+++ b/dviware/catdvi/test/texlogo.tex
@@ -0,0 +1,7 @@
+\documentclass{article}
+
+\begin{document}
+
+\TeX, \LaTeX\ etc.
+
+\end{document}
diff --git a/dviware/catdvi/test/texmext.tex b/dviware/catdvi/test/texmext.tex
new file mode 100644
index 0000000000..35f6d1ceca
--- /dev/null
+++ b/dviware/catdvi/test/texmext.tex
@@ -0,0 +1,40 @@
+\documentclass{article}
+
+\begin{document}
+
+\section*{Some problems for the DVI class}
+
+\begin{enumerate}
+\item
+Let $f$ be a real-valued, nonnegative function on the positive half-axis.
+For every positive integer $i$, put $a_i := f(i)$.
+Assume that $f$ is monotonically decreasing. Then
+$\sum_{i=1}^{\infty} a_i$ is finite iff $\int_1^{\infty} f(x)\,dx$ is.
+
+\item
+And here's a harder one: consider nonnegative solutions $\epsilon$,
+$\delta$ of the equation
+\[
+\bigg(1 + \epsilon \Big(1 + \epsilon \big(1 + \epsilon (1 + \epsilon
+ ) \big) \Big) \bigg) =
+\sqrt{1 + \delta \sqrt {1 + \delta \sqrt {1 + \delta \sqrt{1 + \delta}}}}
+\]
+Is it true (and if so, in which sense) that $\epsilon \ll \delta$ as
+$\delta \rightarrow 0$ ? What happens if the equation is changed to
+\[
+\bigg(1 + \epsilon \Big(1 + \epsilon \big(1 + \epsilon (1 + \epsilon
+ )^2 \big)^2 \Big)^2 \bigg)^2 =
+\sqrt[4]{1 + \delta \sqrt[4] {1 + \delta \sqrt[4] {1 + \delta \sqrt[4]{1 + \delta}}}}
+\]
+
+\item
+Prove that the series
+\[
+\sum_{n=1}^{\infty} \frac{(-1)^n\,n}{(n+1)^2}
+\]
+does converge. (Hint: don't try to use problem 1).
+\end{enumerate}
+Solutions have to be submitted by yesterday, 0730~AM at my office in
+ascii, latin1 and utf-8 encoding.
+
+\end{document}
diff --git a/dviware/catdvi/tfminfo.c b/dviware/catdvi/tfminfo.c
new file mode 100644
index 0000000000..435307f20f
--- /dev/null
+++ b/dviware/catdvi/tfminfo.c
@@ -0,0 +1,131 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "util.h"
+#include "findtfm.h"
+#include "fontinfo.h"
+#include "bytesex.h"
+#include "fixword.h"
+
+#define FONT_INDEX 0
+ /* we use only this one font slot */
+
+char * generic_parms[] = {
+ "slant",
+ "space",
+ "space_stretch",
+ "space_shrink",
+ "x_height",
+ "quad",
+ "extra_space"
+};
+
+char * OMS_parms[] = {
+ "num1",
+ "num2",
+ "num3",
+ "denom1",
+ "denom2",
+ "sup1",
+ "sup2",
+ "sup3",
+ "sub1",
+ "sub2",
+ "supdrop",
+ "subdrop",
+ "delim1",
+ "delim2",
+ "axis_height"
+};
+
+char * OMX_parms[] ={
+ "default_rule_thickness",
+ "big_op_spacing1",
+ "big_op_spacing2",
+ "big_op_spacing3",
+ "big_op_spacing4",
+ "big_op_spacing5"
+};
+
+static size_t desc_copy(
+ char ** to,
+ char ** from,
+ size_t base,
+ size_t count,
+ size_t np
+)
+{
+ if(base > np) return (np + 1);
+ count = min(count, np + 1 - base);
+ memcpy(to + base, from, sizeof(char *) * count);
+ return (base + count);
+}
+
+int main(int argc, char * argv[])
+{
+ int np, enp, i;
+ size_t b;
+ char ** description;
+
+ if(argc != 2) {
+ fputs("Usage error!\n", stderr);
+ exit(1);
+ }
+
+ setup_findtfm(argv[0]);
+
+ font_def(
+ FONT_INDEX,
+ 0, /* checksum - we don't know that */
+ double2fw(1.0), /* scaling */
+ double2fw(10.0), /* design size */
+ 0, /* length of the fontnames directory part */
+ strlen(argv[1]), /* length of the fontnames non-directory part */
+ argv[1] /* fontname (e.g. cmr10) */
+ );
+ np = font_nparams(FONT_INDEX);
+
+ description = malloc((np + 1) * sizeof(char *));
+ for(i = 0; i <= np; ++i) description[i] = "unknown";
+
+ b = 1;
+ enp = lengthof(generic_parms);
+ b = desc_copy(description, generic_parms, b, lengthof(generic_parms), np);
+
+ if(strcmp(font_enc(FONT_INDEX), "TeX math symbols") == 0) {
+ enp += lengthof(OMS_parms);
+ b = desc_copy(
+ description,
+ OMS_parms,
+ b,
+ lengthof(OMS_parms),
+ np
+ );
+ }
+ else if(strcmp(font_enc(FONT_INDEX), "TeX math extension") == 0) {
+ enp += lengthof(OMX_parms);
+ b = desc_copy(
+ description,
+ OMX_parms,
+ b,
+ lengthof(OMX_parms),
+ np
+ );
+ }
+
+ printf("Encoding: %s\n", font_enc(FONT_INDEX));
+ printf("Family: %s\n", font_family(FONT_INDEX));
+
+ printf("Nparams: %d [expected: %d]\n", np, enp);
+ for(i = 1; i <= np; ++i) {
+ printf(
+ "Param%02d: %4.7g [%s]\n",
+ i,
+ fw2double(font_param(FONT_INDEX, i)),
+ description[i]
+ );
+ }
+ exit(0);
+}
+
+
diff --git a/dviware/catdvi/tfminfo.d b/dviware/catdvi/tfminfo.d
new file mode 100644
index 0000000000..47799aedc7
--- /dev/null
+++ b/dviware/catdvi/tfminfo.d
@@ -0,0 +1 @@
+tfminfo.o tfminfo.d : tfminfo.c util.h findtfm.h fontinfo.h bytesex.h fixword.h
diff --git a/dviware/catdvi/util.c b/dviware/catdvi/util.c
new file mode 100644
index 0000000000..13eaec0d49
--- /dev/null
+++ b/dviware/catdvi/util.c
@@ -0,0 +1,227 @@
+/*
+ Copyright (C) 1999 J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl>
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "util.h"
+
+int msglevel = 0; /* the higher, the more messages... */
+int suppress_warnings = 0; /* flag */
+int num_warnings = 0; /* count */
+
+void warning(const char * format, ...)
+{
+ va_list args;
+
+ ++num_warnings;
+
+ va_start(args, format);
+ if (!suppress_warnings) vfprintf(stderr, format, args);
+ va_end(args);
+}
+
+void panic(const char * format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ exit(EXIT_FAILURE);
+}
+
+#if defined(NDEBUG) && defined(__GNUC__)
+/* Nothing. eassert has been "defined away" in util.h already. */
+#else
+void eassert(int expr, const char * format, ...) {
+#ifdef NDEBUG
+ /* Empty body, so a good compiler will optimise calls away */
+#else
+ va_list args;
+
+ if (!expr) {
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ exit(EXIT_FAILURE);
+ }
+#endif /* NDEBUG */
+}
+#endif /* NDEBUG && __GNUC__ */
+
+
+#if defined(NDEBUG) && defined(__GNUC__)
+/* Nothing. pmesg has been "defined away" in util.h already. */
+#else
+void pmesg(int level, const char * format, ...) {
+#ifdef NDEBUG
+ /* Empty body, so a good compiler will optimise calls
+ to pmesg away */
+#else
+ va_list args;
+
+ if (level>msglevel)
+ return;
+
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+#endif /* NDEBUG */
+#endif /* NDEBUG && __GNUC__ */
+}
+
+const char * const util_notreached_format =
+ "Please report a bug. Include in the report "
+ "the following information,\n"
+ "exactly as it is written here: "
+ "\"%s:%i was reached\".\n"
+ "Please include in your report as much detail "
+ "as possible about what you\n"
+ "were doing at the "
+ "time you saw this message. Thank you.\n";
+
+
+
+const char * const util_oom_format = "Out of memory (near %s line %d)\n";
+
+void * util_xmalloc(size_t size, const char * file, int line)
+{
+ void * res;
+
+ res = malloc(size);
+ if(res == NULL && size != 0) panic(util_oom_format, file, line);
+ return res;
+}
+
+
+/* Simulate malloc(0) == NULL behaviour with GNU libc.
+ * Useful for debugging purposes only.
+ * Does not work with C libraries different from GNU libc!
+ */
+#ifdef USE_MALLOC0
+#include <malloc.h>
+
+typedef void * mallhook_func(size_t, const void *);
+mallhook_func * old_mallhook;
+
+/* our replacement malloc */
+void * malloc0(size_t size, const void * caller);
+
+void * malloc0(size_t size, const void * caller)
+{
+ void * result;
+
+ if(size == 0) return NULL;
+
+ /* restore old hook */
+ __malloc_hook = old_mallhook;
+
+ /* call real malloc */
+ result = malloc(size);
+
+ /* save old hook again because it may have changed itself */
+ old_mallhook = __malloc_hook;
+
+ /* hook in again */
+ __malloc_hook = &malloc0;
+
+ return result;
+}
+
+void use_malloc0(void)
+{
+ /* save old hook */
+ old_mallhook = __malloc_hook;
+
+ /* set to our one */
+ __malloc_hook = malloc0;
+}
+#endif /* USE_MALLOC0 */
+
+
+void strupcase(char * s)
+{
+ register char * p;
+
+ for (p = s; *p !=0; ++p) {
+ *p = islower(*p) ?
+ toupper(*p) :
+ *p;
+ }
+}
+
+char * strupcasedup(char const * s)
+{
+ char * su;
+
+ su = malloc(strlen(s) + 1);
+ if (su == NULL) return NULL;
+ strcpy(su, s);
+ /* We don't use strdup because it's not part of ISO C. */
+ strupcase(su);
+
+ return su;
+}
+
+int patmatch(char const * pat, char const * s)
+{
+ for( ; *pat != 0; ++pat, ++s) {
+ switch(*pat) {
+ case '*':
+ ++pat;
+ if(*pat == 0) return 1;
+ /* speedup in frequent case that pattern ends with '*' */
+ do {
+ if(patmatch(pat, s)) return 1;
+ } while(*s++ != 0);
+ return 0;
+ case '?':
+ if(*s == 0) return 0;
+ break;
+#if 0
+ /* Possibly useful extension: '+' matches 0 or 1 characters.
+ * Or even interchange '+', '?' ? Disabeled for now.
+ */
+ case '+':
+ ++pat;
+ return ((*s != 0) && patmatch(pat, s+1)) || patmatch(pat, s);
+#endif
+ case '#':
+ if(!isdigit(*s)) return 0;
+ break;
+#if 0
+ /* Possibly useful extension: '\\' protects next char from
+ * wildcard interpretation. Disabeled for now.
+ */
+ case '\\':
+ ++pat;
+ assert(*pat != 0);
+ /* fall through to default */
+#endif
+ default:
+ if(*pat != *s) return 0;
+ /* this covers premature end of s, too */
+ } /* switch */
+ } /* for */
+ return (*s == 0);
+}
diff --git a/dviware/catdvi/util.d b/dviware/catdvi/util.d
new file mode 100644
index 0000000000..329aa4dde1
--- /dev/null
+++ b/dviware/catdvi/util.d
@@ -0,0 +1 @@
+util.o util.d : util.c util.h
diff --git a/dviware/catdvi/util.h b/dviware/catdvi/util.h
new file mode 100644
index 0000000000..a2ab5e3bd0
--- /dev/null
+++ b/dviware/catdvi/util.h
@@ -0,0 +1,121 @@
+/*
+ Copyright (C) 1999 J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl>
+ Copyright (C) 1999 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <stddef.h>
+
+#ifndef max
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef min
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define lengthof(array) (sizeof(array) / sizeof(array[0]))
+/* the number of elements in an array (a real one, NOT a pointer) */
+
+extern int msglevel;
+extern int suppress_warnings;
+extern int num_warnings;
+
+#ifdef __GNUC__
+# define FORMAT(x) __attribute__((format x))
+#else
+# define FORMAT(x) /* nothing */
+#endif
+
+void warning(const char * format, ...) FORMAT((printf, 1, 2));
+/* print an unsurpressable warning */
+
+void panic(const char * format, ...) FORMAT((printf, 1, 2));
+/* print a message, and exit */
+
+
+#if defined(NDEBUG) && defined(__GNUC__)
+/* gcc's cpp has extensions; it allows for macros with a variable number of
+ * arguments. We use this extension here to preprocess eassert away. */
+#define eassert(int expr, format, args...) ((void)0)
+#else
+void eassert(int expr, const char * format, ...) FORMAT((printf, 2, 3));
+/* Like assert(), but with a descriptive message */
+#endif
+
+
+#if defined(NDEBUG) && defined(__GNUC__)
+/* gcc's cpp has extensions; it allows for macros with a variable number of
+ arguments. We use this extension here to preprocess pmesg away. */
+#define pmesg(level, format, args...) ((void)0)
+#else
+void pmesg(int level, const char * format, ...) FORMAT((printf, 2, 3));
+/* print a message, if it is considered significant enough.
+ Adapted from [K&R2], p. 174 */
+#endif
+
+
+extern const char * const util_notreached_format;
+#define NOTREACHED panic(util_notreached_format, __FILE__, __LINE__)
+
+
+extern const char * const util_oom_format;
+#define enomem( ) panic(util_oom_format, __FILE__, __LINE__)
+
+
+/* xmalloc(size) tries to malloc() size bytes of memory and panics with a
+ * diagnostic message if it didn't get them. There are situations when it is
+ * convenient to ask for zero bytes of memory (variable length arrays in .tfm
+ * data which may have length 0). ISO C allows malloc(0) to return NULL, and
+ * on some systems (e.g. AIX 4.2) it really does, so we must not panic
+ * in this case.
+ *
+ * xmalloc() is implemented as a macro. Memory checkers like to #define
+ * it themselves, and we don't want to stop them.
+ */
+#ifndef xmalloc
+#define xmalloc(size) util_xmalloc(size, __FILE__, __LINE__)
+#endif
+extern void * util_xmalloc(size_t size, const char * file, int line);
+
+/* Simulate malloc(0) == NULL behaviour with GNU libc.
+ * Useful for debugging purposes only.
+ * Does not work with C libraries different from GNU libc !
+ */
+#ifdef USE_MALLOC0
+extern void use_malloc0(void);
+#endif
+
+/* Conver a string in-place to upper case */
+void strupcase(char * s);
+
+/* Return a malloc'ed upper-case copy of a string, NULL if out of memory. */
+char * strupcasedup(char const * s);
+
+/* Simple shell-style pattern matching. Wildcards are:
+ * '*': matches any string (including empty string)
+ * '?': matches any single character
+ * '#': matches any decimal digit (convenient for TeX font names)
+ * Returns true if matching, 0 otherwise.
+ */
+int patmatch(char const * pat, char const * s);
+
+
+#endif /* UTIL_H */
diff --git a/dviware/catdvi/version.h b/dviware/catdvi/version.h
new file mode 100644
index 0000000000..23a8169fd6
--- /dev/null
+++ b/dviware/catdvi/version.h
@@ -0,0 +1,3 @@
+#define PACKAGE "catdvi"
+#define VERSION "0.14"
+
diff --git a/dviware/catdvi/version.h.in b/dviware/catdvi/version.h.in
new file mode 100644
index 0000000000..dcb761509b
--- /dev/null
+++ b/dviware/catdvi/version.h.in
@@ -0,0 +1,3 @@
+#define PACKAGE "@PACKAGE@"
+#define VERSION "@VERSION@"
+
diff --git a/dviware/catdvi/vlist.c b/dviware/catdvi/vlist.c
new file mode 100644
index 0000000000..c1d1b2effb
--- /dev/null
+++ b/dviware/catdvi/vlist.c
@@ -0,0 +1,231 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "vlist.h"
+#include "util.h"
+
+#ifndef NDEBUG
+
+/* try to catch accesses to freed list nodes */
+static const vlist_node_t dead_node = {NULL, NULL, NULL};
+#define free_node(p) {*(p) = dead_node; free(p);}
+
+#else
+
+#define free_node(p) free(p)
+
+#endif
+
+
+void vlist_init(vlist_t * this)
+{
+ this->rend_node.prev = NULL;
+ this->rend_node.next = vlist_end(this);
+ this->rend_node.data = NULL;
+
+ this->end_node.prev = vlist_rend(this);
+ this->end_node.next = NULL;
+ this->end_node.data = NULL;
+
+ this->size = 0;
+}
+
+void vlist_done(vlist_t * this)
+{
+ vlist_clear(this);
+ this->rend_node.next = NULL;
+ this->end_node.prev = NULL;
+ this->size = 0;
+}
+
+
+void vlist_push_front(vlist_t * this, void const * newdata)
+{
+ vlist_insert_before(this, vlist_begin(this), newdata);
+}
+
+void vlist_pop_front(vlist_t * this)
+{
+ assert(this->size > 0);
+ vlist_erase(this, vlist_begin(this));
+}
+
+void vlist_push_back(vlist_t * this, void const * newdata)
+{
+ vlist_insert_after(this, vlist_rbegin(this), newdata);
+}
+
+void vlist_pop_back(vlist_t * this)
+{
+ assert(this->size > 0);
+ vlist_erase(this, vlist_rbegin(this));
+}
+
+
+vitor_t vlist_insert_before(
+ vlist_t * this,
+ vitor_t where,
+ void const * newdata
+)
+{
+ vitor_t prev, newnode;
+
+ assert(where != vlist_rend(this));
+ prev = where->prev;
+
+ newnode = malloc(sizeof(vlist_node_t));
+ if(newnode == NULL) enomem();
+
+ newnode->prev = prev;
+ newnode->next = where;
+ newnode->data = (void *) newdata; /* de-const is intentional */
+
+ prev->next = newnode;
+ where->prev = newnode;
+
+ this->size += 1;
+ return newnode;
+}
+
+vitor_t vlist_insert_after(
+ vlist_t * this,
+ vitor_t where,
+ void const * newdata
+)
+{
+ vitor_t next, newnode;
+
+ assert(where != vlist_end(this));
+ next = where->next;
+
+ newnode = malloc(sizeof(vlist_node_t));
+ if(newnode == NULL) enomem();
+
+ newnode->prev = where;
+ newnode->next = next;
+ newnode->data = (void *) newdata; /* de-const is intentional */
+
+ where->next = newnode;
+ next->prev = newnode;
+
+ this->size += 1;
+ return newnode;
+}
+
+void vlist_erase(vlist_t * this, vitor_t what)
+{
+ vitor_t prev, next;
+
+ assert(what != vlist_rend(this));
+ assert(what != vlist_end(this));
+ prev = what->prev;
+ next = what->next;
+
+ prev->next = next;
+ next->prev = prev;
+
+ free_node(what);
+ this->size -= 1;
+}
+
+void vlist_clear(vlist_t * this)
+{
+ vitor_t p, q;
+
+ for(p = vlist_begin(this); p != vlist_end(this); p = q) {
+ q = p->next;
+ free_node(p);
+ }
+
+ this->rend_node.next = vlist_end(this);
+ this->end_node.prev = vlist_rend(this);
+
+ this->size = 0;
+}
+
+
+void vlist_swap_consecutive(vlist_t * this, vitor_t first, vitor_t second)
+{
+ vitor_t prev, next;
+
+ assert(first != vlist_rend(this));
+ assert(second != vlist_end(this));
+ assert(first->next == second);
+
+ prev = first->prev;
+ next = second->next;
+
+ prev->next = second;
+ second->next = first;
+ first->next = next;
+
+ next->prev = first;
+ first->prev = second;
+ second->prev = prev;
+}
+
+void vlist_move_before(vlist_t * this, vitor_t where, vitor_t what)
+{
+ vitor_t oldprev, oldnext, newprev;
+
+ assert(what != vlist_rend(this));
+ assert(what != vlist_end(this));
+ assert(where != vlist_rend(this));
+ assert(what != where);
+
+ /* unlink what */
+ oldprev = what->prev;
+ oldnext = what->next;
+ oldprev->next = oldnext;
+ oldnext->prev = oldprev;
+
+ /* and link in before where */
+ newprev = where->prev;
+ /* don't do this earlier or it will break if where->prev == what */
+ newprev->next = what;
+ what->next = where;
+ where->prev = what;
+ what->prev = newprev;
+}
+
+void vlist_move_after(vlist_t * this, vitor_t where, vitor_t what)
+{
+ vitor_t oldprev, oldnext, newnext;
+
+ assert(what != vlist_rend(this));
+ assert(what != vlist_end(this));
+ assert(where != vlist_end(this));
+ assert(what != where);
+
+ /* unlink what */
+ oldprev = what->prev;
+ oldnext = what->next;
+ oldprev->next = oldnext;
+ oldnext->prev = oldprev;
+
+ /* and link in after where */
+ newnext = where->next;
+ /* don't do this earlier or it will break if where->next == what */
+ where->next = what;
+ what->next = newnext;
+ newnext->prev = what;
+ what->prev = where;
+}
diff --git a/dviware/catdvi/vlist.d b/dviware/catdvi/vlist.d
new file mode 100644
index 0000000000..bceceb76d9
--- /dev/null
+++ b/dviware/catdvi/vlist.d
@@ -0,0 +1 @@
+vlist.o vlist.d : vlist.c vlist.h util.h
diff --git a/dviware/catdvi/vlist.h b/dviware/catdvi/vlist.h
new file mode 100644
index 0000000000..5939247f8c
--- /dev/null
+++ b/dviware/catdvi/vlist.h
@@ -0,0 +1,119 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef VLIST_H
+#define VLIST_H
+
+/* Non-intrusive generic backlinked list, realised as list of void*.
+ * For variety, I've tried a C++ STL style list instead of traditional
+ * C style.
+ * It turns out this can be done with some elegance even in C.
+ */
+
+typedef struct vlist_node_t vlist_node_t;
+struct vlist_node_t {
+ vlist_node_t * prev;
+ vlist_node_t * next;
+ void * data;
+};
+
+/* The iterator type, in C++ nomenclature */
+typedef vlist_node_t * vitor_t;
+
+typedef struct vlist_t vlist_t;
+struct vlist_t {
+ /* private */
+ vlist_node_t rend_node; /* "inaccessible" node before list head */
+ vlist_node_t end_node; /* "inaccessible" node after list tail */
+ /* public const */
+ size_t size;
+};
+
+/* constructor */
+void vlist_init(vlist_t * this);
+
+/* destructor */
+void vlist_done(vlist_t * this);
+
+/* rend is the iterator before the list head, used as stop value (instead
+ * of NULL) in loops traversing the list backwards.
+ */
+#define vlist_rend(this) (&(this)->rend_node)
+
+/* end is the iterator after the list tail, used as stop value (instead
+ * of NULL) in loops traversing the list forward.
+ * This implementation as macros allows the compiler to recognise end and
+ * rend as run-time constant inside the loop, so that the calculation can
+ * be moved out of the loop and done only once.
+ */
+#define vlist_end(this) (&(this)->end_node)
+
+/* list head */
+#define vlist_begin(this) ((this)->rend_node.next)
+
+/* list tail */
+#define vlist_rbegin(this) ((this)->end_node.prev)
+
+/* insert before head */
+void vlist_push_front(vlist_t * this, void const * newdata);
+
+/* remove head */
+void vlist_pop_front(vlist_t * this);
+
+/* insert after tail */
+void vlist_push_back(vlist_t * this, void const * newdata);
+
+/* remove tail */
+void vlist_pop_back(vlist_t * this);
+
+/* insert before node */
+vitor_t vlist_insert_before(
+ vlist_t * this,
+ vitor_t where,
+ void const * newdata
+);
+
+/* insert after node */
+vitor_t vlist_insert_after(
+ vlist_t * this,
+ vitor_t where,
+ void const * newdata
+);
+
+/* remove node */
+void vlist_erase(vlist_t * this, vitor_t what);
+
+/* remove all nodes */
+void vlist_clear(vlist_t * this);
+
+/* swap consecutive nodes */
+void vlist_swap_consecutive(vlist_t * this, vitor_t first, vitor_t second);
+
+/* move node what before node where */
+void vlist_move_before(vlist_t * this, vitor_t where, vitor_t what);
+
+/* move node what after node where */
+void vlist_move_after(vlist_t * this, vitor_t where, vitor_t what);
+
+/* get *data as lvalue of appropriate type */
+#define vitor_deref(it, type) (*(type *) (it)->data)
+
+/* get data as pointer to appropriate type */
+#define vitor2ptr(it, type) ((type *) (it)->data)
+
+#endif /* VLIST_H */