aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/ttf2pt1
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2015-02-02 15:02:49 +0100
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2015-02-02 15:02:49 +0100
commitb16b9e4656e7199c2aec74a4c8ebc7a875d3ba73 (patch)
tree4361edef0d42d5bf5ac984ef72b4fac35426eae7 /nx-X11/extras/ttf2pt1
parent0d5a83e986f39982c0924652a3662e60b1f23162 (diff)
downloadnx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.tar.gz
nx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.tar.bz2
nx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.zip
massive reduction of unneeded files
Diffstat (limited to 'nx-X11/extras/ttf2pt1')
-rw-r--r--nx-X11/extras/ttf2pt1/CHANGES.html805
-rw-r--r--nx-X11/extras/ttf2pt1/COPYRIGHT87
-rw-r--r--nx-X11/extras/ttf2pt1/FONTS.hpux.html197
-rw-r--r--nx-X11/extras/ttf2pt1/FONTS.html708
-rw-r--r--nx-X11/extras/ttf2pt1/Makefile279
-rw-r--r--nx-X11/extras/ttf2pt1/README.FIRST4
-rw-r--r--nx-X11/extras/ttf2pt1/README.html1182
-rw-r--r--nx-X11/extras/ttf2pt1/bdf.c660
-rw-r--r--nx-X11/extras/ttf2pt1/bitmap.c2633
-rw-r--r--nx-X11/extras/ttf2pt1/byteorder.h24
-rw-r--r--nx-X11/extras/ttf2pt1/cygbuild.sh8
-rw-r--r--nx-X11/extras/ttf2pt1/ft.c808
-rw-r--r--nx-X11/extras/ttf2pt1/global.h174
-rw-r--r--nx-X11/extras/ttf2pt1/pt1.c7374
-rw-r--r--nx-X11/extras/ttf2pt1/pt1.h257
-rw-r--r--nx-X11/extras/ttf2pt1/runt1asm.c61
-rw-r--r--nx-X11/extras/ttf2pt1/t1asm.c606
-rw-r--r--nx-X11/extras/ttf2pt1/ttf.c1480
-rw-r--r--nx-X11/extras/ttf2pt1/ttf.h183
-rw-r--r--nx-X11/extras/ttf2pt1/ttf2pt1.1832
-rw-r--r--nx-X11/extras/ttf2pt1/ttf2pt1.c2722
-rw-r--r--nx-X11/extras/ttf2pt1/ttf2pt1_convert.1516
-rw-r--r--nx-X11/extras/ttf2pt1/ttf2pt1_x2gs.1323
-rw-r--r--nx-X11/extras/ttf2pt1/version.h7
-rw-r--r--nx-X11/extras/ttf2pt1/winbuild.bat11
-rw-r--r--nx-X11/extras/ttf2pt1/windows.h93
26 files changed, 0 insertions, 22034 deletions
diff --git a/nx-X11/extras/ttf2pt1/CHANGES.html b/nx-X11/extras/ttf2pt1/CHANGES.html
deleted file mode 100644
index 9b51d1bc8..000000000
--- a/nx-X11/extras/ttf2pt1/CHANGES.html
+++ /dev/null
@@ -1,805 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>
-TTF2PT1 - CHANGES history
-</TITLE>
-</HEAD>
-<BODY>
-<H2>
-TTF2PT1 - CHANGES history
-</H2>
-
-<!
-(Do not edit this file, it is generated from CHANGES.html!!!)
->
-
-<H4>
-3.4.4-SNAP-030526
-</H4>
-<!
--------
->
-
-<b>New features:</b>
-<ul>
-<li> Improved the auto-vectoring (-OV) alrogithm.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Fix to build all the features on Windows MS C++, by Tomoo Amano.
-</ul>
-
-<H4>
-3.4.3 -- December 2, 2002
-</H4>
-<!
--------
->
-
-<b>New features:</b>
-<ul>
-<li> <tt>scripts/forceiso</tt> got an optional argument to select the
- format of the names for glyphs without standard Latin-1 names.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Changed the glyph names in scripts/forceiso to match those in ttf2pt1.
-<li> Included the missing directory app/TeX.
-</ul>
-
-<H4>
-3.4.2 -- August 30, 2002
-</H4>
-<!
--------
->
-
-<b>New features:</b>
-<ul>
-<li> New map for T2A_compat encoding (for Cyrillic LaTeX) by Mikhail
- Umorin.
-<li> Scripts supporting font conversion for CJK-LaTeX, by Mike Fabian
- from SuSE.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Explicit owner/group/permissions are used to install directories.
-<li> In scripts/convert fixed the addition of encoding name to the font
- name for the external encoding maps, was missing "/" at the start.
-<li> Fixed the divergence between two copies of UniqueID.
-<li> Fixed the recovery after defective empty contours.
-</ul>
-
-<H4>
-3.4.1 -- June 13, 2002
-</H4>
-<!
--------
->
-
-<b>New features:</b>
-<ul>
-<li> Added Autotrace support for the bitmap fonts (-OZ). It's horrible.
-<li> Added vectorization of bitmap fonts (-OV) - functionally the same thing as
- autotrace but home-grown. Works mostly decently but still with large
- space for impprovement.
-<li> Relaxed the conditions for warnings about long glyphs.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Fix by Rob Kolstad for a crash in the new outline smoothing
- code (on small thin contours) and diagnostic for another crash.
-<li> Fix by Holger Huesing for a crash on degenerate contours.
-<li> Fix for bitmaps of zero dimensions.
-<li> The BDF reader does not fail on redefintion of the properties.
-<li> Fix for reading of BDF glyphs with 0 size.
-<li> Fix for a hang when guessing the boldness of some fonts.
-<li> Fix by Adriano Konzen for scaling coefficients in composite glyphs.
-</ul>
-
-<H4>
-3.4.0 -- November 24, 2001
-</H4>
-<!
--------
->
-
-<b>New features:</b>
-<ul>
-<li> Parser for the BDF bitmap fonts.
-<li> Vastly improved the smoothing of the outlines.
-<li> The options are saved as a comment in the output file.
-<li> New script <tt>other/showdf</tt> for visual comparison of the fonts.
-<li> New option <b>-G</b> to select the file types to generate.
-<li> Creation of the dvips encoding files (by Rigel).
-<li> More glyphs in the Chinese maps (by Rigel).
-<li> Made the assignment of ISO8859/1 glyph names to the glyphs in the
- fonts without PostScript names in them dependent on the original
- encoding: no change for the 8-bit encodings, for the Unicode encoding
- the names are assigned to the glyph with the codes 0-255 in Unicode,
- and for the other 16-bit encodings the 8859/1 names are not assigned
- at all.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Added a check for spaces in the PostScript font name in the FreeType
- parser.
-<li> Made "-" a valid character in the glyph names.
-<li> Fixed handling of the Unicode names returned by FreeType, though
- not perfectly.
-<li> Changed the build for FreeType-2.0.4.
-<li> Fixed the handling and printing of bad glyph names.
-<li> Fixed the bug with duplicated glyph names when more than 256 glyphs are
- extracted from a font that has no PostScript glyph names defined.
-<li> Added ability to map a glyph to more than one code when unisng the
- native parser (-pttf).
-</ul>
-
-<H4>
-3.3.5 -- September 12, 2001
-</H4>
-<!
--------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Fixed the scaling of Ascender and Descender in the AFM file.
-<li> Fixed the brekage of "-l adobestd".
-</ul>
-
-<H4>
-3.3.4 -- June 4, 2001
-</H4>
-<!
--------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Cyrillic (full set of glyphs) language tables (by Zvezdan Petkovic).
- Now the languages "russian" and "bulgarian" are provided for compatibility
- only, use the common language "cyrillic" instead.
-<li> More information in <a href="FONTS.html">FONTS</a> on using Cyrillic fonts with
- Netscape (by Zvezdan Petkovic)
-<li> In the Netscape print filter added removal of the clipping path command:
- otherwise Netscape tends to cut off a large piece of the rightmost column
- of the tables.
-<li> One more script for printing from Netscape (by Zvezdan Petkovic).
-<li> Added selection of the base TTF encoding by pid/eid in the external maps.
-<li> Improved the recognition of substituted stems for intersecting contours.
-<li> Improved the substituted hints to make the horizontal positioning of
- the points at the same height more uniform at small pixel sizes.
-<li> Made the algorithm for calculation of standard stem widths more
- selective.
-<li> Added link to the GnuWin32 project.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> TH: Print out metrics of un-encoded glyphs even without "-a" option.
-<li> Added missing "/" in Fontmap generation in convert (by Zvezdan Petkovic).
-<li> Removed unneccessary "\n" in messages in x2gs.
-<li> Removed the broken overoptimisation of "0 0 rmoveto".
-<li> Removed the useless warnings about multiple codes for a glyph.
-<li> Changed the FreeType2 include directory in the Makefile to match the
- FreeType's default.
-</ul>
-
-<H4>
-3.3.3 -- March 4, 2001
-</H4>
-<!
--------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> TH: Added printing of front-end parser in the header of the font file.
-<li> Tested build with FreeType 2.0 Release.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Changed the installation script which on some versions of bash
- copied all files into the share directory.
-<li> Fixed the close sequences of html2man comments in the HTML files,
- now they should display correctly with <tt>lynx</tt>.
-<li> Restored the ability to include un-encoded characters into the
- customised maps (those with codes over 255).
-<li> Fixed the Unicode mapping of the Cyrillic letters "YO" and "yo"
- (by Yuri Shemanin).
-<li> Fixed the spurious aborts when the conversion-by-plane function
- gets called for auto-guessing of encoding.
-</ul>
-
-<H4>
-3.3.2 -- November 20, 2000
-</H4>
-<!
---------------------------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Added generation of man pages.
-<li> Added "make install" and "make uninstall".
-<li> Added language option "-l plane".
-<li> In <tt>other/showg</tt> added better support of comparison files:
-<ul>
- <li> printing of the comparison file legend;
- <li> guessing of missing glyph names in a comparison file by code;
- <li> bounding boxes of all comparison files are used for page layout.
-</ul>
-<li> Added ability to use external t1asm instead of compiling it in.
-<li> Renamed the fonts installation guide from INSTALL*html to FONTS*html
- to avoid confusion with installation of ttf2pt1 itself.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Removed erroneous extra fclose(pfa_file).
-<li> Fixed random memory corruption that manifested with crash on Linux
- when converting fonts not containing glyph names.
-<li> Removed from the output file the comments that confused dvips. Changed
- <tt>other/showg</tt> to work without them.
-<li> In <tt>other/showg</tt> added better checks for missing glyphs, now it
- gives warnings about them and the output file does not crash PostScript.
-</ul>
-
-<b>Other:</b>
-<ul>
-<li> <tt>ttf2pfa</tt> is no longer included, people interested in history
- should look for it in the older versions.
-</ul>
-
-<H4>
-3.3.1 -- October 22, 2000
-</H4>
-<!
--------------------------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Added front-end parser based on the FreeType-2 library. See Makefile
-for build instructions.
-<li> Changed the handling of encodings to accomodate the FreeType model.
-<li> Further cleaned up the front-end parser interface.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Fixed a bug that caused core dump on Alpha machines.
-<li> Fixed a bug in the outline smoothing that occasionally caused core dump.
-<li> Cleaned up warnings from picky compilers
-<li> Fixed more bugs in the Windows port (by Stefan Bauer).
-<li> Fixed the RPM spec file (suggested by Brian Armstrong).
-</ul>
-<p>
-
-<H4>
-3.3.0 -- September 22, 2000
-</H4>
-<!
----------------------------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Converted most of the outlines' processing to floating point
-arithmetic.
-<li> Added splitting of curves crossing the quadrant boundaries (no gross
-damage is done any more to the Marvosym font and others like it).
-<li> Added modular interface for front-end font parsers and option to control
-their selection at run time.
-<li> Grouped the outline processing control options into one to reduce the
-options namespace pollution.
-<li> Thomas moved the Chinese maps into a separate module, chinese-maps.
-<li> Thomas added option -V to print version number. In addition, the version
-number is put in the header of the font file.
-<li> Added long option names (suggested by Thomas).
-<li> Added support for multi-level composite glyphs.
-<li> TH: Made &lt;fontname&gt; command-line argument optional; default to &lt;ttf-file&gt;
-with suffix replaced.
-<li> In <tt>other/showg</tt> added more ways to specify glyphs and the comparison option.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Fixed the VC++ batch file, added batch file for Cygnus GCC on Windows.
-<li> Removed parentheses from the Version string in AFM files because it does
-not help StarOffice anyway. StarOffice 5.2 has been reported to have this
-bug fixed. Added paragraph on StarOffice in FONTS.html.
-<li> Made messages on the '?' option parameter more meaningful (by Johan Vromans).
-<li> Changed the latin1 encoding table to include the Euro sign, Z and z with
-caron (by Thomas Henlich).
-<li> Improved the smoothing code which occasionally had problems with
-joining curves. Also fixed a few minor bugs in it.
-</ul>
-
-<H4>
-3.22 -- May 23, 2000
-</H4>
-<!
---------------------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Included windows support by Frank Siegert (somewhat amended)
-<li> Added control over verbosity of warnings.
-<li> Added arguments and initialization functions to the language
-translation routines.
-<li> Added support of planes determined by arguments to the external
-maps.
-<li> Added compact external maps format (primarily for Eastern fonts).
-<li> Added external maps for Chinese GBK and Big5 encodings (converted
-from ttf2pfb) as well as maps for other Chinese encodings by Wang Lei.
-<li> Added the idea of buckets to speed up the search in external maps.
-<li> Changed the grouping algorithm for substituted hints: now it creates
-a bit bigger files but requires smaller hint stack when being rendered.
-<li> Added maximal limit of hint stack depth, glyphs requiring bigger
-stack get generation of substituted hints disabled. This makes substituted
-hints safe to use, no more lost glyphs due to hint stack overflow.
-<li> Added the font dump program <tt>other/dumpf</tt>.
-<li> Changed the testing HTML generator <tt>other/lst.pl</tt> to use tables.
-<li> Added debugging script <tt>other/cntstems.pl</tt> to count required hint
-stack depth for the glyphs.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> Fixed printing of UID in script/trans. Changed the auto-generated UID to
-be in range 4000000-4999999 which is reserved by Adobe for private use.
-<li> Fixed handling of "cleartomark" in built-in t1asm.
-<li> Added handling of "can't happen" case in straighten() routine
-which actually happened on strange fonts and caused failure on assertion.
-<li> Made it always include the glyph .notdef in the resulting font.
-<li> Placed the version string in AFM file in parentheses, hopefully
-that would fix the problem with StarOffice.
-<li> Improved the smoothing code which occasionally had problems with
-joining curves.
-</ul>
-
-<H4>
-3.21 -- March 1, 2000
-</H4>
-<!
----------------------
->
-
-Sergey Babkin: committed the changes by Petr Titera and
-my bugfixes.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> New Unicode map format with glyph names, by Petr Titera.
-<li> Option to force the Unicode encoding by Petr Titera
- (I changed it to work on any MS encoding, not only Symbol).
-<li> Slightly tweaked the calculation of hints, should be better now.
-</ul>
-
-<b>Bug fixes:</b>
-<ul>
-<li> The unicode-sample.map with description of the map formats
- was lost in the release process, restored and enhanced.
-<li> Renamed the table ISOLatin1Encoding to Fmt3Encoding to reflect
- the way it is used. Saved the original one for reference
- purposes. In the new table renamed "quoteright" to "quotesingle"
- as Thomas Henlich suggested (and he were right).
-<li> In the ISOLatinEncoding table renamed the glyph "grave"
- at octal 0140 to "quoteleft", "quotesingle" at octal 047 to
- "quoteright" to conform to the standard as suggested by
- Martin Trautner).
-<li> Fixed bug in scripts/trans that corrupted the UniqueID record
- in the translated fonts.
-<li> Fixed bug in interaction of substituted hints with BlueZones.
- Now the fonts with hint substitution seem to be always at least
- not worse than without it (well, when they fit in the X11
- file size limit).
-</ul>
-
-
-<H4>
-3.2 -- January 15, 2000
-</H4>
-<!
------------------------
->
-
-Sergey Babkin: combined my changes with the changes by
-Thomas Henlich. The result deserves a not-so-minor version
-increase.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Support of the external Unicode re-encoding maps
- (by Thomas).
-<li> Support for inclusion of all the glyphs from the
- source file into the resulting file (inspired by
- Thomas but I re-implemented it to remove the limitation
- of his implementation: not more than 1024 glyphs).
-<li> The hints substitution. It's an experimental feature
- yet and needs further work.
-<li> Support for UniqueID and its auto-generation.
-<li> Support for the name-based conversions from Unicode
- in general and the adobestd "language" in particular.
-<li> Started the split of the source code into multiple
- files. This needs more work to do it in a cleaner
- way.
-<li> Better framework for the debugging printout
- in the converter.
-<li> Utilities to install the fonts in Netscape
- Navigator/Communicator 4.x.
-<li> Patches for bigger font files in the X11 rasterizer.
-<li> Linux RPM spec-file (by Johan Vromans).
-<li> Added the COPYRIGHT file (BSD-style, as we discussed
- on the mailing list earlier) and the CHANGES file.
-<li> Creation of the <tt>.pfb</tt> files from the <tt>convert</tt>
- script.
-<li> Changed the <tt>.notdef</tt>-s in the built-in
- ISOLatin1Encoding table to some valid names (by Thomas).
- Thomas also suggested replacing `<tt>quoteright</tt>' by
- `<tt>quotesingle</tt>' but this seems to be against the
- Adobe ISOLatin1 table.
-<li> New aliases <tt>windows-1251</tt> and <tt>cp-866</tt> for
- the Russian encodings: those are expected by Netscape
- navigator.
-<li> The font comparison program <tt>other/cmpf</tt>.
-<li> The "magnifying glass" program for glyph outlines:
- <tt>other/showg</tt>.
-<li> Other updates of the tools in the `<tt>other</tt>' subdirectory.
-<li> Added a link to T1LIB in README.
-<li> A few new options in <tt>convert.cfg</tt>.
-</ul>
-
-<b>Bux fixes:</b>
-<ul>
-<li> A bug in the outline smoothing code that corrupted some
- of the fonts (for example, Microsoft Verdana).
-<li> Added explicit `<tt>cleartomark</tt>' to the end of file,
- this seems to be compatible with both old and new version
- of <tt>t1asm</tt> (suggested by Thomas).
-<li> Added the <tt>FontEncoding</tt> statement to the AFM files
- (techincally this was not a bug because this statement
- is optional but some programs want it).
-<li> A coredump when the converter tried to print a warning
- (rather ironically) about a weird glyph width.
-<li> Changed the underscores in the font names to dashes (this
- has been proposed long time ago by Johan Vromans).
-<li> No more glyph names of font names staring with a digit.
-<li> The names of the fonts in font and AFM files are now the
- same as in the generated Ghostscript <tt>Fontmap</tt> file.<br>
- <b>Warning:</b> the names in <tt>Fontmap</tt> have been
- changed.
-<li> The <tt>forceiso</tt> script does not corrupt the character
- and kerning pairs counts any more, and is optional at all.
-<li> Fix for a loop going to 254 instead of 255 (by Thomas).
-<li> Added ':' in the font header (by Thomas).
-<li> A coredump when wrong language name is given (this was
- also fixed by Thomas but I noticed it too late, after
- I already fixed it by myself).
-<li> Fixed the links to the Adobe documents in README.
-</ul>
-
-
-<H4>
-3.13 -- October 18, 1999
-</H4>
-<!
-------------------------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> New option -v for automatic re-scaling based on the vertical size of the font
-<li> Changed the code to use getopt() instead of a home-made version of it.
-<li> Latin2 language support by Szalay Tamas.
-</ul>
-
-<b>Bux fixes:</b>
-<ul>
-<li> Fix for the bug that made possible calls of malloc(0).
-<li> Refinement of the option -w to prevent extra wide spacing
-</ul>
-
-<H4>
-3.12 -- October 2, 1999
-</H4>
-<!
------------------------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Added support for the Bulgarian language (actually, for now just an alias
-of Russian).
-<li> Added option -w that tries to make sure that the character widths are not
-too narrow.
-<li> Added the concept of aliased encodings.
-<li> Now the conversion scripts create and install the .afm files too.
-<li> The conversion script removes the intermediate files after installation.
-<li> Added tunables to the conversion script.
-<li> Installation of the Ghostscript fonts can now be done automatically
-together with the X11 fonts.
-</ul>
-
-<b>Bux fixes:</b>
-<ul>
-<li> (FINALLY!!!) A correct fix for the infamous Red Hat 6.0 stdio "feature".
-<li> A number of little bugs discovered by a picky SGI compiler (well, maybe
-some day I'll try to run it through the UnixWare lint and see what happens).
-<li> A diagnostic message about the empty encodings in the convert script was
-made less cryptic and a bug in the awk sub-script was fixed.
-<li> The .afm creation code now considers the option -t.
-</ul>
-
-<H4>
-3.11 -- May 24, 1999
-</H4>
-<!
---------------------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> It includes the Turkish (Latin5, ISO8859/9)
-language support by Turgut Uyar and Baltic (ISO8859/4) languages support by
-Rihardas Hepas.
-<li> Also the installation script got updated: the configuration parameters
-are moved to a separate file and the generated fonts.dir files should now be
-compatible with Xfsft.
-</ul>
-
-<H4>
-3.1 -- March 28, 1999
-</H4>
-<!
----------------------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Improved the interaction of the character-level hints and font-level hints
-</ul>
-
-
-<H4>
-3.0 -- March 6, 1999
-</H4>
-<!
---------------------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Added HTML documents.
-</ul>
-
-<H4>
-3.0beta2 -- February 14, 1999
-</H4>
-<!
------------------------------
->
-
-Packaged by Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Added ability to print the .afm file instead of the font to STDOUT.
-<li> Added the guessing of the /ForceBold parameter that proved to be useful.
-</ul>
-
-<b>Bux fixes:</b>
-<ul>
-<li> Removed the force-fixed option that proved to be troublesome.
-</ul>
-
-<H4>
-3.0beta1 -- December 11, 1998
-</H4>
-<!
------------------------------
->
-
-By Andrew Weeks.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Added option (passed to t1asm) to create a compressed binary
-version of the font (A PFB file).
-</ul>
-
-<b>Bux fixes:</b>
-<ul>
-<li> Versions of handle_post and handle_cmap that deal with some
-problems with buggy fonts.
-<li> Minor Bug Fixes.
-</ul>
-
-<H4>
-3.0beta-afm -- December 5, 1998
-</H4>
-<!
--------------------------------
->
-
-By Thomas Henlich.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Integration of AFM file creation.
-</ul>
-
-<H4>
-3.0beta -- November 15, 1998
-</H4>
-<!
-----------------------------
->
-
-By Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Added the auto-calculation of the italic angle.
-</ul>
-
-<b>Bux fixes:</b>
-<ul>
-<li> Fixed a couple of bugs.
-</ul>
-
-<H4>
-3.0alpha -- October 19, 1998
-</H4>
-<!
-----------------------------
->
-
-By Sergey Babkin.
-<p>
-
-<b>New features:</b>
-<ul>
-<li> Improved (although still not perfect) handling of
-scaling in composite glyphs
-<li> Automatic correction of outlines to make them more
-smooth (to correct both rounding errors introduced
-during conversion and present in the original font)
-<li> Automatic generation of hints (still has lots of
-space for improvement)
-<li> Automatic generation of BlueValues etc.
-</ul>
-
-<b>Bux fixes:</b>
-<ul>
-<li> Scaling of fonts to 1000x1000 M-square required by
-Type1 standard
-<li> Printing out the contours in reverse direction, because
-TTF directions are different from Type1 ones (that was
-the major reason why the fonts generated by
-version 2.2 were rendered so badly in small sizes)
-</ul>
-
-<H4>
-June 22, 1998 (AKA 2.2)
-</H4>
-<!
--------------
->
-
-By Thomas Henlich.
-<p>
-
-<b>Bux fixes:</b>
-<ul>
-<li> "width" should be "short int" because otherwise:
-characters with negative widths (e.g. -4) become *very* wide (65532)
-<li> The number of /CharStrings is numglyphs and not numglyphs+1
-</ul>
-
-<H4>
-February 13, 1998
-</H4>
-<!
------------------
->
-
-By Mark Heath.
-<p>
-
-<b>Bux fixes:</b>
-<ul>
-<li> An original Bug Reported by Frank, which was just incorrect syntax in the
-Type 1 header, managed to creep back into the Feb 04 Version. This has been
-Fixed in the Feb 13 Version.
-</ul>
-
-<H4>
-February 4, 1998
-</H4>
-<!
-----------------
->
-
-By Mark Heath.
-<p>
-
-<b>Bux fixes:</b>
-<ul>
-<li> A workaround was implemented in ttf2pfa by altering the matrix. I suspect
-I will have to calculate the correct values, as matrix ops are probably not
-allowed in Type 1 format.
-</ul>
-
-<!
----------------------------------------------
->
-<H4>
-The older history seems to be lost.
-</H4>
-
-<I>
-(S.B.: The story how we got the version numbers is rather funny. Initially
-there were no version umbers, the releases were marked by dates. The version
-from June 22 1998 untarred itself into a directory "<tt>ttf2pt1-22</tt>". When I
-made my changes to it I assumed that this was the version number meaning
-version 2.2. Since Mark asked me to send him a complete archive I supposed
-that I have to bump the version number. And I bumped it to 3.0 because the
-changes were rather extensive. Mark silently agreed and released the new
-version as 3.0. And that's the end of the story about how we got this
-Microsoft-like high version number.)
-</I>
-
-</BODY>
-</HTML>
diff --git a/nx-X11/extras/ttf2pt1/COPYRIGHT b/nx-X11/extras/ttf2pt1/COPYRIGHT
deleted file mode 100644
index 85950856b..000000000
--- a/nx-X11/extras/ttf2pt1/COPYRIGHT
+++ /dev/null
@@ -1,87 +0,0 @@
-The following copyright notice applies to all the files provided
-in this distribution unless explicitly noted otherwise
-(the most notable exception being t1asm.c).
-
- Copyright (c) 1997-2002 by the AUTHORS:
- Andrew Weeks <ccsaw@bath.ac.uk>
- Frank M. Siegert <fms@this.net>
- Mark Heath <mheath@netspace.net.au>
- Thomas Henlich <thenlich@rcs.urz.tu-dresden.de>
- Sergey Babkin <babkin@users.sourceforge.net>, <sab123@hotmail.com>
- Turgut Uyar <uyar@cs.itu.edu.tr>
- Rihardas Hepas <rch@WriteMe.Com>
- Szalay Tamas <tomek@elender.hu>
- Johan Vromans <jvromans@squirrel.nl>
- Petr Titera <P.Titera@sh.cvut.cz>
- Lei Wang <lwang@amath8.amt.ac.cn>
- Chen Xiangyang <chenxy@sun.ihep.ac.cn>
- Zvezdan Petkovic <z.petkovic@computer.org>
- Rigel <rigel863@yahoo.com>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the TTF2PT1 Project
- and its contributors.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
-For the approximate list of the AUTHORS' responsibilities see the
-project history.
-
-Other contributions to the project are:
-
-Turgut Uyar <uyar@cs.itu.edu.tr>
- The Unicode translation table for the Turkish language.
-
-Rihardas Hepas <rch@WriteMe.Com>
- The Unicode translation table for the Baltic languages.
-
-Szalay Tamas <tomek@elender.hu>
- The Unicode translation table for the Central European languages.
-
-Johan Vromans <jvromans@squirrel.nl>
- The RPM file.
-
-Petr Titera <P.Titera@sh.cvut.cz>
- The Unicode map format with names, the forced Unicode option.
-
-Frank M. Siegert <frank@this.net>
- Port to Windows
-
-Lei Wang <lwang@amath8.amt.ac.cn>
-Chen Xiangyang <chenxy@sun.ihep.ac.cn>
- Translation maps for Chinese fonts.
-
-Zvezdan Petkovic <z.petkovic@computer.org>
- The Unicode translation tables for the Cyrillic alphabet.
-
-Rigel <rigel863@yahoo.com>
- Generation of the dvips encoding files, modification to the Chinese maps.
-
-I. Lee Hetherington <ilh@lcs.mit.edu>
- The Type1 assembler (from the package 't1utils'), its full copyright
- notice:
- Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.
- Permission is hereby granted to use, modify, and distribute this program
- for any purpose provided this copyright notice and the one below remain
- intact.
-
diff --git a/nx-X11/extras/ttf2pt1/FONTS.hpux.html b/nx-X11/extras/ttf2pt1/FONTS.hpux.html
deleted file mode 100644
index 80889cae2..000000000
--- a/nx-X11/extras/ttf2pt1/FONTS.hpux.html
+++ /dev/null
@@ -1,197 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>
-How to install new Type1 fonts on an HP-UX 10.20 machine
-</TITLE>
-</HEAD>
-<BODY>
-Sergey A. Babkin
-<br>
-<A HREF="mailto:babkin@bellatlantic.net">
-&lt;babkin@bellatlantic.net&gt;</A> or <A HREF="mailto:sab123@hotmail.com">&lt;sab123@hotmail.com&gt;</A>
-<p>
-<!
-(Do not edit this file, it is generated from FONTS.hpux.html!!!)
->
-
-<H3>
-How to install new Type1 fonts on an HP-UX 10.20 machine
-</H3>
-<!
---------------------------------------------------------
->
-
-1. Add the font files to <tt>/usr/lib/X11/fonts/type1.st/typefaces</tt>.
-<p>
-
-2. Add the font descriptions to
-<tt>/usr/lib/X11/fonts/type1.st/typefaces/fonts.scale</tt>. Run `mkfontdir'
-in <tt>/usr/lib/X11/fonts/type1.st/typefaces</tt>. In the descriptions
-you have to specify the font manufacturer as `misc', like:
-<p>
-
-<tt>
-&nbsp;&nbsp;-misc-courier-...
-</tt>
-<p>
-
-3. Copy <tt>/usr/lib/X11/fonts/type1.st/typefaces/fonts.dir</tt> to
-<tt>/usr/lib/X11/fonts/type1.st/licenses/STSYSTEM/DISPLAYS/fonts.dir</tt>.
-Better yet, create a symbolic link.
-<p>
-
-4. For each font encoding you are going to use create a description
-file in <tt>/usr/lib/X11/fonts/stadmin/type1/charsets</tt>. Of course, if you
-are going to use the same fonts in several encodings, the best way
-would be to create fair descriptions of charsets and really store
-only one encoding in typefaces, all the others will be produced
-automatically. That's not difficult at all.
-But the simplest way is to just copy the file <tt>cp.iso8859-1</tt>
-to <tt>cp.<i>&lt;your-encoding-name&gt;</i></tt>, like <tt>cp.koi8-r</tt>.
-<p>
-
-5. Restart you X server and/or font server.
-<p>
-
-<H4>
-What if you don't have the `root' privileges ?
-</H4>
-<!
-----------------------------------------------
->
-
-You still can run the font server and configure your X server
-to get the fonts from it.
-<p>
-
-Further let's suppose that the name on which you are going
-to run the font server is named `somehost'. Login to it
-and configure the font server.
-<p>
-
-First, choose some unused port. Numbers around 9000 are a good
-choice. Verify that this port is not used by somebody else
-by entering
-<p>
-
-<blockquote><tt>
- netstat -naf inet |grep 9000
-</tt></blockquote>
-
-and look what happens. If you get nothing, that's good, this
-port is unused. If you get some lines of data, try abother port.
-<p>
-
-Go to you home directory <tt>$HOME</tt> and create some directory for
-your font server, say, <tt>$HOME/fs</tt>. Copy the directory structure
-of <tt>/usr/lib/X11/fonts/type1.st</tt> into <tt>$HOME/fs</tt>, so that in result
-you get <tt>$HOME/fs/type1.st/<i>&lt;whatever was there&gt;</i></tt>. Copy the directory
-structure of <tt>/usr/lib/X11/fonts/stadmin/type1/charsets</tt> into <tt>$HOME/fs</tt>,
-so that in result you get <tt>$HOME/fs/charsets/<i>&lt;whatever was there&gt;</i></tt>.
-Install the new fonts in these directorues as described above.
-<p>
-
-Then create the fontserver configuration file, say, <tt>$HOME/fs/xfs.cfg</tt>.
-The sample contents (supposing that my <tt>$HOME</tt> is equal to <tt>/home/babkin</tt>)
-is:
-<p>
-
-<!
---------------8&lt;----------- cut here -----------------------------
->
-<hr>
-<tt>
-# font server configuration file
-<br>
-# $XConsortium: config.cpp,v 1.7 91/08/22 11:39:59 rws Exp $
-<br>
-
-<br>
-rasterizers = /usr/lib/X11/fs/ufstrast.sl,/usr/lib/X11/fs/iforast.sl
-<br>
-
-<br>
-clone-self = off
-<br>
-use-syslog = off
-<br>
-catalogue = /home/babkin/fs/type1.st
-<br>
-# in decipoints
-<br>
-default-point-size = 120
-<br>
-default-resolutions = 100,100,75,75
-<br>
-port=9000
-<br>
-error-file=/home/babkin/fs/fs.err
-</tt>
-<hr>
-<!
---------------8&lt;----------- cut here -----------------------------
->
-<p>
-
-Then create the script to start your font server, say, <tt>$HOME/fs/runme</tt>:
-<p>
-
-<!
---------------8&lt;----------- cut here -----------------------------
->
-<hr>
-<tt>
-TYPE1_CODEPAGE_DIR=$HOME/fs/charsets
-<br>
-export TYPE1_CODEPAGE_DIR
-<br>
-kill `ps -ef | grep $HOME/\[f\]s/xfs.cfg | awk '{print $2}'`;
-<br>
-nohup xfs -config $HOME/fs/xfs.cfg &
-</tt>
-<hr>
-<!
---------------8&lt;----------- cut here -----------------------------
->
-<p>
-
-Don't forget to make <tt>$HOME/fs/runme</tt> executable. Then you can
-execute it manually or from you .profile.
-<p>
-
-After you get your font server running, just execute the following
-command (with proper host name and port number) in your X session
-<p>
-
-<blockquote><tt>
- xset fp+ tcp/somehost:9000
-</tt></blockquote>
-
-to get the access to your private font server. You can add this
-information to the configuration data of your X server or just
-put it also into your .profile. In the latter case the best way
-to do that would be like:
-<p>
-
-<!
---------------8&lt;----------- cut here -----------------------------
->
-<hr>
-<tt>
-...
-<br>
-$HOME/fs/runme
-<br>
-sleep 2 # give it some time to start
-<br>
-xset fp+ tcp/somehost:9000
-<br>
-...
-</tt>
-<hr>
-<!
---------------8&lt;----------- cut here -----------------------------
->
-<p>
-</BODY>
-</HTML>
diff --git a/nx-X11/extras/ttf2pt1/FONTS.html b/nx-X11/extras/ttf2pt1/FONTS.html
deleted file mode 100644
index 352bd0693..000000000
--- a/nx-X11/extras/ttf2pt1/FONTS.html
+++ /dev/null
@@ -1,708 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>
-The ttf2pt1 font installation guide
-</TITLE>
-</HEAD>
-<BODY>
-Sergey A. Babkin
-<br>
-<A HREF="mailto:babkin@users.sourceforge.net">
-&lt;babkin@bellatlantic.net&gt;</A> or <A HREF="mailto:sab123@hotmail.com">&lt;sab123@hotmail.com&gt;</A>
-<p>
-<!
-(Do not edit this file, it is generated from FONTS.html!!!)
->
-
-<!-- =defdoc cv ttf2pt1_convert 1 -->
-<!-- =defdoc gs ttf2pt1_x2gs 1 -->
-<H2>
-THE FONT INSTALLATION GUIDE
-<br>
-for the TTF to Type1 converter and fonts generated by it
-</H2>
-<!
-========================================================
->
-
-There is historically a number of problems with the support of the 8-bit
-character encodings. This installation guide pays a lot of attention
-to the 8-bit issues, because these issues are responsible for the
-most of troubles during the installation of fonts. But they are
-not the only things covered in this guide, so it's worth reading
-even if all you need is plain ASCII. For convenience of reading
-I have marked the paragraphs dealing solely with 8-bit problems
-with characters <FONT COLOR="#3333FF"><FONT SIZE=-1>*8*</FONT></FONT>.
-<p>
-
-To simplify this installation the distribution package of the
-converter contains a number of scripts written in shell and
-Perl. So, to run them you will need a shell interpreter (Bourne-shell,
-POSIX-shell, Korn-shell are OK, ba-shell is probably also OK but not
-tested yet). The Perl scripts were tested with Perl5 but probably
-should work with Perl4 too. All the scripts are located in the
-`scripts' subdirectory.
-<p>
-
-This guide considers the following issues of installation of the
-fonts:
-<p>
-
-<b>
-<ul>
-<li> <A HREF="#X11">X11</A><br>
-<li> <A HREF="#gs">Ghostscript</A><br>
-<li> <A HREF="#win">MS Windows</A><br>
-<li> <A HREF="#netscape">Netscape Navigator/Communicator</A><br>
-<li> <A HREF="#rpm">Linux RPM package</A><br>
-<li> <A HREF="#framemaker">FrameMaker</A><br>
-<li> <A HREF="#soffice">StarOffice</A><br>
-</ul>
-</b><p>
-
-<A NAME="X11"></A>
-<H3>
-X11
-</H3>
-<!
-===
->
-
-<!-- =section cv NAME -->
-<!-- =text B&lt;ttf2pt1_convert&gt; - convenience font conversion script -->
-<!-- =stop -->
-To simplify the conversion a set of scripts is provided with <b>ttf2pt1</b>.
-They are collected in the `<TT>scripts</TT>' subdirectory.
-<p>
-
-<!-- =section cv DESCRIPTION -->
-`<b>Convert</b>' is the master conversion script provided with ttf2pt1.
-When installed into a public directory it's named `<b>ttf2pt1_convert</b>'
-to avoid name collisions with the other programs.
-<p>
-<!-- =stop -->
-
-It's called as:
-<p>
-
-<!-- =section cv SYNOPSIS -->
-<!-- =text ttf2pt1_convert B&lt;[config-file]&gt; -->
-<!-- =stop -->
-<blockquote>
- convert <i>[config-file]</i>
-</blockquote>
-
-<!-- =section cv DESCRIPTION -->
-If the configuration file is not specified as an argument then the file
-`<TT>convert.cfg</TT>' in the current directory is used. This file contains
-a set of configuration variables. The distribution contains a sample file
-file `<TT>convert.cfg.sample</TT>'. Please copy it to `<TT>convert.cfg</TT>',
-look inside it and change the configuration variables. The more stable
-configuration variables, such as the path names of the scripts and
-encoding files are located in `<TT>convert</TT>' itself, they are
-automatically updated when installing <b>ttf2pt1</b>.
-<p>
-
-Put all the TTF fonts you want to convert into some directory (this
-may be just the directory that already contains all the Windows
-fonts on a mounted FAT filesystem). If you have fonts in different
-source encoding then put the fonts in each of the encodings
-into a separate directory. Up to 10 source directories are
-supported. If you (in a rather unlikely case) have more source
-directories then you can make two separate runs of the converter,
-converting up to 10 directories at a time.
-<p>
-
-The variables in the configuration file are:
-<p>
-
-<!-- ==over 2 -->
-<!-- ==item * -->
-<B><tt>SRCDIRS</tt></B> - the list of directories (with absolute paths) with
- TTF fonts. Each line contains at least 3 fields: the name of the directory,
- the language of the fonts in it (if you have fonts for different
- languages you have to put them into the separate directories) and the
- encoding of the fonts. Again, if you have some of the TTF typefaces in
- one encoding, and some in another (say, CP-1251 and KOI-8), you have
- to put them into the separate source directories. Some lines may contain
- 4 fields. Then the fourth field is the name of the external map to
- convert the Unicode fonts into the desirable encoding. This map is
- used instead of the built-in map for the specified language.
-<p>
-
-<FONT COLOR="#3333FF"><FONT SIZE=-1>*8*</FONT></FONT>
-An interesting thing is that some languages have more than one
-widely used character encodings. For example, the widely used
-encodings for Russian are IBM CP-866 (MS-DOS and Unix), KOI-8
-(Unix and VAX, also the standard Internet encoding), IBM CP-1251 (MS Windows).
-That's why I have provided the means to generate the converted fonts
-in more than one encoding. See the file <A HREF="encodings/README.html">encodings/README</A> for
-details about the encoding tables. Actually, if you plan to use
-these fonts with Netscape Navigator better use the aliases
-cp-866 instead of ibm-866 and windows-1251 instead of ibm-1251
-because that's what Netscape wants.
-<p>
-
-<!-- ==item * -->
-<b><tt>DSTDIR</tt></b> - directory for the resulting Type1 fonts. Be careful!
- This directory gets completely wiped out before conversion,
- so don't use any already existing directory for this purpose.
-<p>
-
-<!-- ==item * -->
-<b><tt>DSTENC<i>{language}</i></tt></b> - the list of encodings in which the destination
- fonts will be generated for each language. Each font of that
- language will be generated in each of the specified
- encodings. If you don't want any translation, just specify both
- <tt>SRCENC</tt> and <tt>DSTENC</tt> as iso8859-1 (or if you want any other encoding
- specified in the fonts.dir, copy the description of 8859-1 with
- new name and use this new name for <tt>SRCENC</tt> and <tt>DSTENC</tt>).
-<p>
-
-<!-- ==item * -->
-<b><tt>FOUNDRY</tt></b> - the foundry name to be used in the fonts.dir file. I have
- set it to `fromttf' to avoid name conflicts with any existing font for
- sure. But this foundry name is not registered in X11 standards and
- if you want to get the full standard compliance or have a font server
- that enforces such a compliance, use `misc'.
-<p>
-<!-- ==back -->
-
-The next few parameters control the general behavior of the converter.
-They default values are set to something reasonable.
-<p>
-
-<!-- ==over 2 -->
-<!-- ==item * -->
-<b><tt>CORRECTWIDTH</tt></b> - if the value is set to <b><tt>YES</tt></b> then use the
- converter option <tt><b>-w</b></tt>, otherwise don't use it. See the description of
- this option in the <A HREF="README.html">README</A> file.
-<p>
-
-<!-- ==item * -->
-<b><tt>REMOVET1A</tt></b> - if the value is set to <b><tt>YES</tt></b> then after
- conversion remove the un-encoded <tt>.t1a</tt> font files and the
- intermediate <tt>.xpfa</tt> font metric files.
-<p>
-
-<!-- ==item * -->
-<b><tt>INSTALLFONTMAP</tt></b> - a Ghostscript parameter, if the value is set to
- <b><tt>YES</tt></b> then install the entries for the new fonts
- right into the main <tt>Fontmap</tt> file. Otherwise just leave
- the file <tt>Fontmap.ttf</tt> in the Ghostscript configuration
- directory.
-<p>
-
-<!-- ==item * -->
-<b><tt>HINTSUBST</tt></b> - if the value is set to <b><tt>YES</tt></b> use the option
- <tt><b>-H</b></tt>, otherwise don't use it. This option enables the
- hint substitution technique. If you have not installed the X11 patch
- described above, use this option with great caution. See further
- description of this option in the <A HREF="README.html">README</A> file.
-<p>
-
-<!-- ==item * -->
-<b><tt>ENFORCEISO</tt></b> - if the value is set to <b><tt>YES</tt></b> then
- disguise the resulting fonts as the fonts in ISOLatin1 encoding. Historically
- this was neccessary due to the way the installer scripts created the
- X11 font configuration files. It is not neccessary any more for this
- purpose. But if you plan to use these fonts with some other application
- that expects ISOLatin1 encoding then better enable this option.
-<p>
-
-<!-- ==item * -->
-<b><tt>ALLGLYPHS</tt></b> - if the value is set to <b><tt>YES</tt></b> then
- include all the glyphs from the source fonts into the resulting fonts, even
- if these glyphs are inaccessible. If it's set to <b><tt>NO</tt></b> then
- include only the glyphs which have codes assigned to them. The glyphs
- without codes can not be used directly. But some clever programs,
- such as the Type 1 library from XFree86 3.9 and higher can change
- the encoding on the fly and use another set of glyphs. If you have not
- installed the X11 patch described above, use this option with great
- caution. See further description of the option option <tt><b>-a</b></tt> in the
- <A HREF="README.html">README</A> file.
-<p>
-
-<!-- ==item * -->
-<b><tt>GENUID</tt></b> - if the value is set to <b><tt>YES</tt></b> then use
- the option <tt><b>-uA</b></tt> of the converter to generate UniqueIDs for
- the converted fonts. The standard X11 Type 1 library does not use
- this ID, so it may only be neccessary for the other applications.
- The script is clever enough to generate different UniqueID for the
- same font converted to multiple encodings. Also after conversion it
- checks all the fonts generacted during the session for duplicated
- UniqueID and shows those. Still, this does not quarantee that these
- UniqueIDs won't overlap with some other fonts. The UniqueIDs are
- generated as hash values from the font names, so it's guaranteed
- that if the `<tt>convert</tt>' script runs multiple times it will
- generate the same UniqueIDs during each run. See further description
- of this option in the <A HREF="README.html">README</A> file.
-<p>
-
-<!-- ==item * -->
-<b><tt>GENUID</tt></b> - if the value is set to <b><tt>YES</tt></b> then create
- the <tt>.pfb</tt> files, otherwise the <tt>.pfa</tt> files. The <tt>.pfb</tt>
- files are more compact but contain binary data, so you may experience some
- troubles when transferring them through the network.
-<p>
-<!-- ==back -->
-
-The following parameters are used to locate the other scripts and
-configuration files. By default the scripts do a bit of guessing for them:
-they search in the <b>ttf2pt1</b> installation directory if <b>ttf2pt1</b>
-was installed or otherwise suppose that you are running `<tt>convert</tt>' with
-`<tt>scripts</tt>' subdirectory being the current directory.
-<p>
-
-<!-- ==over 2 -->
-<!-- ==item * -->
-<b><tt>ENCDIR</tt></b> - directory containing the descriptions of encodings
-<br>
-<!-- ==item * -->
-<b><tt>MAPDIR</tt></b> - directory containing the external map files
-<p>
-<!-- ==back -->
-
-Besides that a few parameters are built into the `<tt>convert</tt>' script itself.
-You probably won't need to change them:
-<p>
-
-<!-- ==over 2 -->
-<!-- ==item * -->
-<tt><b>T1ASM</b></tt>, <tt><b>TTF2PT1</b></tt>, <tt><b>TRANS</b></tt>, <tt><b>T1FDIR</b></tt>, <tt><b>FORCEISO</b></tt> - paths to the other script
-<p>
-<!-- ==back -->
-
-Also there are a few parameters controlling the installation of
-fonts for Ghostscript. Please look at their description in the
-<A HREF="#gs">Ghostscript</a> section of documentation or in the <b>ttf2pt1_x2gs(1)</b>
-manual page before running `<tt>convert</tt>'. If these parameters are
-set, `<tt>convert</tt>' will call the `<tt>x2gs</tt>' script automatically
-to install the newly converted fonts in Ghostscript.
-<p>
-
-After creating the configuration file run the `<tt>convert</tt>' script. Look at
-the result and the log file in <tt>DSTDIR</tt>.
-<p>
-
-Add the directory with newly converted fonts to the configuration
-of X server or font server. For most of the systems this step is
-very straightforward. For HP-UX it's rather tricky and poorly
-documented, so the file <A HREF="FONTS.hpux.html">FONTS.hpux</A> gives a short description.
-<p>
-
-If you don't have the privileges of the root user, you still can
-configure your private font server. Just use some non-standard
-port number (see <A HREF="FONTS.hpux.html">FONTS.hpux</A> for an example, exept that you won't
-need all the HP-related stuff on any other system).
-<p>
-<!-- =stop -->
-
-<H4>
-Known Problems
-</H4>
-<!
---------------
->
-<!-- =section cv BUGS -->
-<!-- ==head2 Known problems -->
-
-<ul>
-<li> One catch is that the X11 Type 1 font library has a rather low limit
- on the font size. Because of this the fonts with more complicated
- outlines and the enabled hint substitution may not fit into
- this limit. The same applies to the fonts with very complicated
- outlines or with very many glyphs (especially the fonts with
- over 256 glyphs). So you will need to excercise caution with
- these options if you plan using these fonts with X11. Some vendors
- such as HP provide the Type 1 implementation licensed from Adobe
- which should have no such problem.
-<p>
-
- But there is a solution even for the generic X11. A patch located
- in the subdirectory `<tt>app/X11</tt>' fixes this problem as well
- as some other minor problems. Its description is provided in
- <A HREF="app/X11/README.html">app/X11/README</A>.
-<p>
-
- To fix the X11 font library, you have to get the X11 sources. I
- can recommend the ftp sites of the XFree86 project <A HREF="ftp://ftp.xfree86.org">ftp://ftp.xfree86.org</A>
- or of the Open Group <A HREF="ftp://ftp.x.org">ftp://ftp.x.org</A>. This patch was made on the sources
- of XFree86 so you may have better success with applying it to the
- XFree86 distribution. After you have got the sources, make sure
- that you can compile them. Then apply the patch as described.
- Make sure that it was applied properly. Compile the sources again
- (actually, you need only the fonts library, the fonts server, and
- possibly the X server). It would be prudent now to save your old
- font library, font server and, possibly, X server. Then install
- the new recently compiled versions of these files. Of course,
- if you know someone who already has compiled these files for the
- same OS as yours, you can just copy the binary fles from him.
-<p>
-
- Alas, building the X11 system from the source code is not the
- easiest thing in the world and if you have no experience it
- can be quite difficult. In this case just avoid the aforementioned
- features or check each converted font to make sure that it
- works properly.
-<p>
-
-<li> The Type1 font library from the standard X11 distribution
- does not work on HP-UX (at least, up to 10.01). The font server
- supplied with HP-UX up to 10.01 is also broken. Starting from
- HP-UX 10.20 (I don't know about 10.10) they supply a proprietary font
- library and the converted fonts work fine with it, provided that
- they are configured properly (see the file <A HREF="FONTS.hpux.html">FONTS.hpux</A>).
-<p>
-
-<li> The <tt>fonts.scale</tt> files created by the older versions of the
- <tt>ttf2pt1</tt> installation program (up to release 3.1) have conflicted
- with the language definitions of the <tt>Xfsft</tt> font server and
- parts of it included into XFree86. To overcome this incompatibility
- the never versions creats the <tt>fonts.scale</tt> file describing all the
- fonts as belonging to the <tt>adobe-fontspecific</tt> encoding and
- the <tt>fonts.alias</tt> file with the proper names. The drawback of
- this solution is that <tt>xlsfonts</tt> gives the list of twice more
- fonts. But as a side effect the option <tt><b>ENFORCEISO</b></tt> in
- `<tt>convert.cfg</tt>' is not required for X11 any more.
-<p>
-
-<li> The conversion script has no support for Eastern multi-plane fonts.
- Contribution of such a support would be welcome.
-<p>
-</ul>
-<!-- =stop -->
-<!-- =section cv FILES -->
-<!-- ==over 2 -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/scripts/convert.cfg.sample -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/scripts/* -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/README -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/FONTS -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/* -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_BINDIR/ttf2pt1 -->
-<!-- ==back -->
-<!-- =stop -->
-<!-- =section cv SEE ALSO -->
-<!-- ==over 4 -->
-<!-- ==item * -->
-<!-- =text L&lt;ttf2pt1(1)&gt; -->
-<!-- ==item * -->
-<!-- =text L&lt;ttf2pt1_x2gs(1)&gt; -->
-<!-- ==item * -->
-<!-- =text L&lt;t1asm(1)&gt; -->
-<!-- ==back -->
-<!-- =stop -->
-
-<A NAME="gs"></A>
-<H3>
-Ghostscript
-</H3>
-<!
-===========
->
-<!-- =section gs NAME -->
-<!-- =text B&lt;ttf2pt1_x2gs&gt; - font installer for Ghostscript -->
-<!-- =stop -->
-
-<!-- =section gs DESCRIPTION -->
-The fonts generated with <b>ttf2pt1</b> work fine with Ghostscript by
-themselves. The script `<b>x2gs</b>' (or `<b>ttf2pt1_x2gs</b>' when installed
-into a public directory, to avoid name conflicts with other
-programs) links the font files from the X11 direcotry into the Ghostscript
-directory and automatically creates the description file (<tt>Fontmap</tt>)
-in Ghostscript format.
-<!-- =stop -->
-
-It's called as:
-<p>
-
-<!-- =section gs SYNOPSIS -->
-<!-- =text ttf2pt1_x2gs B&lt;[config-file]&gt; -->
-<!-- =stop -->
-<blockquote>
- x2gs <i>[config-file]</i>
-</blockquote>
-
-<!-- =section gs DESCRIPTION -->
-If the configuration file is not specified as an argument then the file
-`<TT>convert.cfg</TT>' in the current directory is used, just like the
-`<tt>convert</tt>' script does. Indeed, this configuration file is used for
-both scripts.
-<p>
-
-The Ghostscript-related parameters in the configuration file are:
-<p>
-
-<b><tt>DSTDIR</tt></b> - the X11 font directory used by `<tt>x2gs</tt>' as the
- source of the fonts. This parameter is common with the X11
- configuration.
-<p>
-
-<b><tt>GSDIR</tt></b> - the base directory of Ghostsript. If this
- parameter is set to an empty string then `<tt>convert</tt>' won't
- call `<tt>x2gs</tt>'. So if you want to get only the X11 fonts
- installed then set this parameter to an empty string. This
- directory may vary on various system, so please check your
- system and set this value accordingly before running the script.
-<p>
-
-<b><tt>GSFONTDIR</tt></b> - the font directory of Ghostscript. In the standard
- Ghostscript installation it's a subdirectory of <tt>GSDIR</tt>
- but some systems may use completely different directories.
-<p>
-
-<b><tt>GSCONFDIR</tt></b> - the configuration subdirectory of Ghostscript
- that contains the <tt>Fontmap</tt> file.
-<p>
-
-<b><tt>INSTALLFONTMAP</tt></b> - if the value is set to <b><tt>YES</tt></b> then
- install the entries for the new fonts right into the main
- <tt>Fontmap</tt> file. Otherwise just leave the file <tt>Fontmap.ttf</tt>
- in the Ghostscript configuration directory.
-<p>
-
-
-After preparing the configuration file run the script. It symbolicaly links
-all the font files and creates the description file <tt>Fontmap.ttf</tt> in
-<tt>GSCONDFIR</tt>. After that there are two choices.
-<p>
-
-If the option <tt>INSTALLFONTMAP</tt> was set to <tt>YES</tt> then
-the font descriptions are also automatically installed into the
-master <tt>Fontmap</tt> file. The script is clever enough to
-detect if it was run multiple times with the same directories
-and if so it replaces the old <tt>Fontmap</tt> entries with
-the new ones instead of just accumulating all of them. You
-may also run it multiple times for multiple X11 directories
-and all the results will be properly collected in the <tt>Fontmap</tt>.
-But it's your responsibility to watch that the names of the
-font files don't overlap. If the X11 font directory gets
-renamed then you have to remove its font entries from the
-<tt>Fontmap</tt> and only after that re-run `<tt>x2gs</tt>'
-for the new directory.
-<p>
-
-On the other hand if the option <tt>INSTALLFONTMAP</tt> was set to
-<tt>NO</tt> then go to the <tt>GSCONFDIR</tt> directory and insert the
-contents of <tt>Fontmap.ttf</tt> into the <tt>Fontmap</tt> file
-manually. This step may be left manual to make the installation
-a little bit more safe.
-<p>
-
-After that you may also want to redefine some of the aliases in
-<tt>Fontmap</tt> to refer to the newly installed fonts.
-But the redefinition of the aliases may be dangerous if the width of
-characters in the new font will be different from the old font.
-Alas, there is no visible solution of this problem yet.
-<p>
-<!-- =stop -->
-<!-- =section gs FILES -->
-<!-- ==over 2 -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/scripts/convert.cfg.sample -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/scripts/* -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/README -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/FONTS -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/* -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_BINDIR/ttf2pt1 -->
-<!-- ==back -->
-<!-- =stop -->
-<!-- =section gs SEE ALSO -->
-<!-- ==over 4 -->
-<!-- ==item * -->
-<!-- =text L&lt;ttf2pt1(1)&gt; -->
-<!-- ==item * -->
-<!-- =text L&lt;ttf2pt1_convert(1)&gt; -->
-<!-- ==item * -->
-<!-- =text L&lt;t1asm(1)&gt; -->
-<!-- ==back -->
-<!-- =stop -->
-
-<A NAME="win"></A>
-<H3>
-MS Windows
-</H3>
-<!
-===========
->
-
-<b>Ttf2pt1</b> can be built on Windows either with native compiler or in
-POSIX emulation mode.
-<p>
-
-Native MS Windows compilers require a different way to build the converter
-instead of the Makefile (their <tt>make</tt> programs commonly are quite weird
-and limited in capabilities). An example of batch file <tt>winbuild.bat</tt>
-is provided for MS Visual C/C++. Probably it can be easily adapted for other
-32-bit Windows and DOS compilers. The important part is to define the
-preprocessor symbol WINDOWS during compilation.
-<p>
-
-Cygnus <tt>make</tt> almost supports full Makefiles but not quite. Seems
-like its POSIX support is also of the same quality "almost but not quite".
-So another command file <tt>cygbuild.sh</tt> is provided for Cygnus GNU C, also
-with the preprocessor symbol WINDOWS defined. It is intended to be run from
-the Cygnus BASH shell. To run the programs produced by the Cygnus compiler
-the Cygnus library file <tt>CYGWIN1.DLL</tt> should be copied first into
-<tt>C:\WINDOWS</tt>.
-<p>
-
-To run the accompanying scripts Perl for Windows will be required as well as
-other tools from the Cygnus set.
-<p>
-
-The Windows support was not particularly tested, so in case of problems with
-building or running the converter please let us know.
-<p>
-
-The pre-built code (possibly of an older version) of ttf2pt1 for MS Windows is
-available from the GnuWin32 project from
-
-<A HREF="http://gnuwin32.sourceforge.net/packages/ttf2pt1.htm">http://gnuwin32.sourceforge.net/packages/ttf2pt1.htm</A>
-<p>
-
-<A NAME="netscape"></a>
-<H3>
-Netscape Navigator/Communicator
-</H3>
-<!
-===============================
->
-
-Basically, the biggest problem with Netscape Navigator is that
-it has built-in fixed PostScript font names and built-in fixed
-glyph tables for them. Oh, no, that's two! Let's start over:
-basically the two biggest problems of Netscape Navigator are
-that (one)it has built-in fixed PostScript font names and (two)
-built-in fixed glyph tables for them and (three) it always
-assumes that the fonts have ISOLatin1 encoding. OK, let's
-start over again: basically the three biggest problems of Netscape
-Navigator are that (one) it has built-in fixed PostScript font names,
-(two) built-in fixed glyph tables for them and (three) it always
-assumes that the fonts have ISOLatin1 encoding and (four) it
-does not remember the scaled font size between the sessions.
-You did not expect such a Spanish Inquisition, did you ? (<A HREF="#nsfn1">*</a>)
-<p>
-
-Luckily, we have solutions for all of these problems. They are
-located in the subdirectory `<tt>app/netscape</tt>' and described
-in <A HREF="app/netscape/README.html">app/netscape/README</a>.
-<p>
-
-<A NAME="nsfn1"></a>
-&nbsp;&nbsp;-------<br>
-&nbsp;&nbsp;<FONT SIZE=-1>*) See Monty Python's Flying Circus, episode 15</FONT></FONT>
-<p>
-
-<FONT COLOR="#3333FF"><FONT SIZE=-1>*8*</FONT></FONT>
-<H4>
-Netscape and cyrillic fonts<br>
-<!
----------------------------
->
-(courtesy of Zvezdan Petkovic)
-</H4>
-
-If you use TrueType fonts in your X, as I do, and you always get
-KOI8-R encoded pages, then your Netscape does not recognise windows-1251
-encoding. Microsoft TrueType fonts simply declare all encodings they
-can support including KOI8-R. For some reason, KOI8-R always wins over
-ISO-8859-5 in Netscape under X. If you are reading other cyrillic
-languages besides Russian, you might want to either erase KOI8-R entries
-from the fonts.dir and fonts.scale files, or alternatively fix Netscape.
-I put this line in my .Xdefaults.
-<p>
-
-<blockquote><tt>
- Netscape*documentFonts.charset*koi8-r: iso-8859-5
-</tt></blockquote>
-<p>
-
-Notice that you can still read Russian sites without trouble because
-Netscape translates KOI8-R to ISO-8859-5 on the fly. I read both Russian
-and Serbian sites with no trouble.
-<p>
-
-<b>Note:</b> <i>If anybody knows the way to tell Netscape under Unix how to
-recognise {windows,ibm,cp}-1251 encoded fonts, I'd like to hear about that.</i>
-<p>
-
-<A NAME="rpm"></a>
-<H3>
-Linux RPM package
-</H3>
-<!
-=================
->
-
-The spec file for the creation of a Linux RPM package is located in
-<tt>app/RPM</tt>. It has been contributed by Johan Vromans. When
-<tt>make all</tt> is ran in the main directory it among the other
-things creates the version of itself adapted to Linux in <tt>app/RPM</tt>,
-you may want to copy that version back to the main directory.
-<p>
-
-<B>Warning:</B> Please note that the install section is incomplete, and
-the installed scripts won't work until the paths inside them
-are corrected.
-<p>
-
-<A NAME="framemaker"></a>
-<H3>
-FrameMaker
-</H3>
-<!
-==========
->
-
-The fonts and AFM files generated by the version 3.2 and higher
-should work with Framemaker without problems. The AFM files
-generated by the previous versions of the converter require a
-line added to them:
-<p>
-
-&nbsp;&nbsp;<tt>EncodingScheme FontSpecific</tt>
-<p>
-
-And the underscores in the font names of the font and AFM files
-generated by the older versions may need to be changed to dashes.
-<p>
-
-<B>NOTE by Jason Baietto:</B> Ignore the directions in the Frame on-line docs
-that say to put a "serverdict begin 0 exitserver" line in the pfa files.
-Doing this caused both my printer and ghostscript to choke on the resulting
-output from FrameMaker, so I would not advise doing this (though your
-mileage may vary).
-<p>
-
-<A NAME="soffice"></a>
-<H3>
-StarOffice
-</H3>
-<!
-==========
->
-
-StarOffice 5.1x has been reported to crash if the <tt>.afm</tt> file contains
-spaces in the values of such statements as <b>Version</b>, <b>Weight</b> etc.
-These spaces are permitted by the Adobe spec, so this is a problem of
-StarOffice. The easiest way to fix these <tt>.afm</tt> files for StarOffice
-is to remove spaces in these strings or remove these strings (in case if
-they are optional) at all. This can be done automatically with a <tt>sed</tt>
-script. It seems that StarOffice 5.2 has this problem fixed, so we decided to
-spend no efforts on providing workarounds for 5.1 with <tt>ttf2pt1</tt>.
-<p>
-
-</BODY>
-</HTML>
diff --git a/nx-X11/extras/ttf2pt1/Makefile b/nx-X11/extras/ttf2pt1/Makefile
deleted file mode 100644
index 2616d4687..000000000
--- a/nx-X11/extras/ttf2pt1/Makefile
+++ /dev/null
@@ -1,279 +0,0 @@
-
-# This file should be configured before running `make'.
-# Uncomment or change the values that are relevant for your OS.
-
-# The preferred C compiler (by default use the OS-specific default value).
-# For BSD/OS, FreeBSD, Linux (all flavors), NetBSD, OpenBSD the default
-# compiler is GNU C.
-# (Note please the politically correct ordering by alphabet ! :-)
-#
-# Use GNU C even if it's not the default compiler
-#
-#CC=gcc
-#
-# Use the standard ANSI C compiler on HP-UX even if it's not default
-#
-#CC=c89
-
-#
-# The system-dependent flags for the C compiler
-#
-# Default
-
-CFLAGS_SYS= -O
-
-# For GNU C
-#
-#CFLAGS_SYS= -O2
-#
-# For GNU C with long options support library (Linux etc.)
-#
-#CFLAGS_SYS= -O2 -D_GNU_SOURCE
-#
-# For GNU C on HP-UX/PA-RISC 1.1
-#
-#CFLAGS_SYS= -O2 -Wa,-w
-#
-# For the standard ANSI C on HP-UX
-#
-#CFLAGS_SYS= +O2 -D_HPUX_SOURCE
-
-#
-# The system-dependent libraries
-#
-# Defalut (for the BSD-style OSes)
-
-LIBS_SYS= -lm
-
-# For SystemV (such as SCO, UnixWare, Solaris, but _NOT_ Linux or HP-UX)
-#
-#LIBS_SYS= -lm -lsocket
-
-#
-# The flags for C compiler for the FreeType-2 library (disabled by default).
-# This WON'T BUILD with FT2-beta8, use the FreeType release 2.0.4
-# http://download.sourceforge.net/freetype/freetype-2.0.4.tar.gz
-
-CFLAGS_FT=
-
-# To enable use of the FreeType-2 library
-# (if the include and lib directory do not match your installation,
-# modify them), also uncomment LIBS_FT
-#
-#CFLAGS_FT = -DUSE_FREETYPE -I/usr/local/include/freetype2 -I/usr/local/include
-
-#
-# The FreeType-2 library flags (disabled by default)
-
-LIBS_FT=
-
-# To enable use of the FreeType-2 library
-# (if the include and lib directory do not match your installation,
-# modify them), also uncomment CFLAGS_FT
-#
-#LIBS_FT= -L/usr/local/lib -lfreetype
-
-#
-# The flags for C compiler for the Autotrace library (disabled by default).
-# USE OF THIS FEATURE IS STRONGLY DISCOURAGED, THE BUILT-IN TRACING
-# (AKA VECTORIZATION) PROVIDES MUCH BETTER RESULTS.
-# The tested version is 0.29a (and the fonts produced with it are
-# absolutely not usable).
-# http://download.sourceforge.net/autotrace/autotrace-0.29.tar.gz
-
-CFLAGS_AT=
-
-# To enable use of the Autotrace library
-# (if the include and lib directory do not match your installation,
-# modify them), also uncomment LIBS_AT
-#
-#CFLAGS_AT = -DUSE_AUTOTRACE -I/usr/local/include
-
-#
-# The Autotrace library flags (disabled by default)
-
-LIBS_AT=
-
-# To enable use of the Autotrace library
-# (if the include and lib directory do not match your installation,
-# modify them), also uncomment CFLAGS_AT
-#
-#LIBS_AT= -L/usr/local/lib -lautotrace
-
-#
-# Preference of front-ends if multiple parsers match a file
-# (by default the build-in front-end takes preference over FreeType)
-
-CFLAGS_PREF=
-
-# To prefer FreeType (if enabled):
-#
-#CFLAGS_PREF= -DPREFER_FREETYPE
-
-# Uncomment the second line to not compile t1asm into ttf2pt1
-CFLAGS_EXTT1ASM=
-#CFLAGS_EXTT1ASM= -DEXTERNAL_T1ASM
-
-CFLAGS= $(CFLAGS_SYS) $(CFLAGS_FT) $(CFLAGS_AT) $(CFLAGS_PREF)
-LIBS= $(LIBS_SYS) $(LIBS_FT) $(LIBS_AT)
-
-# Installation-related stuff
-#
-# The base dir for installation and subdirs in it
-INSTDIR = /usr/local
-# for binaries
-BINDIR = $(INSTDIR)/bin
-# for binaries of little general interest
-LIBXDIR = $(INSTDIR)/libexec/ttf2pt1
-# for scripts, maps/encodings etc.
-SHAREDIR = $(INSTDIR)/share/ttf2pt1
-MANDIR = $(INSTDIR)/man
-
-# owner and group of installed files
-OWNER = root
-GROUP = bin
-
-# After you have configured the Makefile, comment out the following
-# definition:
-warning: docs
- @echo >&2
- @echo " You have to configure the Makefile before running make!" >&2
- @echo "(or if you are lazy and hope that it will work as is run \`make all')">&2
- @echo >&2
-
-DOCS=CHANGES README FONTS FONTS.hpux encodings/README other/README \
- app/X11/README app/netscape/README app/TeX/README
-
-SUBDIRS = app encodings maps scripts other
-TXTFILES = README* FONTS* CHANGES* COPYRIGHT
-
-MANS1=ttf2pt1.1 ttf2pt1_convert.1 ttf2pt1_x2gs.1
-MANS=$(MANS1) $(MANS5)
-
-all: t1asm ttf2pt1 docs mans rpm
-
-docs: $(DOCS)
-
-mans: $(MANS)
-
-clean:
- rm -f t1asm ttf2pt1 *.o app/RPM/Makefile app/RPM/*.spec *.core core.* core
- ( cd other && make clean; )
- ( cd app/netscape && make clean; )
-
-veryclean: clean
- rm -f $(DOCS) $(MANS)
-
-rpm: app/RPM/Makefile app/RPM/ttf2pt1.spec
-
-ttf2pt1.1: README.html
- scripts/html2man . . <README.html
-
-ttf2pt1_convert.1 ttf2pt1_x2gs.1: FONTS.html
- scripts/html2man . . <FONTS.html
-
-app/RPM/Makefile: Makefile
- sed 's/^CFLAGS_SYS.*=.*$$/CFLAGS_SYS= -O2 -D_GNU_SOURCE/;/warning:/,/^$$/s/^/#/' <Makefile >app/RPM/Makefile
-
-app/RPM/ttf2pt1.spec: app/RPM/ttf2pt1.spec.src version.h
- sed 's/^Version:.*/Version: '`grep TTF2PT1_VERSION version.h| cut -d\" -f2`'/' <app/RPM/ttf2pt1.spec.src >$@
-
-t1asm: t1asm.c
- $(CC) $(CFLAGS) -o t1asm -DSTANDALONE t1asm.c $(LIBS)
-
-ttf2pt1.o: ttf2pt1.c ttf.h pt1.h global.h version.h
- $(CC) $(CFLAGS) -c ttf2pt1.c
-
-pt1.o: pt1.c ttf.h pt1.h global.h
- $(CC) $(CFLAGS) -c pt1.c
-
-ttf.o: ttf.c ttf.h pt1.h global.h
- $(CC) $(CFLAGS) -c ttf.c
-
-ft.o: ft.c pt1.h global.h
- $(CC) $(CFLAGS) -c ft.c
-
-bdf.o: bdf.c pt1.h global.h
- $(CC) $(CFLAGS) -c bdf.c
-
-bitmap.o: bitmap.c pt1.h global.h
- $(CC) $(CFLAGS) -c bitmap.c
-
-runt1asm.o: runt1asm.c global.h
- $(CC) $(CFLAGS) $(CFLAGS_EXTT1ASM) -c runt1asm.c
-
-ttf2pt1: ttf2pt1.o pt1.o runt1asm.o ttf.o ft.o bdf.o bitmap.o
- $(CC) $(CFLAGS) -o ttf2pt1 ttf2pt1.o pt1.o runt1asm.o ttf.o ft.o bdf.o bitmap.o $(LIBS)
-
-CHANGES: CHANGES.html
- scripts/unhtml <CHANGES.html >CHANGES
-
-README: README.html
- scripts/unhtml <README.html >README
-
-encodings/README: encodings/README.html
- scripts/unhtml <encodings/README.html >encodings/README
-
-other/README: other/README.html
- scripts/unhtml <other/README.html >other/README
-
-app/X11/README: app/X11/README.html
- scripts/unhtml <app/X11/README.html >app/X11/README
-
-app/netscape/README: app/netscape/README.html
- scripts/unhtml <app/netscape/README.html >app/netscape/README
-
-app/TeX/README: app/TeX/README.html
- scripts/unhtml <app/TeX/README.html >app/TeX/README
-
-FONTS: FONTS.html
- scripts/unhtml <FONTS.html >FONTS
-
-FONTS.hpux: FONTS.hpux.html
- scripts/unhtml <FONTS.hpux.html >FONTS.hpux
-
-install: all
- scripts/inst_dir $(BINDIR) $(OWNER) $(GROUP) 0755
- scripts/inst_dir $(LIBXDIR) $(OWNER) $(GROUP) 0755
- scripts/inst_dir $(SHAREDIR) $(OWNER) $(GROUP) 0755
- scripts/inst_dir $(MANDIR)/man1 $(OWNER) $(GROUP) 0755
- scripts/inst_dir $(MANDIR)/man5 $(OWNER) $(GROUP) 0755
- cp -R $(TXTFILES) $(SUBDIRS) $(SHAREDIR)
- chown -R $(OWNER) $(SHAREDIR)
- chgrp -R $(GROUP) $(SHAREDIR)
- chmod -R go-w $(SHAREDIR)
- scripts/inst_file ttf2pt1 $(BINDIR)/ttf2pt1 $(OWNER) $(GROUP) 0755
- [ -f $(BINDIR)/t1asm ] || scripts/inst_file t1asm $(LIBXDIR)/t1asm $(OWNER) $(GROUP) 0755
- sed 's|^TTF2PT1_BINDIR=$$|TTF2PT1_BINDIR=$(BINDIR)|;\
- s|^TTF2PT1_LIBXDIR=$$|TTF2PT1_LIBXDIR=$(LIBXDIR)|;\
- s|^TTF2PT1_SHAREDIR=$$|TTF2PT1_SHAREDIR=$(SHAREDIR)|;' <scripts/convert >cvt.tmp
- scripts/inst_file cvt.tmp $(BINDIR)/ttf2pt1_convert $(OWNER) $(GROUP) 0755
- scripts/inst_file cvt.tmp $(SHAREDIR)/scripts/convert $(OWNER) $(GROUP) 0755
- rm cvt.tmp
- scripts/inst_file scripts/x2gs $(BINDIR)/ttf2pt1_x2gs $(OWNER) $(GROUP) 0755
- for i in $(MANS1); do { \
- sed 's|TTF2PT1_BINDIR|$(BINDIR)|;\
- s|TTF2PT1_LIBXDIR|$(LIBXDIR)|;\
- s|TTF2PT1_SHAREDIR|$(SHAREDIR)|;' <$$i >$(MANDIR)/man1/$$i \
- && chown $(OWNER) $(MANDIR)/man1/$$i \
- && chgrp $(GROUP) $(MANDIR)/man1/$$i \
- && chmod 0644 $(MANDIR)/man1/$$i \
- || exit 1; \
- } done
-
-uninstall:
- rm -f $(BINDIR)/ttf2pt1 $(BINDIR)/ttf2pt1_convert $(BINDIR)/ttf2pt1_x2gs
- rm -rf $(LIBXDIR)
- rm -rf $(SHAREDIR)
- for i in $(MANS1); do { \
- rm -f $(MANDIR)/man1/$$i $(MANDIR)/man1/$$i.gz; \
- } done
-
-
-# targets for automatic generation of releases and snapshots
-
-snapshot:
- scripts/mkrel snapshot
-
-release:
- scripts/mkrel release
diff --git a/nx-X11/extras/ttf2pt1/README.FIRST b/nx-X11/extras/ttf2pt1/README.FIRST
deleted file mode 100644
index f89db2010..000000000
--- a/nx-X11/extras/ttf2pt1/README.FIRST
+++ /dev/null
@@ -1,4 +0,0 @@
-To get the plain-text README and installation guides run:
-
- make docs
-
diff --git a/nx-X11/extras/ttf2pt1/README.html b/nx-X11/extras/ttf2pt1/README.html
deleted file mode 100644
index b1d6c9c22..000000000
--- a/nx-X11/extras/ttf2pt1/README.html
+++ /dev/null
@@ -1,1182 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>
-TTF2PT1 - A True Type to PostScript Type 1 Converter
-</TITLE>
-</HEAD>
-<BODY>
-<!-- =defdoc t1 ttf2pt1 1 -->
-<H2>
-<!-- =section t1 NAME -->
-TTF2PT1 - A True Type to PostScript Type 1 Font Converter
-<!-- =stop -->
-</H2>
-
-<!
-(Do not edit this file, it is generated from README.html!!!)
->
-<TT>
-[
-<blockquote>
-<!-- =section t1 HISTORY -->
- Based on ttf2pfa by Andrew Weeks, and help from Frank Siegert.
-<BR>
- Modification by Mark Heath.
-<BR>
- Further modification by Sergey Babkin.
-<BR>
- The Type1 assembler by I. Lee Hetherington with modifications by
- Kai-Uwe Herbing.
-<!-- =stop -->
-</blockquote>
-]
-</TT>
-<p>
-
-Ever wanted to install a particular font on your XServer but only could find
-the font you are after in True Type Format?
-<p>
-
-Ever asked <TT>comp.fonts</TT> for a True Type to Type 1 converter and got a List
-of Commercial software that doesn't run on your Operating System?
-<p>
-
-Well, this program should be the answer. This program is written in C (so it
-should be portable) and therefore should run on any OS. The only limitation
-is that the program requires some method of converting Big endian integers into
-local host integers so the network functions ntohs and ntohl are used. These
-can be replaced by macros if your platform doesn't have them.
-Of course the target platform requires a C compiler and command line ability.
-<p>
-
-<!-- =section t1 DESCRIPTION -->
-Ttf2pt1 is a font converter from the True Type format (and some other formats
-supported by the FreeType library as well) to the Adobe Type1 format.
-<p>
-
-The versions 3.0 and later got rather extensive post-processing algorithm that
-brings the converted fonts to the requirements of the Type1 standard, tries to
-correct the rounding errors introduced during conversions and some simple
-kinds of bugs that are typical for the public domain TTF fonts. It
-also generates the hints that enable much better rendering of fonts in
-small sizes that are typical for the computer displays. But everything
-has its price, and some of the optimizations may not work well for certain
-fonts. That's why the options were added to the converter, to control
-the performed optimizations.
-<p>
-<!-- =stop -->
-
-The converter is simple to run, just:
-<p>
-
-<!-- =section t1 SYNOPSIS -->
-<blockquote>
- <tt>ttf2pt1 <i>[-options] ttffont.ttf [Fontname]</i></tt>
-</blockquote>
-or
-<blockquote>
- <tt>ttf2pt1 <i>[-options] ttffont.ttf -</i></tt>
-</blockquote>
-<!-- =stop -->
-<p>
-
-<!-- =section t1 OPTIONS -->
-The first variant creates the file <tt>Fontname.pfa</tt> (or <tt>Fontname.pfb</tt> if the
-option '<b>-b</b>' was used) with the converted font and <tt>Fontname.afm</tt> with the
-font metrics, the second one prints the font or another file (if the option
-'<b>-G</b>' was used) on the standard output from where it can be immediately
-piped through some filter. If no <tt>Fontname</tt> is specified for the first
-variant, the name is generated from <tt>ttffont</tt> by replacing the <tt>.ttf</tt>
-filename suffix.
-<p>
-
-Most of the time no options are neccessary (with a possible exception
-of '<b>-e</b>'). But if there are some troubles with the resulting font, they
-may be used to control the conversion.
-The <B>options</B> are:
-<p>
-
-<!-- ==over 2 -->
-<!-- ==item * -->
-<TT><B>-a</TT></B> - Include all the glyphs from the source file into the converted
- file. If this option is not specified then only the glyphs that have
- been assigned some encoding are included, because the rest of glyphs
- would be inaccessible anyway and would only consume the disk space.
- But some applications are clever enough to change the encoding on
- the fly and thus use the other glyphs, in this case they could
- benefit from using this option. But there is a catch: the X11 library
- has rather low limit for the font size. Including more glyphs increases
- the file size and thus increases the chance of hitting this limit.
- See <A HREF="app/X11/README.html"><tt>app/X11/README</tt></A> for the description of a
- patch to X11 which fixes this problem.
-<p>
-
-<!-- ==item * -->
-<TT><B>-b</TT></B> - Encode the resulting font to produce a ready <tt>.pfb</tt> file.
-<p>
-
-<!-- ==item * -->
-<TT><B>-d <i>suboptions</i></TT></B> - Debugging options. The suboptions are:
-<p>
-
-<blockquote>
- <TT><B>a</TT></B> - Print out the absolute coordinates of dots in outlines. Such
- a font can not be used by any program (that's why this option is
- incompatible with '<b>-e</b>') but it has proven to be a valuable debuging
- information.
-<p>
-
- <TT><B>r</TT></B> - Do not reverse the direction of outlines. The TTF fonts have
- the standard direction of outlines opposite to the Type1 fonts. So
- they should be reversed during proper conversion. This option
- may be used for debugging or to handle a TTF font with wrong
- direction of outlines (possibly, converted in a broken way from
- a Type1 font). The first signs of the wrong direction are the
- letters like "P" or "B" without the unpainted "holes" inside.
-<p>
-</blockquote>
-
-<!-- ==item * -->
-<TT><B>-e</TT></B> - Assemble the resulting font to produce a ready <tt>.pfa</tt> file.
-<I>
- [ </I>S.B.<I>: Personally I don't think that this option is particularly useful.
- The same result may be achieved by piping the unassembled data
- through t1asm, the Type 1 assembler. And, anyways, it's good to
- have the t1utils package handy. But Mark and many users think that
- this functionality is good and it took not much time to add this option. ]
-</I>
-<p>
-
-<!-- ==item * -->
-<TT><B>-F</TT></B> - Force the Unicode encoding: any type of MS encoding specified
- in the font is ignored and the font is treated like it has Unicode
- encoding. <B>WARNING:</B> <I>this option is intended for buggy fonts
- which actually are in Unicode but are marked as something else. The
- effect on the other fonts is unpredictable.</I>
-<p>
-
-<!-- ==item * -->
-<TT><B>-G <i>suboptions</i></TT></B> - File generation options. The suboptions may be lowercase
- or uppercase, the lowercase ones disable the generation of particular
- files, the corresponding uppercase suboptions enable the generation of the
- same kind of files. If the result of ttf2pt1 is requested to be printed on
- the standard output, the last enabling suboption of <b>-G</b> determines
- which file will be written to the standard output and the rest of files
- will be discarded. For example, <b>-G A</b> will request the AFM file.
- The suboptions to disable/enable the generation of the files are:
-<p>
-
-<blockquote>
- <TT><B>f/F</TT></B> - The font file. Depending on the other options this file
- will have one of the suffixes <tt>.t1a</tt>, <tt>.pfa</tt> or <tt>.pfb</tt>. If the conversion result
- is requested on the standard output ('<tt>-</tt>' is used as the output file name)
- then the font file will also be written there by default, if not overwritten
- by another suboption of <b>-G</b>.
- <b>Default: enabled</b>
-<p>
-
- <TT><B>a/A</TT></B> - The Adobe font metrics file (<tt>.afm</tt>).
- <b>Default: enabled</b>
-<p>
-
- <TT><B>e/E</TT></B> - The dvips encoding file (<tt>.enc</tt>).
- <b>Default: disabled</b>
-<p>
-
-</blockquote>
-
-<!-- ==item * -->
-<TT><B>-l <I>language</I>[+<I>argument</I>]</TT></B> - Extract the fonts for the specified language from a
- multi-language Unicode font. If this option is not used the converter
- tries to guess the language by the values of the shell variable LANG.
- If it is not able to guess the language by LANG it tries all the
- languages in the order they are listed.
-<p>
-
- After the plus sign an optional argument for the language extractor
- may be specified. The format of the argument is absolutely up to
- the particular language converter. The primary purpose of the
- argument is to support selection of planes for the multi-plane
- Eastern encodings but it can also be used in any other way. The
- language extractor may decide to add the plane name in some form
- to the name of the resulting font. None of the currently supported
- languages make any use of the argument yet.
-<p>
-
- As of now the following languages are supported:
-<br>
- &nbsp;&nbsp;<TT>latin1</TT> - for all the languages using the Latin-1 encoding
-<br>
- &nbsp;&nbsp;<TT>latin2</TT> - for the Central European languages
-<br>
- &nbsp;&nbsp;<TT>latin4</TT> - for the Baltic languages
-<br>
- &nbsp;&nbsp;<TT>latin5</TT> - for the Turkish language
-<br>
- &nbsp;&nbsp;<TT>cyrillic</TT> - for the languages with Cyrillic alphabet
-<br>
- &nbsp;&nbsp;<TT>russian</TT> - historic synonym for cyrillic
-<br>
- &nbsp;&nbsp;<TT>bulgarian</TT> - historic synonym for cyrillic
-<br>
- &nbsp;&nbsp;<TT>adobestd</TT> - for the AdobeStandard encoding used by TeX
-<br>
- &nbsp;&nbsp;<TT>plane+<i>argument</i></TT> - to select one plane from a multi-byte encoding
-<p>
-
- The argument of the "<tt>plane</tt>" language may be in one of three forms:
-<p>
- &nbsp;&nbsp;<tt>plane+<b>pid=</b><i>&lt;pid&gt;</i><b>,eid=</b><i>&lt;eid&gt;</i></tt>
-<br>
- &nbsp;&nbsp;<tt>plane+<b>pid=</b><i>&lt;pid&gt;</i><b>,eid=</b><i>&lt;eid&gt;</i><b>,</b><i>&lt;plane_number&gt;</i></tt>
-<br>
- &nbsp;&nbsp;<tt>plane+<i>&lt;plane_number&gt;</i></tt>
-<p>
-
- Pid (TTF platform id) and eid (TTF encoding id) select a particular
- TTF encoding table in the original font. They are specified as decimal
- numbers. If this particular encoding table is not present in the font
- file then the conversion fails. The native ("ttf") front-end parser supports
- only pid=3 (Windows platform), the FreeType-based ("ft") front-end supports
- any platform. If pid/eid is not specified then the TTF encoding table is
- determined as usual: Unicode encoding if it's first or an 8-bit encoding
- if not (and for an 8-bit encoding the plane number is silently ignored).
- To prevent the converter from falling back to an 8-bit encoding, specify
- the Unicode pid/eid value explicitly.
-<p>
-
- Plane_number is a hexadecimal (if starts with "<b>0x</b>") or decimal number.
- It gives the values of upper bytes for which 256 characters will be
- selected. If not specified, defaults to 0. It is also used as a font
- name suffix (the leading "0x" is not included into the suffix).
-<p>
-
-<!-- =stop -->
- <B>NOTE:</B>
-<!-- =section t1 BUGS -->
- It seems that many Eastern fonts use features of the TTF format that are
- not supported by the ttf2pt1's built-in front-end parser. Because of
- this for now we recommend using the FreeType-based parser (option
- '<b>-p ft</b>') with the "<tt>plane</tt>" language.
-<p>
-<!-- =stop -->
-
-<!-- =section t1 OPTIONS -->
-<I>
- <B>NOTE:</B>
- You may notice that the language names are not uniform: some are the
- names of particular languages and some are names of encodings. This
- is because of the different approaches. The original idea was to
- implement a conversion from Unicode to the appropriate Windows
- encoding for a given language. And then use the translation tables
- to generate the fonts in whatever final encodings are needed. This
- would allow to pile together the Unicode fonts and the non-Unicode
- Windows fonts for that language and let the program to sort them out
- automatically. And then generate fonts in all the possible encodings
- for that language. An example of this approach is the Russian language
- support. But if there is no multiplicity of encodings used for some
- languages and if the non-Unicode fonts are not considered important
- by the users, another way would be simpler to implement: just provide
- only one table for extraction of the target encoding from Unicode
- and don't bother with the translation tables. The </I>latin*<I> "languages"
- are examples of this approach. If somebody feels that he needs the
- Type1 fonts both in Latin-* and Windows encodings he or she is absolutely
- welcome to submit the code to implement it.
-</I><p>
-
- <B>WARNING:</B>
- Some of the glyphs included into the AdobeStandard encoding are not
- included into the Unicode standard. The most typical examples of such
- glyphs are ligatures like 'fi', 'fl' etc. Because of this the font
- designers may place them at various places. The converter tries to
- do its best, if the glyphs have honest Adobe names and/or are
- placed at the same codes as in the Microsoft fonts they will be
- picked up. Otherwise a possible solution is to use the option '<b>-L</b>'
- with an external map.
-<p>
-
-<!-- ==item * -->
-<TT><B>-L <I>file</I>[+[pid=<I>&lt;pid&gt;</I>,eid=<I>&lt;eid&gt;</I>,][<I>plane</I>]]</TT></B> - Extract the fonts for the specified
- language from a multi-language font using the map from this file. This is
- rather like the option '<b>-l</b>' but the encoding map is not
- compiled into the program, it's taken from that file, so it's
- easy to edit. Examples of such files are provided in
- <tt>maps/adobe-standard-encoding.map</tt>, <tt>CP1250.map</tt>. (<b>NOTE:</b>
- <I>the 'standard encoding' map does not include all the glyphs of the
- AdobeStandard encoding, it's provided only as an example</I>.) The
- description of the supported map formats is in the file
- <tt>maps/unicode-sample.map</tt>.
-<p>
-
- Likewise to '<b>-l</b>', an argument may be specified after the map file
- name. But in this case the argument has fixed meaning: it selects the
- original TTF encoding table (the syntax is the same as in '<b>-l plane</b>')
- and/or a plane of the map file. The plane name also gets added after dash
- to the font name. The plane is a concept used in the Eastern fonts with big
- number of glyphs: one TTF font gets divided into multiple Type1 fonts,
- each containing one plane of up to 256 glyphs. But with a little
- creativity this concept may be used for other purposes of combining
- multiple translation maps into one file. To extract multiple planes
- from a TTF font <tt>ttf2pt1</tt> must be run multiple times, each time with
- a different plane name specified.
-<p>
-
- The default original TTF encoding table used for the option '<b>-L</b>' is
- Unicode. The map files may include directives to specify different original
- TTF encodings. However if the pid/eid pair is specified with
- it overrides any original encoding specified in the map file.
-<p>
-
-<!-- ==item * -->
-<TT><B>-m <i>type</i>=<i>value</i></TT></B> - Set maximal or minimal limits of resources.
- These limits control the the font generation by limiting the resources
- that the font is permitted to require from the PostScript interpreter.
- The currently supported types of limits are:
-<p>
-
-<blockquote>
- <TT><B>h</TT></B> - the maximal hint stack depth for the substituted hints.
- The default value is 128, according to the limitation in X11. This seems to
- be the lowest (and thus the safest) widespread value. To display the
- hint stack depth required by each glyph in a <tt>.t1a</tt> file use the script
- <tt>scripts/cntstems.pl</tt>.
-<p>
-</blockquote>
-
-<!-- ==item * -->
-<TT><B>-O <i>suboptions</i></TT></B> - Outline processing options. The suboptions
- may be lowercase or uppercase, the lowercase ones disable the features,
- the corresponding uppercase suboptions enable the same features.
- The suboptions to disable/enable features are:
-<p>
-
-<blockquote>
- <TT><B>b/B</TT></B> - Guessing of the ForceBold parameter. This parameter helps
- the Type1 engine to rasterize the bold fonts properly at small sizes.
- But the algorithm used to guess the proper value of this flag makes
- that guess based solely on the font name. In rare cases that may cause
- errors, in these cases you may want to disable this guessing.
- <b>Default: enabled</b>
-<p>
-
- <TT><B>h/H</TT></B> - Autogeneration of hints. The really complex outlines
- may confuse the algorithm, so theoretically it may be useful
- sometimes to disable them. Although up to now it seems that
- even bad hints are better than no hints at all.
- <b>Default: enabled</b>
-<p>
-
- <TT><B>u/U</TT></B> - Hint substitution. Hint substitution is a technique
- permitting generation of more detailed hints for the rasterizer. It allows
- to use different sets of hints for different parts of a glyph and change
- these sets as neccessary during rasterization (that's why "substituted").
- So it should improve the quality of the fonts rendered at small sizes.
- But there are two catches: First, the X11 library has rather low limit for
- the font size. More detailed hints increase the file size and thus increase
- the chance of hitting this limit (that does not mean that you shall hit it
- but you may if your fonts are particularly big). This is especially
- probable for Unicode fonts converted with option '<b>-a</b>', so you may want to
- use '<b>-a</b>' together with '<b>-Ou</b>'. See <A HREF="app/X11/README.html"><tt>app/X11/README</tt></A> for the description of
- a patch to X11 which fixes this problem. Second, some rasterizers (again,
- X11 is the typical example) have a limitation for total number of hints
- used when drawing a glyph (also known as the hint stack depth). If that
- stack overflows the glyph is ignored. Starting from version 3.22 <tt>ttf2pt1</tt>
- uses algorithms to minimizing this depth, with the trade-off of slightly
- bigger font files. The glyphs which still exceed the limit set by option
- '<b>-mh</b>' have all the substituted hints removed and only base hints left.
- The algorithms seem to have been refined far enough to make the fonts with
- substituted hints look better than the fonts without them or at least the
- same. Still if the original fonts are not well-designed the detailed
- hinting may emphasize the defects of the design, such as non-even thickness
- of lines. So provided that you are not afraid of the X11 bug the best idea
- would be to generate a font with this feature and without it, then compare
- the results using the program <tt>other/cmpf</tt> (see the description
- in <A HREF="other/README.html"><tt>other/README</tt></A>) and decide which one looks better.
- <b>Default: enabled</b>
-<p>
-
- <TT><B>o/O</TT></B> - Space optimization of the outlines' code. This kind of optimization
- never hurts, and the only reason to disable this feature is for comparison
- of the generated fonts with the fonts generated by the previous versions of
- converter. Well, it _almost_ never hurts. As it turned out there exist
- some brain-damaged printers which don't understand it. Actually this
- feature does not change the outlines at all. The Type 1 font manual
- provides a set of redundant operators that make font description shorter,
- such as '10 hlineto' instead of '0 10 rlineto' to describe a horizontal
- line. This feature enables use of these operators.
- <b>Default: enabled</b>
-<p>
-
- <TT><B>s/S</TT></B> - Smoothing of outlines. If the font is broken in some
- way (even the ones that are not easily noticeable), such smoothing
- may break it further. So disabling this feature is the first thing to be
- tried if some font looks odd. But with smoothing off the hint generation
- algorithms may not work properly too.
- <b>Default: enabled</b>
-<p>
-
- <TT><B>t/T</TT></B> - Auto-scaling to the 1000x1000 Type1 standard matrix. The
- TTF fonts are described in terms of an arbitrary matrix up to
- 4000x4000. The converted fonts must be scaled to conform to
- the Type1 standard. But the scaling introduces additional rounding
- errors, so it may be curious sometimes to look at the font in its
- original scale.
- <b>Default: enabled</b>
-<p>
-
- <TT><B>v/V</TT></B> - Do vectorization on the bitmap fonts. Functionally
- "vectorization" is the same thing as "autotracing", a different word is
- used purely to differentiate it from the Autotrace library. It tries to
- produce nice smooth outlines from bitmaps. This feature is still a work
- in progress though the results are already mostly decent.
- <b>Default: disabled</b>
-<p>
-
- <TT><B>w/W</TT></B> - Glyphs' width corection. This option is designed to be
- used on broken fonts which specify too narrow widths for the
- letters. You can tell that a font can benefit from this option
- if you see that the characters are smashed together without
- any whitespace between them. This option causes the converter
- to set the character widths to the actual width of this character
- plus the width of a typical vertical stem. But on the other hand
- the well-designed fonts may have characters that look better if
- their widths are set slightly narrower. Such well-designed fonts
- will benefit from disabling this feature. You may want to convert
- a font with and without this feature, compare the results and
- select the better one. This feature may be used only on proportional
- fonts, it has no effect on the fixed-width fonts.
- <b>Default: disabled</b>
-<p>
-
- <TT><B>z/Z</TT></B> - Use the Autotrace library on the bitmap fonts. The results
- are horrible and <b>the use of this option is not recommended</b>. This option is
- present for experimental purposes. It may change or be removed in the
- future. The working tracing can be achieved with option <tt><b>-OV</b></tt>.
- <b>Default: disabled</b>
-<p>
-</blockquote>
-
-<!-- ==item * -->
-<TT><B>-p <I>parser_name</I></TT></B> - Use the specified front-end parser to read the font file.
- If this option is not used, ttf2pt1 selects the parser automatically based
- on the suffix of the font file name, it uses the first parser in its
- list that supports this font type. Now two parsers are supported:
-<p>
-
- &nbsp;&nbsp;<TT>ttf</TT> - built-in parser for the ttf files (suffix <tt>.ttf</tt>)
-<br>
- &nbsp;&nbsp;<TT>bdf</TT> - built-in parser for the BDF files (suffix <tt>.bdf</tt>)
-<br>
- &nbsp;&nbsp;<TT>ft</TT> - parser based on the FreeType-2 library (suffixes <tt>.ttf</tt>,
- <tt>.otf</tt>, <tt>.pfa</tt>, <tt>.pfb</tt>)
-<p>
-
- The parser <tt>ft</tt> is <b>NOT</b> linked in by default. See <tt>Makefile</tt>
- for instructions how to enable it. We do no support this parser on
- Windows: probably it will work but nobody tried and nobody knows how
- to build it.
-<p>
-
- The conversion of the bitmap fonts (such as BDF) is simplistic yet,
- producing jagged outlines. When converting such fonts, it might be
- a good idea to turn off the hint substitution (using option <b>-Ou</b>)
- because the hints produced will be huge but not adding much to the
- quality of the fonts.
-<p>
-
-<!-- ==item * -->
-<TT><B>-u <I>number</I></TT></B> - Mark the font with this value as its
- UniqueID. The UniqueID is used by the printers with the hard disks
- to cache the rasterized characters and thus significantly
- speed-up the printing. Some of those printers just can't
- store the fonts without UniqueID on their disk.The problem
- is that the ID is supposed to be unique, as it name says. And
- there is no easy way to create a guaranteed unique ID. Adobe specifies
- the range 4000000-4999999 for private IDs but still it's difficult
- to guarantee the uniqueness within it. So if you don't really need the
- UniqueID don't use it, it's optional. Luckily there are a few millions of
- possible IDs, so the chances of collision are rather low.
- If instead of the number a special value '<tt><b>A</b></tt>' is given
- then the converter generates the value of UniqueID automatically,
- as a hash of the font name. (<b>NOTE:</b> <i> in the version 3.22 the
- algorithm for autogeneration of UniqueID was changed to fit the values
- into the Adobe-spacified range. This means that if UniqueIDs were used
- then the printer's cache may need to be flushed before replacing the
- fonts converted by an old version with fonts converted by a newer version</i>).
- A simple way to find if any of the fonts in a given directory have
- duplicated UniqueIDs is to use the command:
-<p>
-
- <tt>&nbsp;&nbsp;cat *.pf[ab] | grep UniqueID | sort | uniq -c | grep -v ' 1 '</tt>
-<p>
-
- Or if you use <tt>scripts/convert</tt> it will do that for you automatically
- plus it will also give the exact list of files with duplicate UIDs.
-<p>
-
-<!-- ==item * -->
-<TT><B>-v <I>size</I></TT></B> - Re-scale the font to get the size of a typical uppercase
- letter somewhere around the specified size. Actually, it re-scales
- the whole font to get the size of one language-dependent letter to be
- at least of the specified size. Now this letter is "A" in all the
- supported languages. The size is specified in the points of the
- Type 1 coordinate grids, the maximal value is 1000. This is an
- experimental option and should be used with caution. It tries to
- increase the visible font size for a given point size and thus make
- the font more readable. But if overused it may cause the fonts to
- look out of scale. As of now the interesting values of size for
- this option seem to be located mostly between 600 and 850. This
- re-scaling may be quite useful but needs more experience to
- understand the balance of its effects.
-<p>
-
-<!-- ==item * -->
-<TT><B>-W <i>level</i></TT></B> - Select the verbosity level of the warnings.
- Currently the levels from 0 to 4 are supported. Level 0 means no warnings
- at all, level 4 means all the possible warnings. The default level is 3.
- Other levels may be added in the future, so using the level number 99 is
- recommended to get all the possible warnings. Going below level 2 is
- not generally recommended because you may miss valuable information about
- the problems with the fonts being converted.
-<p>
-
-<!-- ==item * -->
-<B>Obsolete option:</B>
-<TT><B>-A</TT></B> - Print the font metrics (.afm file) instead of the font on STDOUT.
- Use <b>-GA</b> instead.
-<p>
-
-<!-- ==item * -->
-<B>Very obsolete option:</B>
-<br>
- The algorithm that implemented the forced fixed width had major
- flaws, so it was disabled. The code is still in the program and
- some day it will be refined and returned back. Meanwhile the
- option name '<b>-f</b>' was reused for another option. The old version was:
-<br>
-<TT><B>-f</TT></B> - Don't try to force the fixed width of font. Normally the converter
- considers the fonts in which the glyph width deviates by not more
- than 5% as buggy fixed width fonts and forces them to have really
- fixed width. If this is undesirable, it can be disabled by this option.
-<p>
-<!-- ==back -->
-
-The <tt>.pfa</tt> font format supposes that the description of the characters
-is binary encoded and encrypted. This converter does not encode or
-encrypt the data by default, you have to specify the option '<b>-e</b>'
-or use the <tt>t1asm</tt> program to assemble (that means, encode and
-encrypt) the font program. The <tt>t1asm</tt> program that is included with
-the converter is actually a part of the <tt>t1utils</tt> package, rather old
-version of which may be obtained from
-<p>
-
-<blockquote>
-<A HREF="http://ttf2pt1.sourceforge.net/t1utils.tar.gz">
- http://ttf2pt1.sourceforge.net/t1utils.tar.gz
-</A>
-</blockquote>
-<p>
-
-Note that <tt>t1asm</tt> from the old version of that package won't work properly
-with the files generated by <tt>ttf2pt1</tt> version 3.20 and later. Please use
-<tt>t1asm</tt> packaged with <tt>ttf2pt1</tt> or from the new version <tt>t1utils</tt>
-instead. For a newer version of <tt>t1utils</tt> please look at
-<p>
-
-<blockquote>
-<A HREF="http://www.lcdf.org/~eddietwo/type/">
- http://www.lcdf.org/~eddietwo/type/
-</A>
-</blockquote>
-<p>
-<!-- =stop -->
-
-<!-- =section t1 EXAMPLES -->
-So, the following command lines:
-<p>
-
-<blockquote>
- <tt>ttf2pt1 -e ttffont.ttf t1font</tt>
-<br>
- <tt>ttf2pt1 ttffont.ttf - | t1asm &gt;t1font.pfa</tt>
-</blockquote>
-<p>
-
-represent two ways to get a working font. The benefit of the second form
-is that other filters may be applied to the font between the converter
-and assembler.
-<p>
-<!-- =stop -->
-
-<H4>
-Installation and deinstallation of the converter
-</H4>
-<!
-------------------------------------------------
->
-
-The converter may be easily installed systemwide with
-
-<blockquote>
- <tt>make install</tt>
-</blockquote>
-
-and uninstalled with
-
-<blockquote>
- <tt>make uninstall</tt>
-</blockquote>
-
-By default the <tt>Makefile</tt> is configured to install in the hierarchy
-of directory <tt>/usr/local</tt>. This destination directory as well as
-the structure of the hierarchy may be changed by editing the <tt>Makefile</tt>.
-
-<H4>
-Installation of the fonts
-</H4>
-<!
--------------------------
->
-
-Running the converter manually becomes somewhat boring if it has to
-be applied to a few hundreds of fonts and then you have to generate the
-<tt>fonts.scale</tt> and/or <tt>Fontmap</tt> files. The <A HREF="FONTS.html"><tt>FONTS</tt></A> file describes how to use
-the supplied scripts to handle such cases easily. It also discusses
-the installation of the fonts for a few widespread programs.
-<p>
-
-<H4>
-Other utilities
-</H4>
-<!
----------------
->
-
-A few other small interesting programs that allow a cloase look at
-the fonts are located in the subdirectory '<tt>other</tt>'. They
-are described shortly in <A HREF="other/README.html">others/README</a>.
-<p>
-
-<H4>
-Optional packages
-</H4>
-<!
------------------
->
-
-Some auxiliary files are not needed by everyone and are big enough that
-moving them to a separate package speeds up the downloads of the main
-package significantly. As of now we have one such optional package:
-<p>
-
-&nbsp;&nbsp;<b>ttf2pt1-chinese</b> - contains the Chinese conversion maps
-<p>
-
-The general versioning policy for the optional packages is the following:
-These packages may have no direct dependency on the ttf2pt1 version.
-But they may be updated in future, as well as some versions of optional
-packages may have dependencies on certain versions of ttf2pt1.
-To avoid unneccessary extra releases on one hand and keep the updates in
-sync with the ttf2pt1 itself on the other hand, a new version of an optional
-package will be released only if there are any changes to it and it will be
-given the same version number as ttf2pt1 released at the same time. So not
-every release of ttf2pt1 would have a corresponding release of all optional
-packages. For example, to get the correct version of optional packages for an
-imaginary release 8.3.4 of ttf2pt1 you would need to look for optional
-packages of the highest version not higher than (but possibly equal to) 8.3.4.
-<p>
-
-<H4>
-TO DO:
-</H4>
-<!
-------
->
-
-<ul>
-<li> Improve hinting.
-<li> Improve the auto-tracing of bitmaps.
-<li> Implement the family-level hints.
-<li> Add generation of CID-fonts.
-<li> Handle the composite glyphs with relative base points.
-<li> Preserve the relative width of stems during scaling to 1000x1000 matrix.
-<li> Add support for bitmap TTF fonts.
-<li> Implement better support of Asian encodings.
-<li> Implement automatic creation of ligatures.
-</ul>
-
-<H4>
-TROUBLESHOOTING AND BUG REPORTS
-</H4>
-<!
--------------------------------
->
-<!-- =section t1 BUGS -->
-<!-- ==head2 Troubleshooting and bug reports -->
-
-Have problems with conversion of some font ? The converter dumps core ? Or your
-printer refuses to understand the converted fonts ? Or some characters are
-missing ? Or some characters look strange ?
-<p>
-
-Send the bug reports to the ttf2pt1 development mailing list at
-<A HREF="mailto:ttf2pt1-devel@lists.sourceforge.net">ttf2pt1-devel@lists.sourceforge.net</A>.
-<p>
-
-Try to collect more information about the problem and include it into
-the bug report. (Of course, even better if you would provide a ready
-fix, but just a detailed bug report is also good). Provide detailed
-information about your problem, this will speed up the response greatly.
-Don't just write "this font looks strange after conversion" but describe
-what's exactly wrong with it: for example, what characters look wrong
-and what exactly is wrong about their look. Providing a link to the
-original font file would be also a good idea. Try to do a little
-troublehooting and report its result. This not only would help with
-the fix but may also give you a temporary work-around for the bug.
-<p>
-
-First, enable full warnings with option '<b>-W99</b>', save them to
-a file and read carefully. Sometimes the prolem is with a not implemented
-feature which is reported in the warnings. Still, reporting about such
-problems may be a good idea: some features were missed to cut corners,
-in hope that no real font is using them. So a report about a font using
-such a feature may motivate someone to implement it. Of course, you
-may be the most motivated person: after all, you are the one wishing
-to convert that font. ;-) Seriously, the philosophy "scrath your own itch"
-seems to be the strongest moving force behind the Open Source software.
-<p>
-
-The next step is playing with the options. This serves a dual purpose:
-on one hand, it helps to localize the bug, on the other hand you may be
-able to get a working version of the font for the meantime while the
-bug is being fixed. The typical options to try out are: first '<b>-Ou</b>', if
-it does not help then '<b>-Os</b>', then '<b>-Oh</b>', then '<b>-Oo</b>'.
-They are described in a bit more detail above. Try them one by one
-and in combinations. See if with them the resulting fonts look better.
-<p>
-
-On some fonts ttf2pt1 just crashes. Commonly that happens because the
-font being converted is highly defective (although sometimes the bug
-is in ttf2pt1 itself). In any case it should not crash, so the reports
-about such cases will help to handle these defects properly in future.
-<p>
-
-We try to respond to the bug reports in a timely fashion but alas, this
-may not always be possible, especially if the problem is complex.
-This is a volunteer project and its resources are limited. Because
-of this we would appreciate bug reports as detailed as possible,
-and we would appreciate the ready fixes and contributions even more.
-<p>
-<!-- =stop -->
-<!-- =section t1 FILES -->
-<!-- ==over 2 -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_LIBXDIR/t1asm -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/* -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/scripts/* -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/other/* -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/README -->
-<!-- ==item * -->
-<!-- =text TTF2PT1_SHAREDIR/FONTS -->
-<!-- ==back -->
-<!-- =stop -->
-
-<H4>
-CONTACTS
-</H4>
-<!
---------
->
-<!-- =section t1 SEE ALSO -->
-<!-- ==over 4 -->
-<!-- ==item * -->
-<!-- =text L&lt;ttf2pt1_convert(1)&gt; -->
-<!-- ==item * -->
-<!-- =text L&lt;ttf2pt1_x2gs(1)&gt; -->
-<!-- ==item * -->
-<!-- =text L&lt;t1asm(1)&gt; -->
-
-<!-- ==item * -->
-<A HREF="http://lists.sourceforge.net/mailman/listinfo/ttf2pt1-announce">
-ttf2pt1-announce@lists.sourceforge.net
-</A><br>
- The mailing list with announcements about ttf2pt1. It is a moderated mailing
- with extremely low traffic. Everyone is encouraged to subscribe to keep in
- touch with the current status of project. To subscribe use the Web interface
- at <A HREF="http://lists.sourceforge.net/mailman/listinfo/ttf2pt1-announce">http://lists.sourceforge.net/mailman/listinfo/ttf2pt1-announce</A>.
- If you have only e-mail access to the Net then send a subscribe request to
- the development mailing list ttf2pt1-devel@lists.sourceforge.net and somebody
- will help you with subscription.
-<p>
-
-<!-- ==item * -->
-<A HREF="mailto:ttf2pt1-devel@lists.sourceforge.net">
-ttf2pt1-devel@lists.sourceforge.net
-</A><br>
-<A HREF="mailto:ttf2pt1-users@lists.sourceforge.net">
-ttf2pt1-users@lists.sourceforge.net
-</A><br>
- The ttf2pt1 mailing lists for development and users issues. They have not
- that much traffic either. To subscribe use the Web interface at
- <A HREF="http://lists.sourceforge.net/mailman/listinfo/ttf2pt1-devel">http://lists.sourceforge.net/mailman/listinfo/ttf2pt1-devel</A>
- and <A HREF="http://lists.sourceforge.net/mailman/listinfo/ttf2pt1-users">http://lists.sourceforge.net/mailman/listinfo/ttf2pt1-users</A>.
- If you have only e-mail access to the Net then send a subscribe request to
- the development mailing list ttf2pt1-devel@lists.sourceforge.net and somebody
- will help you with subscription.
-<p>
-
-<!-- =stop -->
-<A HREF="mailto:mheath@netspace.net.au">
-mheath@netspace.net.au
-</A><br>
- Mark Heath
-<p>
-
-<A HREF="mailto:A.Weeks@mcc.ac.uk">
-A.Weeks@mcc.ac.uk
-</A><br>
- Andrew Weeks
-<p>
-
-<A HREF="mailto:babkin@users.sourceforge.net">
-babkin@users.sourceforge.net</A> (preferred)<br>
-<A HREF="mailto:sab123@hotmail.com">
-sab123@hotmail.com
-</A><br>
-<A HREF="http://members.bellatlantic.net/~babkin">
-http://members.bellatlantic.net/~babkin
-</A><br>
- Sergey Babkin
-<p>
-
-<H4>
-SEE ALSO
-</H4>
-<!
---------
->
-
-<!-- =section t1 SEE ALSO -->
-<!-- ==item * -->
-<A HREF="http://ttf2pt1.sourceforge.net">
-http://ttf2pt1.sourceforge.net
-</A><br>
- The main page of the project.
-<p>
-
-<A HREF="http://www.netspace.net.au/~mheath/ttf2pt1/">
-http://www.netspace.net.au/~mheath/ttf2pt1/
-</A><br>
- The old main page of the project.
-<p>
-<!-- ==back -->
-<!-- =stop -->
-
-<A HREF="http://sourceforge.net/projects/gnuwin32">
-http://sourceforge.net/projects/gnuwin32
-</A><br>
- Precompiled binaries for Windows.
-<p>
-
-<A HREF="http://www.lcdf.org/~eddietwo/type/">
-http://www.lcdf.org/~eddietwo/type/
-</a><br>
- The home page of the Type 1 utilities package.
-<p>
-
-<A HREF="http://www.rightbrain.com/pages/books.html">
-http://www.rightbrain.com/pages/books.html
-</a><br>
- The first book about PostScript on the Web, "Thinking in PostScript".
-<p>
-
-<A HREF="http://fonts.apple.com/TTRefMan/index.html">
-http://fonts.apple.com/TTRefMan/index.html
-</a><br>
- The True Type reference manual.
-<p>
-
-<A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
-http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf
-</a><br>
- Adobe PostScript reference manual.
-<p>
-
-<A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/T1_SPEC.PDF">
-http://partners.adobe.com/asn/developer/PDFS/TN/T1_SPEC.PDF
-</a><br>
- Specification of the Type 1 font format.
-<p>
-
-<A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5015.Type1_Supp.pdf">
-http://partners.adobe.com/asn/developer/PDFS/TN/5015.Type1_Supp.pdf
-</a><br>
- The Type 1 font format supplement.
-<p>
-
-<A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5004.AFM_Spec.pdf">
-http://partners.adobe.com/asn/developer/PDFS/TN/5004.AFM_Spec.pdf
-</A><BR>
- Specification of the Adobe font metrics file format.
-<p>
-
-<A HREF="http://www.cs.wpi.edu/~matt/courses/cs563/talks/surface/bez_surf.html">
-http://www.cs.wpi.edu/~matt/courses/cs563/talks/surface/bez_surf.html
-</A><BR>
-<A HREF="http://www.cs.wpi.edu/~matt/courses/cs563/talks/curves.html">
-http://www.cs.wpi.edu/~matt/courses/cs563/talks/curves.html
-</A><BR>
- Information about the Bezier curves.
-<p>
-
-<A HREF="http://www.neuroinformatik.ruhr-uni-bochum.de/ini/PEOPLE/rmz/t1lib/t1lib.html">
-http://www.neuroinformatik.ruhr-uni-bochum.de/ini/PEOPLE/rmz/t1lib/t1lib.html
-</A><br>
- A stand-alone library supporting the Type1 fonts. Is neccessary
- to compile the programs <tt>other/cmpf</tt> and <tt>other/dmpf</tt>.
-<p>
-
-<A HREF="http://www.freetype.org">
-http://www.freetype.org
-</A><br>
- A library supporting the TTF fonts. Also many useful TTF programs
- are included with it.
-<p>
-
-<A HREF="http://heliotrope.homestead.com/files/printsoft.html">
-http://heliotrope.homestead.com/files/printsoft.html
-</A><br>
- Moses Gold's collection of links to printing software.
-<p>
-
-<A HREF="http://linuxartist.org/fonts/">
-http://linuxartist.org/fonts/
-</A><br>
- Collection of font-related links.
-<p>
-
-<HR>
-<HR>
-<!
-----------------------------------------------------------------------
-----------------------------------------------------------------------
->
-
-Following is the Readme of <tt>ttf2pfa</tt> (true type to type 3 font converter) It
-covers other issues regarding the use of this software. Please note that
-although <tt>ttf2pfa</tt> is a public domain software, <tt>ttf2pt1</tt>
-is instead covered by an Open Source license. See the <tt>COPYRIGHT</tt>
-file for details.
-<p>
-
-Please note also that <tt>ttf2pfa</tt> has not been maintained for a long time.
-All of its functionality has been integrated into <tt>ttf2pt1</tt> and all the
-development moved to <tt>ttf2pt1</tt>, including Andrew Weeks, the author of
-<tt>ttf2pfa</tt>. <tt>Ttf2pfa</tt> is provided for historical reasons only. Please use
-<tt>ttf2pt1</tt> instead.
-
-<HR>
-<!
-----------------------------------------------------------------------
->
-
-<H3>
-True Type to Postscript Font converter
-</H3>
-<!
---------------------------------------
->
-
-My mind is still reeling from the discovery that I was able to write
-this program. What it does is it reads a Microsoft TrueType font and
-creates a Postscript font. '<I>_A_</I> postscript font', that is, not necessarily
-the same font, you understand, but a fair imitation.
-<p>
-
-Run it like this:
-<p>
-
-<blockquote><tt>
- ttf2pfa fontfile.ttf fontname
-</tt></blockquote>
-<p>
-
-The first parameter is the truetype filename, the second is a stem for
-the output file names. The program will create a <tt>fontname.pfa</tt> containing
-the Postscript font and a <tt>fontname.afm</tt> containing the metrics.
-<p>
-
-The motivation behind this is that in Linux if you do not have a
-Postscript printer, but only some other printer, you can only print
-Postscript by using Ghostscript. But the fonts that come with
-Ghostscript are very poor (they are converted from bitmaps and look
-rather lumpy). This is rather frustrating as the PC running Linux
-probably has MS-Windows as well and will therefore have truetype fonts,
-but which are quite useless with Linux, X or Ghostscript.
-<p>
-
-The program has been tested on over a hundred different TrueType fonts
-from various sources, and seems to work fairly well. The converted
-characters look OK, and the program doesn't seem to crash any more. I'm
-not sure about the AFM files though, as I have no means to test them.
-<p>
-
-The fonts generated will not work with X, as the font rasterizer that
-comes with X only copes with Type 1 fonts. If I have the time I may
-modify ttf2pfa to generate Type 1s.
-<p>
-
-<H4>
-Copyright issues
-</H4>
-<!
-----------------
->
-
-I am putting this program into the public domain, so don't bother
-sending me any money, I'd only have to declare it for income tax.
-<p>
-
-Copyright on fonts, however, is a difficult legal question. Any
-copyright statements found in a font will be preserved in the output.
-Whether you are entitled to translate them at all I don't know.
-<p>
-
-If you have a license to run a software package, like say MS-Windows, on
-your PC, then you probably have a right to use any part of it, including
-fonts, on that PC, even if not using that package for its intended
-purpose.
-<p>
-
-I am not a lawyer, however, so this is not a legal opinion, and may be
-garbage.
-<p>
-
-There shouldn't be a any problem with public domain fonts.
-<p>
-
-<H4>
-About the Program
-</H4>
-<!
------------------
->
-
-It was written in C on a IBM PC running Linux.
-<p>
-
-The TrueType format was originally developed by Apple for the MAC, which
-has opposite endianness to the PC, so to ensure compatibility 16 and 32
-bit fields are the wrong way round from the PC's point of view. This is
-the reason for all the 'ntohs' and 'ntohl' calls. Doing it this way
-means the program will also work on big-endian machines like Suns.
-<p>
-
-I doubt whether it will work on a DOS-based PC though.
-<p>
-
-The program produces what technically are Type 3 rather than Type 1
-fonts. They are not compressed or encrypted and are plain text. This is
-so I (and you) can see what's going on, and (if you're a Postscript guru
-and really want to) can alter the outlines.
-<p>
-
-I only translate the outlines, not the 'instructions' that come with
-them. This latter task is probably virtually impossible anyway. TrueType
-outlines are B-splines rather than the Bezier curves that Postscript
-uses. I believe that my conversion algorithm is reasonably correct, if
-nothing else because the characters look right.
-<p>
-
-<H4>
-Problems that may occur
-</H4>
-<!
------------------------
->
-
-Most seriously, very complex characters (with lots of outline segments)
-can make Ghostscript releases 2.x.x fail with a 'limitcheck' error. It
-is possible that this may happen with some older Postscript printers as
-well. Such characters will be flagged by the program and there are
-basically two things you can do. First is to edit the <tt>.pfa</tt> file to
-simplify or remove the offending character. This is not really
-recommended. The second is to use Ghostscript release 3, if you can get
-it. This has much larger limits and does not seem to have any problems
-with complex characters.
-<p>
-
-Then there are buggy fonts (yes, a font can have bugs). I try to deal
-with these in as sane a manner as possible, but it's not always
-possible.
-<p>
-
-<H4>
-Encodings
-</H4>
-<!
----------
->
-
-A postscript font must have a 256 element array, called an encoding,
-each element of which is a name, which is also the name of a procedure
-contained within the font. The 'BuildChar' command takes a byte and uses
-it to index the encoding array to find a character name, and then looks
-that up in the font's procedure table find the commands to draw the
-glyph. However, not all characters need be in the encoding array. Those
-that are not cannot be drawn (at least not using 'show'), however it is
-possible to 're-encode' the font to enable these characters. There are
-several standard encodings: Adobe's original, ISO-Latin1 and Symbol
-being the most commonly encountered.
-<p>
-
-TrueType fonts are organised differently. As well as the glyph
-descriptions there are a number of tables. One of these is a mapping
-from a character set into the glyph array, and another is a mapping from
-the glyph array into a set of Postscript character names. The problems
-are:
-<p>
- 1) Microsoft uses Unicode, a 16-bit system, to encode the font.
-<br>
- 2) that more than one glyph is given the same Postscript name.
-<p>
-
-I deal with (1) by assuming a Latin1 encoding. The MS-Windows and
-Unicode character sets are both supersets of ISO-8859-1. This usually
-means that most characters will be properly encoded, but you should be
-warned that some software may assume that fonts have an Adobe encoding.
-Symbol, or Dingbat, fonts are in fact less of a problem, as they have
-private encodings starting at 0xF000. It is easy to just lose the top
-byte.
-<p>
-
-Postscript fonts can be re-encoded, either manually, or by software.
-Groff, for example, generates postscript that re-encodes fonts with the
-Adobe encoding. The problem here is that not all characters in the Adobe
-set are in the MS-Windows set. In particular there are no fi and fl
-ligatures. This means that conversions of the versions of
-Times-New-Roman and Arial that come with MS-Windows cannot be used
-blindly as replacements for Adobe Times-Roman and Helvetica. You can get
-expanded versions of MS fonts from Microsoft's web site which do contain
-these ligatures (and a lot else besides).
-<p>
-
-I deal with (2) by creating new character names. This can be error-prone
-because I do not know which of them is the correct glyph to give the
-name to. Some (buggy) fonts have large numbers of blank glyphs, all with
-the same name.
-<p>
-
-(almost every TrueType font has three glyphs called <tt>.notdef</tt>, one of them
-is usually an empty square shape, one has no outline and has zero width,
-and one has no outline and a positive width. This example is not really
-a problem with well formed fonts since the <tt>.notdef</tt> characters are only
-used for unprintable characters, which shouldn't occur in your documents
-anyway).
-<p>
-</BODY>
-</HTML>
diff --git a/nx-X11/extras/ttf2pt1/bdf.c b/nx-X11/extras/ttf2pt1/bdf.c
deleted file mode 100644
index 9f6c72720..000000000
--- a/nx-X11/extras/ttf2pt1/bdf.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * The font parser for the BDF files
- *
- * Copyright (c) 2001 by the TTF2PT1 project
- * Copyright (c) 2001 by Sergey Babkin
- *
- * see COPYRIGHT for the full copyright notice
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include "pt1.h"
-#include "global.h"
-
-/* prototypes of call entries */
-static void openfont(char *fname, char *arg);
-static void closefont( void);
-static int getnglyphs ( void);
-static int glnames( GLYPH *glyph_list);
-static void readglyphs( GLYPH *glyph_list);
-static int glenc( GLYPH *glyph_list, int *encoding, int *unimap);
-static void fnmetrics( struct font_metrics *fm);
-static void glpath( int glyphno, GLYPH *glyph_list);
-static void kerning( GLYPH *glyph_list);
-
-/* globals */
-
-/* front-end descriptor */
-struct frontsw bdf_sw = {
- /*name*/ "bdf",
- /*descr*/ "BDF bitmapped fonts",
- /*suffix*/ { "bdf" },
- /*open*/ openfont,
- /*close*/ closefont,
- /*nglyphs*/ getnglyphs,
- /*glnames*/ glnames,
- /*glmetrics*/ readglyphs,
- /*glenc*/ glenc,
- /*fnmetrics*/ fnmetrics,
- /*glpath*/ glpath,
- /*kerning*/ kerning,
-};
-
-/* statics */
-
-#define MAXLINE 10240 /* maximal line length in the input file */
-
-static int lineno; /* line number */
-
-#define GETLEN(s) s, (sizeof(s)-1)
-#define LENCMP(str, txt) strncmp(str, txt, sizeof(txt)-1)
-
-static FILE *bdf_file;
-static int nglyphs;
-static struct font_metrics fmet;
-
-/* many BDF fonts are of small pixel size, so we better try
- * to scale them by an integer to keep the dimensions in
- * whole pixels. However if the size is too big and a non-
- * integer scaling is needed, we use the standard ttf2pt1's
- * scaling abilities.
- */
-static int pixel_size;
-static int scale;
-static int scale_external;
-
-static char *slant;
-static char xlfdname[201];
-static char *spacing;
-static char *charset_reg;
-static char *charset_enc;
-static char *fnwidth;
-static int is_unicode = 0;
-
-/* tempoary storage for returning data to ttf2pt1 later on request */
-static int maxenc = 0;
-static int *fontenc;
-static GENTRY **glpaths;
-
-static int got_glyphs = 0;
-static GLYPH *glyphs;
-static int curgl;
-
-static int readfile(FILE *f, int (*strfunc)(int len, char *str));
-
-/*
- * Read the file and parse each string with strfunc(),
- * until strfunc() returns !=0 or the end of file happens.
- * Returns -1 on EOF or strfunc() returning <0, else 0
- */
-
-static int
-readfile(
- FILE *f,
- int (*strfunc)(int len, char *str)
-)
-{
- static char str[MAXLINE]; /* input line, maybe should be dynamic ? */
- char *s;
- int len, c, res;
-
- len=0;
- while(( c=getc(f) )!=EOF) {
- if(c=='\n') {
- str[len]=0;
-
- res = strfunc(len, str);
- lineno++;
- if(res<0)
- return -1;
- else if(res!=0)
- return 0;
-
- len=0;
- } else if(len<MAXLINE-1) {
- if(c!='\r')
- str[len++]=c;
- } else {
- fprintf(stderr, "**** bdf: line %d is too long (>%d)\n", lineno, MAXLINE-1);
- exit(1);
- }
- }
- return -1; /* EOF */
-}
-
-/*
- * Parse the header of the font file.
- * Stop after the line CHARS is encountered. Ignore the unknown lines.
- */
-
-struct line {
- char *name; /* property name with trailing space */
- int namelen; /* length of the name string */
- enum {
- ALLOW_REPEAT = 0x01, /* this property may be repeated in multiple lines */
- IS_SEEN = 0x02, /* this property has been seen already */
- MUST_SEE = 0x04, /* this property must be seen */
- IS_LAST = 0x08 /* this is the last property to be read */
- } flags;
- char *fmt; /* format string for the arguments, NULL means a string arg */
- int nvals; /* number of values to be read by sscanf */
- void *vp[4]; /* pointers to values to be read */
-};
-
-static struct line header[] = {
- { GETLEN("FONT "), 0, " %200s", 1, {&xlfdname} },
- { GETLEN("SIZE "), MUST_SEE, " %d", 1, {&pixel_size} },
- { GETLEN("FONTBOUNDINGBOX "), MUST_SEE, " %hd %hd %hd %hd", 4,
- {&fmet.bbox[2], &fmet.bbox[3], &fmet.bbox[0], &fmet.bbox[1]} },
- { GETLEN("FAMILY_NAME "), MUST_SEE, NULL, 1, {&fmet.name_family} },
- { GETLEN("WEIGHT_NAME "), MUST_SEE, NULL, 1, {&fmet.name_style} },
- { GETLEN("COPYRIGHT "), 0, NULL, 1, {&fmet.name_copyright} },
- { GETLEN("SLANT "), MUST_SEE, NULL, 1, {&slant} },
- { GETLEN("SPACING "), 0, NULL, 1, {&spacing} },
- { GETLEN("SETWIDTH_NAME "), 0, NULL, 1, {&fnwidth} },
- { GETLEN("CHARSET_REGISTRY "), 0, NULL, 1, {&charset_reg} },
- { GETLEN("CHARSET_ENCODING "), 0, NULL, 1, {&charset_enc} },
- { GETLEN("FONT_ASCENT "), 0, " %hd", 1, {&fmet.ascender} },
- { GETLEN("FONT_DESCENT "), 0, " %hd", 1, {&fmet.descender} },
-
- /* these 2 must go in this order for post-processing */
- { GETLEN("UNDERLINE_THICKNESS "), 0, " %hd", 1, {&fmet.underline_thickness} },
- { GETLEN("UNDERLINE_POSITION "), 0, " %hd", 1, {&fmet.underline_position} },
-
- { GETLEN("CHARS "), MUST_SEE|IS_LAST, " %d", 1, {&nglyphs} },
- { NULL, 0, 0 } /* end mark: name==NULL */
-};
-
-static int
-handle_header(
- int len,
- char *str
-)
-{
- struct line *cl;
- char *s, *p;
- int c;
-
-#if 0
- fprintf(stderr, "line: %s\n", str);
-#endif
- for(cl = header; cl->name != 0; cl++) {
- if(strncmp(str, cl->name, cl->namelen))
- continue;
-#if 0
- fprintf(stderr, "match: %s\n", cl->name);
-#endif
- if(cl->flags & IS_SEEN) {
- if(cl->flags & ALLOW_REPEAT)
- continue;
-
- fprintf(stderr, "**** input line %d redefines the property %s\n", lineno, cl->name);
- exit(1);
- }
- cl->flags |= IS_SEEN;
- if(cl->fmt == 0) {
- s = malloc(len - cl->namelen + 1);
- if(s == 0) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- *((char **)(cl->vp[0])) = s;
-
- /* skip until a quote */
- for(p = str+cl->namelen; (c = *p)!=0; p++) {
- if(c == '"') {
- p++;
- break;
- }
- }
- for(; (c = *p)!=0; p++) {
- if(c == '"') {
- c = *++p;
- if(c == '"')
- *s++ = c;
- else
- break;
- } else
- *s++ = c;
- }
- *s = 0; /* end of line */
- } else {
- c = sscanf(str+cl->namelen, cl->fmt, cl->vp[0], cl->vp[1], cl->vp[2], cl->vp[3]);
- if(c != cl->nvals) {
- fprintf(stderr, "**** property %s at input line %d must have %d arguments\n",
- cl->name, lineno, cl->nvals);
- exit(1);
- }
- }
- if(cl->flags & IS_LAST)
- return 1;
- else
- return 0;
- }
- return 0;
-}
-
-/*
- * Parse the description of the glyphs
- */
-
-static int
-handle_glyphs(
- int len,
- char *str
-)
-{
- static int inbmap=0;
- static char *bmap;
- static int xsz, ysz, xoff, yoff;
- static int curln;
- int i, c;
- char *p, *plim, *psz;
-
- if(!LENCMP(str, "ENDFONT")) {
- if(curgl < nglyphs) {
- fprintf(stderr, "**** unexpected end of font file after %d glyphs\n", curgl);
- exit(1);
- } else
- return 1;
- }
- if(curgl >= nglyphs) {
- fprintf(stderr, "**** file contains more glyphs than advertised (%d)\n", nglyphs);
- exit(1);
- }
- if(!LENCMP(str, "STARTCHAR")) {
- /* sizeof will count \0 instead of ' ' */
- for(i=sizeof("STARTCHAR"); str[i] == ' '; i++)
- {}
-
- glyphs[curgl].name = strdup(str + i);
- if(glyphs[curgl].name == 0) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- } else if(!LENCMP(str, "ENCODING")) {
- if(sscanf(str, "ENCODING %d", &fontenc[curgl])!=1) {
- fprintf(stderr,"**** weird ENCODING statement at line %d\n", lineno);
- exit(1);
- }
- if(fontenc[curgl] == -1) /* compatibility format */
- sscanf(str, "ENCODING -1 %d", &fontenc[curgl]);
- if(fontenc[curgl] > maxenc)
- maxenc = fontenc[curgl];
- } else if(!LENCMP(str, "DWIDTH")) {
- if(sscanf(str, "DWIDTH %d %d", &xsz, &ysz)!=2) {
- fprintf(stderr,"**** weird DWIDTH statement at line %d\n", lineno);
- exit(1);
- }
- glyphs[curgl].width = xsz*scale;
- } else if(!LENCMP(str, "BBX")) {
- if(sscanf(str, "BBX %d %d %d %d", &xsz, &ysz, &xoff, &yoff)!=4) {
- fprintf(stderr,"**** weird BBX statement at line %d\n", lineno);
- exit(1);
- }
- bmap=malloc(xsz*ysz);
- if(bmap==0) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- glyphs[curgl].lsb = -xoff*scale;
- glyphs[curgl].xMin = -xoff*scale;
- glyphs[curgl].xMax = (xsz-xoff)*scale;
- glyphs[curgl].yMin = -yoff*scale;
- glyphs[curgl].yMax = (ysz-xoff)*scale;
- } else if(!LENCMP(str, "BITMAP")) {
- inbmap=1;
- curln=ysz-1; /* the lowest line has index 0 */
- } else if(!LENCMP(str, "ENDCHAR")) {
- inbmap=0;
- if(bmap) {
- glyphs[curgl].lastentry = 0;
- glyphs[curgl].path = 0;
- glyphs[curgl].entries = 0;
- bmp_outline(&glyphs[curgl], scale, bmap, xsz, ysz, xoff, yoff);
- free(bmap);
- /* remember in a static table or it will be erased */
- glpaths[curgl] = glyphs[curgl].entries;
- glyphs[curgl].entries = 0;
-
- if(glpaths[curgl])
- glyphs[curgl].ttf_pathlen = 1;
- else
- glyphs[curgl].ttf_pathlen = 0;
- }
- curgl++;
- } else if(inbmap) {
- if(curln<0) {
- fprintf(stderr,"**** bitmap is longer than %d lines at line %d\n", ysz, lineno);
- exit(1);
- }
-
- i=0;
- p=&bmap[curln*xsz]; psz=p+xsz;
- while(i<len) {
- c=str[i++];
- if(!isxdigit(c)) {
- fprintf(stderr,"**** non-hex digit in bitmap at line %d\n", lineno);
- exit(1);
- }
- if(c<='9')
- c-='0';
- else
- c= tolower(c)-'a'+10;
-
- for(plim=p+4; p<psz && p<plim; c<<=1)
- *p++ = (( c & 0x08 )!=0);
- }
- if(p<psz) {
- fprintf(stderr,"**** bitmap line is too short at line %d\n", lineno);
- exit(1);
- }
- curln--;
- }
- return 0;
-}
-
-/*
- * Read all the possible information about the glyphs
- */
-
-static void
-readglyphs(
- GLYPH *glyph_list
-)
-{
- int i;
- GLYPH *g;
-
- if(got_glyphs)
- return;
-
- /* pass them to handle_glyphs() through statics */
- glyphs = glyph_list;
- curgl = 2; /* skip the empty glyph and .notdef */
-
- /* initialize the empty glyph and .notdef */
-
- for(i=0; i<2; i++) {
- g = &glyphs[i];
- g->lsb = 0;
- g->width = fmet.bbox[2];
- g->xMin = 0;
- g->yMin = 0;
- }
- g = &glyphs[0];
- g->name = ".notdef";
- g->xMax = fmet.bbox[2]*4/5;
- g->yMax = fmet.bbox[3]*4/5;
- g->entries = g->path = g->lastentry = 0;
- /* make it look as a black square */
- fg_rmoveto(g, 0.0, 0.0);
- fg_rlineto(g, 0.0, (double)g->yMax);
- fg_rlineto(g, (double)g->xMax, (double)g->yMax);
- fg_rlineto(g, (double)g->xMax, 0.0);
- fg_rlineto(g, 0.0, 0.0);
- g_closepath(g);
- glpaths[0] = g->entries;
- g->entries = 0;
- g->ttf_pathlen = 4;
-
- g = &glyphs[1];
- g->name = ".null";
- g->xMax = g->yMax = 0;
- g->ttf_pathlen = 0;
-
- if(readfile(bdf_file, handle_glyphs) < 0) {
- fprintf(stderr, "**** file does not contain the ENDFONT line\n");
- exit(1);
- }
- got_glyphs = 1;
-}
-
-/*
- * Open font and prepare to return information to the main driver.
- * May print error and warning messages.
- * Exit on error.
- */
-
-static void
-openfont(
- char *fname,
- char *arg /* unused now */
-)
-{
- struct line *cl;
- int i, l;
-
- if ((bdf_file = fopen(fname, "r")) == NULL) {
- fprintf(stderr, "**** Cannot open file '%s'\n", fname);
- exit(1);
- } else {
- WARNING_2 fprintf(stderr, "Processing file %s\n", fname);
- }
-
- lineno = 1;
-
- for(cl = header; cl->name != 0; cl++)
- cl->flags &= ~IS_SEEN;
- if(readfile(bdf_file, handle_header) < 0) {
- fprintf(stderr, "**** file does not contain the CHARS definition\n");
- exit(1);
- }
- for(cl = header; cl->name != 0; cl++) {
- if( (cl->flags & MUST_SEE) && !(cl->flags & IS_SEEN) ) {
- fprintf(stderr, "**** mandatory property %sis not found in the input line\n",
- cl->name); /* cl->name has a space at the end */
- exit(1);
- }
-
- /* set a few defaults */
- if( !(cl->flags & IS_SEEN) ) {
- if(cl->vp[0] == &fmet.underline_thickness) {
- fmet.underline_thickness = 1;
- } else if(cl->vp[0] == &fmet.underline_position) {
- fmet.underline_position = fmet.bbox[1] + fmet.underline_thickness
- - (pixel_size - fmet.bbox[3]);
- } else if(cl->vp[0] == &fmet.ascender) {
- fmet.ascender = fmet.bbox[2] + fmet.bbox[0];
- } else if(cl->vp[0] == &fmet.descender) {
- fmet.descender = fmet.bbox[0];
- }
- }
- }
-
- nglyphs += 2; /* add empty glyph and .notdef */
-
- /* postprocessing to compensate for the differences in the metric formats */
- fmet.bbox[2] += fmet.bbox[0];
- fmet.bbox[3] += fmet.bbox[1];
-
- scale = 1000/pixel_size; /* XXX ? */
- if(scale*pixel_size < 950) {
- scale = 1;
- scale_external = 1;
- fmet.units_per_em = pixel_size;
- } else {
- scale_external = 0;
- fmet.units_per_em = scale*pixel_size;
-
- fmet.underline_position *= scale;
- fmet.underline_thickness *= scale;
- fmet.ascender *= scale;
- fmet.descender *= scale;
- for(i=0; i<4; i++)
- fmet.bbox[i] *= scale;
- }
-
- fmet.italic_angle = 0.0;
- if(spacing == 0 /* possibly an old font */
- || toupper(spacing[0]) != 'P') /* or anything non-proportional */
- fmet.is_fixed_pitch = 1;
- else
- fmet.is_fixed_pitch = 0;
-
- if(fmet.name_copyright==NULL)
- fmet.name_copyright = "";
-
- /* create the full name */
- l = strlen(fmet.name_family)
- + (fmet.name_style? strlen(fmet.name_style) : 0)
- + (fnwidth? strlen(fnwidth) : 0)
- + strlen("Oblique") + 1;
-
- if(( fmet.name_full = malloc(l) )==NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- strcpy(fmet.name_full, fmet.name_family);
- if(fnwidth && strcmp(fnwidth, "Normal")) {
- strcat(fmet.name_full, fnwidth);
- }
- if(fmet.name_style && strcmp(fmet.name_style, "Medium")) {
- strcat(fmet.name_full, fmet.name_style);
- }
- switch(toupper(slant[0])) {
- case 'O':
- strcat(fmet.name_full, "Oblique");
- break;
- case 'I':
- strcat(fmet.name_full, "Italic");
- break;
- }
-
- fmet.name_ps = fmet.name_full;
- fmet.name_version = "1.0";
-
- if(charset_reg && charset_enc
- && !strcmp(charset_reg, "iso10646") && !strcmp(charset_enc, "1"))
- is_unicode = 1;
-
- if(( fontenc = calloc(nglyphs, sizeof *fontenc) )==NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- for(i=0; i<nglyphs; i++)
- fontenc[i] = -1;
- if(( glpaths = calloc(nglyphs, sizeof *glpaths) )==NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
-}
-
-/*
- * Close font.
- * Exit on error.
- */
-
-static void
-closefont(
- void
-)
-{
- if(fclose(bdf_file) < 0) {
- WARNING_1 fprintf(stderr, "Errors when closing the font file, ignored\n");
- }
-}
-
-/*
- * Get the number of glyphs in font.
- */
-
-static int
-getnglyphs (
- void
-)
-{
- return nglyphs;
-}
-
-/*
- * Get the names of the glyphs.
- * Returns 0 if the names were assigned, non-zero if the font
- * provides no glyph names.
- */
-
-static int
-glnames(
- GLYPH *glyph_list
-)
-{
- readglyphs(glyph_list);
- return 0;
-}
-
-/*
- * Get the original encoding of the font.
- * Returns 1 for if the original encoding is Unicode, 2 if the
- * original encoding is other 16-bit, 0 if 8-bit.
- */
-
-static int
-glenc(
- GLYPH *glyph_list,
- int *encoding,
- int *unimap
-)
-{
- int i, douni, e;
-
- if(is_unicode || forcemap)
- douni = 1;
- else
- douni = 0;
-
- for(i=0; i<nglyphs; i++) {
- e = fontenc[i];
- if(douni)
- e = unicode_rev_lookup(e);
- if(e>=0 && e<ENCTABSZ && encoding[e] == -1)
- encoding[e] = i;
- }
-
- if(is_unicode)
- return 1;
- else if(maxenc > 255)
- return 2;
- else
- return 0;
-}
-
-/*
- * Get the font metrics
- */
-static void
-fnmetrics(
- struct font_metrics *fm
-)
-{
- *fm = fmet;
-}
-
-/*
- * Get the path of contrours for a glyph.
- */
-
-static void
-glpath(
- int glyphno,
- GLYPH *glyf_list
-)
-{
- readglyphs(glyf_list);
- glyf_list[glyphno].entries = glpaths[glyphno];
- glpaths[glyphno] = 0;
-}
-
-/*
- * Get the kerning data.
- */
-
-static void
-kerning(
- GLYPH *glyph_list
-)
-{
- return; /* no kerning in BDF */
-}
diff --git a/nx-X11/extras/ttf2pt1/bitmap.c b/nx-X11/extras/ttf2pt1/bitmap.c
deleted file mode 100644
index d2334e433..000000000
--- a/nx-X11/extras/ttf2pt1/bitmap.c
+++ /dev/null
@@ -1,2633 +0,0 @@
-/*
- * Handling of the bitmapped glyphs
- *
- * Copyright (c) 2001 by the TTF2PT1 project
- * Copyright (c) 2001 by Sergey Babkin
- *
- * see COPYRIGHT for the full copyright notice
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "pt1.h"
-#include "global.h"
-
-/* possible values of limits */
-#define L_NONE 0 /* nothing here */
-#define L_ON 1 /* black is on up/right */
-#define L_OFF 2 /* black is on down/left */
-
-static int warnedhints = 0;
-
-
-#ifdef USE_AUTOTRACE
-#include <autotrace/autotrace.h>
-
-/*
- * Produce an autotraced outline from a bitmap.
- * scale - factor to scale the sizes
- * bmap - array of dots by lines, xsz * ysz
- * xoff, yoff - offset of the bitmap's lower left corner
- * from the logical position (0,0)
- */
-
-static void
-autotraced_bmp_outline(
- GLYPH *g,
- int scale,
- char *bmap,
- int xsz,
- int ysz,
- int xoff,
- int yoff
-)
-{
- at_bitmap_type atb;
- at_splines_type *atsp;
- at_fitting_opts_type *atoptsp;
- at_spline_list_type *slp;
- at_spline_type *sp;
- int i, j, k;
- double lastx, lasty;
- double fscale;
- char *xbmap;
-
- fscale = (double)scale;
-
- /* provide a white margin around the bitmap */
- xbmap = malloc((ysz+2)*(xsz+2));
- if(xbmap == 0) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- memset(xbmap, 0, xsz+2); /* top margin */
- for(i=0, j=xsz+2; i<ysz; i++, j+=xsz+2) {
- xbmap[j] = 0; /* left margin */
- memcpy(&xbmap[j+1], &bmap[xsz*(ysz-1-i)], xsz); /* a line of bitmap */
- xbmap[j+xsz+1] = 0; /* right margin */
- }
- memset(xbmap+j, 0, xsz+2); /* bottom margin */
- xoff--; yoff-=2; /* compensate for the margins */
-
- atoptsp = at_fitting_opts_new();
-
- atb.width = xsz+2;
- atb.height = ysz+2;
- atb.np = 1;
- atb.bitmap = xbmap;
-
- atsp = at_splines_new(&atb, atoptsp);
-
- lastx = lasty = -1.;
- for(i=0; i<atsp->length; i++) {
- slp = &atsp->data[i];
-#if 0
- fprintf(stderr, "%s: contour %d: %d entries clockwise=%d color=%02X%02X%02X\n",
- g->name, i, slp->length, slp->clockwise, slp->color.r, slp->color.g, slp->color.b);
-#endif
- if(slp->length == 0)
- continue;
-#if 0
- if(slp->color.r + slp->color.g + slp->color.b == 0)
- continue;
-#endif
- fg_rmoveto(g, fscale*(slp->data[0].v[0].x+xoff), fscale*(slp->data[0].v[0].y+yoff));
- for(j=0; j<slp->length; j++) {
-#if 0
- fprintf(stderr, " ");
- for(k=0; k<4; k++)
- fprintf(stderr, "(%g %g) ",
- fscale*(slp->data[j].v[k].x+xoff),
- fscale*(ysz-slp->data[j].v[k].y+yoff)
- );
- fprintf(stderr, "\n");
-#endif
- fg_rrcurveto(g,
- fscale*(slp->data[j].v[1].x+xoff), fscale*(slp->data[j].v[1].y+yoff),
- fscale*(slp->data[j].v[2].x+xoff), fscale*(slp->data[j].v[2].y+yoff),
- fscale*(slp->data[j].v[3].x+xoff), fscale*(slp->data[j].v[3].y+yoff) );
- }
- g_closepath(g);
- }
-
- at_splines_free(atsp);
- at_fitting_opts_free(atoptsp);
- free(xbmap);
-}
-
-#endif /*USE_AUTOTRACE*/
-
-/* an extension of gentry for description of the fragments */
-typedef struct gex_frag GEX_FRAG;
-struct gex_frag {
- /* indexes to len, the exact values and order are important */
-#define GEXFI_NONE -1
-#define GEXFI_CONVEX 0
-#define GEXFI_CONCAVE 1
-#define GEXFI_LINE 2 /* a line with steps varying by +-1 pixel */
-#define GEXFI_EXACTLINE 3 /* a line with exactly the same steps */
-#define GEXFI_SERIF 4 /* small serifs at the ends of stemsi - must be last */
-#define GEXFI_COUNT 5 /* maximal index + 1 */
- unsigned short len[GEXFI_COUNT]; /* length of various fragment types starting here */
- unsigned short lenback[GEXFI_COUNT]; /* length back to the start of curve */
-
- signed char ixstart; /* index of the frag type that starts here */
- signed char ixcont; /* index of the frag type that continues here */
-
- short flags;
-#define GEXFF_HLINE 0x0001 /* the exact line is longer in "horizontal" dimension */
-#define GEXFF_EXTR 0x0002 /* this gentry is an extremum in some direction */
-#define GEXFF_CIRC 0x0004 /* the joint at this gentry is for a circular curve */
-#define GEXFF_DRAWCURVE 0x0008 /* vect[] describes a curve to draw */
-#define GEXFF_DRAWLINE 0x0010 /* vect[] describes a line to draw */
-#define GEXFF_SPLIT 0x0020 /* is a result of splitting a line */
-#define GEXFF_SYMNEXT 0x0040 /* this subfrag is symmetric with next one */
-#define GEXFF_DONE 0x0080 /* this subfrag has been vectorized */
-#define GEXFF_LONG 0x0100 /* this gentry is longer than 1 pixel */
-
- unsigned short aidx; /* index of gentry in the array representing the contour */
-
- unsigned short vectlen; /* number of gentries represented by vect[] */
-
- /* coordinates for vectored replacement of this fragment */
- /* (already scaled because it's needed for curve approximation) */
- double vect[4 /*ref.points*/][2 /*X,Y*/];
-
- double bbox[2 /*X,Y*/]; /* absolute sizes of bounding box of a subfragment */
-
- /* used when splitting the curved frags into subfrags */
- GENTRY *prevsub; /* to gentries describing neighboring subfrags */
- GENTRY *nextsub;
- GENTRY *ordersub; /* single-linked list describing the order of calculation */
-
- int sublen; /* length of this subfrag */
- /* the symmetry across the subfrags */
- int symaxis; /* the symmetry axis, with next subfrag */
- int symxlen; /* min length of adjacent symmetric frags */
- /* the symmetry within this subfrag (the axis is always diagonal) */
- GENTRY *symge; /* symge->i{x,y}3 is the symmetry point of symge==0 if none */
-
-};
-#define X_FRAG(ge) ((GEX_FRAG *)((ge)->ext))
-
-/* various interesting tables related to GEX_FRAG */
-static char *gxf_name[GEXFI_COUNT] = {"Convex", "Concave", "Line", "ExLine", "Serif"};
-static int gxf_cvk[2] = {-1, 1}; /* coefficients of concaveness */
-
-/*
- * Dump the contents of X_EXT()->len and ->lenback for a contour
- */
-static void
-gex_dump_contour(
- GENTRY *ge,
- int clen
-)
-{
- int i, j;
-
- for(j = 0; j < GEXFI_COUNT; j++) {
- fprintf(stderr, "%-8s", gxf_name[j]);
- for(i = 0; i < clen; i++, ge = ge->frwd)
- fprintf(stderr, " %2d", X_FRAG(ge)->len[j]);
- fprintf(stderr, " %p\n (back) ", ge);
- for(i = 0; i < clen; i++, ge = ge->frwd)
- fprintf(stderr, " %2d", X_FRAG(ge)->lenback[j]);
- fprintf(stderr, "\n");
- }
-}
-
-/*
- * Calculate values of X_EXT()->lenback[] for all entries in
- * a contour. The contour is identified by:
- * ge - any gentry of the contour
- * clen - contour length
- */
-
-static void
-gex_calc_lenback(
- GENTRY *ge,
- int clen
-)
-{
- int i, j;
- int end;
- GEX_FRAG *f;
- int len[GEXFI_COUNT]; /* length of the most recent fragment */
- int count[GEXFI_COUNT]; /* steps since beginning of the fragment */
-
- for(j = 0; j < GEXFI_COUNT; j++)
- len[j] = count[j] = 0;
-
- end = clen;
- for(i = 0; i < end; i++, ge = ge->frwd) {
- f = X_FRAG(ge);
- for(j = 0; j < GEXFI_COUNT; j++) {
- if(len[j] != count[j]) {
- f->lenback[j] = count[j]++;
- } else
- f->lenback[j] = 0;
- if(f->len[j] != 0) {
- len[j] = f->len[j];
- count[j] = 1; /* start with the next gentry */
- /* if the fragment will wrap over the start, process to its end */
- if(i < clen && i + len[j] > end)
- end = i + len[j];
- }
- }
- }
- gex_dump_contour(ge, clen);
-}
-
-/* Limit a curve to not exceed the given coordinates
- * at its given side
- */
-
-static void
-limcurve(
- double curve[4][2 /*X,Y*/],
- double lim[2 /*X,Y*/],
- int where /* 0 - start, 3 - end */
-)
-{
- int other = 3-where; /* the other end */
- int sgn[2 /*X,Y*/]; /* sign for comparison */
- double t, from, to, nt, t2, nt2, tt[4];
- double val[2 /*X,Y*/];
- int i;
-
- for(i=0; i<2; i++)
- sgn[i] = fsign(curve[other][i] - curve[where][i]);
-
-#if 0
- fprintf(stderr, " limit (%g,%g)-(%g,%g) at %d by (%g,%g), sgn(%d,%d)\n",
- curve[0][0], curve[0][1], curve[3][0], curve[3][1],
- where, lim[0], lim[1], sgn[0], sgn[1]);
-#endif
- /* a common special case */
- if( sgn[0]*(curve[where][0] - lim[0]) >= 0.
- && sgn[1]*(curve[where][1] - lim[1]) >= 0. )
- return; /* nothing to do */
-
- if(other==0) {
- from = 0.;
- to = 1.;
- } else {
- from = 1.;
- to = 0.;
- }
-#if 0
- fprintf(stderr, "t=");
-#endif
- while( fabs(from-to) > 0.00001 ) {
- t = 0.5 * (from+to);
- t2 = t*t;
- nt = 1.-t;
- nt2 = nt*nt;
- tt[0] = nt2*nt;
- tt[1] = 3*nt2*t;
- tt[2] = 3*nt*t2;
- tt[3] = t*t2;
- for(i=0; i<2; i++)
- val[i] = curve[0][i]*tt[0] + curve[1][i]*tt[1]
- + curve[2][i]*tt[2] + curve[3][i]*tt[3];
-#if 0
- fprintf(stderr, "%g(%g,%g) ", t, val[0], val[1]);
-#endif
- if(fabs(val[0] - lim[0]) < 0.1
- || fabs(val[1] - lim[1]) < 0.1)
- break;
-
- if(sgn[0] * (val[0] - lim[0]) < 0.
- || sgn[1] * (val[1] - lim[1]) < 0.)
- to = t;
- else
- from = t;
- }
- /* now t is the point of splitting */
-#define SPLIT(pt1, pt2) ( (pt1) + t*((pt2)-(pt1)) ) /* order is important! */
- for(i=0; i<2; i++) {
- double v11, v12, v13, v21, v22, v31; /* intermediate points */
-
- v11 = SPLIT(curve[0][i], curve[1][i]);
- v12 = SPLIT(curve[1][i], curve[2][i]);
- v13 = SPLIT(curve[2][i], curve[3][i]);
- v21 = SPLIT(v11, v12);
- v22 = SPLIT(v12, v13);
- v31 = SPLIT(v21, v22);
- if(other==0) {
- curve[1][i] = v11;
- curve[2][i] = v21;
- curve[3][i] = fabs(v31 - lim[i]) < 0.1 ? lim[i] : v31;
- } else {
- curve[0][i] = fabs(v31 - lim[i]) < 0.1 ? lim[i] : v31;
- curve[1][i] = v22;
- curve[2][i] = v13;
- }
- }
-#undef SPLIT
-#if 0
- fprintf(stderr, "\n");
-#endif
-}
-
-/*
- * Vectorize a subfragment of a curve fragment. All the data has been already
- * collected by this time
- */
-
-static void
-dosubfrag(
- GLYPH *g,
- int fti, /* fragment type index */
- GENTRY *firstge, /* first gentry of fragment */
- GENTRY *ge, /* first gentry of subfragment */
- double fscale
-)
-{
- GENTRY *gel, *gei; /* last gentry of this subfrag */
- GEX_FRAG *f, *ff, *lf, *pf, *xf;
- /* maximal amount of space that can be used at the beginning and the end */
- double fixfront[2], fixend[2]; /* fixed points - used to show direction */
- double mvfront[2], mvend[2]; /* movable points */
- double limfront[2], limend[2]; /* limit of movement for movabel points */
- double sympt;
- int outfront, outend; /* the beginning/end is going outwards */
- int symfront, symend; /* a ready symmetric fragment is present at front/end */
- int drnd[2 /*X,Y*/]; /* size of the round part */
- int i, j, a1, a2, ndots;
- double avg2, max2; /* squared distances */
- struct dot_dist *dots, *usedots;
-
- ff = X_FRAG(firstge);
- f = X_FRAG(ge);
- gel = f->nextsub;
- lf = X_FRAG(gel);
- if(f->prevsub != 0)
- pf = X_FRAG(f->prevsub);
- else
- pf = 0;
-
- for(i=0; i<2; i++)
- drnd[i] = gel->bkwd->ipoints[i][2] - ge->ipoints[i][2];
-
- if(f->prevsub==0 && f->ixcont == GEXFI_NONE) {
- /* nothing to join with : may use the whole length */
- for(i = 0; i < 2; i++)
- limfront[i] = ge->bkwd->ipoints[i][2];
- } else {
- /* limit to a half */
- for(i = 0; i < 2; i++)
- limfront[i] = 0.5 * (ge->ipoints[i][2] + ge->bkwd->ipoints[i][2]);
- }
- if( (ge->ix3 == ge->bkwd->ix3) /* vert */
- ^ (isign(ge->bkwd->ix3 - ge->frwd->ix3)==isign(ge->bkwd->iy3 - ge->frwd->iy3))
- ^ (fti == GEXFI_CONCAVE) /* counter-clockwise */ ) {
- /* the beginning is not a flat 90-degree end */
- outfront = 1;
- for(i = 0; i < 2; i++)
- fixfront[i] = ge->frwd->ipoints[i][2];
- } else {
- outfront = 0;
- for(i = 0; i < 2; i++)
- fixfront[i] = ge->ipoints[i][2];
- }
-
- if(lf->nextsub==0 && lf->ixstart == GEXFI_NONE) {
- /* nothing to join with : may use the whole length */
- for(i = 0; i < 2; i++)
- limend[i] = gel->ipoints[i][2];
- } else {
- /* limit to a half */
- for(i = 0; i < 2; i++)
- limend[i] = 0.5 * (gel->ipoints[i][2] + gel->bkwd->ipoints[i][2]);
- }
- gei = gel->bkwd->bkwd;
- if( (gel->ix3 == gel->bkwd->ix3) /* vert */
- ^ (isign(gel->ix3 - gei->ix3)==isign(gel->iy3 - gei->iy3))
- ^ (fti == GEXFI_CONVEX) /* clockwise */ ) {
- /* the end is not a flat 90-degree end */
- outend = 1;
- for(i = 0; i < 2; i++)
- fixend[i] = gel->bkwd->bkwd->ipoints[i][2];
- } else {
- outend = 0;
- for(i = 0; i < 2; i++)
- fixend[i] = gel->bkwd->ipoints[i][2];
- }
-
- for(i = 0; i < 2; i++) {
- fixfront[i] *= fscale;
- limfront[i] *= fscale;
- fixend[i] *= fscale;
- limend[i] *= fscale;
- }
-
- fprintf(stderr, " %d out(%d[%d %d %d],%d[%d %d %d]) drnd(%d, %d)\n",
- fti,
- outfront,
- (ge->ix3 == ge->bkwd->ix3),
- (isign(ge->bkwd->ix3 - ge->frwd->ix3)==isign(ge->bkwd->iy3 - ge->frwd->iy3)),
- (fti == GEXFI_CONCAVE),
- outend,
- (gel->ix3 == gel->bkwd->ix3),
- (isign(gel->ix3 - gei->ix3)==isign(gel->iy3 - gei->iy3)),
- (fti == GEXFI_CONVEX),
- drnd[0], drnd[1]);
-
- /* prepare to calculate the distances */
- ndots = f->sublen - 1;
- dots = malloc(sizeof(*dots) * ndots);
- if(dots == 0) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- for(i = 0, gei = ge; i < ndots; i++, gei = gei->frwd) {
- for(a1 = 0; a1 < 2; a1++)
- dots[i].p[a1] = fscale * gei->ipoints[a1][2];
- }
-
- /* see if we can mirror a ready symmetric curve */
-
- /* check symmetry with the fragment before this */
- symfront = (pf != 0 && (pf->flags & GEXFF_SYMNEXT) && (pf->flags & GEXFF_DONE)
- && ( outend && f->sublen <= pf->sublen
- || ( pf->sublen == f->sublen
- && (lf->sublen == 0
- || ( abs(limfront[0]-limend[0]) >= abs(pf->vect[0][0]-pf->vect[3][0])
- && abs(limfront[1]-limend[1]) >= abs(pf->vect[0][1]-pf->vect[3][1]) ))
- )
- )
- );
- /* check symmetry with the fragment after this */
- symend = ( (f->flags & GEXFF_SYMNEXT) && (lf->flags & GEXFF_DONE)
- && ( outfront && f->sublen <= lf->sublen
- || ( lf->sublen == f->sublen
- && (pf == 0
- || ( abs(limfront[0]-limend[0]) >= abs(lf->vect[0][0]-lf->vect[3][0])
- && abs(limfront[1]-limend[1]) >= abs(lf->vect[0][1]-lf->vect[3][1]) ))
- )
- )
- );
- if(symfront || symend) {
- /* mirror the symmetric neighbour subfrag */
- if(symfront) {
- a1 = (ge->ix3 != ge->bkwd->ix3); /* the symmetry axis */
- a2 = !a1; /* the other axis (goes along the extremum gentry) */
-
- /* the symmetry point on a2 */
- sympt = fscale * 0.5 * (ge->ipoints[a2][2] + ge->bkwd->ipoints[a2][2]);
- xf = pf; /* the symmetric fragment */
- } else {
- a1 = (gel->ix3 != gel->bkwd->ix3); /* the symmetry axis */
- a2 = !a1; /* the other axis (goes along the extremum gentry) */
-
- /* the symmetry point on a2 */
- sympt = fscale * 0.5 * (gel->ipoints[a2][2] + gel->bkwd->ipoints[a2][2]);
- xf = lf; /* the symmetric fragment */
- }
- fprintf(stderr, " sym with %p f=%d(%p) e=%d(%p) a1=%c a2=%c sympt=%g\n",
- xf, symfront, pf, symend, lf,
- a1 ? 'Y': 'X', a2 ? 'Y': 'X', sympt
- );
- for(i=0; i<4; i++) {
- f->vect[3-i][a1] = xf->vect[i][a1];
- f->vect[3-i][a2] = sympt - (xf->vect[i][a2]-sympt);
- }
- if(symfront) {
- if(outend || lf->sublen==0)
- limcurve(f->vect, limend, 3);
- } else {
- if(outfront || pf == 0)
- limcurve(f->vect, limfront, 0);
- }
- avg2 = fdotcurvdist2(f->vect, dots, ndots, &max2);
- fprintf(stderr, " avg=%g max=%g fscale=%g\n", sqrt(avg2), sqrt(max2), fscale);
- if(max2 <= fscale*fscale) {
- f->flags |= (GEXFF_DONE | GEXFF_DRAWCURVE);
- f->vectlen = f->sublen;
- free(dots);
- return;
- }
- }
-
- if( !outfront && !outend && f->symge != 0) {
- /* a special case: try a circle segment as an approximation */
- double lenfront, lenend, len, maxlen;
-
- /* coefficient for a Bezier approximation of a circle */
-#define CIRCLE_FRAC 0.55
-
- a1 = (ge->ix3 == ge->bkwd->ix3); /* get the axis along the front */
- a2 = !a1; /* axis along the end */
-
- lenfront = fixfront[a1] - limfront[a1];
- lenend = fixend[a2] - limend[a2];
- if(fabs(lenfront) < fabs(lenend))
- len = fabs(lenfront);
- else
- len = fabs(lenend);
-
- /* make it go close to the round shape */
- switch(f->sublen) {
- case 2:
- maxlen = fscale;
- break;
- case 4:
- case 6:
- maxlen = fscale * 2.;
- break;
- default:
- maxlen = fscale * abs(ge->frwd->frwd->ipoints[a1][2]
- - ge->ipoints[a1][2]);
- break;
- }
- if(len > maxlen)
- len = maxlen;
-
- mvfront[a1] = fixfront[a1] - fsign(lenfront) * len;
- mvfront[a2] = limfront[a2];
- mvend[a2] = fixend[a2] - fsign(lenend) * len;
- mvend[a1] = limend[a1];
-
- for(i=0; i<2; i++) {
- f->vect[0][i] = mvfront[i];
- f->vect[3][i] = mvend[i];
- }
- f->vect[1][a1] = mvfront[a1] + CIRCLE_FRAC*(mvend[a1]-mvfront[a1]);
- f->vect[1][a2] = mvfront[a2];
- f->vect[2][a1] = mvend[a1];
- f->vect[2][a2] = mvend[a2] + CIRCLE_FRAC*(mvfront[a2]-mvend[a2]);
-
- avg2 = fdotcurvdist2(f->vect, dots, ndots, &max2);
- fprintf(stderr, " avg=%g max=%g fscale=%g\n", sqrt(avg2), sqrt(max2), fscale);
- if(max2 <= fscale*fscale) {
- f->flags |= (GEXFF_DONE | GEXFF_DRAWCURVE);
- f->vectlen = f->sublen;
- free(dots);
- return;
- }
-#undef CIRCLE_FRAC
- }
- for(i=0; i<2; i++) {
- f->vect[0][i] = limfront[i];
- f->vect[1][i] = fixfront[i];
- f->vect[2][i] = fixend[i];
- f->vect[3][i] = limend[i];
- }
- usedots = dots;
- if(outfront) {
- usedots++; ndots--;
- }
- if(outend)
- ndots--;
- if( fcrossrayscv(f->vect, NULL, NULL) == 0) {
- fprintf(stderr, "**** Internal error: rays must cross but don't at %p-%p\n",
- ge, gel);
- fprintf(stderr, " (%g, %g) (%g, %g) (%g, %g) (%g, %g)\n",
- limfront[0], limfront[1],
- fixfront[0], fixfront[1],
- fixend[0], fixend[1],
- limend[0], limend[1]
- );
- dumppaths(g, NULL, NULL);
- exit(1);
- } else {
- if(ndots != 0)
- fapproxcurve(f->vect, usedots, ndots);
- f->flags |= (GEXFF_DONE | GEXFF_DRAWCURVE);
- f->vectlen = f->sublen;
- }
- free(dots);
-}
-
-/*
- * Subtract a list of gentries (covered by a fragment of higher
- * priority) from the set of fragments of a given
- * type.
- *
- * An example is subtraction of the long exact line fragments
- * from the curve fragments which get overridden.
- */
-
-static void
-frag_subtract(
- GLYPH *g,
- GENTRY **age, /* array of gentries for this contour */
- int clen, /* length of the contour */
- GENTRY *ge, /* first gentry to be subtracted */
- int slen, /* number of gentries in the list to be subtracted */
- int d /* type of fragments from which to subtract, as in GEXFI_... */
-)
-{
- GENTRY *pge;
- GEX_FRAG *f, *pf;
- int len, i, j;
-
- f = X_FRAG(ge);
- len = slen;
-
- /* check if we overlap the end of some fragment */
- if(f->lenback[d]) {
- /* chop off the end of conflicting fragment */
- len = f->lenback[d];
- pge = age[(f->aidx + clen - len)%clen];
- pf = X_FRAG(pge);
- if(pf->len[d] == clen+1 && pf->flags & GEXFF_CIRC) {
- /* the conflicting fragment is self-connected */
-
- pf->len[d] = 0;
- /* calculate the new value for lenback */
- len = clen+1 - slen;
- for(pge = ge; len > 0; pge = pge->bkwd, len--)
- X_FRAG(pge)->lenback[d] = len;
- /* now pge points to the last entry of the line,
- * which is also the new first entry of the curve
- */
- X_FRAG(pge)->len[d] = clen+2 - slen;
- /* clean lenback of gentries covered by the line */
- for(pge = ge->frwd, j = slen-1; j > 0; pge = pge->frwd, j--)
- X_FRAG(pge)->lenback[d] = 0;
- fprintf(stderr, " cut %s circular frag to %p-%p\n",
- gxf_name[d], pge, ge);
- gex_dump_contour(ge, clen);
- } else {
- /* when we chop off a piece of fragment, we leave the remaining
- * piece(s) overlapping with the beginning and possibly the end
- * of the line fragment under consideration
- */
- fprintf(stderr, " cut %s frag at %p from len=%d to len=%d (end %p)\n",
- gxf_name[d], pge, pf->len[d], len+1, ge);
- j = pf->len[d] - len - 1; /* how many gentries are chopped off */
- pf->len[d] = len + 1;
- i = slen - 1;
- for(pge = ge->frwd; j > 0 && i > 0; j--, i--, pge = pge->frwd)
- X_FRAG(pge)->lenback[d] = 0;
- gex_dump_contour(ge, clen);
-
- if(j != 0) {
- /* the conflicting fragment is split in two by this line
- * fragment, fix up its tail
- */
-
- fprintf(stderr, " end of %s frag len=%d %p-",
- gxf_name[d], j+1, pge->bkwd);
- X_FRAG(pge->bkwd)->len[d] = j+1; /* the overlapping */
- for(i = 1; j > 0; j--, i++, pge = pge->frwd)
- X_FRAG(pge)->lenback[d] = i;
- fprintf(stderr, "%p\n", pge->bkwd);
- gex_dump_contour(ge, clen);
- }
- }
- }
- /* check if we overlap the beginning of some fragments */
- i = slen-1; /* getntries remaining to consider */
- j = 0; /* gentries remaining in the overlapping fragment */
- for(pge = ge; i > 0; i--, pge = pge->frwd) {
- if(j > 0) {
- X_FRAG(pge)->lenback[d] = 0;
- j--;
- }
- /* the beginning of one fragment may be the end of another
- * fragment, in this case if j-- above results in 0, that will
- * cause it to check the same gentry for the beginning
- */
- if(j == 0) {
- pf = X_FRAG(pge);
- j = pf->len[d];
- if(j != 0) {
- fprintf(stderr, " removed %s frag at %p len=%d\n",
- gxf_name[d], pge, j);
- gex_dump_contour(ge, clen);
- pf->len[d] = 0;
- j--;
- }
- }
- }
- /* pge points at the last gentry of the line fragment */
- if(j > 1) { /* we have the tail of a fragment left */
- fprintf(stderr, " end of %s frag len=%d %p-",
- gxf_name[d], j, pge);
- X_FRAG(pge)->len[d] = j; /* the overlapping */
- for(i = 0; j > 0; j--, i++, pge = pge->frwd)
- X_FRAG(pge)->lenback[d] = i;
- fprintf(stderr, "%p\n", pge->bkwd);
- gex_dump_contour(ge, clen);
- } else if(j == 1) {
- X_FRAG(pge)->lenback[d] = 0;
- }
-}
-
-/*
- * Produce an outline from a bitmap.
- * scale - factor to scale the sizes
- * bmap - array of dots by lines, xsz * ysz
- * xoff, yoff - offset of the bitmap's lower left corner
- * from the logical position (0,0)
- */
-
-void
-bmp_outline(
- GLYPH *g,
- int scale,
- char *bmap,
- int xsz,
- int ysz,
- int xoff,
- int yoff
-)
-{
- char *hlm, *vlm; /* arrays of the limits of outlines */
- char *amp; /* map of ambiguous points */
- int x, y;
- char *ip, *op;
- double fscale;
-
- if(xsz==0 || ysz==0)
- return;
-
-#ifdef USE_AUTOTRACE
- if(use_autotrace) {
- autotraced_bmp_outline(g, scale, bmap, xsz, ysz, xoff, yoff);
- return;
- }
-#endif /*USE_AUTOTRACE*/
-
- fscale = (double)scale;
- g->flags &= ~GF_FLOAT; /* build it as int first */
-
- if(!warnedhints) {
- warnedhints = 1;
- if(hints && subhints) {
- WARNING_2 fprintf(stderr,
- "Use of hint substitution on bitmap fonts is not recommended\n");
- }
- }
-
-#if 0
- printbmap(bmap, xsz, ysz, xoff, yoff);
-#endif
-
- /* now find the outlines */
- hlm=calloc( xsz, ysz+1 ); /* horizontal limits */
- vlm=calloc( xsz+1, ysz ); /* vertical limits */
- amp=calloc( xsz, ysz ); /* ambiguous points */
-
- if(hlm==0 || vlm==0 || amp==0) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
-
- /*
- * hlm and vlm represent a grid of horisontal and
- * vertical lines. Each pixel is surrounded by the grid
- * from all the sides. The values of [hv]lm mark the
- * parts of grid where the pixel value switches from white
- * to black and back.
- */
-
- /* find the horizontal limits */
- ip=bmap; op=hlm;
- /* 1st row */
- for(x=0; x<xsz; x++) {
- if(ip[x])
- op[x]=L_ON;
- }
- ip+=xsz; op+=xsz;
- /* internal rows */
- for(y=1; y<ysz; y++) {
- for(x=0; x<xsz; x++) {
- if(ip[x]) {
- if(!ip[x-xsz])
- op[x]=L_ON;
- } else {
- if(ip[x-xsz])
- op[x]=L_OFF;
- }
- }
- ip+=xsz; op+=xsz;
- }
-
- /* last row */
- ip-=xsz;
- for(x=0; x<xsz; x++) {
- if(ip[x])
- op[x]=L_OFF;
- }
-
- /* find the vertical limits */
- ip=bmap; op=vlm;
- for(y=0; y<ysz; y++) {
- if(ip[0])
- op[0]=L_ON;
- for(x=1; x<xsz; x++) {
- if(ip[x]) {
- if(!ip[x-1])
- op[x]=L_ON;
- } else {
- if(ip[x-1])
- op[x]=L_OFF;
- }
- }
- if(ip[xsz-1])
- op[xsz]=L_OFF;
- ip+=xsz; op+=xsz+1;
- }
-
- /*
- * Ambiguous points are the nodes of the grids
- * that are between two white and two black pixels
- * located in a checkerboard style. Actually
- * there are only two patterns that may be
- * around an ambiguous point:
- *
- * X|. .|X
- * -*- -*-
- * .|X X|.
- *
- * where "|" and "-" represent the grid (respectively members
- * of vlm and hlm), "*" represents an ambiguous point
- * and "X" and "." represent black and white pixels.
- *
- * If these sample pattern occur in the lower left corner
- * of the bitmap then this ambiguous point will be
- * located at amp[1][1] or in other words amp[1*xsz+1].
- *
- * These points are named "ambiguous" because it's
- * not easy to guess what did the font creator mean
- * at these points. So we are going to treat them
- * specially, doing no aggressive smoothing.
- */
-
- /* find the ambiguous points */
- for(y=ysz-1; y>0; y--)
- for(x=xsz-1; x>0; x--) {
- if(bmap[y*xsz+x]) {
- if( !bmap[y*xsz+x-1] && !bmap[y*xsz-xsz+x] && bmap[y*xsz-xsz+x-1] )
- amp[y*xsz+x]=1;
- } else {
- if( bmap[y*xsz+x-1] && bmap[y*xsz-xsz+x] && !bmap[y*xsz-xsz+x-1] )
- amp[y*xsz+x]=1;
- }
- }
-
-#if 0
- printlimits(hlm, vlm, amp, xsz, ysz);
-#endif
-
- /* generate the vectored (stepping) outline */
-
- while(1) {
- int found = 0;
- int outer; /* flag: this is an outer contour */
- int hor, newhor; /* flag: the current contour direction is horizontal */
- int dir; /* previous direction of the coordinate, 1 - L_ON, 0 - L_OFF */
- int startx, starty; /* start of a contour */
- int firstx, firsty; /* start of the current line */
- int newx, newy; /* new coordinates to try */
- char *lm, val;
- int maxx, maxy, xor;
-
- for(y=ysz; !found && y>0; y--)
- for(x=0; x<xsz; x++)
- if(hlm[y*xsz+x] > L_NONE)
- goto foundcontour;
- break; /* have no contours left */
-
- foundcontour:
- ig_rmoveto(g, x+xoff, y+yoff); /* intermediate as int */
-
- startx = firstx = x;
- starty = firsty = y;
-
- if(hlm[y*xsz+x] == L_OFF) {
- outer = 1; dir = 0;
- hlm[y*xsz+x] = -hlm[y*xsz+x]; /* mark as seen */
- hor = 1; x++;
- } else {
- outer = 0; dir = 0;
- hor = 0; y--;
- vlm[y*(xsz+1)+x] = -vlm[y*(xsz+1)+x]; /* mark as seen */
- }
-
- while(x!=startx || y!=starty) {
-#if 0
- printf("trace (%d, %d) outer=%d hor=%d dir=%d\n", x, y, outer, hor, dir);
-#endif
-
- /* initialization common for try1 and try2 */
- if(hor) {
- lm = vlm; maxx = xsz+1; maxy = ysz; newhor = 0;
- } else {
- lm = hlm; maxx = xsz; maxy = ysz+1; newhor = 1;
- }
- xor = (outer ^ hor ^ dir);
-
- try1:
- /* first we try to change axis, to keep the
- * contour as long as possible
- */
-
- newx = x; newy = y;
- if(!hor && (!outer ^ dir))
- newx--;
- if(hor && (!outer ^ dir))
- newy--;
-
- if(newx < 0 || newx >= maxx || newy < 0 || newy >= maxy)
- goto try2;
-
- if(!xor)
- val = L_ON;
- else
- val = L_OFF;
-#if 0
- printf("try 1, want %d have %d at %c(%d, %d)\n", val, lm[newy*maxx + newx],
- (newhor ? 'h':'v'), newx, newy);
-#endif
- if( lm[newy*maxx + newx] == val )
- goto gotit;
-
- try2:
- /* try to change the axis anyway */
-
- newx = x; newy = y;
- if(!hor && (outer ^ dir))
- newx--;
- if(hor && (outer ^ dir))
- newy--;
-
- if(newx < 0 || newx >= maxx || newy < 0 || newy >= maxy)
- goto try3;
-
- if(xor)
- val = L_ON;
- else
- val = L_OFF;
-#if 0
- printf("try 2, want %d have %d at %c(%d, %d)\n", val, lm[newy*maxx + newx],
- (newhor ? 'h':'v'), newx, newy);
-#endif
- if( lm[newy*maxx + newx] == val )
- goto gotit;
-
- try3:
- /* try to continue in the old direction */
-
- if(hor) {
- lm = hlm; maxx = xsz; maxy = ysz+1;
- } else {
- lm = vlm; maxx = xsz+1; maxy = ysz;
- }
- newhor = hor;
- newx = x; newy = y;
- if(hor && dir)
- newx--;
- if(!hor && !dir)
- newy--;
-
- if(newx < 0 || newx >= maxx || newy < 0 || newy >= maxy)
- goto badtry;
-
- if(dir)
- val = L_ON;
- else
- val = L_OFF;
-#if 0
- printf("try 3, want %d have %d at %c(%d, %d)\n", val, lm[newy*maxx + newx],
- (newhor ? 'h':'v'), newx, newy);
-#endif
- if( lm[newy*maxx + newx] == val )
- goto gotit;
-
- badtry:
- fprintf(stderr, "**** Internal error in the contour detection code at (%d, %d)\n", x, y);
- fprintf(stderr, "glyph='%s' outer=%d hor=%d dir=%d\n", g->name, outer, hor, dir);
- fflush(stdout);
- exit(1);
-
- gotit:
- if(hor != newhor) { /* changed direction, end the previous line */
- ig_rlineto(g, x+xoff, y+yoff); /* intermediate as int */
- firstx = x; firsty = y;
- }
- lm[newy*maxx + newx] = -lm[newy*maxx + newx];
- hor = newhor;
- dir = (val == L_ON);
- if(newhor)
- x -= (dir<<1)-1;
- else
- y += (dir<<1)-1;
- }
-#if 0
- printf("trace (%d, %d) outer=%d hor=%d dir=%d\n", x, y, outer, hor, dir);
-#endif
- ig_rlineto(g, x+xoff, y+yoff); /* intermediate as int */
- g_closepath(g);
- }
-
-
- /* try to vectorize the curves and sloped lines in the bitmap */
- if(vectorize) {
- GENTRY *ge, *pge, *cge, *loopge;
- int i;
- int skip;
-
- dumppaths(g, NULL, NULL);
-
- /* allocate the extensions */
- for(cge=g->entries; cge!=0; cge=cge->next) {
- cge->ext = calloc(1, sizeof(GEX_FRAG) );
- if(cge->ext == 0) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- }
-
- for(cge=g->entries; cge!=0; cge=cge->next) {
- if(cge->type != GE_MOVE)
- continue;
-
- /* we've found the beginning of a contour */
- {
- int d, vert, count, stepmore, delaystop;
- int vdir, hdir, fullvdir, fullhdir, len;
- int dx, dy, lastdx, lastdy;
- int k1, k2, reversal, smooth, good;
- int line[2 /*H,V*/], maxlen[2 /*H,V*/], minlen[2 /*H,V*/];
- GENTRY **age; /* array of gentries in a contour */
- int clen; /* contour length, size of ths array */
- int i, j;
- GEX_FRAG *f;
-
- /* we know that all the contours start at the top-left corner,
- * so at most it might be before/after the last element of
- * the last/first fragment
- */
-
- ge = cge->next;
- pge = ge->bkwd;
- if(ge->ix3 == pge->ix3) { /* a vertical line */
- /* we want to start always from a horizontal line because
- * then we always start from top and that is quaranteed to be a
- * fragment boundary, so move the start point of the contour
- */
- pge->prev->next = pge->next;
- pge->next->prev = pge->prev;
- cge->next = pge;
- pge->prev = cge;
- pge->next = ge;
- ge->prev = pge;
- ge = pge; pge = ge->bkwd;
- cge->ix3 = pge->ix3; cge->iy3 = pge->iy3;
- }
-
- /* fill the array of gentries */
- clen = 1;
- for(ge = cge->next->frwd; ge != cge->next; ge = ge->frwd)
- clen++;
- age = (GENTRY **)malloc(sizeof(*age) * clen);
- ge = cge->next;
- count = 0;
- do {
- age[count] = ge;
- X_FRAG(ge)->aidx = count++;
-
- /* and by the way find the extremums */
- for(i=0; i<2; i++) {
- if( isign(ge->frwd->ipoints[i][2] - ge->ipoints[i][2])
- * isign(ge->bkwd->bkwd->ipoints[i][2] - ge->bkwd->ipoints[i][2]) == 1) {
- X_FRAG(ge)->flags |= GEXFF_EXTR;
- fprintf(stderr, " %s extremum at %p\n", (i?"vert":"hor"), ge);
- }
- if(abs(ge->ipoints[i][2] - ge->bkwd->ipoints[i][2]) > 1)
- X_FRAG(ge)->flags |= GEXFF_LONG;
- }
-
- ge = ge->frwd;
- } while(ge != cge->next);
-
- /* Find the serif fragments, looking as either of:
- * -+ |
- * | |
- * +-+ +-+
- * | |
- * +--... +--...
- * with the thickness of serifs being 1 pixel. We make no
- * difference between serifs on vertical and horizontal stems.
- */
-
- ge = cge->next;
- do {
- GENTRY *nge;
- int pdx, pdy, ndx, ndy;
-
- /* two gentries of length 1 mean a potential serif */
- pge = ge->bkwd;
- nge = ge->frwd;
-
- dx = nge->ix3 - pge->ix3;
- dy = nge->iy3 - pge->iy3;
-
- if(abs(dx) != 1 || abs(dy) != 1) /* 2 small ones */
- continue;
-
- if(
- (!(X_FRAG(ge)->flags & GEXFF_EXTR)
- || !(X_FRAG(ge->bkwd)->flags & GEXFF_EXTR))
- && (!(X_FRAG(ge->frwd)->flags & GEXFF_EXTR)
- || !(X_FRAG(ge->frwd->frwd)->flags & GEXFF_EXTR))
- )
- continue; /* either side must be a couple of extremums */
-
- pdx = pge->ix3 - pge->bkwd->ix3;
- pdy = pge->iy3 - pge->bkwd->iy3;
- ndx = nge->frwd->ix3 - nge->ix3;
- ndy = nge->frwd->iy3 - nge->iy3;
-
- if(pdx*dx + pdy*dy > 0 && ndx*dx + ndy*dy > 0)
- continue; /* definitely not a serif but a round corner */
-
- if(abs(pdx) + abs(pdy) == 1 || abs(ndx) + abs(ndy) == 1)
- continue;
-
- /* we've found a serif including this and next gentry */
- X_FRAG(ge)->len[GEXFI_SERIF] = 2;
-
- } while( (ge = ge->frwd) != cge->next );
-
-
- /* Find the convex and concave fragments, defined as:
- * convex (clockwise): dy/dx <= dy0/dx0,
- * or a reversal: dy/dx == - dy0/dx0 && abs(dxthis) == 1 && dy/dx > 0
- * concave (counter-clockwise): dy/dx >= dy0/dx0,
- * or a reversal: dy/dx == - dy0/dx0 && abs(dxthis) == 1 && dy/dx < 0
- *
- * Where dx and dy are measured between the end of this gentry
- * and the start of the previous one (dx0 and dy0 are the same
- * thing calculated for the previous gentry and its previous one),
- * dxthis is between the end and begginning of this gentry.
- *
- * A reversal is a situation when the curve changes its direction
- * along the x axis, so it passes through a momentary vertical
- * direction.
- */
- for(d = GEXFI_CONVEX; d<= GEXFI_CONCAVE; d++) {
- ge = cge->next;
- pge = ge->bkwd; /* the beginning of the fragment */
- count = 1;
- lastdx = pge->ix3 - pge->bkwd->bkwd->ix3;
- lastdy = pge->iy3 - pge->bkwd->bkwd->iy3;
-
-#define CHKCURVCONN(ge, msg) do { \
- dx = (ge)->ix3 - (ge)->bkwd->bkwd->ix3; \
- dy = (ge)->iy3 - (ge)->bkwd->bkwd->iy3; \
- if(0 && msg) { \
- fprintf(stderr, " %p: dx=%d dy=%d dx0=%d dy0=%d ", \
- (ge), dx, dy, lastdx, lastdy); \
- } \
- k1 = X_FRAG(ge)->flags; \
- k2 = X_FRAG((ge)->bkwd)->flags; \
- if(0 && msg) { \
- fprintf(stderr, "fl=%c%c%c%c ", \
- (k1 & GEXFF_EXTR) ? 'X' : '-', \
- (k1 & GEXFF_LONG) ? 'L' : '-', \
- (k2 & GEXFF_EXTR) ? 'X' : '-', \
- (k2 & GEXFF_LONG) ? 'L' : '-' \
- ); \
- } \
- if( (k1 & GEXFF_EXTR) && (k2 & GEXFF_LONG) \
- || (k2 & GEXFF_EXTR) && (k1 & GEXFF_LONG) ) { \
- smooth = 0; \
- good = reversal = -1; /* for debugging */ \
- } else { \
- k1 = dy * lastdx; \
- k2 = lastdy * dx; \
- smooth = (abs(dx)==1 || abs(dy)==1); \
- good = (k1 - k2)*gxf_cvk[d] >= 0; \
- if(smooth && !good) { \
- reversal = (k1 == -k2 && abs((ge)->ix3 - (ge)->bkwd->ix3)==1 \
- && dy*dx*gxf_cvk[d] < 0); \
- } else \
- reversal = 0; \
- } \
- if(0 && msg) { \
- fprintf(stderr, "k1=%d k2=%d pge=%p count=%d %s good=%d rev=%d\n", \
- k1, k2, pge, count, gxf_name[d], good, reversal); \
- } \
- } while(0)
-
- do {
- CHKCURVCONN(ge, 1);
-
- if(smooth && (good || reversal) )
- count++;
- else {
- /* can't continue */
-#if 0
- if(count >= 4) { /* worth remembering */
- fprintf(stderr, " %s frag %p-%p count=%d\n", gxf_name[d], pge, ge->bkwd, count);
- }
-#endif
- X_FRAG(pge)->len[d] = count;
- if(smooth) {
- pge = ge->bkwd;
- count = 2;
- } else {
- pge = ge;
- count = 1;
- }
- }
- lastdx = dx; lastdy = dy;
- ge = ge->frwd;
- } while(ge != cge->next);
-
- /* see if we can connect the last fragment to the first */
- CHKCURVCONN(ge, 1);
-
- if(smooth && (good || reversal) ) {
- /* -1 to avoid ge->bkwd being counted twice */
- if( X_FRAG(ge->bkwd)->len[d] >= 2 )
- count += X_FRAG(ge->bkwd)->len[d] - 1;
- else if(count == clen+1) {
- /* we are joining a circular (closed) curve, check whether it
- * can be joined at any point or whether it has a discontinuity
- * at the point where we join it now
- */
- lastdx = dx; lastdy = dy;
- CHKCURVCONN(ge->frwd, 0);
-
- if(smooth && (good || reversal) ) {
- /* yes, the curve is truly a circular one and can be
- * joined at any point
- */
-
-#if 0
- fprintf(stderr, " found a circular joint point at %p\n", pge);
-#endif
- /* make sure that in a circular fragment we start from an extremum */
- while( ! (X_FRAG(pge)->flags & GEXFF_EXTR) )
- pge = pge->frwd;
- X_FRAG(pge)->flags |= GEXFF_CIRC;
- }
- }
-#if 0
- fprintf(stderr, " %s joined %p to %p count=%d bk_count=%d\n", gxf_name[d], pge, ge->bkwd,
- count, X_FRAG(ge->bkwd)->len[d] );
-#endif
- X_FRAG(ge->bkwd)->len[d] = 0;
- }
- X_FRAG(pge)->len[d] = count;
-#if 0
- if(count >= 4) { /* worth remembering */
- fprintf(stderr, " %s last frag %p-%p count=%d\n", gxf_name[d], pge, ge->bkwd, count);
- }
-#endif
-#undef CHKCURVCONN
-
- /* do postprocessing */
- ge = cge->next;
- do {
- f = X_FRAG(ge);
- len = f->len[d];
-#if 0
- fprintf(stderr, " %p %s len=%d clen=%d\n", ge, gxf_name[d], len, clen);
-#endif
- if(len < 3) /* get rid of the fragments that are too short */
- f->len[d] = 0;
- else if(len == 3) {
- /* _
- * drop the |_| - shaped fragments, leave alone the _| - shaped
- * (and even those only if not too short in pixels),
- * those left alone are further filtered later
- */
- k1 = (ge->ix3 == ge->bkwd->ix3); /* axis of the start */
- if(isign(ge->ipoints[k1][2] - ge->bkwd->ipoints[k1][2])
- != isign(ge->frwd->ipoints[k1][2] - ge->frwd->frwd->ipoints[k1][2])
- && abs(ge->frwd->frwd->ipoints[k1][2] - ge->bkwd->ipoints[k1][2]) > 2) {
-#if 0
- fprintf(stderr, " %s frag %p count=%d good shape\n",
- gxf_name[d], ge, count);
-#endif
- } else
- f->len[d] = 0;
- } else if(len == clen+1)
- break; /* a closed fragment, nothing else interesting */
- else { /* only for open fragments */
- GENTRY *gem, *gex, *gei, *ges;
-
- ges = ge; /* the start entry */
- gem = age[(f->aidx + f->len[d])%clen]; /* entry past the end of the fragment */
-
- gei = ge->frwd;
- if( (ge->ix3 == ge->bkwd->ix3) /* vert */
- ^ (isign(ge->bkwd->ix3 - gei->ix3)==isign(ge->bkwd->iy3 - gei->iy3))
- ^ !(d == GEXFI_CONVEX) /* counter-clockwise */ ) {
-
-#if 0
- fprintf(stderr, " %p: %s potential spurious start\n", ge, gxf_name[d]);
-#endif
- /* the beginning may be a spurious entry */
-
- gex = 0; /* the extremum closest to the beginning - to be found */
- for(gei = ge->frwd; gei != gem; gei = gei->frwd) {
- if(X_FRAG(gei)->flags & GEXFF_EXTR) {
- gex = gei;
- break;
- }
- }
- if(gex == 0)
- gex = gem->bkwd;
-
- /* A special case: ignore the spurious ends on small curves that
- * either enclose an 1-pixel-wide extremum or are 1-pixel deep.
- * Any 5-or-less-pixel-long curve with extremum 2 steps away
- * qualifies for that.
- */
-
- if(len <= 5 && gex == ge->frwd->frwd) {
- good = 0;
-#if 0
- fprintf(stderr, " E");
-#endif
- } else {
- good = 1; /* assume that ge is not spurious */
-
- /* gei goes backwards, gex goes forwards from the extremum */
- gei = gex;
- /* i is the symmetry axis, j is the other axis (X=0 Y=1) */
- i = (gex->ix3 != gex->bkwd->ix3);
- j = !i;
- for( ; gei!=ge && gex!=gem; gei=gei->bkwd, gex=gex->frwd) {
- if( gei->bkwd->ipoints[i][2] != gex->ipoints[i][2]
- || gei->bkwd->ipoints[j][2] - gei->ipoints[j][2]
- != gex->bkwd->ipoints[j][2] - gex->ipoints[j][2]
- ) {
- good = 0; /* no symmetry - must be spurious */
-#if 0
- fprintf(stderr, " M(%p,%p)(%d %d,%d)(%d %d,%d)",
- gei, gex,
- i, gei->bkwd->ipoints[i][2], gex->ipoints[i][2],
- j, gei->bkwd->ipoints[j][2] - gei->ipoints[j][2],
- gex->bkwd->ipoints[j][2] - gex->ipoints[j][2] );
-#endif
- break;
- }
- }
- if(gex == gem) { /* oops, the other side is too short */
- good = 0;
-#if 0
- fprintf(stderr, " X");
-#endif
- }
- if(good && gei == ge) {
- if( isign(gei->bkwd->ipoints[j][2] - gei->ipoints[j][2])
- != isign(gex->bkwd->ipoints[j][2] - gex->ipoints[j][2]) ) {
- good = 0; /* oops, goes into another direction */
-#if 0
- fprintf(stderr, " D");
-#endif
- }
- }
- }
- if(!good) { /* it is spurious, drop it */
-#if 0
- fprintf(stderr, " %p: %s spurious start\n", ge, gxf_name[d]);
-#endif
- f->len[d] = 0;
- ges = ge->frwd;
- len--;
- X_FRAG(ges)->len[d] = len;
- }
- }
-
- gei = gem->bkwd->bkwd->bkwd;
- if( (gem->ix3 != gem->bkwd->ix3) /* gem->bkwd is vert */
- ^ (isign(gem->bkwd->ix3 - gei->ix3)==isign(gem->bkwd->iy3 - gei->iy3))
- ^ (d == GEXFI_CONVEX) /* clockwise */ ) {
-
-#if 0
- fprintf(stderr, " %p: %s potential spurious end\n", gem->bkwd, gxf_name[d]);
-#endif
- /* the end may be a spurious entry */
-
- gex = 0; /* the extremum closest to the end - to be found */
- for(gei = gem->bkwd->bkwd; gei != ges->bkwd; gei = gei->bkwd) {
- if(X_FRAG(gei)->flags & GEXFF_EXTR) {
- gex = gei;
- break;
- }
- }
- if(gex == 0)
- gex = ges;
-
- good = 1; /* assume that gem->bkwd is not spurious */
- /* gei goes backwards, gex goes forwards from the extremum */
- gei = gex;
- /* i is the symmetry axis, j is the other axis (X=0 Y=1) */
- i = (gex->ix3 != gex->bkwd->ix3);
- j = !i;
- for( ; gei!=ges->bkwd && gex!=gem->bkwd; gei=gei->bkwd, gex=gex->frwd) {
- if( gei->bkwd->ipoints[i][2] != gex->ipoints[i][2]
- || gei->bkwd->ipoints[j][2] - gei->ipoints[j][2]
- != gex->bkwd->ipoints[j][2] - gex->ipoints[j][2]
- ) {
- good = 0; /* no symmetry - must be spurious */
-#if 0
- fprintf(stderr, " M(%p,%p)(%d %d,%d)(%d %d,%d)",
- gei, gex,
- i, gei->bkwd->ipoints[i][2], gex->ipoints[i][2],
- j, gei->bkwd->ipoints[j][2] - gei->ipoints[j][2],
- gex->bkwd->ipoints[j][2] - gex->ipoints[j][2] );
-#endif
- break;
- }
- }
- if(gei == ges->bkwd) { /* oops, the other side is too short */
- good = 0;
-#if 0
- fprintf(stderr, " X");
-#endif
- }
- if(good && gex == gem->bkwd) {
- if( isign(gei->bkwd->ipoints[j][2] - gei->ipoints[j][2])
- != isign(gex->bkwd->ipoints[j][2] - gex->ipoints[j][2]) ) {
- good = 0; /* oops, goes into another direction */
-#if 0
- fprintf(stderr, " D");
-#endif
- }
- }
- if(!good) { /* it is spurious, drop it */
-#if 0
- fprintf(stderr, " %p: %s spurious end\n", gem->bkwd, gxf_name[d]);
-#endif
- X_FRAG(ges)->len[d] = --len;
- }
- }
- if(len < 4) {
- X_FRAG(ges)->len[d] = 0;
-#if 0
- fprintf(stderr, " %p: %s frag discarded, too small now\n", ge, gxf_name[d]);
-#endif
- }
- if(ges != ge) {
- if(ges == cge->next)
- break; /* went around the loop */
- else {
- ge = ges->frwd; /* don't look at this fragment twice */
- continue;
- }
- }
- }
-
- ge = ge->frwd;
- } while(ge != cge->next);
- }
-
- /* Find the straight line fragments.
- * Even though the lines are sloped, they are called
- * "vertical" or "horizontal" according to their longer
- * dimension. All the steps in the shother dimension must
- * be 1 pixel long, all the steps in the longer dimension
- * must be within the difference of 1 pixel.
- */
- for(d = GEXFI_LINE; d<= GEXFI_EXACTLINE; d++) {
- ge = cge->next;
- pge = ge->bkwd; /* the beginning of the fragment */
- count = 1;
- delaystop = 0;
- do {
- int h;
-
- stepmore = 0;
- hdir = isign(ge->ix3 - ge->bkwd->ix3);
- vdir = isign(ge->iy3 - ge->bkwd->iy3);
- vert = (hdir == 0);
- if(count==1) {
- /* at this point pge==ge->bkwd */
- /* account for the previous gentry, which was !vert */
- if(!vert) { /* prev was vertical */
- maxlen[0] = minlen[0] = 0;
- maxlen[1] = minlen[1] = abs(pge->iy3 - pge->bkwd->iy3);
- line[0] = (maxlen[1] == 1);
- line[1] = 1;
- fullhdir = hdir;
- fullvdir = isign(pge->iy3 - pge->bkwd->iy3);
- } else {
- maxlen[0] = minlen[0] = abs(pge->ix3 - pge->bkwd->ix3);
- maxlen[1] = minlen[1] = 0;
- line[0] = 1;
- line[1] = (maxlen[0] == 1);
- fullhdir = isign(pge->ix3 - pge->bkwd->ix3);
- fullvdir = vdir;
- }
- }
- h = line[0]; /* remember the prevalent direction */
-#if 0
- fprintf(stderr, " %p: v=%d(%d) h=%d(%d) vl(%d,%d,%d) hl=(%d,%d,%d) %s count=%d ",
- ge, vdir, fullvdir, hdir, fullhdir,
- line[1], minlen[1], maxlen[1],
- line[0], minlen[0], maxlen[0],
- gxf_name[d], count);
-#endif
- if(vert) {
- if(vdir != fullvdir)
- line[0] = line[1] = 0;
- len = abs(ge->iy3 - ge->bkwd->iy3);
- } else {
- if(hdir != fullhdir)
- line[0] = line[1] = 0;
- len = abs(ge->ix3 - ge->bkwd->ix3);
- }
-#if 0
- fprintf(stderr, "len=%d\n", len);
-#endif
- if(len != 1) /* this is not a continuation in the short dimension */
- line[!vert] = 0;
-
- /* can it be a continuation in the long dimension ? */
- if( line[vert] ) {
- if(maxlen[vert]==0)
- maxlen[vert] = minlen[vert] = len;
- else if(maxlen[vert]==minlen[vert]) {
- if(d == GEXFI_EXACTLINE) {
- if(len != maxlen[vert])
- line[vert] = 0; /* it can't */
- } else if(len < maxlen[vert]) {
- if(len < minlen[vert]-1)
- line[vert] = 0; /* it can't */
- else
- minlen[vert] = len;
- } else {
- if(len > maxlen[vert]+1)
- line[vert] = 0; /* it can't */
- else
- maxlen[vert] = len;
- }
- } else if(len < minlen[vert] || len > maxlen[vert])
- line[vert] = 0; /* it can't */
- }
-
- if(line[0] == 0 && line[1] == 0) {
-#if 0
- if(count >= 3)
- fprintf(stderr, " %s frag %p-%p count=%d\n", gxf_name[d], pge, ge->bkwd, count);
-#endif
- X_FRAG(pge)->len[d] = count;
- if(d == GEXFI_EXACTLINE && h) {
- X_FRAG(pge)->flags |= GEXFF_HLINE;
- }
- if(count == 1)
- pge = ge;
- else {
- stepmore = 1; /* may reconsider the 1st gentry */
- pge = ge = ge->bkwd;
- count = 1;
- }
- } else
- count++;
-
- ge = ge->frwd;
- if(ge == cge->next && !stepmore)
- delaystop = 1; /* consider the first gentry again */
- } while(stepmore || ge != cge->next ^ delaystop);
- /* see if there is an unfinished line left */
- if(count != 1) {
-#if 0
- if(count >= 3)
- fprintf(stderr, " %s frag %p-%p count=%d\n", gxf_name[d], pge, ge->bkwd, count);
-#endif
- X_FRAG(ge->bkwd->bkwd)->len[d] = 0;
- X_FRAG(pge)->len[d] = count;
- }
- }
-
- /* do postprocessing of the lines */
-#if 0
- fprintf(stderr, "Line postprocessing\n");
- gex_dump_contour(cge->next, clen);
-#endif
-
- /* the non-exact line frags are related to exact line frags sort
- * of like to individual gentries: two kinds of exact frags
- * must be interleaved, with one kind having the size of 3
- * and the other kind having the size varying within +-2.
- */
-
- ge = cge->next;
- do {
- GEX_FRAG *pf, *lastf1, *lastf2;
- int len1, len2, fraglen;
-
- f = X_FRAG(ge);
-
- fraglen = f->len[GEXFI_LINE];
- if(fraglen >= 4) {
-
- vert = 0; /* vert is a pseudo-directon */
- line[0] = line[1] = 1;
- maxlen[0] = minlen[0] = maxlen[1] = minlen[1] = 0;
- lastf2 = lastf1 = f;
- len2 = len1 = 0;
- for(pge = ge, i = 1; i < fraglen; i++, pge=pge->frwd) {
- pf = X_FRAG(pge);
- len = pf->len[GEXFI_EXACTLINE];
-#if 0
- fprintf(stderr, " pge=%p i=%d of %d ge=%p exLen=%d\n", pge, i,
- f->len[GEXFI_LINE], ge, len);
-#endif
- len1++; len2++;
- if(len==0) {
- continue;
- }
- vert = !vert; /* alternate the pseudo-direction */
- if(len > 3)
- line[!vert] = 0;
- if(maxlen[vert] == 0)
- maxlen[vert] = minlen[vert] = len;
- else if(maxlen[vert]-2 >= len && minlen[vert]+2 <= len) {
- if(len > maxlen[vert])
- maxlen[vert] = len;
- else if(len < minlen[vert])
- minlen[vert] = len;
- } else
- line[vert] = 0;
- if(line[0] == 0 && line[1] == 0) {
-#if 0
- fprintf(stderr, " Line breaks at %p %c(%d, %d) %c(%d, %d) len=%d fl=%d l2=%d l1=%d\n",
- pge, (!vert)?'*':' ', minlen[0], maxlen[0],
- vert?'*':' ', minlen[1], maxlen[1], len, fraglen, len2, len1);
-#endif
- if(lastf2 != lastf1) {
- lastf2->len[GEXFI_LINE] = len2-len1;
- }
- lastf1->len[GEXFI_LINE] = len1+1;
- pf->len[GEXFI_LINE] = fraglen+1 - i;
-#if 0
- gex_dump_contour(pge, clen);
-#endif
-
- /* continue with the line */
- vert = 0; /* vert is a pseudo-directon */
- line[0] = line[1] = 1;
- maxlen[0] = minlen[0] = maxlen[1] = minlen[1] = 0;
- lastf2 = lastf1 = f;
- len2 = len1 = 0;
- } else {
- lastf1 = pf;
- len1 = 0;
- }
- }
- }
-
- ge = ge->frwd;
- } while(ge != cge->next);
-#if 0
- fprintf(stderr, "Line postprocessing part 2\n");
- gex_dump_contour(cge->next, clen);
-#endif
-
- ge = cge->next;
- do {
- f = X_FRAG(ge);
-
- if(f->len[GEXFI_LINE] >= 4) {
- len = f->len[GEXFI_EXACTLINE];
- /* if a non-exact line covers precisely two exact lines,
- * split it
- */
- if(len > 0 && f->len[GEXFI_LINE] >= len+1) {
- GEX_FRAG *pf;
- pge = age[(f->aidx + len - 1)%clen]; /* last gentry of exact line */
- pf = X_FRAG(pge);
- if(f->len[GEXFI_LINE] + 1 == len + pf->len[GEXFI_EXACTLINE]) {
- f->len[GEXFI_LINE] = len;
- f->flags |= GEXFF_SPLIT;
- pf->len[GEXFI_LINE] = pf->len[GEXFI_EXACTLINE];
- pf->flags |= GEXFF_SPLIT;
- }
- }
- }
-
- ge = ge->frwd;
- } while(ge != cge->next);
-#if 0
- fprintf(stderr, "Line postprocessing part 2a\n");
- gex_dump_contour(cge->next, clen);
-#endif
- ge = cge->next;
- do {
- f = X_FRAG(ge);
-
- /* too small lines are of no interest */
- if( (f->flags & GEXFF_SPLIT)==0 && f->len[GEXFI_LINE] < 4)
- f->len[GEXFI_LINE] = 0;
-
- len = f->len[GEXFI_EXACTLINE];
- /* too small exact lines are of no interest */
- if(len < 3) /* exact lines may be shorter */
- f->len[GEXFI_EXACTLINE] = 0;
- /* get rid of inexact additions to the end of the exact lines */
- else if(f->len[GEXFI_LINE] == len+1)
- f->len[GEXFI_LINE] = len;
- /* same at the beginning */
- else {
- int diff = X_FRAG(ge->bkwd)->len[GEXFI_LINE] - len;
-
- if(diff == 1 || diff == 2) {
- X_FRAG(ge->bkwd)->len[GEXFI_LINE] = 0;
- f->len[GEXFI_LINE] = len;
- }
- }
-
- ge = ge->frwd;
- } while(ge != cge->next);
-#if 0
- fprintf(stderr, "Line postprocessing is completed\n");
- gex_dump_contour(cge->next, clen);
-#endif
-
- gex_calc_lenback(cge->next, clen); /* prepare data */
-
- /* resolve conflicts between lines and curves */
-
- /*
- * the short (3-gentry) curve frags must have one of the ends
- * coinciding with another curve frag of the same type
- */
-
- for(d = GEXFI_CONVEX; d<= GEXFI_CONCAVE; d++) {
- ge = cge->next;
- do {
- f = X_FRAG(ge);
-
- if(f->len[d] == 3) {
- pge = age[(f->aidx + 2)%clen]; /* last gentry of this frag */
- if(f->lenback[d] == 0 && X_FRAG(pge)->len[d] == 0) {
- fprintf(stderr, " discarded small %s at %p-%p\n", gxf_name[d], ge, pge);
- f->len[d] = 0;
- X_FRAG(ge->frwd)->lenback[d] = 0;
- X_FRAG(ge->frwd->frwd)->lenback[d] = 0;
- }
- }
- ge = ge->frwd;
- } while(ge != cge->next);
- }
-
- /* the serifs take priority over everything else */
- ge = cge->next;
- do {
- f = X_FRAG(ge);
-
- len = f->len[GEXFI_SERIF];
- if(len == 0)
- continue;
-
- if(len != 2) { /* this is used in the code below */
- fprintf(stderr, "Internal error at %s line %d: serif frags len is %d\n",
- __FILE__, __LINE__, len);
- exit(1);
- }
-
- for(d = 0; d < GEXFI_SERIF; d++) {
- /* serifs may not have common ends with the other fragments,
- * this is expressed as extending them by 1 gentry on each side
- */
- frag_subtract(g, age, clen, ge->bkwd, len+2, d);
- }
- } while( (ge = ge->frwd) != cge->next);
-
- /*
- * longer exact lines take priority over curves; shorter lines
- * and inexact lines are resolved with convex/concave conflicts
- */
- ge = cge->next;
- do {
- f = X_FRAG(ge);
-
- len = f->len[GEXFI_EXACTLINE];
-
- if(len < 6) { /* line is short */
- ge = ge->frwd;
- continue;
- }
-
- fprintf(stderr, " line at %p len=%d\n", ge, f->len[GEXFI_EXACTLINE]);
- for(d = GEXFI_CONVEX; d<= GEXFI_CONCAVE; d++) {
- frag_subtract(g, age, clen, ge, len, d);
- }
-
- ge = ge->frwd;
- } while(ge != cge->next);
-
- /*
- * The exact lines take priority over curves that coincide
- * with them or extend by only one gentry on either side
- * (but not both sides). By this time it applies only to the
- * small exact lines.
- *
- * An interesting general case is when a curve matches more
- * than one exact line going diamond-like.
- */
-
- ge = cge->next;
- do {
- int done, len2;
- int sharpness;
- GEX_FRAG *pf;
-
- f = X_FRAG(ge);
-
- /* "sharpness" shows how a group of exact line frags is connected: if the gentries
- * of some of them overlap, the curve matching requirement is loosened: it may
- * extend up to 1 gentry beyond each end of the group of exact line frags
- * (sharpness=2); otherwise it may extend to only one end (sharpness=1)
- */
- sharpness = 1;
-
- len = f->len[GEXFI_EXACTLINE];
- if(len >= 4) {
- while(len < clen) {
- done = 0;
- pf = X_FRAG(ge->bkwd);
- for(d = GEXFI_CONVEX; d<= GEXFI_CONCAVE; d++) {
- if(f->len[d] == len || f->len[d] == len+1) {
-
- fprintf(stderr, " removed %s frag at %p len=%d linelen=%d\n",
- gxf_name[d], ge, f->len[d], len);
- pge = ge->frwd;
- for(i = f->len[d]; i > 1; i--, pge = pge->frwd)
- X_FRAG(pge)->lenback[d] = 0;
- f->len[d] = 0;
- gex_dump_contour(ge, clen);
- done = 1;
- } else if(pf->len[d] == len+1 || pf->len[d] == len+sharpness) {
- fprintf(stderr, " removed %s frag at %p len=%d next linelen=%d\n",
- gxf_name[d], ge->bkwd, pf->len[d], len);
- pge = ge;
- for(i = pf->len[d]; i > 1; i--, pge = pge->frwd)
- X_FRAG(pge)->lenback[d] = 0;
- pf->len[d] = 0;
- gex_dump_contour(ge, clen);
- done = 1;
- }
- }
- if(done)
- break;
-
- /* is there any chance to match a sequence of exect lines ? */
- if(f->len[GEXFI_CONVEX] < len && f->len[GEXFI_CONCAVE] < len
- && pf->len[GEXFI_CONVEX] < len && pf->len[GEXFI_CONCAVE] < len)
- break;
-
- done = 1;
- /* check whether the line is connected to another exact line at an extremum */
- pge = age[(f->aidx + len - 1)%clen]; /* last gentry of exact line */
- len2 = X_FRAG(pge)->len[GEXFI_EXACTLINE];
- if(len2 > 0) {
- if( len2 >= 4 && (X_FRAG(pge)->flags & GEXFF_EXTR) ) {
- len += len2 - 1;
- sharpness = 2;
- done = 0;
- }
- } else {
- /* see if the extremum is between two exact lines */
- pge = pge->frwd;
- if(X_FRAG(pge)->flags & GEXFF_EXTR) {
- pge = pge->frwd;
- len2 = X_FRAG(pge)->len[GEXFI_EXACTLINE];
- if(len2 >= 4) {
- len += len2 + 1;
- done = 0;
- }
- }
- }
- if(done)
- break;
- }
- }
-
- ge = ge->frwd;
- } while(ge != cge->next);
-
- /*
- * The lines may cover only whole curves (or otherwise empty space),
- * so cut them where they overlap parts of the curves. If 2 or less
- * gentries are left in the line, remove the line.
- * If a line and a curve fully coincide, remove the line. Otherwise
- * remove the curves that are completely covered by the lines.
- */
-
- ge = cge->next;
- do {
- f = X_FRAG(ge);
-
- reconsider_line:
- len = f->len[GEXFI_LINE];
-
- if(len == 0) {
- ge = ge->frwd;
- continue;
- }
-
- if(f->len[GEXFI_CONVEX] >= len
- || f->len[GEXFI_CONCAVE] >= len) {
- line_completely_covered:
- fprintf(stderr, " removed covered Line frag at %p len=%d\n",
- ge, len);
- f->len[GEXFI_LINE] = 0;
- for(pge = ge->frwd; len > 1; len--, pge = pge->frwd)
- X_FRAG(pge)->lenback[GEXFI_LINE] = 0;
- gex_dump_contour(ge, clen);
- ge = ge->frwd;
- continue;
- }
-
- k1 = 0; /* how much to cut at the front */
- for(d = GEXFI_CONVEX; d<= GEXFI_CONCAVE; d++) {
- if(f->lenback[d]) {
- pge = age[(f->aidx + clen - f->lenback[d])%clen];
- i = X_FRAG(pge)->len[d] - f->lenback[d] - 1;
- if(i > k1)
- k1 = i;
- }
- }
-
- k2 = 0; /* how much to cut at the end */
- pge = age[(f->aidx + len)%clen]; /* gentry after the end */
- for(d = GEXFI_CONVEX; d<= GEXFI_CONCAVE; d++) {
- i = X_FRAG(pge)->lenback[d] - 1;
- if(i > k2)
- k2 = i;
- }
-
- if(k1+k2 > 0 && k1+k2 >= len-3) {
- fprintf(stderr, " k1=%d k2=%d\n", k1, k2);
- goto line_completely_covered;
- }
-
-
- if(k2 != 0) { /* cut the end */
- len -= k2;
- f->len[GEXFI_LINE] = len;
- /* pge still points after the end */
- for(i = k2, pge = pge->bkwd; i > 0; i--, pge = pge->bkwd)
- X_FRAG(pge)->lenback[GEXFI_LINE] = 0;
- }
- if(k1 != 0) { /* cut the beginning */
- len -= k1;
- f->len[GEXFI_LINE] = 0;
- for(i = 1, pge = ge->frwd; i < k1; i++, pge = pge->frwd)
- X_FRAG(pge)->lenback[GEXFI_LINE] = 0;
- X_FRAG(pge)->len[GEXFI_LINE] = len;
- for(i = 0; i < len; i++, pge = pge->frwd)
- X_FRAG(pge)->lenback[GEXFI_LINE] = i;
- }
- if(k1 != 0 || k2 != 0) {
- fprintf(stderr, " cut Line frag at %p by (%d,%d) to len=%d\n",
- ge, k1, k2, len);
- gex_dump_contour(ge, clen);
-
- goto reconsider_line; /* the line may have to be cut again */
- }
- pge = age[(f->aidx + k1)%clen]; /* new beginning */
- good = 1; /* flag: no need do do a debugging dump */
- for(i=1; i<len; i++, pge = pge->frwd)
- for(d = GEXFI_CONVEX; d<= GEXFI_CONCAVE; d++) {
- if(X_FRAG(pge)->len[d]) {
- fprintf(stderr, " removed %s frag at %p len=%d covered by line\n",
- gxf_name[d], pge, X_FRAG(pge)->len[d], len);
- good = 0;
- }
- X_FRAG(pge)->len[d] = 0;
- }
- pge = age[(f->aidx + k1 + 1)%clen]; /* next after new beginning */
- for(i=1; i<len; i++, pge = pge->frwd)
- for(d = GEXFI_CONVEX; d<= GEXFI_CONCAVE; d++)
- X_FRAG(pge)->lenback[d] = 0;
- if(!good)
- gex_dump_contour(ge, clen);
-
- ge = ge->frwd;
- } while(ge != cge->next);
-
- /* Resolve conflicts between curves */
- for(d = GEXFI_CONVEX; d<= GEXFI_CONCAVE; d++) {
- dx = (GEXFI_CONVEX + GEXFI_CONCAVE) - d; /* the other type */
- ge = cge->next;
- do {
- GENTRY *sge;
-
- f = X_FRAG(ge);
- len = f->len[d];
- if(len < 2) {
- ge = ge->frwd;
- continue;
- }
- sge = ge; /* the start of fragment */
-
- i = f->len[dx];
- if(i != 0) { /* two curved frags starting here */
- /* should be i!=len because otherwise they would be
- * covered by an exact line
- */
- if(i > len) {
- curve_completely_covered:
- /* remove the convex frag */
- fprintf(stderr, " removed %s frag at %p len=%d covered by %s\n",
- gxf_name[d], ge, len, gxf_name[dx]);
- f->len[d] = 0;
- for(pge = ge->frwd, j = 1; j < len; j++, pge = pge->frwd)
- X_FRAG(pge)->lenback[d] = 0;
- gex_dump_contour(ge, clen);
-
- ge = ge->frwd; /* the frag is gone, nothing more to do */
- continue;
- } else {
- /* remove the concave frag */
- fprintf(stderr, " removed %s frag at %p len=%d covered by %s\n",
- gxf_name[dx], ge, i, gxf_name[d]);
- f->len[dx] = 0;
- for(pge = ge->frwd, j = 1; j < i; j++, pge = pge->frwd)
- X_FRAG(pge)->lenback[dx] = 0;
- gex_dump_contour(ge, clen);
- }
- }
-
-
- k1 = X_FRAG(ge->frwd)->lenback[dx];
- if(k1 != 0) { /* conflict at the front */
- GENTRY *gels, *gele, *gei;
-
- pge = age[(f->aidx + clen - (k1-1))%clen]; /* first gentry of concave frag */
- k2 = X_FRAG(pge)->len[dx]; /* its length */
-
- i = k2 - (k1-1); /* amount of overlap */
- if(i > len)
- i = len;
- /* i >= 2 by definition */
- if(i >= k2-1) { /* covers the other frag - maybe with 1 gentry showing */
- fprintf(stderr, " removed %s frag at %p len=%d covered by %s\n",
- gxf_name[dx], pge, k2, gxf_name[d]);
- X_FRAG(pge)->len[dx] = 0;
- for(pge = pge->frwd, j = 1; j < k2; j++, pge = pge->frwd)
- X_FRAG(pge)->lenback[dx] = 0;
- if(i >= len-1) { /* covers our frag too - maybe with 1 gentry showing */
- /* our frag will be removed as well, prepare a line to replace it */
- gels = ge;
- gele = age[(f->aidx + i - 1)%clen];
- fprintf(stderr, " new Line frag at %p-%p len=%d\n", gels, gele, i);
- X_FRAG(gels)->len[GEXFI_LINE] = i;
- for(gei = gels->frwd, j = 1; j < i; gei = gei->frwd, j++)
- X_FRAG(gei)->lenback[GEXFI_LINE] = j;
- } else {
- gex_dump_contour(ge, clen);
- ge = ge->frwd;
- continue;
- }
- }
- if(i >= len-1) /* covers our frag - maybe with 1 gentry showing */
- goto curve_completely_covered;
-
- /* XXX need to do something better for the case when a curve frag
- * is actually nothing but an artifact of two other curves of
- * the opposite type touching each other, like on the back of "3"
- */
-
- /* change the overlapping part to a line */
- gels = ge;
- gele = age[(f->aidx + i - 1)%clen];
- /* give preference to local extremums */
- if(X_FRAG(gels)->flags & GEXFF_EXTR) {
- gels = gels->frwd;
- i--;
- }
- if(X_FRAG(gele)->flags & GEXFF_EXTR) {
- gele = gele->bkwd;
- i--;
- }
- if(gels->bkwd == gele) {
- /* Oops the line became negative. Probably should
- * never happen but I can't think of any formal reasoning
- * leading to that, so check just in case. Restore
- * the previous state.
- */
- gels = gele; gele = gels->frwd; i = 2;
- }
-
- j = X_FRAG(gels)->lenback[dx] + 1; /* new length */
- if(j != k2) {
- X_FRAG(pge)->len[dx] = j;
- fprintf(stderr, " cut %s frag at %p len=%d to %p len=%d end overlap with %s\n",
- gxf_name[dx], pge, k2, gels, j, gxf_name[d]);
- for(gei = gels->frwd; j < k2; gei = gei->frwd, j++)
- X_FRAG(gei)->lenback[dx] = 0;
- }
-
- if(gele != ge) {
- sge = gele;
- f->len[d] = 0;
- fprintf(stderr, " cut %s frag at %p len=%d ", gxf_name[d], ge, len);
- len--;
- for(gei = ge->frwd; gei != gele; gei = gei->frwd, len--)
- X_FRAG(gei)->lenback[d] = 0;
- X_FRAG(gele)->len[d] = len;
- X_FRAG(gele)->lenback[d] = 0;
- fprintf(stderr, "to %p len=%d start overlap with %s\n",
- sge, len, gxf_name[dx]);
- for(gei = gei->frwd, j = 1; j < len; gei = gei->frwd, j++)
- X_FRAG(gei)->lenback[d] = j;
-
- }
- if(i > 1) {
- fprintf(stderr, " new Line frag at %p-%p len=%d\n", gels, gele, i);
- X_FRAG(gels)->len[GEXFI_LINE] = i;
- for(gei = gels->frwd, j = 1; j < i; gei = gei->frwd, j++)
- X_FRAG(gei)->lenback[GEXFI_LINE] = j;
- }
- gex_dump_contour(ge, clen);
- }
-
- ge = ge->frwd;
- } while(ge != cge->next);
- }
-
- /*
- * Assert that there are no conflicts any more and
- * for each gentry find the fragment types that start
- * and continue here.
- */
- ge = cge->next;
- do {
- f = X_FRAG(ge);
- dx = GEXFI_NONE; /* type that starts here */
- dy = GEXFI_NONE; /* type that goes through here */
- /* GEXFI_EXACTLINE and GEXFI_SERIF are auxiliary and don't
- * generate any actual lines/curves in the result
- */
- for(d = GEXFI_CONVEX; d<= GEXFI_LINE; d++) {
- if(f->len[d]) {
- if(dx >= 0) {
- fprintf(stderr, "**** Internal error in vectorization\n");
- fprintf(stderr, "CONFLICT in %s at %p between %s and %s\n",
- g->name, ge, gxf_name[dx], gxf_name[d]);
- dumppaths(g, cge->next, cge->next->bkwd);
- gex_dump_contour(ge, clen);
- exit(1);
- }
- dx = d;
- }
- if(f->lenback[d]) {
- if(dy >= 0) {
- fprintf(stderr, "**** Internal error in vectorization\n");
- fprintf(stderr, "CONFLICT in %s at %p between %s and %s\n",
- g->name, ge, gxf_name[dy], gxf_name[d]);
- dumppaths(g, cge->next, cge->next->bkwd);
- gex_dump_contour(ge, clen);
- exit(1);
- }
- dy = d;
- }
- }
- f->ixstart = dx;
- f->ixcont = dy;
- ge = ge->frwd;
- } while(ge != cge->next);
-
- /*
- * make sure that the contour does not start in the
- * middle of a fragment
- */
- ge = cge->next; /* old start of the contour */
- f = X_FRAG(ge);
- if(f->ixstart == GEXFI_NONE && f->ixcont != GEXFI_NONE) {
- /* oops, it's mid-fragment, move the start */
- GENTRY *xge;
-
- xge = ge->bkwd->next; /* entry following the contour */
-
- /* find the first gentry of this frag */
- pge = age[(f->aidx + clen - f->lenback[f->ixcont])%clen];
-
- ge->prev = ge->bkwd;
- ge->bkwd->next = ge;
-
- cge->next = pge;
- pge->prev = cge;
-
- pge->bkwd->next = xge;
- if(xge)
- xge->prev = pge->bkwd;
-
- cge->ix3 = pge->bkwd->ix3; cge->iy3 = pge->bkwd->iy3;
- }
-
- /* vectorize each fragment separately
- * make 2 passes: first handle the straight lines, then
- * the curves to allow the curver to be connected smoothly
- * to the straights
- */
- ge = cge->next;
- do { /* pass 1 */
- f = X_FRAG(ge);
- switch(f->ixstart) {
- case GEXFI_LINE:
- len = f->len[GEXFI_LINE];
- pge = age[(f->aidx + len - 1)%clen]; /* last gentry */
-
- if(ge->iy3 == ge->bkwd->iy3) { /* frag starts and ends horizontally */
- k1 = 1/*Y*/ ; /* across the direction of start */
- k2 = 0/*X*/ ; /* along the direction of start */
- } else { /* frag starts and ends vertically */
- k1 = 0/*X*/ ; /* across the direction of start */
- k2 = 1/*Y*/ ; /* along the direction of start */
- }
-
- if(len % 2) {
- /* odd number of entries in the frag */
- double halfstep, halfend;
-
- f->vect[0][k1] = fscale * ge->ipoints[k1][2];
- f->vect[3][k1] = fscale * pge->ipoints[k1][2];
-
- halfstep = (pge->ipoints[k2][2] - ge->bkwd->ipoints[k2][2])
- * 0.5 / ((len+1)/2);
- if(f->ixcont != GEXFI_NONE) {
- halfend = (ge->ipoints[k2][2] - ge->bkwd->ipoints[k2][2]) * 0.5;
- if(fabs(halfstep) < fabs(halfend)) /* must be at least half gentry away */
- halfstep = halfend;
- }
- if(X_FRAG(pge)->ixstart != GEXFI_NONE) {
- halfend = (pge->ipoints[k2][2] - pge->bkwd->ipoints[k2][2]) * 0.5;
- if(fabs(halfstep) < fabs(halfend)) /* must be at least half gentry away */
- halfstep = halfend;
- }
- f->vect[0][k2] = fscale * (ge->bkwd->ipoints[k2][2] + halfstep);
- f->vect[3][k2] = fscale * (pge->ipoints[k2][2] - halfstep);
- } else {
- /* even number of entries */
- double halfstep, halfend;
-
- f->vect[0][k1] = fscale * ge->ipoints[k1][2];
- halfstep = (pge->ipoints[k2][2] - ge->bkwd->ipoints[k2][2])
- * 0.5 / (len/2);
- if(f->ixcont != GEXFI_NONE) {
- halfend = (ge->ipoints[k2][2] - ge->bkwd->ipoints[k2][2]) * 0.5;
- if(fabs(halfstep) < fabs(halfend)) /* must be at least half gentry away */
- halfstep = halfend;
- }
- f->vect[0][k2] = fscale * (ge->bkwd->ipoints[k2][2] + halfstep);
-
- halfstep = (pge->ipoints[k1][2] - ge->bkwd->ipoints[k1][2])
- * 0.5 / (len/2);
- if(X_FRAG(pge)->ixstart != GEXFI_NONE) {
- halfend = (pge->ipoints[k1][2] - pge->bkwd->ipoints[k1][2]) * 0.5;
- if(fabs(halfstep) < fabs(halfend)) /* must be at least half gentry away */
- halfstep = halfend;
- }
- f->vect[3][k1] = fscale * (pge->ipoints[k1][2] - halfstep);
- f->vect[3][k2] = fscale * pge->ipoints[k2][2];
- }
- f->vectlen = len;
- f->flags |= GEXFF_DRAWLINE;
- break;
- }
- } while((ge = ge->frwd) != cge->next);
-
- ge = cge->next;
- do { /* pass 2 */
- /* data for curves */
- GENTRY *firstge, *lastge, *gef, *gel, *gei, *gex;
- GENTRY *ordhd; /* head of the order list */
- GENTRY **ordlast;
- int nsub; /* number of subfrags */
- GEX_FRAG *ff, *lf, *xf;
-
- f = X_FRAG(ge);
- switch(f->ixstart) {
- case GEXFI_CONVEX:
- case GEXFI_CONCAVE:
- len = f->len[f->ixstart];
- firstge = ge;
- lastge = age[(f->aidx + len - 1)%clen]; /* last gentry */
-
- nsub = 0;
- gex = firstge;
- xf = X_FRAG(gex);
- xf->prevsub = 0;
- xf->sublen = 1;
- xf->flags &= ~GEXFF_DONE;
- for(gei = firstge->frwd; gei != lastge; gei = gei->frwd) {
- xf->sublen++;
- if(X_FRAG(gei)->flags & GEXFF_EXTR) {
- xf->nextsub = gei;
- for(i=0; i<2; i++)
- xf->bbox[i] = abs(gei->ipoints[i][2] - gex->bkwd->ipoints[i][2]);
- nsub++;
- xf = X_FRAG(gei);
- xf->prevsub = gex;
- xf->sublen = 1;
- xf->flags &= ~GEXFF_DONE;
- gex = gei;
- }
- }
- xf->sublen++;
- xf->nextsub = gei;
- for(i=0; i<2; i++)
- xf->bbox[i] = abs(gei->ipoints[i][2] - gex->bkwd->ipoints[i][2]);
- nsub++;
- ff = xf; /* remember the beginning of the last subfrag */
- xf = X_FRAG(gei);
- xf->prevsub = gex;
- if(firstge != lastge) {
- xf->nextsub = 0;
- xf->sublen = 0;
-
- /* correct the bounding box of the last and first subfrags for
- * intersections with other fragments
- */
- if(xf->ixstart != GEXFI_NONE) {
- /* ff points to the beginning of the last subfrag */
- for(i=0; i<2; i++)
- ff->bbox[i] -= 0.5 * abs(lastge->ipoints[i][2] - lastge->bkwd->ipoints[i][2]);
- }
- ff = X_FRAG(firstge);
- if(ff->ixcont != GEXFI_NONE) {
- for(i=0; i<2; i++)
- ff->bbox[i] -= 0.5 * abs(firstge->ipoints[i][2] - firstge->bkwd->ipoints[i][2]);
- }
- }
-
- fprintf(stderr, " %s frag %p%s nsub=%d\n", gxf_name[f->ixstart],
- ge, (f->flags&GEXFF_CIRC)?" circular":"", nsub);
-
- /* find the symmetry between the subfragments */
- for(gef = firstge, count=0; count < nsub; gef = ff->nextsub, count++) {
- ff = X_FRAG(gef);
- gex = ff->nextsub;
- xf = X_FRAG(gex);
- gel = xf->nextsub;
- if(gel == 0) {
- ff->flags &= ~GEXFF_SYMNEXT;
- break; /* not a circular frag */
- }
- good = 1; /* assume that we have symmetry */
- /* gei goes backwards, gex goes forwards from the extremum */
- gei = gex;
- /* i is the symmetry axis, j is the other axis (X=0 Y=1) */
- ff->symaxis = i = (gex->ix3 != gex->bkwd->ix3);
- j = !i;
- for( ; gei!=gef && gex!=gel; gei=gei->bkwd, gex=gex->frwd) {
- if( gei->bkwd->ipoints[i][2] != gex->ipoints[i][2]
- || gei->bkwd->ipoints[j][2] - gei->ipoints[j][2]
- != gex->bkwd->ipoints[j][2] - gex->ipoints[j][2]
- ) {
- good = 0; /* no symmetry */
- break;
- }
- }
- if(good) {
- if( isign(gei->bkwd->ipoints[j][2] - gei->ipoints[j][2])
- != isign(gex->bkwd->ipoints[j][2] - gex->ipoints[j][2]) ) {
- good = 0; /* oops, goes into another direction */
- }
- }
- if(good)
- ff->flags |= GEXFF_SYMNEXT;
- else
- ff->flags &= ~GEXFF_SYMNEXT;
- }
-
- for(gef = firstge, count=0; count < nsub; gef = ff->nextsub, count++) {
- ff = X_FRAG(gef);
- if((ff->flags & GEXFF_SYMNEXT)==0) {
- ff->symxlen = 0;
- continue;
- }
- gex = ff->prevsub;
- if(gex == 0 || (X_FRAG(gex)->flags & GEXFF_SYMNEXT)==0) {
- ff->symxlen = 0;
- continue;
- }
- ff->symxlen = X_FRAG(gex)->sublen;
- xf = X_FRAG(ff->nextsub);
- if(xf->sublen < ff->symxlen)
- ff->symxlen = xf->sublen;
- }
-
- /* find the symmetry inside the subfragments */
- for(gef = firstge, count=0; count < nsub; gef = ff->nextsub, count++) {
- ff = X_FRAG(gef);
-
- if(ff->sublen % 2) {
- /* we must have an even number of gentries for diagonal symmetry */
- ff->symge = 0;
- continue;
- }
-
- /* gei goes forwards from the front */
- gei = gef->frwd;
- /* gex goes backwards from the back */
- gex = ff->nextsub->bkwd;
-
- /* i is the direction of gei, j is the direction of gex */
- i = (gei->iy3 != gei->bkwd->iy3);
- j = !i;
- for( ; gei->bkwd != gex; gei=gei->frwd, gex=gex->bkwd) {
- if( abs(gei->bkwd->ipoints[i][2] - gei->ipoints[i][2])
- != abs(gex->bkwd->ipoints[j][2] - gex->ipoints[j][2]) )
- break; /* no symmetry */
- i = j;
- j = !j;
- }
- if(gei->bkwd == gex)
- ff->symge = gex;
- else
- ff->symge = 0; /* no symmetry */
- }
-
- /* find the order of calculation:
- * prefer to start from long fragments that have the longest
- * neighbours symmetric with them, with all being equal prefer
- * the fragments that have smaller physical size
- */
- ordhd = 0;
- for(gef = firstge, count=0; count < nsub; gef = ff->nextsub, count++) {
- ff = X_FRAG(gef);
-
- for(ordlast = &ordhd; *ordlast != 0; ordlast = &xf->ordersub) {
- xf = X_FRAG(*ordlast);
- if(ff->sublen > xf->sublen)
- break;
- if(ff->sublen < xf->sublen)
- continue;
- if(ff->symxlen > xf->symxlen)
- break;
- if(ff->symxlen < xf->symxlen)
- continue;
- if(ff->bbox[0] < xf->bbox[0] || ff->bbox[1] < xf->bbox[1])
- break;
- }
-
- ff->ordersub = *ordlast;
- *ordlast = gef;
- }
-
- /* vectorize the subfragments */
- for(gef = ordhd; gef != 0; gef = ff->ordersub) {
-
- /* debugging stuff */
- ff = X_FRAG(gef);
- fprintf(stderr, " %p-%p bbox[%g,%g] sym=%p %s len=%d xlen=%d\n",
- gef, ff->nextsub, ff->bbox[0], ff->bbox[1], ff->symge,
- (ff->flags & GEXFF_SYMNEXT) ? "symnext" : "",
- ff->sublen, ff->symxlen);
-
- dosubfrag(g, f->ixstart, firstge, gef, fscale);
- }
-
- break;
- }
- } while((ge = ge->frwd) != cge->next);
-
- free(age);
-
- }
-
- }
-
- /* all the fragments are found, extract the vectorization */
- pge = g->entries;
- g->entries = g->lastentry = 0;
- g->flags |= GF_FLOAT;
- loopge = 0;
- skip = 0;
-
- for(ge = pge; ge != 0; ge = ge->next) {
- GEX_FRAG *f, *pf;
-
- switch(ge->type) {
- case GE_LINE:
- f = X_FRAG(ge);
- if(skip == 0) {
- if(f->flags & (GEXFF_DRAWLINE|GEXFF_DRAWCURVE)) {
- /* draw a line to the start point */
- fg_rlineto(g, f->vect[0][0], f->vect[0][1]);
- /* draw the fragment */
- if(f->flags & GEXFF_DRAWCURVE)
- fg_rrcurveto(g,
- f->vect[1][0], f->vect[1][1],
- f->vect[2][0], f->vect[2][1],
- f->vect[3][0], f->vect[3][1]);
- else
- fg_rlineto(g, f->vect[3][0], f->vect[3][1]);
- skip = f->vectlen - 2;
- } else {
- fg_rlineto(g, fscale * ge->ix3, fscale * ge->iy3);
- }
- } else
- skip--;
- break;
- case GE_MOVE:
- fg_rmoveto(g, -1e6, -1e6); /* will be fixed by GE_PATH */
- skip = 0;
- /* remember the reference to update it later */
- loopge = g->lastentry;
- break;
- case GE_PATH:
- /* update the first MOVE of this contour */
- if(loopge) {
- loopge->fx3 = g->lastentry->fx3;
- loopge->fy3 = g->lastentry->fy3;
- loopge = 0;
- }
- g_closepath(g);
- break;
- }
- }
- for(ge = pge; ge != 0; ge = cge) {
- cge = ge->next;
- free(ge->ext);
- free(ge);
- }
- dumppaths(g, NULL, NULL);
-
- /* end of vectorization logic */
- } else {
- /* convert the data to float */
- GENTRY *ge;
- double x, y;
-
- for(ge = g->entries; ge != 0; ge = ge->next) {
- ge->flags |= GEF_FLOAT;
- if(ge->type != GE_MOVE && ge->type != GE_LINE)
- continue;
-
- x = fscale * ge->ix3;
- y = fscale * ge->iy3;
-
- ge->fx3 = x;
- ge->fy3 = y;
- }
- g->flags |= GF_FLOAT;
- }
-
- free(hlm); free(vlm); free(amp);
-}
-
-#if 0
-/* print out the bitmap */
-printbmap(bmap, xsz, ysz, xoff, yoff)
- char *bmap;
- int xsz, ysz, xoff, yoff;
-{
- int x, y;
-
- for(y=ysz-1; y>=0; y--) {
- putchar( (y%10==0) ? y/10+'0' : ' ' );
- putchar( y%10+'0' );
- for(x=0; x<xsz; x++)
- putchar( bmap[y*xsz+x] ? 'X' : '.' );
- if(-yoff==y)
- putchar('_'); /* mark the baseline */
- putchar('\n');
- }
- putchar(' '); putchar(' ');
- for(x=0; x<xsz; x++)
- putchar( x%10+'0' );
- putchar('\n'); putchar(' '); putchar(' ');
- for(x=0; x<xsz; x++)
- putchar( (x%10==0) ? x/10+'0' : ' ' );
- putchar('\n');
-}
-
-/* print out the limits of outlines */
-printlimits(hlm, vlm, amp, xsz, ysz)
- char *hlm, *vlm, *amp;
- int xsz, ysz;
-{
- int x, y;
- static char h_char[]={ ' ', '~', '^' };
- static char v_char[]={ ' ', '(', ')' };
-
- for(y=ysz-1; y>=0; y--) {
- for(x=0; x<xsz; x++) {
- if(amp[y*xsz+x])
- putchar('!'); /* ambigouos point is always on a limit */
- else
- putchar(v_char[ vlm[y*(xsz+1)+x] & (L_ON|L_OFF) ]);
- putchar(h_char[ hlm[(y+1)*xsz+x] & (L_ON|L_OFF) ]);
- }
- putchar(v_char[ vlm[y*(xsz+1)+x] & (L_ON|L_OFF) ]);
- putchar('\n');
- }
- /* last line */
- for(x=0; x<xsz; x++) {
- putchar(' ');
- putchar(h_char[ hlm[x] & (L_ON|L_OFF) ]);
- }
- putchar(' ');
- putchar('\n');
-}
-#endif /* 0 */
diff --git a/nx-X11/extras/ttf2pt1/byteorder.h b/nx-X11/extras/ttf2pt1/byteorder.h
deleted file mode 100644
index c139817e5..000000000
--- a/nx-X11/extras/ttf2pt1/byteorder.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * see COPYRIGHT
- */
-
-/* This defines the macroes ntohs and ntohl, which convert short and long
- ints from network order (used on 68000 chips, and in TrueType font
- files) to whatever order your computer uses. #define _BIG_ENDIAN or not
- to control which set of definitions apply. If you don't know, try both. If
- you have a peculiar machine you're on your own.
-*/
-
-#if defined(_BIG_ENDIAN)
-#define ntohl(x) (x)
-#define ntohs(x) (x)
-#else
-#define ntohs(x) \
- ((USHORT)((((USHORT)(x) & 0x00ff) << 8) | \
- (((USHORT)(x) & 0xff00) >> 8)))
-#define ntohl(x) \
- ((ULONG)((((ULONG)(x) & 0x000000ffU) << 24) | \
- (((ULONG)(x) & 0x0000ff00U) << 8) | \
- (((ULONG)(x) & 0x00ff0000U) >> 8) | \
- (((ULONG)(x) & 0xff000000U) >> 24)))
-#endif
diff --git a/nx-X11/extras/ttf2pt1/cygbuild.sh b/nx-X11/extras/ttf2pt1/cygbuild.sh
deleted file mode 100644
index df109f81e..000000000
--- a/nx-X11/extras/ttf2pt1/cygbuild.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-:
-# this file should be run from Cygnus BASH
-# file to build ttf2pt1 with Cygnus GCC on Windows
-# don't forget to copy CYGWIN1.DLL into C:\WINDOWS
-
-gcc -o ttf2pt1 -DWINDOWS ttf2pt1.c pt1.c t1asm.c ttf.c -lm
-gcc -o t1asm -DWINDOWS -DSTANDALONE t1asm.c
-
diff --git a/nx-X11/extras/ttf2pt1/ft.c b/nx-X11/extras/ttf2pt1/ft.c
deleted file mode 100644
index 60a429654..000000000
--- a/nx-X11/extras/ttf2pt1/ft.c
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * The font parser using the FreeType library version 2.
- *
- * see COPYRIGHT
- *
- */
-
-#ifdef USE_FREETYPE
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <sys/types.h>
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TRUETYPE_TABLES_H
-#include FT_BBOX_H
-#include FT_GLYPH_H
-
-#include FT_CONFIG_CONFIG_H
-#include FT_CONFIG_OPTIONS_H
-#include FT_ERRORS_H
-#include FT_SYSTEM_H
-#include FT_IMAGE_H
-#include FT_TYPES_H
-#include FT_OUTLINE_H
-#include FT_MODULE_H
-#include FT_RENDER_H
-#include FT_TYPE1_TABLES_H
-#include FT_TRUETYPE_IDS_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_MULTIPLE_MASTERS_H
-#include FT_SFNT_NAMES_H
-
-#ifdef XP_PSTEXT
-#include "os.h"
-#include "Xproto.h"
-#include "font.h"
-#include "fontstruct.h"
-#include "fntfilst.h"
-#include "fontutil.h"
-#include "fontenc.h"
-#include "ft.h"
-#define NOT_IN_FTFUNCS
-#include "ftfuncs.h"
-#endif /* XP_PSTEXT */
-
-#include "pt1.h"
-#include "global.h"
-
-/* prototypes of call entries */
-static void openfont(char *fname, char *arg);
-static void closefont( void);
-static int getnglyphs ( void);
-static int glnames( GLYPH *glyph_list);
-static void glmetrics( GLYPH *glyph_list);
-static int glenc( GLYPH *glyph_list, int *encoding, int *unimap);
-static void fnmetrics( struct font_metrics *fm);
-static void glpath( int glyphno, GLYPH *glyph_list);
-static void kerning( GLYPH *glyph_list);
-
-/* globals */
-
-/* front-end descriptor */
-struct frontsw freetype_sw = {
- /*name*/ "ft",
- /*descr*/ "based on the FreeType2 library",
- /*suffix*/ { "ttf", "ttc", "otf", "otc", "pfa", "pfb" },
- /*open*/ openfont,
- /*close*/ closefont,
- /*nglyphs*/ getnglyphs,
- /*glnames*/ glnames,
- /*glmetrics*/ glmetrics,
- /*glenc*/ glenc,
- /*fnmetrics*/ fnmetrics,
- /*glpath*/ glpath,
- /*kerning*/ kerning,
-};
-
-/* statics */
-
-static char * dupcnstring( unsigned char *s, int len);
-
-#ifndef XP_PSTEXT
-static FT_Library library;
-#endif /* !XP_PSTEXT */
-static FT_Face face;
-
-static int enc_type, enc_found;
-
-/* SFNT functions do not seem to be included by default in FT2beta8 */
-#define ENABLE_SFNT
-
-/*
- * Open font and prepare to return information to the main driver.
- * May print error and warning messages.
- * Exit on error.
- */
-
-static void
-openfont(
- char *fname,
- char *arg /* unused now */
-)
-{
- FT_Error error;
-
-#ifdef XP_PSTEXT
- extern FT_Face xp_pstext_ft_face;
- extern FT_Library ftypeLibrary; /* defined in xc/lib/font/FreeType/ftfuncs.c */
-
- face = xp_pstext_ft_face;
-#else
- if( FT_Init_FreeType( &library ) ) {
- fprintf(stderr, "** FreeType initialization failed\n");
- exit(1);
- }
-
- if( error = FT_New_Face( library, fname, 0, &face ) ) {
- if ( error == FT_Err_Unknown_File_Format )
- fprintf(stderr, "**** %s has format unknown to FreeType\n", fname);
- else
- fprintf(stderr, "**** Cannot access %s ****\n", fname);
- exit(1);
- }
-#endif /* XP_PSTEXT */
-
- if(FT_HAS_FIXED_SIZES(face)) {
- WARNING_1 fprintf(stderr, "Font contains bitmaps\n");
- }
- if(FT_HAS_MULTIPLE_MASTERS(face)) {
- WARNING_1 fprintf(stderr, "Font contains multiple masters, using default\n");
- }
-
- if(ISDBG(FT)) fprintf(stderr," %d units per EM\n", face->units_per_EM);
-
- enc_found = 0;
-}
-
-/*
- * Close font.
- * Exit on error.
- */
-
-static void
-closefont(
- void
-)
-{
-#ifdef XP_PSTEXT
- /* NOP */
-#else
- if( FT_Done_Face(face) ) {
- WARNING_1 fprintf(stderr, "Errors when closing the font file, ignored\n");
- }
- if( FT_Done_FreeType(library) ) {
- WARNING_1 fprintf(stderr, "Errors when stopping FreeType, ignored\n");
- }
-#endif /* XP_PSTEXT */
-}
-
-/*
- * Get the number of glyphs in font.
- */
-
-static int
-getnglyphs (
- void
-)
-{
- if(ISDBG(FT)) fprintf(stderr, "%d glyphs in font\n", face->num_glyphs);
- return (int)face->num_glyphs;
-}
-
-/*
- * Get the names of the glyphs.
- * Returns 0 if the names were assigned, non-zero if the font
- * provides no glyph names.
- */
-
-static int
-glnames(
- GLYPH *glyph_list
-)
-{
-#define MAX_NAMELEN 1024
-
-#ifdef XP_PSTEXT
- char buf[1024];
- long i;
- FT_Error error;
-
-#ifdef XP_ONLY_BLOCKS
- extern unsigned long xp_font_block_offset;
- extern FTFontPtr xp_xtf;
- int bc; /* block counter */
-
-
- /* FixMe: This code should use PsOut_Get_FreeType_Glyph_Name() instead of
- * duplicating the code
- */
- for( bc = xp_font_block_offset ; bc < (xp_font_block_offset+256) ; bc++ ) {
- /* Remap X11 font index to FreeType font index */
- i = FTRemap(face, &xp_xtf->mapping, bc);
-
- if( i >= face->num_glyphs )
- continue;
-#else
- for(i=0; i < face->num_glyphs; i++) {
-#endif /* XP_ONLY_BLOCKS */
- if( FT_Has_PS_Glyph_Names(face) ) {
- error = FT_Get_Glyph_Name(face, i, buf, MAX_NAMELEN);
- }
- else
- {
- error = -1;
- }
-
- if( error ) {
- /* Check for unicode mapping
- * See Adobe document "Unicode and Glyph Names"
- * (http://partners.adobe.com/asn/tech/type/unicodegn.jsp)
- */
- if( (xp_xtf->mapping.mapping->type == FONT_ENCODING_UNICODE) &&
- (i < 0xFFFE) )
- {
- sprintf(buf, "uni%04lx", i);
- }
- else
- {
- sprintf(buf, "ch%02lx", i);
- }
- }
- glyph_list[i].name = strdup(buf);
- if(ISDBG(FT)) fprintf(stderr, "%d has name %s\n", i, buf);
- if (glyph_list[i].name == NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- }
-
- return 0;
-#else
- char bf[1024];
- long i;
-
- if( ! FT_HAS_GLYPH_NAMES(face) ) {
- WARNING_1 fprintf(stderr, "Font has no glyph names\n");
- return 1;
- }
-
- for(i=0; i < face->num_glyphs; i++) {
- if( FT_Get_Glyph_Name(face, i, bf, MAX_NAMELEN) || bf[0]==0 ) {
- sprintf(bf, "_g_%d", i);
- WARNING_2 fprintf(stderr,
- "Glyph No. %d has no postscript name, becomes %s\n", i, bf);
- }
- glyph_list[i].name = strdup(bf);
- if(ISDBG(FT)) fprintf(stderr, "%d has name %s\n", i, bf);
- if (glyph_list[i].name == NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- }
-
- return 0;
-#endif /* XP_PSTEXT */
-}
-
-/*
- * Get the metrics of the glyphs.
- */
-
-static void
-glmetrics(
- GLYPH *glyph_list
-)
-{
- GLYPH *g;
- int i;
- FT_Glyph_Metrics *met;
- FT_BBox bbox;
- FT_Glyph gly;
-
-#ifdef XP_ONLY_BLOCKS
- extern unsigned long xp_font_block_offset;
- extern FTFontPtr xp_xtf;
- int bc; /* block counter */
-
- for( bc = xp_font_block_offset ; bc < (xp_font_block_offset+256) ; bc++ ) {
- /* Remap X11 font index to FreeType font index */
- i = FTRemap(face, &xp_xtf->mapping, bc);
-
- if( i >= face->num_glyphs )
- continue;
-
-#else
- for(i=0; i < face->num_glyphs; i++) {
-#endif /* XP_ONLY_BLOCKS */
- g = &(glyph_list[i]);
-
- if( FT_Load_Glyph(face, i, FT_LOAD_NO_BITMAP|FT_LOAD_NO_SCALE) ) {
- fprintf(stderr, "Can't load glyph %s, skipped\n", g->name);
- continue;
- }
-
- met = &face->glyph->metrics;
-
- if(FT_HAS_HORIZONTAL(face)) {
- g->width = met->horiAdvance;
- g->lsb = met->horiBearingX;
- } else {
- WARNING_2 fprintf(stderr, "Glyph %s has no horizontal metrics, guessed them\n", g->name);
- g->width = met->width;
- g->lsb = 0;
- }
-
- if( FT_Get_Glyph(face->glyph, &gly) ) {
- fprintf(stderr, "Can't access glyph %s bbox, skipped\n", g->name);
- continue;
- }
-
- FT_Glyph_Get_CBox(gly, ft_glyph_bbox_unscaled, &bbox);
- g->xMin = bbox.xMin;
- g->yMin = bbox.yMin;
- g->xMax = bbox.xMax;
- g->yMax = bbox.yMax;
-
- g->ttf_pathlen = face->glyph->outline.n_points;
- }
-}
-
-/*
- * Get the original encoding of the font.
- * Returns 1 for if the original encoding is Unicode, 2 if the
- * original encoding is other 16-bit, 0 if 8-bit.
- */
-
-static int
-glenc(
- GLYPH *glyph_list,
- int *encoding,
- int *unimap
-)
-{
-#ifdef XP_PSTEXT
- int i,
- e;
- unsigned code;
- extern FTFontPtr xp_xtf;
- extern unsigned long xp_font_block_offset;
-
- enc_found = 1;
- enc_type = 0;
-
- for(i=0; i<ENCTABSZ; i++) {
- if(encoding[i] != -1)
- continue;
-
- /* Remap X11 font index to FreeType font index */
- code = FTRemap(face, &xp_xtf->mapping, xp_font_block_offset+i);
-
- if(code == 0)
- continue; /* .notdef */
-
- encoding[i] = code;
- }
-
- return enc_type;
-#else
- int i, e;
- unsigned code;
-
- if(ISDBG(FT))
- for(e=0; e < face->num_charmaps; e++) {
- fprintf(stderr, "found encoding pid=%d eid=%d\n",
- face->charmaps[e]->platform_id,
- face->charmaps[e]->encoding_id);
- }
-
- if(enc_found)
- goto populate_map;
-
- enc_type = 0;
-
- /* first check for an explicit PID/EID */
-
- if(force_pid != -1) {
- for(e=0; e < face->num_charmaps; e++) {
- if(face->charmaps[e]->platform_id == force_pid
- && face->charmaps[e]->encoding_id == force_eid) {
- WARNING_1 fprintf(stderr, "Found Encoding PID=%d/EID=%d\n",
- force_pid, force_eid);
- if( FT_Set_Charmap(face, face->charmaps[e]) ) {
- fprintf(stderr, "**** Cannot set charmap in FreeType ****\n");
- exit(1);
- }
- enc_type = 1;
- goto populate_map;
- }
- }
- fprintf(stderr, "*** TTF encoding table PID=%d/EID=%d not found\n",
- force_pid, force_eid);
- exit(1);
- }
-
- /* next check for a direct Adobe mapping */
-
- if(!forcemap) {
- for(e=0; e < face->num_charmaps; e++) {
- if(face->charmaps[e]->encoding == ft_encoding_adobe_custom) {
- WARNING_1 fputs("Found Adobe Custom Encoding\n", stderr);
- if( FT_Set_Charmap(face, face->charmaps[e]) ) {
- fprintf(stderr, "**** Cannot set charmap in FreeType ****\n");
- exit(1);
- }
- goto populate_map;
- }
- }
- }
-
- for(e=0; e < face->num_charmaps; e++) {
- if(face->charmaps[e]->platform_id == 3) {
- switch(face->charmaps[e]->encoding_id) {
- case 0:
- WARNING_1 fputs("Found Symbol Encoding\n", stderr);
- break;
- case 1:
- WARNING_1 fputs("Found Unicode Encoding\n", stderr);
- enc_type = 1;
- break;
- default:
- WARNING_1 {
- fprintf(stderr,
- "****MS Encoding ID %d not supported****\n",
- face->charmaps[e]->encoding_id);
- fputs("Treating it like Symbol encoding\n", stderr);
- }
- break;
- }
- break;
- }
- }
- if(e >= face->num_charmaps) {
- WARNING_1 fputs("No Microsoft encoding, using first encoding available\n", stderr);
- e = 0;
- }
-
- if( FT_Set_Charmap(face, face->charmaps[e]) ) {
- fprintf(stderr, "**** Cannot set charmap in FreeType ****\n");
- exit(1);
- }
-
-populate_map:
- enc_found = 1;
- for(i=0; i<ENCTABSZ; i++) {
- if(encoding[i] != -1)
- continue;
- if(enc_type == 1 || forcemap) {
- code = unimap[i];
- if(code == (unsigned) -1)
- continue;
- } else
- code = i;
-
- code = FT_Get_Char_Index(face, code);
- if(0 && ISDBG(FT)) fprintf(stderr, "code of %3d is %3d\n", i, code);
- if(code == 0)
- continue; /* .notdef */
- encoding[i] = code;
- }
-
- return enc_type;
-#endif /* XP_PSTEXT */
-}
-
-/* duplicate a string with counter to a 0-terminated string */
-static char *
-dupcnstring(
- unsigned char *s,
- int len
-)
-{
- char *res, *out;
- int i, c;
- static int warned=0;
-
- if(( res = malloc(len+1) )==NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
-
- out = res;
- for(i=0; i<len; i++) {
- if(( c=s[i] )>=' ' && c!=127)
- *out++ = c;
- else if(!warned) {
- warned=1;
- WARNING_1 fprintf(stderr, "Some font name strings are in Unicode, may not show properly\n");
- }
- }
- *out = 0;
- return res;
-}
-
-/*
- * Get the font metrics
- */
-static void
-fnmetrics(
- struct font_metrics *fm
-)
-{
- char *str;
- static char *fieldstocheck[3];
-#ifdef ENABLE_SFNT
- FT_SfntName sn;
-#endif /* ENABLE_SFNT */
- int i;
-
- fm->italic_angle = 0.0; /* FreeType hides the angle */
- fm->underline_position = face->underline_position;
- fm->underline_thickness = face->underline_thickness;
- fm->is_fixed_pitch = FT_IS_FIXED_WIDTH(face);
-
- fm->ascender = face->ascender;
- fm->descender = face->descender;
-
- fm->units_per_em = face->units_per_EM;
-
- fm->bbox[0] = face->bbox.xMin;
- fm->bbox[1] = face->bbox.yMin;
- fm->bbox[2] = face->bbox.xMax;
- fm->bbox[3] = face->bbox.yMax;
-
-#ifdef ENABLE_SFNT
- if( FT_Get_Sfnt_Name(face, TT_NAME_ID_COPYRIGHT, &sn) )
-#endif /* ENABLE_SFNT */
- fm->name_copyright = "";
-#ifdef ENABLE_SFNT
- else
- fm->name_copyright = dupcnstring(sn.string, sn.string_len);
-#endif /* ENABLE_SFNT */
-
- fm->name_family = face->family_name;
-
- fm->name_style = face->style_name;
- if(fm->name_style == NULL)
- fm->name_style = "";
-
-#ifdef ENABLE_SFNT
- if( FT_Get_Sfnt_Name(face, TT_NAME_ID_FULL_NAME, &sn) )
-#endif /* ENABLE_SFNT */
- {
- int len;
-
- len = strlen(fm->name_family) + strlen(fm->name_style) + 2;
- if(( fm->name_full = malloc(len) )==NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- strcpy(fm->name_full, fm->name_family);
- if(strlen(fm->name_style) != 0) {
- strcat(fm->name_full, " ");
- strcat(fm->name_full, fm->name_style);
- }
- }
-#ifdef ENABLE_SFNT
- else
- fm->name_full = dupcnstring(sn.string, sn.string_len);
-#endif /* ENABLE_SFNT */
-
-#ifdef ENABLE_SFNT
- if( FT_Get_Sfnt_Name(face, TT_NAME_ID_VERSION_STRING, &sn) )
-#endif /* ENABLE_SFNT */
- fm->name_version = "1.0";
-#ifdef ENABLE_SFNT
- else
- fm->name_version = dupcnstring(sn.string, sn.string_len);
-#endif /* ENABLE_SFNT */
-
-#ifdef XP_PSTEXT
- {
- extern const char *xp_psfontname;
-
- fm->name_ps = strdup(xp_psfontname);
-
- /* Handle the rare case if a family name was not provided by the TTF
- * font (like Solaris TTF fonts in /usr/openwin/lib/locale/ko.UTF-8/X11/fonts/TrueType,
- * /usr/openwin/lib/locale/ko/X11/fonts/TrueType) - in this case we
- * have to generate a family name somehow... */
- if(fm->name_family == NULL)
- fm->name_family = fm->name_ps;
- }
-#else
-
-#ifdef ENABLE_SFNT
- if( FT_Get_Sfnt_Name(face, TT_NAME_ID_PS_NAME , &sn) ) {
-#endif /* ENABLE_SFNT */
- if(( fm->name_ps = strdup(fm->name_full) )==NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
-#ifdef ENABLE_SFNT
- } else
- fm->name_ps = dupcnstring(sn.string, sn.string_len);
-#endif /* ENABLE_SFNT */
-
-#endif /* XP_PSTEXT */
-
- for(i=0; fm->name_ps[i]!=0; i++)
- if(fm->name_ps[i] == ' ')
- fm->name_ps[i] = '_'; /* no spaces in the Postscript name *m */
-
- /* guess the boldness from the font names */
- fm->force_bold=0;
-
- fieldstocheck[0] = fm->name_style;
- fieldstocheck[1] = fm->name_full;
- fieldstocheck[2] = fm->name_ps;
-
- for(i=0; !fm->force_bold && i<sizeof fieldstocheck /sizeof(fieldstocheck[0]); i++) {
- str=fieldstocheck[i];
- for(i=0; str[i]!=0; i++) {
- if( (str[i]=='B'
- || str[i]=='b'
- && ( i==0 || !isalpha(str[i-1]) )
- )
- && !strncmp("old",&str[i+1],3)
- && !islower(str[i+4])
- ) {
- fm->force_bold=1;
- break;
- }
- }
- }
-}
-
-/*
- * Functions to decompose the outlines
- */
-
-static GLYPH *curg;
-static double lastx, lasty;
-
-static int
-outl_moveto(
- FT_Vector *to,
- void *unused
-)
-{
- double tox, toy;
-
- tox = fscale((double)to->x); toy = fscale((double)to->y);
-
- /* FreeType does not do explicit closepath() */
- if(curg->lastentry) {
- g_closepath(curg);
- }
- fg_rmoveto(curg, tox, toy);
- lastx = tox; lasty = toy;
-
- return 0;
-}
-
-static int
-outl_lineto(
- FT_Vector *to,
- void *unused
-)
-{
- double tox, toy;
-
- tox = fscale((double)to->x); toy = fscale((double)to->y);
-
- fg_rlineto(curg, tox, toy);
- lastx = tox; lasty = toy;
-
- return 0;
-}
-
-static int
-outl_conicto(
- FT_Vector *control1,
- FT_Vector *to,
- void *unused
-)
-{
- double c1x, c1y, tox, toy;
-
- c1x = fscale((double)control1->x); c1y = fscale((double)control1->y);
- tox = fscale((double)to->x); toy = fscale((double)to->y);
-
- fg_rrcurveto(curg,
- (lastx + 2.0 * c1x) / 3.0, (lasty + 2.0 * c1y) / 3.0,
- (2.0 * c1x + tox) / 3.0, (2.0 * c1y + toy) / 3.0,
- tox, toy );
- lastx = tox; lasty = toy;
-
- return 0;
-}
-
-static int
-outl_cubicto(
- FT_Vector *control1,
- FT_Vector *control2,
- FT_Vector *to,
- void *unused
-)
-{
- double c1x, c1y, c2x, c2y, tox, toy;
-
- c1x = fscale((double)control1->x); c1y = fscale((double)control1->y);
- c2x = fscale((double)control2->x); c2y = fscale((double)control2->y);
- tox = fscale((double)to->x); toy = fscale((double)to->y);
-
- fg_rrcurveto(curg, c1x, c1y, c2x, c2y, tox, toy);
- lastx = tox; lasty = toy;
-
- return 0;
-}
-
-static FT_Outline_Funcs ft_outl_funcs = {
- outl_moveto,
- outl_lineto,
- outl_conicto,
- outl_cubicto,
- 0,
- 0
-};
-
-/*
- * Get the path of contrours for a glyph.
- */
-
-static void
-glpath(
- int glyphno,
- GLYPH *glyf_list
-)
-{
- FT_Outline *ol;
-
- curg = &glyf_list[glyphno];
-
- if( FT_Load_Glyph(face, glyphno, FT_LOAD_NO_BITMAP|FT_LOAD_NO_SCALE|FT_LOAD_NO_HINTING)
- || face->glyph->format != ft_glyph_format_outline ) {
- fprintf(stderr, "Can't load glyph %s, skipped\n", curg->name);
- return;
- }
-
- ol = &face->glyph->outline;
- lastx = 0.0; lasty = 0.0;
-
- if( FT_Outline_Decompose(ol, &ft_outl_funcs, NULL) ) {
- fprintf(stderr, "Can't decompose outline of glyph %s, skipped\n", curg->name);
- return;
- }
-
- /* FreeType does not do explicit closepath() */
- if(curg->lastentry) {
- g_closepath(curg);
- }
-
- if(ol->flags & ft_outline_reverse_fill) {
- assertpath(curg->entries, __FILE__, __LINE__, curg->name);
- reversepaths(curg);
- }
-}
-
-/*
- * Get the kerning data.
- */
-
-static void
-kerning(
- GLYPH *glyph_list
-)
-{
- int i, j, n;
- int nglyphs = face->num_glyphs;
- FT_Vector k;
- GLYPH *gl;
-
- if( nglyphs == 0 || !FT_HAS_KERNING(face) ) {
- WARNING_1 fputs("No Kerning data\n", stderr);
- return;
- }
-
- for(i=0; i<nglyphs; i++) {
- if( (glyph_list[i].flags & GF_USED) ==0)
- continue;
- for(j=0; j<nglyphs; j++) {
- if( (glyph_list[j].flags & GF_USED) ==0)
- continue;
- if( FT_Get_Kerning(face, i, j, ft_kerning_unscaled, &k) )
- continue;
- if( k.x == 0 )
- continue;
-
- addkernpair(i, j, k.x);
- }
- }
-}
-
-#endif
diff --git a/nx-X11/extras/ttf2pt1/global.h b/nx-X11/extras/ttf2pt1/global.h
deleted file mode 100644
index 4d53878f7..000000000
--- a/nx-X11/extras/ttf2pt1/global.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * see COPYRIGHT
- */
-
-
-/* options */
-
-extern int encode; /* encode the resulting file */
-extern int pfbflag; /* produce compressed file */
-extern int wantafm; /* want to see .afm instead of .t1a on stdout */
-extern int correctvsize; /* try to correct the vertical size of characters */
-extern int wantuid; /* user wants UniqueID entry in the font */
-extern int allglyphs; /* convert all glyphs, not only 256 of them */
-extern int warnlevel; /* the level of permitted warnings */
-extern int forcemap; /* do mapping even on non-Unicode fonts */
-/* options - maximal limits */
-extern int max_stemdepth; /* maximal depth of stem stack in interpreter */
-/* options - debugging */
-extern int absolute; /* print out in absolute values */
-extern int reverse; /* reverse font to Type1 path directions */
-/* options - suboptions of Outline Processing */
-extern int optimize; /* enables space optimization */
-extern int smooth; /* enable smoothing of outlines */
-extern int transform; /* enables transformation to 1000x1000 matrix */
-extern int hints; /* enables autogeneration of hints */
-extern int subhints; /* enables autogeneration of substituted hints */
-extern int trybold; /* try to guess whether the font is bold */
-extern int correctwidth; /* try to correct the character width */
-extern int vectorize; /* vectorize the bitmaps */
-extern int use_autotrace; /* use the autotrace library on bitmap */
-/* options - suboptions of File Generation */
-extern int gen_pfa; /* generate the font file */
-extern int gen_afm; /* generate the metrics file */
-extern int gen_dvienc; /* generate the dvips encoding file */
-
-/* not quite options to select a particular source encoding */
-extern int force_pid; /* specific platform id */
-extern int force_eid; /* specific encoding id */
-
-/* other globals */
-extern FILE *null_file, *pfa_file, *afm_file, *dvienc_file;
-extern int numglyphs;
-
-/* warnings */
-
-#define WARNING_1 if(warnlevel >= 1)
-#define WARNING_2 if(warnlevel >= 2)
-#define WARNING_3 if(warnlevel >= 3)
-#define WARNING_4 if(warnlevel >= 4)
-
-/*
- * Bitmap control macros
- */
-
-#define BITMAP_BYTES(size) (((size)+7)>>3)
-#define DEF_BITMAP(name, size) unsigned char name[BITMAP_BYTES(size)]
-#define SET_BITMAP(name, bit) ( name[(bit)>>3] |= (1<<((bit)&7)) )
-#define CLR_BITMAP(name, bit) ( name[(bit)>>3] &= ~(1<<((bit)&7)) )
-#define IS_BITMAP(name, bit) ( name[(bit)>>3] & (1<<((bit)&7)) )
-
-/* debugging */
-
-/* debug flags */
-#define DEBUG_UNICODE 0x00000001 /* unicode to 8-bit code conversion */
-#define DEBUG_MAINSTEMS 0x00000002 /* glyph-wide main stem generation */
-#define DEBUG_SUBSTEMS 0x00000004 /* substituted stem generation */
-#define DEBUG_STEMS (DEBUG_MAINSTEMS|DEBUG_SUBSTEMS)
-#define DEBUG_REVERSAL 0x00000008 /* reversal of the paths */
-#define DEBUG_FIXCVDIR 0x00000010 /* fixcvdir() */
-#define DEBUG_STEMOVERLAP 0x00000020 /* stemoverlap() */
-#define DEBUG_BLUESTEMS 0x00000040 /* markbluestems() */
-#define DEBUG_STRAIGHTEN 0x00000080 /* markbluestems() */
-#define DEBUG_EXTMAP 0x00000100 /* parsing of external map */
-#define DEBUG_TOINT 0x00000200 /* conversion of path to integer */
-#define DEBUG_BUILDG 0x00000400 /* building of glyph path */
-#define DEBUG_QUAD 0x00000800 /* splitting curves by quadrants */
-#define DEBUG_SQEQ 0x00001000 /* square equation solver */
-#define DEBUG_COMPOSITE 0x00002000 /* handling of composite glyphs */
-#define DEBUG_FCONCISE 0x00004000 /* normalization of curves */
-#define DEBUG_FT 0x00008000 /* FreeType front-end */
-#define DEBUG_BITMAP 0x00010000 /* conversion from bitmap */
-#define DEBUG_DISABLED 0x80000000 /* special flag: temporary disable debugging */
-
-#if 0
-/* at what we want to look now */
-#ifndef DEBUG
-# define DEBUG (DEBUG_BITMAP)
-#endif
-
-/* uncomment the next line if debugging data is wanted for one glyph only */
-#define DBG_GLYPH "C118" /* */
-#endif
-
-#if 1
-# define ISDBG(name) (0)
-# define ENABLEDBG(condition) (0)
-# define DISABLEDBG(condition) (0)
-#else
- extern int debug; /* collection of the flags */
-/* this ISDBG will only work on ANSI C, not K&R */
-# define ISDBG(name) ( (debug & DEBUG_DISABLED) ? 0 : (debug & (DEBUG_##name)) )
-# define ENABLEDBG(condition) ( (condition) ? (debug&=~DEBUG_DISABLED) : 0 )
-# define DISABLEDBG(condition) ( (condition) ? (debug|=DEBUG_DISABLED) : 0 )
-#endif
-
-#ifdef DBG_GLYPH
-# define DBG_TO_GLYPH(g) DISABLEDBG( strcmp( (g)->name, DBG_GLYPH ) )
-# define DBG_FROM_GLYPH(g) ENABLEDBG(1)
-#else
-# define DBG_TO_GLYPH(g) (0)
-# define DBG_FROM_GLYPH(g) (0)
-#endif
-
-/* prototypes */
-int iscale( int val);
-double fscale( double val);
-int unicode_rev_lookup( int unival);
-void bmp_outline( GLYPH *g, int scale, char *bmap,
- int xsz, int ysz, int xoff, int yoff);
-int isign( int x);
-int fsign( double x);
-
-/* global metrics for a font */
-
-struct font_metrics {
- /* post */
- double italic_angle;
- short underline_position;
- short underline_thickness;
- short is_fixed_pitch;
-
- /* hhea */
- short ascender;
- short descender;
-
- /* head */
- unsigned short units_per_em;
- short bbox[4];
-
- /* name */
- char *name_copyright;
- char *name_family;
- char *name_style;
- char *name_full;
- char *name_version;
- char *name_ps;
-
- /* other */
- int force_bold;
-};
-
-/* size of the encoding table - glyphs beyond 255 are actually unnumbered */
-
-#define ENCTABSZ 1024
-
-/* switch table structure for front-ends */
-
-#define MAXSUFFIX 10
-
-struct frontsw {
- char *name; /* name of the front end */
- char *descr; /* description of the front end */
- char *suffix[MAXSUFFIX]; /* possible file name suffixes */
-
- void (*open)(char *fname, char *arg); /* open font file */
- void (*close)(void); /* close font file */
- int (*nglyphs)(void); /* get the number of glyphs */
- int (*glnames)(GLYPH *glyphs); /* get the names of glyphs */
- void (*glmetrics)(GLYPH *glyphs); /* get the metrics of glyphs */
- int (*glenc)(GLYPH *glyphs, int *enc, int *unimap); /* get the encoding */
- void (*fnmetrics)(struct font_metrics *fm); /* get the font metrics */
- void (*glpath)(int glyphno, GLYPH *glyphs); /* get the glyph path */
- void (*kerning)(GLYPH *glyph_list); /* extract the kerning data */
-};
diff --git a/nx-X11/extras/ttf2pt1/pt1.c b/nx-X11/extras/ttf2pt1/pt1.c
deleted file mode 100644
index b1c46d57a..000000000
--- a/nx-X11/extras/ttf2pt1/pt1.c
+++ /dev/null
@@ -1,7374 +0,0 @@
-/*
- * see COPYRIGHT
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <time.h>
-#include <ctype.h>
-#include <math.h>
-
-#ifndef WINDOWS
-# include <netinet/in.h>
-# include <unistd.h>
-#else
-# include "windows.h"
-#endif
-
-#include "ttf.h"
-#include "pt1.h"
-#include "global.h"
-
-/* big and small values for comparisons */
-#define FBIGVAL (1e20)
-#define FEPS (100000./FBIGVAL)
-
-/* names of the axes */
-#define X 0
-#define Y 1
-
-/* the GENTRY extension structure used in fforceconcise() */
-
-struct gex_con {
- double d[2 /*X, Y*/]; /* sizes of curve */
- double sin2; /* squared sinus of the angle to the next gentry */
- double len2; /* squared distance between the endpoints */
-
-/* number of reference dots taken from each curve */
-#define NREFDOTS 3
-
- double dots[NREFDOTS][2]; /* reference dots */
-
- int flags; /* flags for gentry and tits joint to the next gentry */
-/* a vertical or horizontal line may be in 2 quadrants at once */
-#define GEXF_QUL 0x00000001 /* in up-left quadrant */
-#define GEXF_QUR 0x00000002 /* in up-right quadrant */
-#define GEXF_QDR 0x00000004 /* in down-right quadrant */
-#define GEXF_QDL 0x00000008 /* in down-left quadrant */
-#define GEXF_QMASK 0x0000000F /* quadrant mask */
-
-/* if a line is nearly vertical or horizontal, we remember that idealized quartant too */
-#define GEXF_QTO_IDEAL(f) (((f)&0xF)<<4)
-#define GEXF_QFROM_IDEAL(f) (((f)&0xF0)>>4)
-#define GEXF_IDQ_L 0x00000090 /* left */
-#define GEXF_IDQ_R 0x00000060 /* right */
-#define GEXF_IDQ_U 0x00000030 /* up */
-#define GEXF_IDQ_D 0x000000C0 /* down */
-
-/* possibly can be joined with conditions:
- * (in order of increasing preference, the numeric order is important)
- */
-#define GEXF_JLINE 0x00000100 /* into one line */
-#define GEXF_JIGN 0x00000200 /* if one entry's tangent angle is ignored */
-#define GEXF_JID 0x00000400 /* if one entry is idealized to hor/vert */
-#define GEXF_JFLAT 0x00000800 /* if one entry is flattened */
-#define GEXF_JGOOD 0x00001000 /* perfectly, no additional maodifications */
-
-#define GEXF_JMASK 0x00001F00 /* the mask of all above */
-#define GEXF_JCVMASK 0x00001E00 /* the mask of all above except JLINE */
-
-/* which entry needs to be modified for conditional joining */
-#define GEXF_JIGN1 0x00002000
-#define GEXF_JIGN2 0x00004000
-#define GEXF_JIGNDIR(dir) (GEXF_JIGN1<<(dir))
-#define GEXF_JID1 0x00008000
-#define GEXF_JID2 0x00010000
-#define GEXF_JIDDIR(dir) (GEXF_JID1<<(dir))
-#define GEXF_JFLAT1 0x00020000
-#define GEXF_JFLAT2 0x00040000
-#define GEXF_JFLATDIR(dir) (GEXF_JFLAT1<<(dir))
-
-#define GEXF_VERT 0x00100000 /* is nearly vertical */
-#define GEXF_HOR 0x00200000 /* is nearly horizontal */
-#define GEXF_FLAT 0x00400000 /* is nearly flat */
-
-#define GEXF_VDOTS 0x01000000 /* the dots are valid */
-
- signed char isd[2 /*X,Y*/]; /* signs of the sizes */
-};
-typedef struct gex_con GEX_CON;
-
-/* convenience macros */
-#define X_CON(ge) ((GEX_CON *)((ge)->ext))
-#define X_CON_D(ge) (X_CON(ge)->d)
-#define X_CON_DX(ge) (X_CON(ge)->d[0])
-#define X_CON_DY(ge) (X_CON(ge)->d[1])
-#define X_CON_ISD(ge) (X_CON(ge)->isd)
-#define X_CON_ISDX(ge) (X_CON(ge)->isd[0])
-#define X_CON_ISDY(ge) (X_CON(ge)->isd[1])
-#define X_CON_SIN2(ge) (X_CON(ge)->sin2)
-#define X_CON_LEN2(ge) (X_CON(ge)->len2)
-#define X_CON_F(ge) (X_CON(ge)->flags)
-
-/* performance statistics about guessing the concise curves */
-static int ggoodcv=0, ggoodcvdots=0, gbadcv=0, gbadcvdots=0;
-
-int stdhw, stdvw; /* dominant stems widths */
-int stemsnaph[12], stemsnapv[12]; /* most typical stem width */
-
-int bluevalues[14];
-int nblues;
-int otherblues[10];
-int notherb;
-int bbox[4]; /* the FontBBox array */
-double italic_angle;
-
-GLYPH *glyph_list;
-int encoding[ENCTABSZ]; /* inverse of glyph[].char_no */
-int kerning_pairs = 0;
-
-/* prototypes */
-static void fixcvdir( GENTRY * ge, int dir);
-static void fixcvends( GENTRY * ge);
-static int fgetcvdir( GENTRY * ge);
-static int igetcvdir( GENTRY * ge);
-static int fiszigzag( GENTRY *ge);
-static int iiszigzag( GENTRY *ge);
-static GENTRY * freethisge( GENTRY *ge);
-static void addgeafter( GENTRY *oge, GENTRY *nge );
-static GENTRY * newgentry( int flags);
-static void debugstems( char *name, STEM * hstems, int nhs, STEM * vstems, int nvs);
-static int addbluestems( STEM *s, int n);
-static void sortstems( STEM * s, int n);
-static int stemoverlap( STEM * s1, STEM * s2);
-static int steminblue( STEM *s);
-static void markbluestems( STEM *s, int nold);
-static int joinmainstems( STEM * s, int nold, int useblues);
-static void joinsubstems( STEM * s, short *pairs, int nold, int useblues);
-static void fixendpath( GENTRY *ge);
-static void fdelsmall( GLYPH *g, double minlen);
-static void alloc_gex_con( GENTRY *ge);
-static double fjointsin2( GENTRY *ge1, GENTRY *ge2);
-#if 0
-static double fcvarea( GENTRY *ge);
-#endif
-static double fcvval( GENTRY *ge, int axis, double t);
-static void fsampledots( GENTRY *ge, double dots[][2], int ndots);
-static void fnormalizege( GENTRY *ge);
-static void fanalyzege( GENTRY *ge);
-static void fanalyzejoint( GENTRY *ge);
-static void fconcisecontour( GLYPH *g, GENTRY *ge);
-static double fclosegap( GENTRY *from, GENTRY *to, int axis,
- double gap, double *ret);
-
-int
-isign(
- int x
-)
-{
- if (x > 0)
- return 1;
- else if (x < 0)
- return -1;
- else
- return 0;
-}
-
-int
-fsign(
- double x
-)
-{
- if (x > 0.0)
- return 1;
- else if (x < 0.0)
- return -1;
- else
- return 0;
-}
-
-static GENTRY *
-newgentry(
- int flags
-)
-{
- GENTRY *ge;
-
- ge = calloc(1, sizeof(GENTRY));
-
- if (ge == 0) {
- fprintf(stderr, "***** Memory allocation error *****\n");
- exit(255);
- }
- ge->stemid = -1;
- ge->flags = flags;
- /* the rest is set to 0 by calloc() */
- return ge;
-}
-
-/*
- * Routines to print out Postscript functions with optimization
- */
-
-void
-rmoveto(
- int dx,
- int dy
-)
-{
- if (optimize && dx == 0)
- fprintf(pfa_file, "%d vmoveto\n", dy);
- else if (optimize && dy == 0)
- fprintf(pfa_file, "%d hmoveto\n", dx);
- else
- fprintf(pfa_file, "%d %d rmoveto\n", dx, dy);
-}
-
-void
-rlineto(
- int dx,
- int dy
-)
-{
- if (optimize && dx == 0 && dy == 0) /* for special pathologic
- * case */
- return;
- else if (optimize && dx == 0)
- fprintf(pfa_file, "%d vlineto\n", dy);
- else if (optimize && dy == 0)
- fprintf(pfa_file, "%d hlineto\n", dx);
- else
- fprintf(pfa_file, "%d %d rlineto\n", dx, dy);
-}
-
-void
-rrcurveto(
- int dx1,
- int dy1,
- int dx2,
- int dy2,
- int dx3,
- int dy3
-)
-{
- /* first two ifs are for crazy cases that occur surprisingly often */
- if (optimize && dx1 == 0 && dx2 == 0 && dx3 == 0)
- rlineto(0, dy1 + dy2 + dy3);
- else if (optimize && dy1 == 0 && dy2 == 0 && dy3 == 0)
- rlineto(dx1 + dx2 + dx3, 0);
- else if (optimize && dy1 == 0 && dx3 == 0)
- fprintf(pfa_file, "%d %d %d %d hvcurveto\n",
- dx1, dx2, dy2, dy3);
- else if (optimize && dx1 == 0 && dy3 == 0)
- fprintf(pfa_file, "%d %d %d %d vhcurveto\n",
- dy1, dx2, dy2, dx3);
- else
- fprintf(pfa_file, "%d %d %d %d %d %d rrcurveto\n",
- dx1, dy1, dx2, dy2, dx3, dy3);
-}
-
-void
-closepath(void)
-{
- fprintf(pfa_file, "closepath\n");
-}
-
-/*
- * Many of the path processing routines exist (or will exist) in
- * both floating-point and integer version. Fimally most of the
- * processing will go in floating point and the integer processing
- * will become legacy.
- * The names of floating routines start with f, names of integer
- * routines start with i, and those old routines existing in one
- * version only have no such prefix at all.
- */
-
-/*
-** Routine that checks integrity of the path, for debugging
-*/
-
-void
-assertpath(
- GENTRY * from,
- char *file,
- int line,
- char *name
-)
-{
- GENTRY *first, *pe, *ge;
- int isfloat;
-
- if(from==0)
- return;
- isfloat = (from->flags & GEF_FLOAT);
- pe = from->prev;
- for (ge = from; ge != 0; pe = ge, ge = ge->next) {
- if( (ge->flags & GEF_FLOAT) ^ isfloat ) {
- fprintf(stderr, "**! assertpath: called from %s line %d (%s) ****\n", file, line, name);
- fprintf(stderr, "float flag changes from %s to %s at 0x%p (type %c, prev type %c)\n",
- (isfloat ? "TRUE" : "FALSE"), (isfloat ? "FALSE" : "TRUE"), ge, ge->type, pe->type);
- abort();
- }
- if (pe != ge->prev) {
- fprintf(stderr, "**! assertpath: called from %s line %d (%s) ****\n", file, line, name);
- fprintf(stderr, "unidirectional chain 0x%x -next-> 0x%x -prev-> 0x%x \n",
- pe, ge, ge->prev);
- abort();
- }
-
- switch(ge->type) {
- case GE_MOVE:
- break;
- case GE_PATH:
- if (ge->prev == 0) {
- fprintf(stderr, "**! assertpath: called from %s line %d (%s) ****\n", file, line, name);
- fprintf(stderr, "empty path at 0x%x \n", ge);
- abort();
- }
- break;
- case GE_LINE:
- case GE_CURVE:
- if(ge->frwd->bkwd != ge) {
- fprintf(stderr, "**! assertpath: called from %s line %d (%s) ****\n", file, line, name);
- fprintf(stderr, "unidirectional chain 0x%x -frwd-> 0x%x -bkwd-> 0x%x \n",
- ge, ge->frwd, ge->frwd->bkwd);
- abort();
- }
- if(ge->prev->type == GE_MOVE) {
- first = ge;
- if(ge->bkwd->next->type != GE_PATH) {
- fprintf(stderr, "**! assertpath: called from %s line %d (%s) ****\n", file, line, name);
- fprintf(stderr, "broken first backlink 0x%x -bkwd-> 0x%x -next-> 0x%x \n",
- ge, ge->bkwd, ge->bkwd->next);
- abort();
- }
- }
- if(ge->next->type == GE_PATH) {
- if(ge->frwd != first) {
- fprintf(stderr, "**! assertpath: called from %s line %d (%s) ****\n", file, line, name);
- fprintf(stderr, "broken loop 0x%x -...-> 0x%x -frwd-> 0x%x \n",
- first, ge, ge->frwd);
- abort();
- }
- }
- break;
- }
-
- }
-}
-
-void
-assertisfloat(
- GLYPH *g,
- char *msg
-)
-{
- if( !(g->flags & GF_FLOAT) ) {
- fprintf(stderr, "**! Glyph %s is not float: %s\n", g->name, msg);
- abort();
- }
- if(g->lastentry) {
- if( !(g->lastentry->flags & GEF_FLOAT) ) {
- fprintf(stderr, "**! Glyphs %s last entry is int: %s\n", g->name, msg);
- abort();
- }
- }
-}
-
-void
-assertisint(
- GLYPH *g,
- char *msg
-)
-{
- if( (g->flags & GF_FLOAT) ) {
- fprintf(stderr, "**! Glyph %s is not int: %s\n", g->name, msg);
- abort();
- }
- if(g->lastentry) {
- if( (g->lastentry->flags & GEF_FLOAT) ) {
- fprintf(stderr, "**! Glyphs %s last entry is float: %s\n", g->name, msg);
- abort();
- }
- }
-}
-
-
-/*
- * Routines to save the generated data about glyph
- */
-
-void
-fg_rmoveto(
- GLYPH * g,
- double x,
- double y)
-{
- GENTRY *oge;
-
- if (ISDBG(BUILDG))
- fprintf(stderr, "%s: f rmoveto(%g, %g)\n", g->name, x, y);
-
- assertisfloat(g, "adding float MOVE");
-
- if ((oge = g->lastentry) != 0) {
- if (oge->type == GE_MOVE) { /* just eat up the first move */
- oge->fx3 = x;
- oge->fy3 = y;
- } else if (oge->type == GE_LINE || oge->type == GE_CURVE) {
- fprintf(stderr, "Glyph %s: MOVE in middle of path\n", g->name);
- } else {
- GENTRY *nge;
-
- nge = newgentry(GEF_FLOAT);
- nge->type = GE_MOVE;
- nge->fx3 = x;
- nge->fy3 = y;
-
- oge->next = nge;
- nge->prev = oge;
- g->lastentry = nge;
- }
- } else {
- GENTRY *nge;
-
- nge = newgentry(GEF_FLOAT);
- nge->type = GE_MOVE;
- nge->fx3 = x;
- nge->fy3 = y;
- nge->bkwd = (GENTRY*)&g->entries;
- g->entries = g->lastentry = nge;
- }
-
- if (0 && ISDBG(BUILDG))
- dumppaths(g, NULL, NULL);
-}
-
-void
-ig_rmoveto(
- GLYPH * g,
- int x,
- int y)
-{
- GENTRY *oge;
-
- if (ISDBG(BUILDG))
- fprintf(stderr, "%s: i rmoveto(%d, %d)\n", g->name, x, y);
-
- assertisint(g, "adding int MOVE");
-
- if ((oge = g->lastentry) != 0) {
- if (oge->type == GE_MOVE) { /* just eat up the first move */
- oge->ix3 = x;
- oge->iy3 = y;
- } else if (oge->type == GE_LINE || oge->type == GE_CURVE) {
- fprintf(stderr, "Glyph %s: MOVE in middle of path, ignored\n", g->name);
- } else {
- GENTRY *nge;
-
- nge = newgentry(0);
- nge->type = GE_MOVE;
- nge->ix3 = x;
- nge->iy3 = y;
-
- oge->next = nge;
- nge->prev = oge;
- g->lastentry = nge;
- }
- } else {
- GENTRY *nge;
-
- nge = newgentry(0);
- nge->type = GE_MOVE;
- nge->ix3 = x;
- nge->iy3 = y;
- nge->bkwd = (GENTRY*)&g->entries;
- g->entries = g->lastentry = nge;
- }
-
-}
-
-void
-fg_rlineto(
- GLYPH * g,
- double x,
- double y)
-{
- GENTRY *oge, *nge;
-
- if (ISDBG(BUILDG))
- fprintf(stderr, "%s: f rlineto(%g, %g)\n", g->name, x, y);
-
- assertisfloat(g, "adding float LINE");
-
- nge = newgentry(GEF_FLOAT);
- nge->type = GE_LINE;
- nge->fx3 = x;
- nge->fy3 = y;
-
- if ((oge = g->lastentry) != 0) {
- if (x == oge->fx3 && y == oge->fy3) { /* empty line */
- /* ignore it or we will get in troubles later */
- free(nge);
- return;
- }
- if (g->path == 0) {
- g->path = nge;
- nge->bkwd = nge->frwd = nge;
- } else {
- oge->frwd = nge;
- nge->bkwd = oge;
- g->path->bkwd = nge;
- nge->frwd = g->path;
- }
-
- oge->next = nge;
- nge->prev = oge;
- g->lastentry = nge;
- } else {
- WARNING_1 fprintf(stderr, "Glyph %s: LINE outside of path\n", g->name);
- free(nge);
- }
-
- if (0 && ISDBG(BUILDG))
- dumppaths(g, NULL, NULL);
-}
-
-void
-ig_rlineto(
- GLYPH * g,
- int x,
- int y)
-{
- GENTRY *oge, *nge;
-
- if (ISDBG(BUILDG))
- fprintf(stderr, "%s: i rlineto(%d, %d)\n", g->name, x, y);
-
- assertisint(g, "adding int LINE");
-
- nge = newgentry(0);
- nge->type = GE_LINE;
- nge->ix3 = x;
- nge->iy3 = y;
-
- if ((oge = g->lastentry) != 0) {
- if (x == oge->ix3 && y == oge->iy3) { /* empty line */
- /* ignore it or we will get in troubles later */
- free(nge);
- return;
- }
- if (g->path == 0) {
- g->path = nge;
- nge->bkwd = nge->frwd = nge;
- } else {
- oge->frwd = nge;
- nge->bkwd = oge;
- g->path->bkwd = nge;
- nge->frwd = g->path;
- }
-
- oge->next = nge;
- nge->prev = oge;
- g->lastentry = nge;
- } else {
- WARNING_1 fprintf(stderr, "Glyph %s: LINE outside of path\n", g->name);
- free(nge);
- }
-
-}
-
-void
-fg_rrcurveto(
- GLYPH * g,
- double x1,
- double y1,
- double x2,
- double y2,
- double x3,
- double y3)
-{
- GENTRY *oge, *nge;
-
- oge = g->lastentry;
-
- if (ISDBG(BUILDG))
- fprintf(stderr, "%s: f rrcurveto(%g, %g, %g, %g, %g, %g)\n"
- ,g->name, x1, y1, x2, y2, x3, y3);
-
- assertisfloat(g, "adding float CURVE");
-
- if (oge && oge->fx3 == x1 && x1 == x2 && x2 == x3) /* check if it's
- * actually a line */
- fg_rlineto(g, x1, y3);
- else if (oge && oge->fy3 == y1 && y1 == y2 && y2 == y3)
- fg_rlineto(g, x3, y1);
- else {
- nge = newgentry(GEF_FLOAT);
- nge->type = GE_CURVE;
- nge->fx1 = x1;
- nge->fy1 = y1;
- nge->fx2 = x2;
- nge->fy2 = y2;
- nge->fx3 = x3;
- nge->fy3 = y3;
-
- if (oge != 0) {
- if (x3 == oge->fx3 && y3 == oge->fy3) {
- free(nge); /* consider this curve empty */
- /* ignore it or we will get in troubles later */
- return;
- }
- if (g->path == 0) {
- g->path = nge;
- nge->bkwd = nge->frwd = nge;
- } else {
- oge->frwd = nge;
- nge->bkwd = oge;
- g->path->bkwd = nge;
- nge->frwd = g->path;
- }
-
- oge->next = nge;
- nge->prev = oge;
- g->lastentry = nge;
- } else {
- WARNING_1 fprintf(stderr, "Glyph %s: CURVE outside of path\n", g->name);
- free(nge);
- }
- }
-
- if (0 && ISDBG(BUILDG))
- dumppaths(g, NULL, NULL);
-}
-
-void
-ig_rrcurveto(
- GLYPH * g,
- int x1,
- int y1,
- int x2,
- int y2,
- int x3,
- int y3)
-{
- GENTRY *oge, *nge;
-
- oge = g->lastentry;
-
- if (ISDBG(BUILDG))
- fprintf(stderr, "%s: i rrcurveto(%d, %d, %d, %d, %d, %d)\n"
- ,g->name, x1, y1, x2, y2, x3, y3);
-
- assertisint(g, "adding int CURVE");
-
- if (oge && oge->ix3 == x1 && x1 == x2 && x2 == x3) /* check if it's
- * actually a line */
- ig_rlineto(g, x1, y3);
- else if (oge && oge->iy3 == y1 && y1 == y2 && y2 == y3)
- ig_rlineto(g, x3, y1);
- else {
- nge = newgentry(0);
- nge->type = GE_CURVE;
- nge->ix1 = x1;
- nge->iy1 = y1;
- nge->ix2 = x2;
- nge->iy2 = y2;
- nge->ix3 = x3;
- nge->iy3 = y3;
-
- if (oge != 0) {
- if (x3 == oge->ix3 && y3 == oge->iy3) {
- free(nge); /* consider this curve empty */
- /* ignore it or we will get in troubles later */
- return;
- }
- if (g->path == 0) {
- g->path = nge;
- nge->bkwd = nge->frwd = nge;
- } else {
- oge->frwd = nge;
- nge->bkwd = oge;
- g->path->bkwd = nge;
- nge->frwd = g->path;
- }
-
- oge->next = nge;
- nge->prev = oge;
- g->lastentry = nge;
- } else {
- WARNING_1 fprintf(stderr, "Glyph %s: CURVE outside of path\n", g->name);
- free(nge);
- }
- }
-}
-
-void
-g_closepath(
- GLYPH * g
-)
-{
- GENTRY *oge, *nge;
-
- if (ISDBG(BUILDG))
- fprintf(stderr, "%s: closepath\n", g->name);
-
- oge = g->lastentry;
-
- if (g->path == 0) {
- WARNING_1 fprintf(stderr, "Warning: **** closepath on empty path in glyph \"%s\" ****\n",
- g->name);
- if (oge == 0) {
- WARNING_1 fprintf(stderr, "No previois entry\n");
- } else {
- WARNING_1 fprintf(stderr, "Previous entry type: %c\n", oge->type);
- if (oge->type == GE_MOVE) {
- g->lastentry = oge->prev;
- if (oge->prev == 0)
- g->entries = 0;
- else
- g->lastentry->next = 0;
- free(oge);
- }
- }
- return;
- }
-
- nge = newgentry(oge->flags & GEF_FLOAT); /* keep the same type */
- nge->type = GE_PATH;
-
- g->path = 0;
-
- oge->next = nge;
- nge->prev = oge;
- g->lastentry = nge;
-
- if (0 && ISDBG(BUILDG))
- dumppaths(g, NULL, NULL);
-}
-
-/*
- * * SB * Routines to smooth and fix the glyphs
- */
-
-/*
-** we don't want to see the curves with coinciding middle and
-** outer points
-*/
-
-static void
-fixcvends(
- GENTRY * ge
-)
-{
- int dx, dy;
- int x0, y0, x1, y1, x2, y2, x3, y3;
-
- if (ge->type != GE_CURVE)
- return;
-
- if(ge->flags & GEF_FLOAT) {
- fprintf(stderr, "**! fixcvends(0x%x) on floating entry, ABORT\n", ge);
- abort(); /* dump core */
- }
-
- x0 = ge->prev->ix3;
- y0 = ge->prev->iy3;
- x1 = ge->ix1;
- y1 = ge->iy1;
- x2 = ge->ix2;
- y2 = ge->iy2;
- x3 = ge->ix3;
- y3 = ge->iy3;
-
-
- /* look at the start of the curve */
- if (x1 == x0 && y1 == y0) {
- dx = x2 - x1;
- dy = y2 - y1;
-
- if ((dx == 0 && dy == 0)
- || (x2 == x3 && y2 == y3)) {
- /* Oops, we actually have a straight line */
- /*
- * if it's small, we hope that it will get optimized
- * later
- */
- if (abs(x3 - x0) <= 2 || abs(y3 - y0) <= 2) {
- ge->ix1 = x3;
- ge->iy1 = y3;
- ge->ix2 = x0;
- ge->iy2 = y0;
- } else {/* just make it a line */
- ge->type = GE_LINE;
- }
- } else {
- if (abs(dx) < 4 && abs(dy) < 4) { /* consider it very
- * small */
- ge->ix1 = x2;
- ge->iy1 = y2;
- } else if (abs(dx) < 8 && abs(dy) < 8) { /* consider it small */
- ge->ix1 += dx / 2;
- ge->iy1 += dy / 2;
- } else {
- ge->ix1 += dx / 4;
- ge->iy1 += dy / 4;
- }
- /* make sure that it's still on the same side */
- if (abs(x3 - x0) * abs(dy) < abs(y3 - y0) * abs(dx)) {
- if (abs(x3 - x0) * abs(ge->iy1 - y0) > abs(y3 - y0) * abs(ge->ix1 - x0))
- ge->ix1 += isign(dx);
- } else {
- if (abs(x3 - x0) * abs(ge->iy1 - y0) < abs(y3 - y0) * abs(ge->ix1 - x0))
- ge->iy1 += isign(dy);
- }
-
- ge->ix2 += (x3 - x2) / 8;
- ge->iy2 += (y3 - y2) / 8;
- /* make sure that it's still on the same side */
- if (abs(x3 - x0) * abs(y3 - y2) < abs(y3 - y0) * abs(x3 - x2)) {
- if (abs(x3 - x0) * abs(y3 - ge->iy2) > abs(y3 - y0) * abs(x3 - ge->ix2))
- ge->iy1 -= isign(y3 - y2);
- } else {
- if (abs(x3 - x0) * abs(y3 - ge->iy2) < abs(y3 - y0) * abs(x3 - ge->ix2))
- ge->ix1 -= isign(x3 - x2);
- }
-
- }
- } else if (x2 == x3 && y2 == y3) {
- dx = x1 - x2;
- dy = y1 - y2;
-
- if (dx == 0 && dy == 0) {
- /* Oops, we actually have a straight line */
- /*
- * if it's small, we hope that it will get optimized
- * later
- */
- if (abs(x3 - x0) <= 2 || abs(y3 - y0) <= 2) {
- ge->ix1 = x3;
- ge->iy1 = y3;
- ge->ix2 = x0;
- ge->iy2 = y0;
- } else {/* just make it a line */
- ge->type = GE_LINE;
- }
- } else {
- if (abs(dx) < 4 && abs(dy) < 4) { /* consider it very
- * small */
- ge->ix2 = x1;
- ge->iy2 = y1;
- } else if (abs(dx) < 8 && abs(dy) < 8) { /* consider it small */
- ge->ix2 += dx / 2;
- ge->iy2 += dy / 2;
- } else {
- ge->ix2 += dx / 4;
- ge->iy2 += dy / 4;
- }
- /* make sure that it's still on the same side */
- if (abs(x3 - x0) * abs(dy) < abs(y3 - y0) * abs(dx)) {
- if (abs(x3 - x0) * abs(ge->iy2 - y3) > abs(y3 - y0) * abs(ge->ix2 - x3))
- ge->ix2 += isign(dx);
- } else {
- if (abs(x3 - x0) * abs(ge->iy2 - y3) < abs(y3 - y0) * abs(ge->ix2 - x3))
- ge->iy2 += isign(dy);
- }
-
- ge->ix1 += (x0 - x1) / 8;
- ge->iy1 += (y0 - y1) / 8;
- /* make sure that it's still on the same side */
- if (abs(x3 - x0) * abs(y0 - y1) < abs(y3 - y0) * abs(x0 - x1)) {
- if (abs(x3 - x0) * abs(y0 - ge->iy1) > abs(y3 - y0) * abs(x0 - ge->ix1))
- ge->iy1 -= isign(y0 - y1);
- } else {
- if (abs(x3 - x0) * abs(y0 - ge->iy1) < abs(y3 - y0) * abs(x0 - ge->ix1))
- ge->ix1 -= isign(x0 - x1);
- }
-
- }
- }
-}
-
-/*
-** After transformations we want to make sure that the resulting
-** curve is going in the same quadrant as the original one,
-** because rounding errors introduced during transformations
-** may make the result completeley wrong.
-**
-** `dir' argument describes the direction of the original curve,
-** it is the superposition of two values for the front and
-** rear ends of curve:
-**
-** >EQUAL - goes over the line connecting the ends
-** =EQUAL - coincides with the line connecting the ends
-** <EQUAL - goes under the line connecting the ends
-**
-** See CVDIR_* for exact definitions.
-*/
-
-static void
-fixcvdir(
- GENTRY * ge,
- int dir
-)
-{
- int a, b, c, d;
- double kk, kk1, kk2;
- int changed;
- int fdir, rdir;
-
- if(ge->flags & GEF_FLOAT) {
- fprintf(stderr, "**! fixcvdir(0x%x) on floating entry, ABORT\n", ge);
- abort(); /* dump core */
- }
-
- fdir = (dir & CVDIR_FRONT) - CVDIR_FEQUAL;
- if ((dir & CVDIR_REAR) == CVDIR_RSAME)
- rdir = fdir; /* we need only isign, exact value doesn't matter */
- else
- rdir = (dir & CVDIR_REAR) - CVDIR_REQUAL;
-
- fixcvends(ge);
-
- c = isign(ge->ix3 - ge->prev->ix3); /* note the direction of
- * curve */
- d = isign(ge->iy3 - ge->prev->iy3);
-
- a = ge->iy3 - ge->prev->iy3;
- b = ge->ix3 - ge->prev->ix3;
- kk = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
- a = ge->iy1 - ge->prev->iy3;
- b = ge->ix1 - ge->prev->ix3;
- kk1 = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
- a = ge->iy3 - ge->iy2;
- b = ge->ix3 - ge->ix2;
- kk2 = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
-
- changed = 1;
- while (changed) {
- if (ISDBG(FIXCVDIR)) {
- /* for debugging */
- fprintf(stderr, "fixcvdir %d %d (%d %d %d %d %d %d) %f %f %f\n",
- fdir, rdir,
- ge->ix1 - ge->prev->ix3,
- ge->iy1 - ge->prev->iy3,
- ge->ix2 - ge->ix1,
- ge->iy2 - ge->iy1,
- ge->ix3 - ge->ix2,
- ge->iy3 - ge->iy2,
- kk1, kk, kk2);
- }
- changed = 0;
-
- if (fdir > 0) {
- if (kk1 > kk) { /* the front end has problems */
- if (c * (ge->ix1 - ge->prev->ix3) > 0) {
- ge->ix1 -= c;
- changed = 1;
- } if (d * (ge->iy2 - ge->iy1) > 0) {
- ge->iy1 += d;
- changed = 1;
- }
- /* recalculate the coefficients */
- a = ge->iy3 - ge->prev->iy3;
- b = ge->ix3 - ge->prev->ix3;
- kk = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
- a = ge->iy1 - ge->prev->iy3;
- b = ge->ix1 - ge->prev->ix3;
- kk1 = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
- }
- } else if (fdir < 0) {
- if (kk1 < kk) { /* the front end has problems */
- if (c * (ge->ix2 - ge->ix1) > 0) {
- ge->ix1 += c;
- changed = 1;
- } if (d * (ge->iy1 - ge->prev->iy3) > 0) {
- ge->iy1 -= d;
- changed = 1;
- }
- /* recalculate the coefficients */
- a = ge->iy1 - ge->prev->iy3;
- b = ge->ix1 - ge->prev->ix3;
- kk1 = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
- a = ge->iy3 - ge->prev->iy3;
- b = ge->ix3 - ge->prev->ix3;
- kk = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
- }
- }
- if (rdir > 0) {
- if (kk2 < kk) { /* the rear end has problems */
- if (c * (ge->ix2 - ge->ix1) > 0) {
- ge->ix2 -= c;
- changed = 1;
- } if (d * (ge->iy3 - ge->iy2) > 0) {
- ge->iy2 += d;
- changed = 1;
- }
- /* recalculate the coefficients */
- a = ge->iy3 - ge->prev->iy3;
- b = ge->ix3 - ge->prev->ix3;
- kk = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
- a = ge->iy3 - ge->iy2;
- b = ge->ix3 - ge->ix2;
- kk2 = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
- }
- } else if (rdir < 0) {
- if (kk2 > kk) { /* the rear end has problems */
- if (c * (ge->ix3 - ge->ix2) > 0) {
- ge->ix2 += c;
- changed = 1;
- } if (d * (ge->iy2 - ge->iy1) > 0) {
- ge->iy2 -= d;
- changed = 1;
- }
- /* recalculate the coefficients */
- a = ge->iy3 - ge->prev->iy3;
- b = ge->ix3 - ge->prev->ix3;
- kk = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
- a = ge->iy3 - ge->iy2;
- b = ge->ix3 - ge->ix2;
- kk2 = fabs(a == 0 ? (b == 0 ? 1. : 100000.) : ((double) b / (double) a));
- }
- }
- }
- fixcvends(ge);
-}
-
-/* Get the directions of ends of curve for further usage */
-
-/* expects that the previous element is also float */
-
-static int
-fgetcvdir(
- GENTRY * ge
-)
-{
- double a, b;
- double k, k1, k2;
- int dir = 0;
-
- if( !(ge->flags & GEF_FLOAT) ) {
- fprintf(stderr, "**! fgetcvdir(0x%x) on int entry, ABORT\n", ge);
- abort(); /* dump core */
- }
-
- a = fabs(ge->fy3 - ge->prev->fy3);
- b = fabs(ge->fx3 - ge->prev->fx3);
- k = a < FEPS ? (b < FEPS ? 1. : 100000.) : ( b / a);
-
- a = fabs(ge->fy1 - ge->prev->fy3);
- b = fabs(ge->fx1 - ge->prev->fx3);
- if(a < FEPS) {
- if(b < FEPS) {
- a = fabs(ge->fy2 - ge->prev->fy3);
- b = fabs(ge->fx2 - ge->prev->fx3);
- k1 = a < FEPS ? (b < FEPS ? k : 100000.) : ( b / a);
- } else
- k1 = FBIGVAL;
- } else
- k1 = b / a;
-
- a = fabs(ge->fy3 - ge->fy2);
- b = fabs(ge->fx3 - ge->fx2);
- if(a < FEPS) {
- if(b < FEPS) {
- a = fabs(ge->fy3 - ge->fy1);
- b = fabs(ge->fx3 - ge->fx1);
- k2 = a < FEPS ? (b < FEPS ? k : 100000.) : ( b / a);
- } else
- k2 = FBIGVAL;
- } else
- k2 = b / a;
-
- if(fabs(k1-k) < 0.0001)
- dir |= CVDIR_FEQUAL;
- else if (k1 < k)
- dir |= CVDIR_FUP;
- else
- dir |= CVDIR_FDOWN;
-
- if(fabs(k2-k) < 0.0001)
- dir |= CVDIR_REQUAL;
- else if (k2 > k)
- dir |= CVDIR_RUP;
- else
- dir |= CVDIR_RDOWN;
-
- return dir;
-}
-
-
-/* expects that the previous element is also int */
-
-static int
-igetcvdir(
- GENTRY * ge
-)
-{
- int a, b;
- double k, k1, k2;
- int dir = 0;
-
- if(ge->flags & GEF_FLOAT) {
- fprintf(stderr, "**! igetcvdir(0x%x) on floating entry, ABORT\n", ge);
- abort(); /* dump core */
- }
-
- a = ge->iy3 - ge->prev->iy3;
- b = ge->ix3 - ge->prev->ix3;
- k = (a == 0) ? (b == 0 ? 1. : 100000.) : fabs((double) b / (double) a);
-
- a = ge->iy1 - ge->prev->iy3;
- b = ge->ix1 - ge->prev->ix3;
- if(a == 0) {
- if(b == 0) {
- a = ge->iy2 - ge->prev->iy3;
- b = ge->ix2 - ge->prev->ix3;
- k1 = (a == 0) ? (b == 0 ? k : 100000.) : fabs((double) b / (double) a);
- } else
- k1 = FBIGVAL;
- } else
- k1 = fabs((double) b / (double) a);
-
- a = ge->iy3 - ge->iy2;
- b = ge->ix3 - ge->ix2;
- if(a == 0) {
- if(b == 0) {
- a = ge->iy3 - ge->iy1;
- b = ge->ix3 - ge->ix1;
- k2 = (a == 0) ? (b == 0 ? k : 100000.) : fabs((double) b / (double) a);
- } else
- k2 = FBIGVAL;
- } else
- k2 = fabs((double) b / (double) a);
-
- if(fabs(k1-k) < 0.0001)
- dir |= CVDIR_FEQUAL;
- else if (k1 < k)
- dir |= CVDIR_FUP;
- else
- dir |= CVDIR_FDOWN;
-
- if(fabs(k2-k) < 0.0001)
- dir |= CVDIR_REQUAL;
- else if (k2 > k)
- dir |= CVDIR_RUP;
- else
- dir |= CVDIR_RDOWN;
-
- return dir;
-}
-
-#if 0
-/* a function just to test the work of fixcvdir() */
-static void
-testfixcvdir(
- GLYPH * g
-)
-{
- GENTRY *ge;
- int dir;
-
- for (ge = g->entries; ge != 0; ge = ge->next) {
- if (ge->type == GE_CURVE) {
- dir = igetcvdir(ge);
- fixcvdir(ge, dir);
- }
- }
-}
-#endif
-
-static int
-iround(
- double val
-)
-{
- return (int) (val > 0 ? val + 0.5 : val - 0.5);
-}
-
-/* for debugging - dump the glyph
- * mark with a star the entries from start to end inclusive
- * (start == NULL means don't mark any, end == NULL means to the last)
- */
-
-void
-dumppaths(
- GLYPH *g,
- GENTRY *start,
- GENTRY *end
-)
-{
- GENTRY *ge;
- int i;
- char mark=' ';
-
- fprintf(stderr, "Glyph %s:\n", g->name);
-
- /* now do the conversion */
- for(ge = g->entries; ge != 0; ge = ge->next) {
- if(ge == start)
- mark = '*';
- fprintf(stderr, " %c %8x", mark, ge);
- switch(ge->type) {
- case GE_MOVE:
- case GE_LINE:
- if(ge->flags & GEF_FLOAT)
- fprintf(stderr," %c float (%g, %g)\n", ge->type, ge->fx3, ge->fy3);
- else
- fprintf(stderr," %c int (%d, %d)\n", ge->type, ge->ix3, ge->iy3);
- break;
- case GE_CURVE:
- if(ge->flags & GEF_FLOAT) {
- fprintf(stderr," C float ");
- for(i=0; i<3; i++)
- fprintf(stderr,"(%g, %g) ", ge->fxn[i], ge->fyn[i]);
- fprintf(stderr,"\n");
- } else {
- fprintf(stderr," C int ");
- for(i=0; i<3; i++)
- fprintf(stderr,"(%d, %d) ", ge->ixn[i], ge->iyn[i]);
- fprintf(stderr,"\n");
- }
- break;
- default:
- fprintf(stderr, " %c\n", ge->type);
- break;
- }
- if(ge == end)
- mark = ' ';
- }
-}
-
-/*
- * Routine that converts all entries in the path from float to int
- */
-
-void
-pathtoint(
- GLYPH *g
-)
-{
- GENTRY *ge;
- int x[3], y[3];
- int i;
-
-
- if(ISDBG(TOINT))
- fprintf(stderr, "TOINT: glyph %s\n", g->name);
- assertisfloat(g, "converting path to int\n");
-
- fdelsmall(g, 1.0); /* get rid of sub-pixel contours */
- assertpath(g->entries, __FILE__, __LINE__, g->name);
-
- /* 1st pass, collect the directions of the curves: have
- * to do that in advance, while everyting is float
- */
- for(ge = g->entries; ge != 0; ge = ge->next) {
- if( !(ge->flags & GEF_FLOAT) ) {
- fprintf(stderr, "**! glyphs %s has int entry, found in conversion to int\n",
- g->name);
- exit(1);
- }
- if(ge->type == GE_CURVE) {
- ge->dir = fgetcvdir(ge);
- }
- }
-
- /* now do the conversion */
- for(ge = g->entries; ge != 0; ge = ge->next) {
- switch(ge->type) {
- case GE_MOVE:
- case GE_LINE:
- if(ISDBG(TOINT))
- fprintf(stderr," %c float x=%g y=%g\n", ge->type, ge->fx3, ge->fy3);
- x[0] = iround(ge->fx3);
- y[0] = iround(ge->fy3);
- for(i=0; i<3; i++) { /* put some valid values everywhere, for convenience */
- ge->ixn[i] = x[0];
- ge->iyn[i] = y[0];
- }
- if(ISDBG(TOINT))
- fprintf(stderr," int x=%d y=%d\n", ge->ix3, ge->iy3);
- break;
- case GE_CURVE:
- if(ISDBG(TOINT))
- fprintf(stderr," %c float ", ge->type);
-
- for(i=0; i<3; i++) {
- if(ISDBG(TOINT))
- fprintf(stderr,"(%g, %g) ", ge->fxn[i], ge->fyn[i]);
- x[i] = iround(ge->fxn[i]);
- y[i] = iround(ge->fyn[i]);
- }
-
- if(ISDBG(TOINT))
- fprintf(stderr,"\n int ");
-
- for(i=0; i<3; i++) {
- ge->ixn[i] = x[i];
- ge->iyn[i] = y[i];
- if(ISDBG(TOINT))
- fprintf(stderr,"(%d, %d) ", ge->ixn[i], ge->iyn[i]);
- }
- ge->flags &= ~GEF_FLOAT; /* for fixcvdir */
- fixcvdir(ge, ge->dir);
-
- if(ISDBG(TOINT)) {
- fprintf(stderr,"\n fixed ");
- for(i=0; i<3; i++)
- fprintf(stderr,"(%d, %d) ", ge->ixn[i], ge->iyn[i]);
- fprintf(stderr,"\n");
- }
-
- break;
- }
- ge->flags &= ~GEF_FLOAT;
- }
- g->flags &= ~GF_FLOAT;
-}
-
-
-/* check whether we can fix up the curve to change its size by (dx,dy) */
-/* 0 means NO, 1 means YES */
-
-/* for float: if scaling would be under 10% */
-
-int
-fcheckcv(
- GENTRY * ge,
- double dx,
- double dy
-)
-{
- if( !(ge->flags & GEF_FLOAT) ) {
- fprintf(stderr, "**! fcheckcv(0x%x) on int entry, ABORT\n", ge);
- abort(); /* dump core */
- }
-
- if (ge->type != GE_CURVE)
- return 0;
-
- if( fabs(ge->fx3 - ge->prev->fx3) < fabs(dx) * 10 )
- return 0;
-
- if( fabs(ge->fy3 - ge->prev->fy3) < fabs(dy) * 10 )
- return 0;
-
- return 1;
-}
-
-/* for int: if won't create new zigzags at the ends */
-
-int
-icheckcv(
- GENTRY * ge,
- int dx,
- int dy
-)
-{
- int xdep, ydep;
-
- if(ge->flags & GEF_FLOAT) {
- fprintf(stderr, "**! icheckcv(0x%x) on floating entry, ABORT\n", ge);
- abort(); /* dump core */
- }
-
- if (ge->type != GE_CURVE)
- return 0;
-
- xdep = ge->ix3 - ge->prev->ix3;
- ydep = ge->iy3 - ge->prev->iy3;
-
- if (ge->type == GE_CURVE
- && (xdep * (xdep + dx)) > 0
- && (ydep * (ydep + dy)) > 0) {
- return 1;
- } else
- return 0;
-}
-
-/* float connect the ends of open contours */
-
-void
-fclosepaths(
- GLYPH * g
-)
-{
- GENTRY *ge, *fge, *xge, *nge;
- int i;
-
- assertisfloat(g, "fclosepaths float\n");
-
- for (xge = g->entries; xge != 0; xge = xge->next) {
- if( xge->type != GE_PATH )
- continue;
-
- ge = xge->prev;
- if(ge == 0 || (ge->type != GE_LINE && ge->type!= GE_CURVE)) {
- fprintf(stderr, "**! Glyph %s got empty path\n",
- g->name);
- exit(1);
- }
-
- fge = ge->frwd;
- if (fge->prev == 0 || fge->prev->type != GE_MOVE) {
- fprintf(stderr, "**! Glyph %s got strange beginning of path\n",
- g->name);
- exit(1);
- }
- fge = fge->prev;
- if (fge->fx3 != ge->fx3 || fge->fy3 != ge->fy3) {
- /* we have to fix this open path */
-
- WARNING_4 fprintf(stderr, "Glyph %s got path open by dx=%g dy=%g\n",
- g->name, fge->fx3 - ge->fx3, fge->fy3 - ge->fy3);
-
-
- /* add a new line */
- nge = newgentry(GEF_FLOAT);
- (*nge) = (*ge);
- nge->fx3 = fge->fx3;
- nge->fy3 = fge->fy3;
- nge->type = GE_LINE;
-
- addgeafter(ge, nge);
-
- if (fabs(ge->fx3 - fge->fx3) <= 2 && fabs(ge->fy3 - fge->fy3) <= 2) {
- /*
- * small change, try to get rid of the new entry
- */
-
- double df[2];
-
- for(i=0; i<2; i++) {
- df[i] = ge->fpoints[i][2] - fge->fpoints[i][2];
- df[i] = fclosegap(nge, nge, i, df[i], NULL);
- }
-
- if(df[0] == 0. && df[1] == 0.) {
- /* closed gap successfully, remove the added entry */
- freethisge(nge);
- }
- }
- }
- }
-}
-
-void
-smoothjoints(
- GLYPH * g
-)
-{
- GENTRY *ge, *ne;
- int dx1, dy1, dx2, dy2, k;
- int dir;
-
- return; /* this stuff seems to create problems */
-
- assertisint(g, "smoothjoints int");
-
- if (g->entries == 0) /* nothing to do */
- return;
-
- for (ge = g->entries->next; ge != 0; ge = ge->next) {
- ne = ge->frwd;
-
- /*
- * although there should be no one-line path * and any path
- * must end with CLOSEPATH, * nobody can say for sure
- */
-
- if (ge == ne || ne == 0)
- continue;
-
- /* now handle various joints */
-
- if (ge->type == GE_LINE && ne->type == GE_LINE) {
- dx1 = ge->ix3 - ge->prev->ix3;
- dy1 = ge->iy3 - ge->prev->iy3;
- dx2 = ne->ix3 - ge->ix3;
- dy2 = ne->iy3 - ge->iy3;
-
- /* check whether they have the same direction */
- /* and the same slope */
- /* then we can join them into one line */
-
- if (dx1 * dx2 >= 0 && dy1 * dy2 >= 0 && dx1 * dy2 == dy1 * dx2) {
- /* extend the previous line */
- ge->ix3 = ne->ix3;
- ge->iy3 = ne->iy3;
-
- /* and get rid of the next line */
- freethisge(ne);
- }
- } else if (ge->type == GE_LINE && ne->type == GE_CURVE) {
- fixcvends(ne);
-
- dx1 = ge->ix3 - ge->prev->ix3;
- dy1 = ge->iy3 - ge->prev->iy3;
- dx2 = ne->ix1 - ge->ix3;
- dy2 = ne->iy1 - ge->iy3;
-
- /* if the line is nearly horizontal and we can fix it */
- if (dx1 != 0 && 5 * abs(dy1) / abs(dx1) == 0
- && icheckcv(ne, 0, -dy1)
- && abs(dy1) <= 4) {
- dir = igetcvdir(ne);
- ge->iy3 -= dy1;
- ne->iy1 -= dy1;
- fixcvdir(ne, dir);
- if (ge->next != ne)
- ne->prev->iy3 -= dy1;
- dy1 = 0;
- } else if (dy1 != 0 && 5 * abs(dx1) / abs(dy1) == 0
- && icheckcv(ne, -dx1, 0)
- && abs(dx1) <= 4) {
- /* the same but vertical */
- dir = igetcvdir(ne);
- ge->ix3 -= dx1;
- ne->ix1 -= dx1;
- fixcvdir(ne, dir);
- if (ge->next != ne)
- ne->prev->ix3 -= dx1;
- dx1 = 0;
- }
- /*
- * if line is horizontal and curve begins nearly
- * horizontally
- */
- if (dy1 == 0 && dx2 != 0 && 5 * abs(dy2) / abs(dx2) == 0) {
- dir = igetcvdir(ne);
- ne->iy1 -= dy2;
- fixcvdir(ne, dir);
- dy2 = 0;
- } else if (dx1 == 0 && dy2 != 0 && 5 * abs(dx2) / abs(dy2) == 0) {
- /* the same but vertical */
- dir = igetcvdir(ne);
- ne->ix1 -= dx2;
- fixcvdir(ne, dir);
- dx2 = 0;
- }
- } else if (ge->type == GE_CURVE && ne->type == GE_LINE) {
- fixcvends(ge);
-
- dx1 = ge->ix3 - ge->ix2;
- dy1 = ge->iy3 - ge->iy2;
- dx2 = ne->ix3 - ge->ix3;
- dy2 = ne->iy3 - ge->iy3;
-
- /* if the line is nearly horizontal and we can fix it */
- if (dx2 != 0 && 5 * abs(dy2) / abs(dx2) == 0
- && icheckcv(ge, 0, dy2)
- && abs(dy2) <= 4) {
- dir = igetcvdir(ge);
- ge->iy3 += dy2;
- ge->iy2 += dy2;
- fixcvdir(ge, dir);
- if (ge->next != ne)
- ne->prev->iy3 += dy2;
- dy2 = 0;
- } else if (dy2 != 0 && 5 * abs(dx2) / abs(dy2) == 0
- && icheckcv(ge, dx2, 0)
- && abs(dx2) <= 4) {
- /* the same but vertical */
- dir = igetcvdir(ge);
- ge->ix3 += dx2;
- ge->ix2 += dx2;
- fixcvdir(ge, dir);
- if (ge->next != ne)
- ne->prev->ix3 += dx2;
- dx2 = 0;
- }
- /*
- * if line is horizontal and curve ends nearly
- * horizontally
- */
- if (dy2 == 0 && dx1 != 0 && 5 * abs(dy1) / abs(dx1) == 0) {
- dir = igetcvdir(ge);
- ge->iy2 += dy1;
- fixcvdir(ge, dir);
- dy1 = 0;
- } else if (dx2 == 0 && dy1 != 0 && 5 * abs(dx1) / abs(dy1) == 0) {
- /* the same but vertical */
- dir = igetcvdir(ge);
- ge->ix2 += dx1;
- fixcvdir(ge, dir);
- dx1 = 0;
- }
- } else if (ge->type == GE_CURVE && ne->type == GE_CURVE) {
- fixcvends(ge);
- fixcvends(ne);
-
- dx1 = ge->ix3 - ge->ix2;
- dy1 = ge->iy3 - ge->iy2;
- dx2 = ne->ix1 - ge->ix3;
- dy2 = ne->iy1 - ge->iy3;
-
- /*
- * check if we have a rather smooth joint at extremal
- * point
- */
- /* left or right extremal point */
- if (abs(dx1) <= 4 && abs(dx2) <= 4
- && dy1 != 0 && 5 * abs(dx1) / abs(dy1) == 0
- && dy2 != 0 && 5 * abs(dx2) / abs(dy2) == 0
- && ((ge->iy3 < ge->prev->iy3 && ne->iy3 < ge->iy3)
- || (ge->iy3 > ge->prev->iy3 && ne->iy3 > ge->iy3))
- && (ge->ix3 - ge->prev->ix3) * (ne->ix3 - ge->ix3) < 0
- ) {
- dir = igetcvdir(ge);
- ge->ix2 += dx1;
- dx1 = 0;
- fixcvdir(ge, dir);
- dir = igetcvdir(ne);
- ne->ix1 -= dx2;
- dx2 = 0;
- fixcvdir(ne, dir);
- }
- /* top or down extremal point */
- else if (abs(dy1) <= 4 && abs(dy2) <= 4
- && dx1 != 0 && 5 * abs(dy1) / abs(dx1) == 0
- && dx2 != 0 && 5 * abs(dy2) / abs(dx2) == 0
- && ((ge->ix3 < ge->prev->ix3 && ne->ix3 < ge->ix3)
- || (ge->ix3 > ge->prev->ix3 && ne->ix3 > ge->ix3))
- && (ge->iy3 - ge->prev->iy3) * (ne->iy3 - ge->iy3) < 0
- ) {
- dir = igetcvdir(ge);
- ge->iy2 += dy1;
- dy1 = 0;
- fixcvdir(ge, dir);
- dir = igetcvdir(ne);
- ne->iy1 -= dy2;
- dy2 = 0;
- fixcvdir(ne, dir);
- }
- /* or may be we just have a smooth junction */
- else if (dx1 * dx2 >= 0 && dy1 * dy2 >= 0
- && 10 * abs(k = abs(dx1 * dy2) - abs(dy1 * dx2)) < (abs(dx1 * dy2) + abs(dy1 * dx2))) {
- int tries[6][4];
- int results[6];
- int i, b;
-
- /* build array of changes we are going to try */
- /* uninitalized entries are 0 */
- if (k > 0) {
- static int t1[6][4] = {
- {0, 0, 0, 0},
- {-1, 0, 1, 0},
- {-1, 0, 0, 1},
- {0, -1, 1, 0},
- {0, -1, 0, 1},
- {-1, -1, 1, 1}};
- memcpy(tries, t1, sizeof tries);
- } else {
- static int t1[6][4] = {
- {0, 0, 0, 0},
- {1, 0, -1, 0},
- {1, 0, 0, -1},
- {0, 1, -1, 0},
- {0, 1, 0, -1},
- {1, 1, -1, -1}};
- memcpy(tries, t1, sizeof tries);
- }
-
- /* now try the changes */
- results[0] = abs(k);
- for (i = 1; i < 6; i++) {
- results[i] = abs((abs(dx1) + tries[i][0]) * (abs(dy2) + tries[i][1]) -
- (abs(dy1) + tries[i][2]) * (abs(dx2) + tries[i][3]));
- }
-
- /* and find the best try */
- k = abs(k);
- b = 0;
- for (i = 1; i < 6; i++)
- if (results[i] < k) {
- k = results[i];
- b = i;
- }
- /* and finally apply it */
- if (dx1 < 0)
- tries[b][0] = -tries[b][0];
- if (dy2 < 0)
- tries[b][1] = -tries[b][1];
- if (dy1 < 0)
- tries[b][2] = -tries[b][2];
- if (dx2 < 0)
- tries[b][3] = -tries[b][3];
-
- dir = igetcvdir(ge);
- ge->ix2 -= tries[b][0];
- ge->iy2 -= tries[b][2];
- fixcvdir(ge, dir);
- dir = igetcvdir(ne);
- ne->ix1 += tries[b][3];
- ne->iy1 += tries[b][1];
- fixcvdir(ne, dir);
- }
- }
- }
-}
-
-/* debugging: print out stems of a glyph */
-static void
-debugstems(
- char *name,
- STEM * hstems,
- int nhs,
- STEM * vstems,
- int nvs
-)
-{
- int i;
-
- fprintf(pfa_file, "%% %s\n", name);
- fprintf(pfa_file, "%% %d horizontal stems:\n", nhs);
- for (i = 0; i < nhs; i++)
- fprintf(pfa_file, "%% %3d %d (%d...%d) %c %c%c%c%c\n", i, hstems[i].value,
- hstems[i].from, hstems[i].to,
- ((hstems[i].flags & ST_UP) ? 'U' : 'D'),
- ((hstems[i].flags & ST_END) ? 'E' : '-'),
- ((hstems[i].flags & ST_FLAT) ? 'F' : '-'),
- ((hstems[i].flags & ST_ZONE) ? 'Z' : ' '),
- ((hstems[i].flags & ST_TOPZONE) ? 'T' : ' '));
- fprintf(pfa_file, "%% %d vertical stems:\n", nvs);
- for (i = 0; i < nvs; i++)
- fprintf(pfa_file, "%% %3d %d (%d...%d) %c %c%c\n", i, vstems[i].value,
- vstems[i].from, vstems[i].to,
- ((vstems[i].flags & ST_UP) ? 'U' : 'D'),
- ((vstems[i].flags & ST_END) ? 'E' : '-'),
- ((vstems[i].flags & ST_FLAT) ? 'F' : '-'));
-}
-
-/* add pseudo-stems for the limits of the Blue zones to the stem array */
-static int
-addbluestems(
- STEM *s,
- int n
-)
-{
- int i;
-
- for(i=0; i<nblues && i<2; i+=2) { /* baseline */
- s[n].value=bluevalues[i];
- s[n].flags=ST_UP|ST_ZONE;
- /* don't overlap with anything */
- s[n].origin=s[n].from=s[n].to= -10000+i;
- n++;
- s[n].value=bluevalues[i+1];
- s[n].flags=ST_ZONE;
- /* don't overlap with anything */
- s[n].origin=s[n].from=s[n].to= -10000+i+1;
- n++;
- }
- for(i=2; i<nblues; i+=2) { /* top zones */
- s[n].value=bluevalues[i];
- s[n].flags=ST_UP|ST_ZONE|ST_TOPZONE;
- /* don't overlap with anything */
- s[n].origin=s[n].from=s[n].to= -10000+i;
- n++;
- s[n].value=bluevalues[i+1];
- s[n].flags=ST_ZONE|ST_TOPZONE;
- /* don't overlap with anything */
- s[n].origin=s[n].from=s[n].to= -10000+i+1;
- n++;
- }
- for(i=0; i<notherb; i+=2) { /* bottom zones */
- s[n].value=otherblues[i];
- s[n].flags=ST_UP|ST_ZONE;
- /* don't overlap with anything */
- s[n].origin=s[n].from=s[n].to= -10000+i+nblues;
- n++;
- s[n].value=otherblues[i+1];
- s[n].flags=ST_ZONE;
- /* don't overlap with anything */
- s[n].origin=s[n].from=s[n].to= -10000+i+1+nblues;
- n++;
- }
- return n;
-}
-
-/* sort stems in array */
-static void
-sortstems(
- STEM * s,
- int n
-)
-{
- int i, j;
- STEM x;
-
-
- /* a simple sorting */
- /* hm, the ordering criteria are not quite simple :-)
- * if the values are tied
- * ST_UP always goes under not ST_UP
- * ST_ZONE goes on the most outer side
- * ST_END goes towards inner side after ST_ZONE
- * ST_FLAT goes on the inner side
- */
-
- for (i = 0; i < n; i++)
- for (j = i + 1; j < n; j++) {
- if(s[i].value < s[j].value)
- continue;
- if(s[i].value == s[j].value) {
- if( (s[i].flags & ST_UP) < (s[j].flags & ST_UP) )
- continue;
- if( (s[i].flags & ST_UP) == (s[j].flags & ST_UP) ) {
- if( s[i].flags & ST_UP ) {
- if(
- ((s[i].flags & (ST_ZONE|ST_FLAT|ST_END)) ^ ST_FLAT)
- >
- ((s[j].flags & (ST_ZONE|ST_FLAT|ST_END)) ^ ST_FLAT)
- )
- continue;
- } else {
- if(
- ((s[i].flags & (ST_ZONE|ST_FLAT|ST_END)) ^ ST_FLAT)
- <
- ((s[j].flags & (ST_ZONE|ST_FLAT|ST_END)) ^ ST_FLAT)
- )
- continue;
- }
- }
- }
- x = s[j];
- s[j] = s[i];
- s[i] = x;
- }
-}
-
-/* check whether two stem borders overlap */
-
-static int
-stemoverlap(
- STEM * s1,
- STEM * s2
-)
-{
- int result;
-
- if ((s1->from <= s2->from && s1->to >= s2->from)
- || (s2->from <= s1->from && s2->to >= s1->from))
- result = 1;
- else
- result = 0;
-
- if (ISDBG(STEMOVERLAP))
- fprintf(pfa_file, "%% overlap %d(%d..%d)x%d(%d..%d)=%d\n",
- s1->value, s1->from, s1->to, s2->value, s2->from, s2->to, result);
- return result;
-}
-
-/*
- * check if the stem [border] is in an appropriate blue zone
- * (currently not used)
- */
-
-static int
-steminblue(
- STEM *s
-)
-{
- int i, val;
-
- val=s->value;
- if(s->flags & ST_UP) {
- /* painted size up, look at lower zones */
- if(nblues>=2 && val>=bluevalues[0] && val<=bluevalues[1] )
- return 1;
- for(i=0; i<notherb; i++) {
- if( val>=otherblues[i] && val<=otherblues[i+1] )
- return 1;
- }
- } else {
- /* painted side down, look at upper zones */
- for(i=2; i<nblues; i++) {
- if( val>=bluevalues[i] && val<=bluevalues[i+1] )
- return 1;
- }
- }
-
- return 0;
-}
-
-/* mark the outermost stem [borders] in the blue zones */
-
-static void
-markbluestems(
- STEM *s,
- int nold
-)
-{
- int i, j, a, b, c;
- /*
- * traverse the list of Blue Values, mark the lowest upper
- * stem in each bottom zone and the topmost lower stem in
- * each top zone with ST_BLUE
- */
-
- /* top zones */
- for(i=2; i<nblues; i+=2) {
- a=bluevalues[i]; b=bluevalues[i+1];
- if(ISDBG(BLUESTEMS))
- fprintf(pfa_file, "%% looking at blue zone %d...%d\n", a, b);
- for(j=nold-1; j>=0; j--) {
- if( s[j].flags & (ST_ZONE|ST_UP|ST_END) )
- continue;
- c=s[j].value;
- if(c<a) /* too low */
- break;
- if(c<=b) { /* found the topmost stem border */
- /* mark all the stems with the same value */
- if(ISDBG(BLUESTEMS))
- fprintf(pfa_file, "%% found D BLUE at %d\n", s[j].value);
- /* include ST_END values */
- while( s[j+1].value==c && (s[j+1].flags & ST_ZONE)==0 )
- j++;
- s[j].flags |= ST_BLUE;
- for(j--; j>=0 && s[j].value==c
- && (s[j].flags & (ST_UP|ST_ZONE))==0 ; j--)
- s[j].flags |= ST_BLUE;
- break;
- }
- }
- }
- /* baseline */
- if(nblues>=2) {
- a=bluevalues[0]; b=bluevalues[1];
- for(j=0; j<nold; j++) {
- if( (s[j].flags & (ST_ZONE|ST_UP|ST_END))!=ST_UP )
- continue;
- c=s[j].value;
- if(c>b) /* too high */
- break;
- if(c>=a) { /* found the lowest stem border */
- /* mark all the stems with the same value */
- if(ISDBG(BLUESTEMS))
- fprintf(pfa_file, "%% found U BLUE at %d\n", s[j].value);
- /* include ST_END values */
- while( s[j-1].value==c && (s[j-1].flags & ST_ZONE)==0 )
- j--;
- s[j].flags |= ST_BLUE;
- for(j++; j<nold && s[j].value==c
- && (s[j].flags & (ST_UP|ST_ZONE))==ST_UP ; j++)
- s[j].flags |= ST_BLUE;
- break;
- }
- }
- }
- /* bottom zones: the logic is the same as for baseline */
- for(i=0; i<notherb; i+=2) {
- a=otherblues[i]; b=otherblues[i+1];
- for(j=0; j<nold; j++) {
- if( (s[j].flags & (ST_UP|ST_ZONE|ST_END))!=ST_UP )
- continue;
- c=s[j].value;
- if(c>b) /* too high */
- break;
- if(c>=a) { /* found the lowest stem border */
- /* mark all the stems with the same value */
- if(ISDBG(BLUESTEMS))
- fprintf(pfa_file, "%% found U BLUE at %d\n", s[j].value);
- /* include ST_END values */
- while( s[j-1].value==c && (s[j-1].flags & ST_ZONE)==0 )
- j--;
- s[j].flags |= ST_BLUE;
- for(j++; j<nold && s[j].value==c
- && (s[j].flags & (ST_UP|ST_ZONE))==ST_UP ; j++)
- s[j].flags |= ST_BLUE;
- break;
- }
- }
- }
-}
-
-/* Eliminate invalid stems, join equivalent lines and remove nested stems
- * to build the main (non-substituted) set of stems.
- * XXX add consideration of the italic angle
- */
-static int
-joinmainstems(
- STEM * s,
- int nold,
- int useblues /* do we use the blue values ? */
-)
-{
-#define MAX_STACK 1000
- STEM stack[MAX_STACK];
- int nstack = 0;
- int sbottom = 0;
- int nnew;
- int i, j, k;
- int a, b, c, w1, w2, w3;
- int fw, fd;
- /*
- * priority of the last found stem:
- * 0 - nothing found yet
- * 1 - has ST_END in it (one or more)
- * 2 - has no ST_END and no ST_FLAT, can override only one stem
- * with priority 1
- * 3 - has no ST_END and at least one ST_FLAT, can override one
- * stem with priority 2 or any number of stems with priority 1
- * 4 (handled separately) - has ST_BLUE, can override anything
- */
- int readystem = 0;
- int pri;
- int nlps = 0; /* number of non-committed
- * lowest-priority stems */
-
-
- for (i = 0, nnew = 0; i < nold; i++) {
- if (s[i].flags & (ST_UP|ST_ZONE)) {
- if(s[i].flags & ST_BLUE) {
- /* we just HAVE to use this value */
- if (readystem)
- nnew += 2;
- readystem=0;
-
- /* remember the list of Blue zone stems with the same value */
- for(a=i, i++; i<nold && s[a].value==s[i].value
- && (s[i].flags & ST_BLUE); i++)
- {}
- b=i; /* our range is a <= i < b */
- c= -1; /* index of our best guess up to now */
- pri=0;
- /* try to find a match, don't cross blue zones */
- for(; i<nold && (s[i].flags & ST_BLUE)==0; i++) {
- if(s[i].flags & ST_UP) {
- if(s[i].flags & ST_TOPZONE)
- break;
- else
- continue;
- }
- for(j=a; j<b; j++) {
- if(!stemoverlap(&s[j], &s[i]) )
- continue;
- /* consider priorities */
- if( ( (s[j].flags|s[i].flags) & (ST_FLAT|ST_END) )==ST_FLAT ) {
- c=i;
- goto bluematch;
- }
- if( ((s[j].flags|s[i].flags) & ST_END)==0 ) {
- if(pri < 2) {
- c=i; pri=2;
- }
- } else {
- if(pri == 0) {
- c=i; pri=1;
- }
- }
- }
- }
- bluematch:
- /* clean up the stack */
- nstack=sbottom=0;
- readystem=0;
- /* add this stem */
- s[nnew++]=s[a];
- if(c<0) { /* make one-dot-wide stem */
- if(nnew>=b) { /* have no free space */
- for(j=nold; j>=b; j--) /* make free space */
- s[j]=s[j-1];
- b++;
- nold++;
- }
- s[nnew]=s[a];
- s[nnew].flags &= ~(ST_UP|ST_BLUE);
- nnew++;
- i=b-1;
- } else {
- s[nnew++]=s[c];
- i=c; /* skip up to this point */
- }
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% +stem %d...%d U BLUE\n",
- s[nnew-2].value, s[nnew-1].value);
- } else {
- if (nstack >= MAX_STACK) {
- WARNING_1 fprintf(stderr, "Warning: **** converter's stem stack overflow ****\n");
- nstack = 0;
- }
- stack[nstack++] = s[i];
- }
- } else if(s[i].flags & ST_BLUE) {
- /* again, we just HAVE to use this value */
- if (readystem)
- nnew += 2;
- readystem=0;
-
- /* remember the list of Blue zone stems with the same value */
- for(a=i, i++; i<nold && s[a].value==s[i].value
- && (s[i].flags & ST_BLUE); i++)
- {}
- b=i; /* our range is a <= i < b */
- c= -1; /* index of our best guess up to now */
- pri=0;
- /* try to find a match */
- for (i = nstack - 1; i >= 0; i--) {
- if( (stack[i].flags & ST_UP)==0 ) {
- if( (stack[i].flags & (ST_ZONE|ST_TOPZONE))==ST_ZONE )
- break;
- else
- continue;
- }
- for(j=a; j<b; j++) {
- if(!stemoverlap(&s[j], &stack[i]) )
- continue;
- /* consider priorities */
- if( ( (s[j].flags|stack[i].flags) & (ST_FLAT|ST_END) )==ST_FLAT ) {
- c=i;
- goto bluedownmatch;
- }
- if( ((s[j].flags|stack[i].flags) & ST_END)==0 ) {
- if(pri < 2) {
- c=i; pri=2;
- }
- } else {
- if(pri == 0) {
- c=i; pri=1;
- }
- }
- }
- }
- bluedownmatch:
- /* if found no match make a one-dot-wide stem */
- if(c<0) {
- c=0;
- stack[0]=s[b-1];
- stack[0].flags |= ST_UP;
- stack[0].flags &= ~ST_BLUE;
- }
- /* remove all the stems conflicting with this one */
- readystem=0;
- for(j=nnew-2; j>=0; j-=2) {
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% ?stem %d...%d -- %d\n",
- s[j].value, s[j+1].value, stack[c].value);
- if(s[j+1].value < stack[c].value) /* no conflict */
- break;
- if(s[j].flags & ST_BLUE) {
- /* oops, we don't want to spoil other blue zones */
- stack[c].value=s[j+1].value+1;
- break;
- }
- if( (s[j].flags|s[j+1].flags) & ST_END ) {
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% -stem %d...%d p=1\n",
- s[j].value, s[j+1].value);
- continue; /* pri==1, silently discard it */
- }
- /* we want to discard no nore than 2 stems of pri>=2 */
- if( ++readystem > 2 ) {
- /* change our stem to not conflict */
- stack[c].value=s[j+1].value+1;
- break;
- } else {
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% -stem %d...%d p>=2\n",
- s[j].value, s[j+1].value);
- continue;
- }
- }
- nnew=j+2;
- /* add this stem */
- if(nnew>=b-1) { /* have no free space */
- for(j=nold; j>=b-1; j--) /* make free space */
- s[j]=s[j-1];
- b++;
- nold++;
- }
- s[nnew++]=stack[c];
- s[nnew++]=s[b-1];
- /* clean up the stack */
- nstack=sbottom=0;
- readystem=0;
- /* set the next position to search */
- i=b-1;
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% +stem %d...%d D BLUE\n",
- s[nnew-2].value, s[nnew-1].value);
- } else if (nstack > 0) {
-
- /*
- * check whether our stem overlaps with anything in
- * stack
- */
- for (j = nstack - 1; j >= sbottom; j--) {
- if (s[i].value <= stack[j].value)
- break;
- if (stack[j].flags & ST_ZONE)
- continue;
-
- if ((s[i].flags & ST_END)
- || (stack[j].flags & ST_END))
- pri = 1;
- else if ((s[i].flags & ST_FLAT)
- || (stack[j].flags & ST_FLAT))
- pri = 3;
- else
- pri = 2;
-
- if ((pri < readystem && s[nnew + 1].value >= stack[j].value)
- || !stemoverlap(&stack[j], &s[i]))
- continue;
-
- if (readystem > 1 && s[nnew + 1].value < stack[j].value) {
- nnew += 2;
- readystem = 0;
- nlps = 0;
- }
- /*
- * width of the previous stem (if it's
- * present)
- */
- w1 = s[nnew + 1].value - s[nnew].value;
-
- /* width of this stem */
- w2 = s[i].value - stack[j].value;
-
- if (readystem == 0) {
- /* nothing yet, just add a new stem */
- s[nnew] = stack[j];
- s[nnew + 1] = s[i];
- readystem = pri;
- if (pri == 1)
- nlps = 1;
- else if (pri == 2)
- sbottom = j;
- else {
- sbottom = j + 1;
- while (sbottom < nstack
- && stack[sbottom].value <= stack[j].value)
- sbottom++;
- }
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% +stem %d...%d p=%d n=%d\n",
- stack[j].value, s[i].value, pri, nlps);
- } else if (pri == 1) {
- if (stack[j].value > s[nnew + 1].value) {
- /*
- * doesn't overlap with the
- * previous one
- */
- nnew += 2;
- nlps++;
- s[nnew] = stack[j];
- s[nnew + 1] = s[i];
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% +stem %d...%d p=%d n=%d\n",
- stack[j].value, s[i].value, pri, nlps);
- } else if (w2 < w1) {
- /* is narrower */
- s[nnew] = stack[j];
- s[nnew + 1] = s[i];
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% /stem %d...%d p=%d n=%d %d->%d\n",
- stack[j].value, s[i].value, pri, nlps, w1, w2);
- }
- } else if (pri == 2) {
- if (readystem == 2) {
- /* choose the narrower stem */
- if (w1 > w2) {
- s[nnew] = stack[j];
- s[nnew + 1] = s[i];
- sbottom = j;
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% /stem %d...%d p=%d n=%d\n",
- stack[j].value, s[i].value, pri, nlps);
- }
- /* else readystem==1 */
- } else if (stack[j].value > s[nnew + 1].value) {
- /*
- * value doesn't overlap with
- * the previous one
- */
- nnew += 2;
- nlps = 0;
- s[nnew] = stack[j];
- s[nnew + 1] = s[i];
- sbottom = j;
- readystem = pri;
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% +stem %d...%d p=%d n=%d\n",
- stack[j].value, s[i].value, pri, nlps);
- } else if (nlps == 1
- || stack[j].value > s[nnew - 1].value) {
- /*
- * we can replace the top
- * stem
- */
- nlps = 0;
- s[nnew] = stack[j];
- s[nnew + 1] = s[i];
- readystem = pri;
- sbottom = j;
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% /stem %d...%d p=%d n=%d\n",
- stack[j].value, s[i].value, pri, nlps);
- }
- } else if (readystem == 3) { /* that means also
- * pri==3 */
- /* choose the narrower stem */
- if (w1 > w2) {
- s[nnew] = stack[j];
- s[nnew + 1] = s[i];
- sbottom = j + 1;
- while (sbottom < nstack
- && stack[sbottom].value <= stack[j].value)
- sbottom++;
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% /stem %d...%d p=%d n=%d\n",
- stack[j].value, s[i].value, pri, nlps);
- }
- } else if (pri == 3) {
- /*
- * we can replace as many stems as
- * neccessary
- */
- nnew += 2;
- while (nnew > 0 && s[nnew - 1].value >= stack[j].value) {
- nnew -= 2;
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% -stem %d..%d\n",
- s[nnew].value, s[nnew + 1].value);
- }
- nlps = 0;
- s[nnew] = stack[j];
- s[nnew + 1] = s[i];
- readystem = pri;
- sbottom = j + 1;
- while (sbottom < nstack
- && stack[sbottom].value <= stack[j].value)
- sbottom++;
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% +stem %d...%d p=%d n=%d\n",
- stack[j].value, s[i].value, pri, nlps);
- }
- }
- }
- }
- if (readystem)
- nnew += 2;
-
- /* change the 1-pixel-wide stems to 20-pixel-wide stems if possible
- * the constant 20 is recommended in the Type1 manual
- */
- if(useblues) {
- for(i=0; i<nnew; i+=2) {
- if(s[i].value != s[i+1].value)
- continue;
- if( ((s[i].flags ^ s[i+1].flags) & ST_BLUE)==0 )
- continue;
- if( s[i].flags & ST_BLUE ) {
- if(nnew>i+2 && s[i+2].value<s[i].value+22)
- s[i+1].value=s[i+2].value-2; /* compensate for fuzziness */
- else
- s[i+1].value+=20;
- } else {
- if(i>0 && s[i-1].value>s[i].value-22)
- s[i].value=s[i-1].value+2; /* compensate for fuzziness */
- else
- s[i].value-=20;
- }
- }
- }
- /* make sure that no stem it stretched between
- * a top zone and a bottom zone
- */
- if(useblues) {
- for(i=0; i<nnew; i+=2) {
- a=10000; /* lowest border of top zone crosing the stem */
- b= -10000; /* highest border of bottom zone crossing the stem */
-
- for(j=2; j<nblues; j++) {
- c=bluevalues[j];
- if( c>=s[i].value && c<=s[i+1].value && c<a )
- a=c;
- }
- if(nblues>=2) {
- c=bluevalues[1];
- if( c>=s[i].value && c<=s[i+1].value && c>b )
- b=c;
- }
- for(j=1; j<notherb; j++) {
- c=otherblues[j];
- if( c>=s[i].value && c<=s[i+1].value && c>b )
- b=c;
- }
- if( a!=10000 && b!= -10000 ) { /* it is stretched */
- /* split the stem into 2 ghost stems */
- for(j=nnew+1; j>i+1; j--) /* make free space */
- s[j]=s[j-2];
- nnew+=2;
-
- if(s[i].value+22 >= a)
- s[i+1].value=a-2; /* leave space for fuzziness */
- else
- s[i+1].value=s[i].value+20;
-
- if(s[i+3].value-22 <= b)
- s[i+2].value=b+2; /* leave space for fuzziness */
- else
- s[i+2].value=s[i+3].value-20;
-
- i+=2;
- }
- }
- }
- /* look for triple stems */
- for (i = 0; i < nnew; i += 2) {
- if (nnew - i >= 6) {
- a = s[i].value + s[i + 1].value;
- b = s[i + 2].value + s[i + 3].value;
- c = s[i + 4].value + s[i + 5].value;
-
- w1 = s[i + 1].value - s[i].value;
- w2 = s[i + 3].value - s[i + 2].value;
- w3 = s[i + 5].value - s[i + 4].value;
-
- fw = w3 - w1; /* fuzz in width */
- fd = ((c - b) - (b - a)); /* fuzz in distance
- * (doubled) */
-
- /* we are able to handle some fuzz */
- /*
- * it doesn't hurt if the declared stem is a bit
- * narrower than actual unless it's an edge in
- * a blue zone
- */
- if (abs(abs(fd) - abs(fw)) * 5 < w2
- && abs(fw) * 20 < (w1 + w3)) { /* width dirrerence <10% */
-
- if(useblues) { /* check that we don't disturb any blue stems */
- j=c; k=a;
- if (fw > 0) {
- if (fd > 0) {
- if( s[i+5].flags & ST_BLUE )
- continue;
- j -= fw;
- } else {
- if( s[i+4].flags & ST_BLUE )
- continue;
- j += fw;
- }
- } else if(fw < 0) {
- if (fd > 0) {
- if( s[i+1].flags & ST_BLUE )
- continue;
- k -= fw;
- } else {
- if( s[i].flags & ST_BLUE )
- continue;
- k += fw;
- }
- }
- pri = ((j - b) - (b - k));
-
- if (pri > 0) {
- if( s[i+2].flags & ST_BLUE )
- continue;
- } else if(pri < 0) {
- if( s[i+3].flags & ST_BLUE )
- continue;
- }
- }
-
- /*
- * first fix up the width of 1st and 3rd
- * stems
- */
- if (fw > 0) {
- if (fd > 0) {
- s[i + 5].value -= fw;
- c -= fw;
- } else {
- s[i + 4].value += fw;
- c += fw;
- }
- } else {
- if (fd > 0) {
- s[i + 1].value -= fw;
- a -= fw;
- } else {
- s[i].value += fw;
- a += fw;
- }
- }
- fd = ((c - b) - (b - a));
-
- if (fd > 0) {
- s[i + 2].value += abs(fd) / 2;
- } else {
- s[i + 3].value -= abs(fd) / 2;
- }
-
- s[i].flags |= ST_3;
- i += 4;
- }
- }
- }
-
- return (nnew & ~1); /* number of lines must be always even */
-}
-
-/*
- * these macros and function allow to set the base stem,
- * check that it's not empty and subtract another stem
- * from the base stem (possibly dividing it into multiple parts)
- */
-
-/* pairs for pieces of the base stem */
-static short xbstem[MAX_STEMS*2];
-/* index of the last point */
-static int xblast= -1;
-
-#define setbasestem(from, to) \
- (xbstem[0]=from, xbstem[1]=to, xblast=1)
-#define isbaseempty() (xblast<=0)
-
-/* returns 1 if was overlapping, 0 otherwise */
-static int
-subfrombase(
- int from,
- int to
-)
-{
- int a, b;
- int i, j;
-
- if(isbaseempty())
- return 0;
-
- /* handle the simple case simply */
- if(from > xbstem[xblast] || to < xbstem[0])
- return 0;
-
- /* the binary search may be more efficient */
- /* but for now the linear search is OK */
- for(b=1; from > xbstem[b]; b+=2) {} /* result: from <= xbstem[b] */
- for(a=xblast-1; to < xbstem[a]; a-=2) {} /* result: to >= xbstem[a] */
-
- /* now the interesting examples are:
- * (it was hard for me to understand, so I looked at the examples)
- * 1
- * a|-----| |-----|b |-----| |-----|
- * f|-----|t
- * 2
- * a|-----|b |-----| |-----| |-----|
- * f|--|t
- * 3
- * a|-----|b |-----| |-----| |-----|
- * f|-----|t
- * 4
- * |-----|b a|-----| |-----| |-----|
- * f|------------|t
- * 5
- * |-----| |-----|b |-----| a|-----|
- * f|-----------------------------|t
- * 6
- * |-----|b |-----| |-----| a|-----|
- * f|--------------------------------------------------|t
- * 7
- * |-----|b |-----| a|-----| |-----|
- * f|--------------------------|t
- */
-
- if(a < b-1) /* hits a gap - example 1 */
- return 0;
-
- /* now the subtraction itself */
-
- if(a==b-1 && from > xbstem[a] && to < xbstem[b]) {
- /* overlaps with only one subrange and splits it - example 2 */
- j=xblast; i=(xblast+=2);
- while(j>=b)
- xbstem[i--]=xbstem[j--];
- xbstem[b]=from-1;
- xbstem[b+1]=to+1;
- return 1;
- /* becomes
- * 2a
- * a|b || |-----| |-----| |-----|
- * f|--|t
- */
- }
-
- if(xbstem[b-1] < from) {
- /* cuts the back of this subrange - examples 3, 4, 7 */
- xbstem[b] = from-1;
- b+=2;
- /* becomes
- * 3a
- * a|----| |-----|b |-----| |-----|
- * f|-----|t
- * 4a
- * |---| a|-----|b |-----| |-----|
- * f|------------|t
- * 7a
- * |---| |-----|b a|-----| |-----|
- * f|--------------------------|t
- */
- }
-
- if(xbstem[a+1] > to) {
- /* cuts the front of this subrange - examples 4a, 5, 7a */
- xbstem[a] = to+1;
- a-=2;
- /* becomes
- * 4b
- * a|---| |---|b |-----| |-----|
- * f|------------|t
- * 5b
- * |-----| |-----|b a|-----| ||
- * f|-----------------------------|t
- * 7b
- * |---| a|-----|b || |-----|
- * f|--------------------------|t
- */
- }
-
- if(a < b-1) /* now after modification it hits a gap - examples 3a, 4b */
- return 1; /* because we have removed something */
-
- /* now remove the subranges completely covered by the new stem */
- /* examples 5b, 6, 7b */
- i=b-1; j=a+2;
- /* positioned as:
- * 5b i j
- * |-----| |-----|b a|-----| ||
- * f|-----------------------------|t
- * 6 i xblast j
- * |-----|b |-----| |-----| a|-----|
- * f|--------------------------------------------------|t
- * 7b i j
- * |---| a|-----|b || |-----|
- * f|--------------------------|t
- */
- while(j <= xblast)
- xbstem[i++]=xbstem[j++];
- xblast=i-1;
- return 1;
-}
-
-/* for debugging */
-static void
-printbasestem(void)
-{
- int i;
-
- printf("( ");
- for(i=0; i<xblast; i+=2)
- printf("%d-%d ", xbstem[i], xbstem[i+1]);
- printf(") %d\n", xblast);
-}
-
-/*
- * Join the stem borders to build the sets of substituted stems
- * XXX add consideration of the italic angle
- */
-static void
-joinsubstems(
- STEM * s,
- short *pairs,
- int nold,
- int useblues /* do we use the blue values ? */
-)
-{
- int i, j, x;
- static unsigned char mx[MAX_STEMS][MAX_STEMS];
-
- /* we do the substituted groups of stems first
- * and it looks like it's going to be REALLY SLOW
- * AND PAINFUL but let's bother about it later
- */
-
- /* for the substituted stems we don't bother about [hv]stem3 -
- * anyway the X11R6 rasterizer does not bother about hstem3
- * at all and is able to handle only one global vstem3
- * per glyph
- */
-
- /* clean the used part of matrix */
- for(i=0; i<nold; i++)
- for(j=0; j<nold; j++)
- mx[i][j]=0;
-
- /* build the matrix of stem pairs */
- for(i=0; i<nold; i++) {
- if( s[i].flags & ST_ZONE )
- continue;
- if(s[i].flags & ST_BLUE)
- mx[i][i]=1; /* allow to pair with itself if no better pair */
- if(s[i].flags & ST_UP) { /* the down-stems are already matched */
- setbasestem(s[i].from, s[i].to);
- for(j=i+1; j<nold; j++) {
- if(s[i].value==s[j].value
- || s[j].flags & ST_ZONE ) {
- continue;
- }
- x=subfrombase(s[j].from, s[j].to);
-
- if(s[j].flags & ST_UP) /* match only up+down pairs */
- continue;
-
- mx[i][j]=mx[j][i]=x;
-
- if(isbaseempty()) /* nothing else to do */
- break;
- }
- }
- }
-
- if(ISDBG(SUBSTEMS)) {
- fprintf(pfa_file, "%% ");
- for(j=0; j<nold; j++)
- putc( j%10==0 ? '0'+(j/10)%10 : ' ', pfa_file);
- fprintf(pfa_file, "\n%% ");
- for(j=0; j<nold; j++)
- putc('0'+j%10, pfa_file);
- putc('\n', pfa_file);
- for(i=0; i<nold; i++) {
- fprintf(pfa_file, "%% %3d ",i);
- for(j=0; j<nold; j++)
- putc( mx[i][j] ? 'X' : '.', pfa_file);
- putc('\n', pfa_file);
- }
- }
-
- /* now use the matrix to find the best pair for each stem */
- for(i=0; i<nold; i++) {
- int pri, lastpri, v, f;
-
- x= -1; /* best pair: none */
- lastpri=0;
-
- v=s[i].value;
- f=s[i].flags;
-
- if(f & ST_ZONE) {
- pairs[i]= -1;
- continue;
- }
-
- if(f & ST_UP) {
- for(j=i+1; j<nold; j++) {
- if(mx[i][j]==0)
- continue;
-
- if( (f | s[j].flags) & ST_END )
- pri=1;
- else if( (f | s[j].flags) & ST_FLAT )
- pri=3;
- else
- pri=2;
-
- if(lastpri==0
- || ( pri > lastpri
- && ( lastpri==1 || s[j].value-v<20 || (s[x].value-v)*2 >= s[j].value-v ) ) ) {
- lastpri=pri;
- x=j;
- }
- }
- } else {
- for(j=i-1; j>=0; j--) {
- if(mx[i][j]==0)
- continue;
-
- if( (f | s[j].flags) & ST_END )
- pri=1;
- else if( (f | s[j].flags) & ST_FLAT )
- pri=3;
- else
- pri=2;
-
- if(lastpri==0
- || ( pri > lastpri
- && ( lastpri==1 || v-s[j].value<20 || (v-s[x].value)*2 >= v-s[j].value ) ) ) {
- lastpri=pri;
- x=j;
- }
- }
- }
- if(x== -1 && mx[i][i])
- pairs[i]=i; /* a special case */
- else
- pairs[i]=x;
- }
-
- if(ISDBG(SUBSTEMS)) {
- for(i=0; i<nold; i++) {
- j=pairs[i];
- if(j>0)
- fprintf(pfa_file, "%% %d...%d (%d x %d)\n", s[i].value, s[j].value, i, j);
- }
- }
-}
-
-/*
- * Make all the stems originating at the same value get the
- * same width. Without this the rasterizer may move the dots
- * randomly up or down by one pixel, and that looks bad.
- * The prioritisation is the same as in findstemat().
- */
-static void
-uniformstems(
- STEM * s,
- short *pairs,
- int ns
-)
-{
- int i, j, from, to, val, dir;
- int pri, prevpri[2], wd, prevwd[2], prevbest[2];
-
- for(from=0; from<ns; from=to) {
- prevpri[0] = prevpri[1] = 0;
- prevwd[0] = prevwd[1] = 0;
- prevbest[0] = prevbest[1] = -1;
- val = s[from].value;
-
- for(to = from; to<ns && s[to].value == val; to++) {
- dir = ((s[to].flags & ST_UP)!=0);
-
- i=pairs[to]; /* the other side of this stem */
- if(i<0 || i==to)
- continue; /* oops, no other side */
- wd=abs(s[i].value-val);
- if(wd == 0)
- continue;
- pri=1;
- if( (s[to].flags | s[i].flags) & ST_END )
- pri=0;
- if( prevbest[dir] == -1 || pri > prevpri[dir] || wd<prevwd[dir] ) {
- prevbest[dir]=i;
- prevpri[dir]=pri;
- prevwd[dir]=wd;
- }
- }
-
- for(i=from; i<to; i++) {
- dir = ((s[i].flags & ST_UP)!=0);
- if(prevbest[dir] >= 0) {
- if(ISDBG(SUBSTEMS)) {
- fprintf(stderr, "at %d (%s %d) pair %d->%d(%d)\n", i,
- (dir ? "UP":"DOWN"), s[i].value, pairs[i], prevbest[dir],
- s[prevbest[dir]].value);
- }
- pairs[i] = prevbest[dir];
- }
- }
- }
-}
-
-/*
- * Find the best stem in the array at the specified (value, origin),
- * related to the entry ge.
- * Returns its index in the array sp, -1 means "none".
- * prevbest is the result for the other end of the line, we must
- * find something better than it or leave it as it is.
- */
-static int
-findstemat(
- int value,
- int origin,
- GENTRY *ge,
- STEM *sp,
- short *pairs,
- int ns,
- int prevbest /* -1 means "none" */
-)
-{
- int i, min, max;
- int v, si;
- int pri, prevpri; /* priority, 0 = has ST_END, 1 = no ST_END */
- int wd, prevwd; /* stem width */
-
- si= -1; /* nothing yet */
-
- /* stems are ordered by value, binary search */
- min=0; max=ns; /* min <= i < max */
- while( min < max ) {
- i=(min+max)/2;
- v=sp[i].value;
- if(v<value)
- min=i+1;
- else if(v>value)
- max=i;
- else {
- si=i; /* temporary value */
- break;
- }
- }
-
- if( si < 0 ) /* found nothing this time */
- return prevbest;
-
- /* find the priority of the prevbest */
- /* we expect that prevbest has a pair */
- if(prevbest>=0) {
- i=pairs[prevbest];
- prevpri=1;
- if( (sp[prevbest].flags | sp[i].flags) & ST_END )
- prevpri=0;
- prevwd=abs(sp[i].value-value);
- }
-
- /* stems are not ordered by origin, so now do the linear search */
-
- while( si>0 && sp[si-1].value==value ) /* find the first one */
- si--;
-
- for(; si<ns && sp[si].value==value; si++) {
- if(sp[si].origin != origin)
- continue;
- if(sp[si].ge != ge) {
- if(ISDBG(SUBSTEMS)) {
- fprintf(stderr,
- "dbg: possible self-intersection at v=%d o=%d exp_ge=0x%x ge=0x%x\n",
- value, origin, ge, sp[si].ge);
- }
- continue;
- }
- i=pairs[si]; /* the other side of this stem */
- if(i<0)
- continue; /* oops, no other side */
- pri=1;
- if( (sp[si].flags | sp[i].flags) & ST_END )
- pri=0;
- wd=abs(sp[i].value-value);
- if( prevbest == -1 || pri >prevpri
- || (pri==prevpri && prevwd==0) || (wd!=0 && wd<prevwd) ) {
- prevbest=si;
- prevpri=pri;
- prevwd=wd;
- continue;
- }
- }
-
- return prevbest;
-}
-
-/* add the substems for one glyph entry
- * (called from groupsubstems())
- * returns 0 if all OK, 1 if too many groups
- */
-
-static int gssentry_lastgrp=0; /* reset to 0 for each new glyph */
-
-static int
-gssentry( /* crazy number of parameters */
- GENTRY *ge,
- STEM *hs, /* horizontal stems, sorted by value */
- short *hpairs,
- int nhs,
- STEM *vs, /* vertical stems, sorted by value */
- short *vpairs,
- int nvs,
- STEMBOUNDS *s,
- short *egp,
- int *nextvsi,
- int *nexthsi /* -2 means "check by yourself" */
-) {
- enum {
- SI_VP, /* vertical primary */
- SI_HP, /* horizontal primary */
- SI_SIZE /* size of the array */
- };
- int si[SI_SIZE]; /* indexes of relevant stems */
-
- /* the bounds of the existing relevant stems */
- STEMBOUNDS r[ sizeof(si) / sizeof(si[0]) * 2 ];
- char rexpand; /* by how much we need to expand the group */
- int nr; /* and the number of them */
-
- /* yet more temporary storage */
- short lb, hb, isvert;
- int conflict, grp;
- int i, j, x, y;
-
-
- /* for each line or curve we try to find a horizontal and
- * a vertical stem corresponding to its first point
- * (corresponding to the last point of the previous
- * glyph entry), because the directions of the lines
- * will be eventually reversed and it will then become the last
- * point. And the T1 rasterizer applies the hints to
- * the last point.
- *
- */
-
- /* start with the common part, the first point */
- x=ge->prev->ix3;
- y=ge->prev->iy3;
-
- if(*nextvsi == -2)
- si[SI_VP]=findstemat(x, y, ge, vs, vpairs, nvs, -1);
- else {
- si[SI_VP]= *nextvsi; *nextvsi= -2;
- }
- if(*nexthsi == -2)
- si[SI_HP]=findstemat(y, x, ge, hs, hpairs, nhs, -1);
- else {
- si[SI_HP]= *nexthsi; *nexthsi= -2;
- }
-
- /*
- * For the horizontal lines we make sure that both
- * ends of the line have the same horizontal stem,
- * and the same thing for vertical lines and stems.
- * In both cases we enforce the stem for the next entry.
- * Otherwise unpleasant effects may arise.
- */
-
- if(ge->type==GE_LINE) {
- if(ge->ix3==x) { /* vertical line */
- *nextvsi=si[SI_VP]=findstemat(x, ge->iy3, ge->frwd, vs, vpairs, nvs, si[SI_VP]);
- } else if(ge->iy3==y) { /* horizontal line */
- *nexthsi=si[SI_HP]=findstemat(y, ge->ix3, ge->frwd, hs, hpairs, nhs, si[SI_HP]);
- }
- }
-
- if(si[SI_VP]+si[SI_HP] == -2) /* no stems, leave it alone */
- return 0;
-
- /* build the array of relevant bounds */
- nr=0;
- for(i=0; i< sizeof(si) / sizeof(si[0]); i++) {
- STEM *sp;
- short *pairs;
- int step;
- int f;
- int nzones, firstzone, binzone, einzone;
- int btype, etype;
-
- if(si[i] < 0)
- continue;
-
- if(i<SI_HP) {
- r[nr].isvert=1; sp=vs; pairs=vpairs;
- } else {
- r[nr].isvert=0; sp=hs; pairs=hpairs;
- }
-
- r[nr].low=sp[ si[i] ].value;
- r[nr].high=sp[ pairs[ si[i] ] ].value;
-
- if(r[nr].low > r[nr].high) {
- j=r[nr].low; r[nr].low=r[nr].high; r[nr].high=j;
- step= -1;
- } else {
- step=1;
- }
-
- /* handle the interaction with Blue Zones */
-
- if(i>=SI_HP) { /* only for horizontal stems */
- if(si[i]==pairs[si[i]]) {
- /* special case, the outermost stem in the
- * Blue Zone without a pair, simulate it to 20-pixel
- */
- if(sp[ si[i] ].flags & ST_UP) {
- r[nr].high+=20;
- for(j=si[i]+1; j<nhs; j++)
- if( (sp[j].flags & (ST_ZONE|ST_TOPZONE))
- == (ST_ZONE|ST_TOPZONE) ) {
- if(r[nr].high > sp[j].value-2)
- r[nr].high=sp[j].value-2;
- break;
- }
- } else {
- r[nr].low-=20;
- for(j=si[i]-1; j>=0; j--)
- if( (sp[j].flags & (ST_ZONE|ST_TOPZONE))
- == (ST_ZONE) ) {
- if(r[nr].low < sp[j].value+2)
- r[nr].low=sp[j].value+2;
- break;
- }
- }
- }
-
- /* check that the stem borders don't end up in
- * different Blue Zones */
- f=sp[ si[i] ].flags;
- nzones=0; einzone=binzone=0;
- for(j=si[i]; j!=pairs[ si[i] ]; j+=step) {
- if( (sp[j].flags & ST_ZONE)==0 )
- continue;
- /* if see a zone border going in the same direction */
- if( ((f ^ sp[j].flags) & ST_UP)==0 ) {
- if( ++nzones == 1 ) {
- firstzone=sp[j].value; /* remember the first one */
- etype=sp[j].flags & ST_TOPZONE;
- }
- einzone=1;
-
- } else { /* the opposite direction */
- if(nzones==0) { /* beginning is in a blue zone */
- binzone=1;
- btype=sp[j].flags & ST_TOPZONE;
- }
- einzone=0;
- }
- }
-
- /* beginning and end are in Blue Zones of different types */
- if( binzone && einzone && (btype ^ etype)!=0 ) {
- if( sp[si[i]].flags & ST_UP ) {
- if(firstzone > r[nr].low+22)
- r[nr].high=r[nr].low+20;
- else
- r[nr].high=firstzone-2;
- } else {
- if(firstzone < r[nr].high-22)
- r[nr].low=r[nr].high-20;
- else
- r[nr].low=firstzone+2;
- }
- }
- }
-
- if(ISDBG(SUBSTEMS))
- fprintf(pfa_file, "%% at(%d,%d)[%d,%d] %d..%d %c (%d x %d)\n", x, y, i, nr,
- r[nr].low, r[nr].high, r[nr].isvert ? 'v' : 'h',
- si[i], pairs[si[i]]);
-
- nr++;
- }
-
- /* now try to find a group */
- conflict=0; /* no conflicts found yet */
- for(j=0; j<nr; j++)
- r[j].already=0;
-
- /* check if it fits into the last group */
- grp = gssentry_lastgrp;
- i = (grp==0)? 0 : egp[grp-1];
- for(; i<egp[grp]; i++) {
- lb=s[i].low; hb=s[i].high; isvert=s[i].isvert;
- for(j=0; j<nr; j++)
- if( r[j].isvert==isvert /* intersects */
- && r[j].low <= hb && r[j].high >= lb ) {
- if( r[j].low == lb && r[j].high == hb ) /* coincides */
- r[j].already=1;
- else
- conflict=1;
- }
-
- if(conflict)
- break;
- }
-
- if(conflict) { /* nope, check all the groups */
- for(j=0; j<nr; j++)
- r[j].already=0;
-
- for(i=0, grp=0; i<egp[NSTEMGRP-1]; i++) {
- if(i == egp[grp]) { /* checked all stems in a group */
- if(conflict) {
- grp++; conflict=0; /* check the next group */
- for(j=0; j<nr; j++)
- r[j].already=0;
- } else
- break; /* insert into this group */
- }
-
- lb=s[i].low; hb=s[i].high; isvert=s[i].isvert;
- for(j=0; j<nr; j++)
- if( r[j].isvert==isvert /* intersects */
- && r[j].low <= hb && r[j].high >= lb ) {
- if( r[j].low == lb && r[j].high == hb ) /* coincides */
- r[j].already=1;
- else
- conflict=1;
- }
-
- if(conflict)
- i=egp[grp]-1; /* fast forward to the next group */
- }
- }
-
- /* do we have any empty group ? */
- if(conflict && grp < NSTEMGRP-1) {
- grp++; conflict=0;
- for(j=0; j<nr; j++)
- r[j].already=0;
- }
-
- if(conflict) { /* oops, can't find any group to fit */
- return 1;
- }
-
- /* OK, add stems to this group */
-
- rexpand = nr;
- for(j=0; j<nr; j++)
- rexpand -= r[j].already;
-
- if(rexpand > 0) {
- for(i=egp[NSTEMGRP-1]-1; i>=egp[grp]; i--)
- s[i+rexpand]=s[i];
- for(i=0; i<nr; i++)
- if(!r[i].already)
- s[egp[grp]++]=r[i];
- for(i=grp+1; i<NSTEMGRP; i++)
- egp[i]+=rexpand;
- }
-
- ge->stemid = gssentry_lastgrp = grp;
- return 0;
-}
-
-/*
- * Create the groups of substituted stems from the list.
- * Each group will be represented by a subroutine in the Subs
- * array.
- */
-
-static void
-groupsubstems(
- GLYPH *g,
- STEM *hs, /* horizontal stems, sorted by value */
- short *hpairs,
- int nhs,
- STEM *vs, /* vertical stems, sorted by value */
- short *vpairs,
- int nvs
-)
-{
- GENTRY *ge;
- int i, j;
-
- /* temporary storage */
- STEMBOUNDS s[MAX_STEMS*2];
- /* indexes in there, pointing past the end each stem group */
- short egp[NSTEMGRP];
-
- int nextvsi, nexthsi; /* -2 means "check by yourself" */
-
- for(i=0; i<NSTEMGRP; i++)
- egp[i]=0;
-
- nextvsi=nexthsi= -2; /* processed no horiz/vert line */
-
- gssentry_lastgrp = 0; /* reset the last group for new glyph */
-
- for (ge = g->entries; ge != 0; ge = ge->next) {
- if(ge->type!=GE_LINE && ge->type!=GE_CURVE) {
- nextvsi=nexthsi= -2; /* next path is independent */
- continue;
- }
-
- if( gssentry(ge, hs, hpairs, nhs, vs, vpairs, nvs, s, egp, &nextvsi, &nexthsi) ) {
- WARNING_2 fprintf(stderr, "*** glyph %s requires over %d hint subroutines, ignored them\n",
- g->name, NSTEMGRP);
- /* it's better to have no substituted hints at all than have only part */
- for (ge = g->entries; ge != 0; ge = ge->next)
- ge->stemid= -1;
- g->nsg=0; /* just to be safe, already is 0 by initialization */
- return;
- }
-
- /*
- * handle the last vert/horiz line of the path specially,
- * correct the hint for the first entry of the path
- */
- if(ge->frwd != ge->next && (nextvsi != -2 || nexthsi != -2) ) {
- if( gssentry(ge->frwd, hs, hpairs, nhs, vs, vpairs, nvs, s, egp, &nextvsi, &nexthsi) ) {
- WARNING_2 fprintf(stderr, "*** glyph %s requires over %d hint subroutines, ignored them\n",
- g->name, NSTEMGRP);
- /* it's better to have no substituted hints at all than have only part */
- for (ge = g->entries; ge != 0; ge = ge->next)
- ge->stemid= -1;
- g->nsg=0; /* just to be safe, already is 0 by initialization */
- return;
- }
- }
-
- }
-
- /* find the index of the first empty group - same as the number of groups */
- if(egp[0]>0) {
- for(i=1; i<NSTEMGRP && egp[i]!=egp[i-1]; i++)
- {}
- g->nsg=i;
- } else
- g->nsg=0;
-
- if(ISDBG(SUBSTEMS)) {
- fprintf(pfa_file, "%% %d substem groups (%d %d %d)\n", g->nsg,
- g->nsg>1 ? egp[g->nsg-2] : -1,
- g->nsg>0 ? egp[g->nsg-1] : -1,
- g->nsg<NSTEMGRP ? egp[g->nsg] : -1 );
- j=0;
- for(i=0; i<g->nsg; i++) {
- fprintf(pfa_file, "%% grp %3d: ", i);
- for(; j<egp[i]; j++) {
- fprintf(pfa_file, " %4d...%-4d %c ", s[j].low, s[j].high,
- s[j].isvert ? 'v' : 'h');
- }
- fprintf(pfa_file, "\n");
- }
- }
-
- if(g->nsg==1) { /* it would be the same as the main stems */
- /* so erase it */
- for (ge = g->entries; ge != 0; ge = ge->next)
- ge->stemid= -1;
- g->nsg=0;
- }
-
- if(g->nsg>0) {
- if( (g->nsbs=malloc(g->nsg * sizeof (egp[0]))) == 0 ) {
- fprintf(stderr, "**** not enough memory for substituted hints ****\n");
- exit(255);
- }
- memmove(g->nsbs, egp, g->nsg * sizeof(short));
- if( (g->sbstems=malloc(egp[g->nsg-1] * sizeof (s[0]))) == 0 ) {
- fprintf(stderr, "**** not enough memory for substituted hints ****\n");
- exit(255);
- }
- memmove(g->sbstems, s, egp[g->nsg-1] * sizeof(s[0]));
- }
-}
-
-void
-buildstems(
- GLYPH * g
-)
-{
- STEM hs[MAX_STEMS], vs[MAX_STEMS]; /* temporary working
- * storage */
- short hs_pairs[MAX_STEMS], vs_pairs[MAX_STEMS]; /* best pairs for these stems */
- STEM *sp;
- GENTRY *ge, *nge, *pge;
- int nx, ny;
- int ovalue;
- int totals, grp, lastgrp;
-
- assertisint(g, "buildstems int");
-
- g->nhs = g->nvs = 0;
- memset(hs, 0, sizeof hs);
- memset(vs, 0, sizeof vs);
-
- /* first search the whole character for possible stem points */
-
- for (ge = g->entries; ge != 0; ge = ge->next) {
- if (ge->type == GE_CURVE) {
-
- /*
- * SURPRISE!
- * We consider the stems bound by the
- * H/V ends of the curves as flat ones.
- *
- * But we don't include the point on the
- * other end into the range.
- */
-
- /* first check the beginning of curve */
- /* if it is horizontal, add a hstem */
- if (ge->iy1 == ge->prev->iy3) {
- hs[g->nhs].value = ge->iy1;
-
- if (ge->ix1 < ge->prev->ix3)
- hs[g->nhs].flags = ST_FLAT | ST_UP;
- else
- hs[g->nhs].flags = ST_FLAT;
-
- hs[g->nhs].origin = ge->prev->ix3;
- hs[g->nhs].ge = ge;
-
- if (ge->ix1 < ge->prev->ix3) {
- hs[g->nhs].from = ge->ix1+1;
- hs[g->nhs].to = ge->prev->ix3;
- if(hs[g->nhs].from > hs[g->nhs].to)
- hs[g->nhs].from--;
- } else {
- hs[g->nhs].from = ge->prev->ix3;
- hs[g->nhs].to = ge->ix1-1;
- if(hs[g->nhs].from > hs[g->nhs].to)
- hs[g->nhs].to++;
- }
- if (ge->ix1 != ge->prev->ix3)
- g->nhs++;
- }
- /* if it is vertical, add a vstem */
- else if (ge->ix1 == ge->prev->ix3) {
- vs[g->nvs].value = ge->ix1;
-
- if (ge->iy1 > ge->prev->iy3)
- vs[g->nvs].flags = ST_FLAT | ST_UP;
- else
- vs[g->nvs].flags = ST_FLAT;
-
- vs[g->nvs].origin = ge->prev->iy3;
- vs[g->nvs].ge = ge;
-
- if (ge->iy1 < ge->prev->iy3) {
- vs[g->nvs].from = ge->iy1+1;
- vs[g->nvs].to = ge->prev->iy3;
- if(vs[g->nvs].from > vs[g->nvs].to)
- vs[g->nvs].from--;
- } else {
- vs[g->nvs].from = ge->prev->iy3;
- vs[g->nvs].to = ge->iy1-1;
- if(vs[g->nvs].from > vs[g->nvs].to)
- vs[g->nvs].to++;
- }
-
- if (ge->iy1 != ge->prev->iy3)
- g->nvs++;
- }
- /* then check the end of curve */
- /* if it is horizontal, add a hstem */
- if (ge->iy3 == ge->iy2) {
- hs[g->nhs].value = ge->iy3;
-
- if (ge->ix3 < ge->ix2)
- hs[g->nhs].flags = ST_FLAT | ST_UP;
- else
- hs[g->nhs].flags = ST_FLAT;
-
- hs[g->nhs].origin = ge->ix3;
- hs[g->nhs].ge = ge->frwd;
-
- if (ge->ix3 < ge->ix2) {
- hs[g->nhs].from = ge->ix3;
- hs[g->nhs].to = ge->ix2-1;
- if( hs[g->nhs].from > hs[g->nhs].to )
- hs[g->nhs].to++;
- } else {
- hs[g->nhs].from = ge->ix2+1;
- hs[g->nhs].to = ge->ix3;
- if( hs[g->nhs].from > hs[g->nhs].to )
- hs[g->nhs].from--;
- }
-
- if (ge->ix3 != ge->ix2)
- g->nhs++;
- }
- /* if it is vertical, add a vstem */
- else if (ge->ix3 == ge->ix2) {
- vs[g->nvs].value = ge->ix3;
-
- if (ge->iy3 > ge->iy2)
- vs[g->nvs].flags = ST_FLAT | ST_UP;
- else
- vs[g->nvs].flags = ST_FLAT;
-
- vs[g->nvs].origin = ge->iy3;
- vs[g->nvs].ge = ge->frwd;
-
- if (ge->iy3 < ge->iy2) {
- vs[g->nvs].from = ge->iy3;
- vs[g->nvs].to = ge->iy2-1;
- if( vs[g->nvs].from > vs[g->nvs].to )
- vs[g->nvs].to++;
- } else {
- vs[g->nvs].from = ge->iy2+1;
- vs[g->nvs].to = ge->iy3;
- if( vs[g->nvs].from > vs[g->nvs].to )
- vs[g->nvs].from--;
- }
-
- if (ge->iy3 != ge->iy2)
- g->nvs++;
- } else {
-
- /*
- * check the end of curve for a not smooth
- * local extremum
- */
- nge = ge->frwd;
-
- if (nge == 0)
- continue;
- else if (nge->type == GE_LINE) {
- nx = nge->ix3;
- ny = nge->iy3;
- } else if (nge->type == GE_CURVE) {
- nx = nge->ix1;
- ny = nge->iy1;
- } else
- continue;
-
- /* check for vertical extremums */
- if ((ge->iy3 > ge->iy2 && ge->iy3 > ny)
- || (ge->iy3 < ge->iy2 && ge->iy3 < ny)) {
- hs[g->nhs].value = ge->iy3;
- hs[g->nhs].from
- = hs[g->nhs].to
- = hs[g->nhs].origin = ge->ix3;
- hs[g->nhs].ge = ge->frwd;
-
- if (ge->ix3 < ge->ix2
- || nx < ge->ix3)
- hs[g->nhs].flags = ST_UP;
- else
- hs[g->nhs].flags = 0;
-
- if (ge->ix3 != ge->ix2 || nx != ge->ix3)
- g->nhs++;
- }
- /*
- * the same point may be both horizontal and
- * vertical extremum
- */
- /* check for horizontal extremums */
- if ((ge->ix3 > ge->ix2 && ge->ix3 > nx)
- || (ge->ix3 < ge->ix2 && ge->ix3 < nx)) {
- vs[g->nvs].value = ge->ix3;
- vs[g->nvs].from
- = vs[g->nvs].to
- = vs[g->nvs].origin = ge->iy3;
- vs[g->nvs].ge = ge->frwd;
-
- if (ge->iy3 > ge->iy2
- || ny > ge->iy3)
- vs[g->nvs].flags = ST_UP;
- else
- vs[g->nvs].flags = 0;
-
- if (ge->iy3 != ge->iy2 || ny != ge->iy3)
- g->nvs++;
- }
- }
-
- } else if (ge->type == GE_LINE) {
- nge = ge->frwd;
-
- /* if it is horizontal, add a hstem */
- /* and the ends as vstems if they brace the line */
- if (ge->iy3 == ge->prev->iy3
- && ge->ix3 != ge->prev->ix3) {
- hs[g->nhs].value = ge->iy3;
- if (ge->ix3 < ge->prev->ix3) {
- hs[g->nhs].flags = ST_FLAT | ST_UP;
- hs[g->nhs].from = ge->ix3;
- hs[g->nhs].to = ge->prev->ix3;
- } else {
- hs[g->nhs].flags = ST_FLAT;
- hs[g->nhs].from = ge->prev->ix3;
- hs[g->nhs].to = ge->ix3;
- }
- hs[g->nhs].origin = ge->ix3;
- hs[g->nhs].ge = ge->frwd;
-
- pge = ge->bkwd;
-
- /* add beginning as vstem */
- vs[g->nvs].value = pge->ix3;
- vs[g->nvs].origin
- = vs[g->nvs].from
- = vs[g->nvs].to = pge->iy3;
- vs[g->nvs].ge = ge;
-
- if(pge->type==GE_CURVE)
- ovalue=pge->iy2;
- else
- ovalue=pge->prev->iy3;
-
- if (pge->iy3 > ovalue)
- vs[g->nvs].flags = ST_UP | ST_END;
- else if (pge->iy3 < ovalue)
- vs[g->nvs].flags = ST_END;
- else
- vs[g->nvs].flags = 0;
-
- if( vs[g->nvs].flags != 0 )
- g->nvs++;
-
- /* add end as vstem */
- vs[g->nvs].value = ge->ix3;
- vs[g->nvs].origin
- = vs[g->nvs].from
- = vs[g->nvs].to = ge->iy3;
- vs[g->nvs].ge = ge->frwd;
-
- if(nge->type==GE_CURVE)
- ovalue=nge->iy1;
- else
- ovalue=nge->iy3;
-
- if (ovalue > ge->iy3)
- vs[g->nvs].flags = ST_UP | ST_END;
- else if (ovalue < ge->iy3)
- vs[g->nvs].flags = ST_END;
- else
- vs[g->nvs].flags = 0;
-
- if( vs[g->nvs].flags != 0 )
- g->nvs++;
-
- g->nhs++;
- }
- /* if it is vertical, add a vstem */
- /* and the ends as hstems if they brace the line */
- else if (ge->ix3 == ge->prev->ix3
- && ge->iy3 != ge->prev->iy3) {
- vs[g->nvs].value = ge->ix3;
- if (ge->iy3 > ge->prev->iy3) {
- vs[g->nvs].flags = ST_FLAT | ST_UP;
- vs[g->nvs].from = ge->prev->iy3;
- vs[g->nvs].to = ge->iy3;
- } else {
- vs[g->nvs].flags = ST_FLAT;
- vs[g->nvs].from = ge->iy3;
- vs[g->nvs].to = ge->prev->iy3;
- }
- vs[g->nvs].origin = ge->iy3;
- vs[g->nvs].ge = ge->frwd;
-
- pge = ge->bkwd;
-
- /* add beginning as hstem */
- hs[g->nhs].value = pge->iy3;
- hs[g->nhs].origin
- = hs[g->nhs].from
- = hs[g->nhs].to = pge->ix3;
- hs[g->nhs].ge = ge;
-
- if(pge->type==GE_CURVE)
- ovalue=pge->ix2;
- else
- ovalue=pge->prev->ix3;
-
- if (pge->ix3 < ovalue)
- hs[g->nhs].flags = ST_UP | ST_END;
- else if (pge->ix3 > ovalue)
- hs[g->nhs].flags = ST_END;
- else
- hs[g->nhs].flags = 0;
-
- if( hs[g->nhs].flags != 0 )
- g->nhs++;
-
- /* add end as hstem */
- hs[g->nhs].value = ge->iy3;
- hs[g->nhs].origin
- = hs[g->nhs].from
- = hs[g->nhs].to = ge->ix3;
- hs[g->nhs].ge = ge->frwd;
-
- if(nge->type==GE_CURVE)
- ovalue=nge->ix1;
- else
- ovalue=nge->ix3;
-
- if (ovalue < ge->ix3)
- hs[g->nhs].flags = ST_UP | ST_END;
- else if (ovalue > ge->ix3)
- hs[g->nhs].flags = ST_END;
- else
- hs[g->nhs].flags = 0;
-
- if( hs[g->nhs].flags != 0 )
- g->nhs++;
-
- g->nvs++;
- }
- /*
- * check the end of line for a not smooth local
- * extremum
- */
- nge = ge->frwd;
-
- if (nge == 0)
- continue;
- else if (nge->type == GE_LINE) {
- nx = nge->ix3;
- ny = nge->iy3;
- } else if (nge->type == GE_CURVE) {
- nx = nge->ix1;
- ny = nge->iy1;
- } else
- continue;
-
- /* check for vertical extremums */
- if ((ge->iy3 > ge->prev->iy3 && ge->iy3 > ny)
- || (ge->iy3 < ge->prev->iy3 && ge->iy3 < ny)) {
- hs[g->nhs].value = ge->iy3;
- hs[g->nhs].from
- = hs[g->nhs].to
- = hs[g->nhs].origin = ge->ix3;
- hs[g->nhs].ge = ge->frwd;
-
- if (ge->ix3 < ge->prev->ix3
- || nx < ge->ix3)
- hs[g->nhs].flags = ST_UP;
- else
- hs[g->nhs].flags = 0;
-
- if (ge->ix3 != ge->prev->ix3 || nx != ge->ix3)
- g->nhs++;
- }
- /*
- * the same point may be both horizontal and vertical
- * extremum
- */
- /* check for horizontal extremums */
- if ((ge->ix3 > ge->prev->ix3 && ge->ix3 > nx)
- || (ge->ix3 < ge->prev->ix3 && ge->ix3 < nx)) {
- vs[g->nvs].value = ge->ix3;
- vs[g->nvs].from
- = vs[g->nvs].to
- = vs[g->nvs].origin = ge->iy3;
- vs[g->nvs].ge = ge->frwd;
-
- if (ge->iy3 > ge->prev->iy3
- || ny > ge->iy3)
- vs[g->nvs].flags = ST_UP;
- else
- vs[g->nvs].flags = 0;
-
- if (ge->iy3 != ge->prev->iy3 || ny != ge->iy3)
- g->nvs++;
- }
- }
- }
-
- g->nhs=addbluestems(hs, g->nhs);
- sortstems(hs, g->nhs);
- sortstems(vs, g->nvs);
-
- if (ISDBG(STEMS))
- debugstems(g->name, hs, g->nhs, vs, g->nvs);
-
- /* find the stems interacting with the Blue Zones */
- markbluestems(hs, g->nhs);
-
- if(subhints) {
- if (ISDBG(SUBSTEMS))
- fprintf(pfa_file, "%% %s: joining subst horizontal stems\n", g->name);
- joinsubstems(hs, hs_pairs, g->nhs, 1);
- uniformstems(hs, hs_pairs, g->nhs);
-
- if (ISDBG(SUBSTEMS))
- fprintf(pfa_file, "%% %s: joining subst vertical stems\n", g->name);
- joinsubstems(vs, vs_pairs, g->nvs, 0);
-
- groupsubstems(g, hs, hs_pairs, g->nhs, vs, vs_pairs, g->nvs);
- }
-
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% %s: joining main horizontal stems\n", g->name);
- g->nhs = joinmainstems(hs, g->nhs, 1);
- if (ISDBG(MAINSTEMS))
- fprintf(pfa_file, "%% %s: joining main vertical stems\n", g->name);
- g->nvs = joinmainstems(vs, g->nvs, 0);
-
- if (ISDBG(MAINSTEMS))
- debugstems(g->name, hs, g->nhs, vs, g->nvs);
-
- if(g->nhs > 0) {
- if ((sp = malloc(sizeof(STEM) * g->nhs)) == 0) {
- fprintf(stderr, "**** not enough memory for hints ****\n");
- exit(255);
- }
- g->hstems = sp;
- memcpy(sp, hs, sizeof(STEM) * g->nhs);
- } else
- g->hstems = 0;
-
- if(g->nvs > 0) {
- if ((sp = malloc(sizeof(STEM) * g->nvs)) == 0) {
- fprintf(stderr, "**** not enough memory for hints ****\n");
- exit(255);
- }
- g->vstems = sp;
- memcpy(sp, vs, sizeof(STEM) * g->nvs);
- } else
- g->vstems = 0;
-
- /* now check that the stems won't overflow the interpreter's stem stack:
- * some interpreters (like X11) push the stems on each change into
- * stack and pop them only after the whole glyphs is completed.
- */
-
- totals = (g->nhs+g->nvs) / 2; /* we count whole stems, not halves */
- lastgrp = -1;
-
- for (ge = g->entries; ge != 0; ge = ge->next) {
- grp=ge->stemid;
- if(grp >= 0 && grp != lastgrp) {
- if(grp==0)
- totals += g->nsbs[0];
- else
- totals += g->nsbs[grp] - g->nsbs[grp-1];
-
- lastgrp = grp;
- }
- }
-
- /* be on the safe side, check for >= , not > */
- if(totals >= max_stemdepth) { /* oops, too deep */
- WARNING_2 {
- fprintf(stderr, "Warning: glyph %s needs hint stack depth %d\n", g->name, totals);
- fprintf(stderr, " (limit %d): removed the substituted hints from it\n", max_stemdepth);
- }
- if(g->nsg > 0) {
- for (ge = g->entries; ge != 0; ge = ge->next)
- ge->stemid = -1;
- free(g->sbstems); g->sbstems = 0;
- free(g->nsbs); g->nsbs = 0;
- g->nsg = 0;
- }
- }
-
- /* now check if there are too many main stems */
- totals = (g->nhs+g->nvs) / 2; /* we count whole stems, not halves */
- if(totals >= max_stemdepth) {
- /* even worse, too much of non-substituted stems */
- WARNING_2 {
- fprintf(stderr, "Warning: glyph %s has %d main hints\n", g->name, totals);
- fprintf(stderr, " (limit %d): removed the hints from it\n", max_stemdepth);
- }
- if(g->vstems) {
- free(g->vstems); g->vstems = 0; g->nvs = 0;
- }
- if(g->hstems) {
- free(g->hstems); g->hstems = 0; g->nhs = 0;
- }
- }
-}
-
-/* convert weird curves that are close to lines into lines.
-*/
-
-void
-fstraighten(
- GLYPH * g
-)
-{
- GENTRY *ge, *pge, *nge, *ige;
- double df;
- int dir;
- double iln, oln;
- int svdir, i, o;
-
- for (ige = g->entries; ige != 0; ige = ige->next) {
- if (ige->type != GE_CURVE)
- continue;
-
- ge = ige;
- pge = ge->bkwd;
- nge = ge->frwd;
-
- df = 0.;
-
- /* look for vertical then horizontal */
- for(i=0; i<2; i++) {
- o = !i; /* other axis */
-
- iln = fabs(ge->fpoints[i][2] - pge->fpoints[i][2]);
- oln = fabs(ge->fpoints[o][2] - pge->fpoints[o][2]);
- /*
- * if current curve is almost a vertical line, and it
- * doesn't begin or end horizontally (and the prev/next
- * line doesn't join smoothly ?)
- */
- if( oln < 1.
- || ge->fpoints[o][2] == ge->fpoints[o][1]
- || ge->fpoints[o][0] == pge->fpoints[o][2]
- || iln > 2.
- || (iln > 1. && iln/oln > 0.1) )
- continue;
-
-
- if(ISDBG(STRAIGHTEN))
- fprintf(stderr,"** straighten almost %s\n", (i? "horizontal":"vertical"));
-
- df = ge->fpoints[i][2] - pge->fpoints[i][2];
- dir = fsign(ge->fpoints[o][2] - pge->fpoints[o][2]);
- ge->type = GE_LINE;
-
- /*
- * suck in all the sequence of such almost lines
- * going in the same direction but not deviating
- * too far from vertical
- */
- iln = fabs(nge->fpoints[i][2] - ge->fpoints[i][2]);
- oln = nge->fpoints[o][2] - ge->fpoints[o][2];
-
- while (fabs(df) <= 5 && nge->type == GE_CURVE
- && dir == fsign(oln) /* that also gives oln != 0 */
- && iln <= 2.
- && ( iln <= 1. || iln/fabs(oln) <= 0.1 ) ) {
- ge->fx3 = nge->fx3;
- ge->fy3 = nge->fy3;
-
- if(ISDBG(STRAIGHTEN))
- fprintf(stderr,"** straighten collapsing %s\n", (i? "horizontal":"vertical"));
- freethisge(nge);
- fixendpath(ge);
- pge = ge->bkwd;
- nge = ge->frwd;
-
- df = ge->fpoints[i][2] - pge->fpoints[i][2];
-
- iln = fabs(nge->fpoints[i][2] - ge->fpoints[i][2]);
- oln = nge->fpoints[o][2] - ge->fpoints[o][2];
- }
-
- /* now check what do we have as previous/next line */
-
- if(ge != pge) {
- if( pge->type == GE_LINE && pge->fpoints[i][2] == pge->prev->fpoints[i][2]
- && fabs(pge->fpoints[o][2] != pge->prev->fpoints[o][2]) ) {
- if(ISDBG(STRAIGHTEN)) fprintf(stderr,"** straighten join with previous 0x%x 0x%x\n", pge, ge);
- /* join the previous line with current */
- pge->fx3 = ge->fx3;
- pge->fy3 = ge->fy3;
-
- ige = freethisge(ge)->prev; /* keep the iterator valid */
- ge = pge;
- fixendpath(ge);
- pge = ge->bkwd;
- }
- }
-
- if(ge != nge) {
- if (nge->type == GE_LINE && nge->fpoints[i][2] == ge->fpoints[i][2]
- && fabs(nge->fpoints[o][2] != ge->fpoints[o][2]) ) {
- if(ISDBG(STRAIGHTEN)) fprintf(stderr,"** straighten join with next 0x%x 0x%x\n", ge, nge);
- /* join the next line with current */
- ge->fx3 = nge->fx3;
- ge->fy3 = nge->fy3;
-
- freethisge(nge);
- fixendpath(ge);
- pge = ge->bkwd;
- nge = ge->frwd;
-
- }
- }
-
- if(ge != pge) {
- /* try to align the lines if neccessary */
- if(df != 0.)
- fclosegap(ge, ge, i, df, NULL);
- } else {
- /* contour consists of only one line, get rid of it */
- ige = freethisge(ge); /* keep the iterator valid */
- if(ige == 0) /* this was the last contour */
- return;
- ige = ige->prev;
- }
-
- break; /* don't bother looking at the other axis */
- }
- }
-}
-
-/* solve a square equation,
- * returns the number of solutions found, the solutions
- * are stored in res which should point to array of two doubles.
- * min and max limit the area for solutions
- */
-
-static int
-fsqequation(
- double a,
- double b,
- double c,
- double *res,
- double min,
- double max
-)
-{
- double D;
- int n;
-
- if(ISDBG(SQEQ)) fprintf(stderr, "sqeq(%g,%g,%g) [%g;%g]\n", a, b, c, min, max);
-
- if(fabs(a) < 0.000001) { /* if a linear equation */
- n=0;
- if(fabs(b) < 0.000001) /* not an equation at all */
- return 0;
- res[0] = -c/b;
- if(ISDBG(SQEQ)) fprintf(stderr, "sqeq: linear t=%g\n", res[0]);
- if(res[0] >= min && res[0] <= max)
- n++;
- return n;
- }
-
- D = b*b - 4.0*a*c;
- if(ISDBG(SQEQ)) fprintf(stderr, "sqeq: D=%g\n", D);
- if(D<0)
- return 0;
-
- D = sqrt(D);
-
- n=0;
- res[0] = (-b+D) / (2*a);
- if(ISDBG(SQEQ)) fprintf(stderr, "sqeq: t1=%g\n", res[0]);
- if(res[0] >= min && res[0] <= max)
- n++;
-
- res[n] = (-b-D) / (2*a);
- if(ISDBG(SQEQ)) fprintf(stderr, "sqeq: t2=%g\n", res[n]);
- if(res[n] >= min && res[n] <= max)
- n++;
-
- /* return 2nd solution only if it's different enough */
- if(n==2 && fabs(res[0]-res[1])<0.000001)
- n=1;
-
- return n;
-}
-
-/* check that the curves don't cross quadrant boundary */
-/* (float) */
-
-/*
- Here we make sure that the curve does not continue past
- horizontal or vertical extremums. The horizontal points are
- explained, vertical points are by analogy.
-
- The horizontal points are where the derivative
- dy/dx is equal to 0. But the Bezier curves are defined by
- parametric formulas
- x=fx(t)
- y=fy(t)
- so finding this derivative is complicated.
- Also even if we find some point (x,y) splitting at this point
- is far not obvious. Fortunately we can use dy/dt = 0 instead,
- this gets to a rather simple square equation and splitting
- at a known value of t is simple.
-
- The formulas are:
-
- y = A*(1-t)^3 + 3*B*(1-t)^2*t + 3*C*(1-t)*t^2 + D*t^3
- y = (-A+3*B-3*C+D)*t^3 + (3*A-6*B+3*C)*t^2 + (-3*A+3*B)*t + A
- dy/dt = 3*(-A+3*B-3*C+D)*t^2 + 2*(3*A-6*B+3*C)*t + (-3*A+3*B)
- */
-
-void
-ffixquadrants(
- GLYPH *g
-)
-{
- GENTRY *ge, *nge;
- int i, j, np, oldnp;
- double sp[5]; /* split points, last one empty */
- char dir[5]; /* for debugging, direction by which split happened */
- double a, b, *pts; /* points of a curve */
-
- for (ge = g->entries; ge != 0; ge = ge->next) {
- if (ge->type != GE_CURVE)
- continue;
-
- doagain:
- np = 0; /* no split points yet */
- if(ISDBG(QUAD)) {
- fprintf(stderr, "%s: trying 0x%x (%g %g) (%g %g) (%g %g) (%g %g)\n ", g->name,
- ge, ge->prev->fx3, ge->prev->fy3, ge->fx1, ge->fy1, ge->fx2, ge->fy2,
- ge->fx3, ge->fy3);
- }
- for(i=0; i<2; i++) { /* first for x then for y */
- /* find the cooridnates of control points */
- a = ge->prev->fpoints[i][2];
- pts = &ge->fpoints[i][0];
-
- oldnp = np;
- np += fsqequation(
- 3.0*(-a + 3.0*pts[0] - 3.0*pts[1] + pts[2]),
- 6.0*(a - 2.0*pts[0] + pts[1]),
- 3.0*(-a + pts[0]),
- &sp[np],
- 0.0, 1.0); /* XXX range is [0;1] */
-
- if(np == oldnp)
- continue;
-
- if(ISDBG(QUAD))
- fprintf(stderr, "%s: 0x%x: %d pts(%c): ",
- g->name, ge, np-oldnp, i? 'y':'x');
-
- /* remove points that are too close to the ends
- * because hor/vert ends are permitted, also
- * if the split point is VERY close to the ends
- * but not exactly then just flatten it and check again.
- */
- for(j = oldnp; j<np; j++) {
- dir[j] = i;
- if(ISDBG(QUAD))
- fprintf(stderr, "%g ", sp[j]);
- if(sp[j] < 0.03) { /* front end of curve */
- if(ge->fpoints[i][0] != ge->prev->fpoints[i][2]) {
- ge->fpoints[i][0] = ge->prev->fpoints[i][2];
- if(ISDBG(QUAD)) fprintf(stderr, "flattened at front\n");
- goto doagain;
- }
- if( ge->fpoints[i][1] != ge->fpoints[i][0]
- && fsign(ge->fpoints[i][2] - ge->fpoints[i][1])
- != fsign(ge->fpoints[i][1] - ge->fpoints[i][0]) ) {
- ge->fpoints[i][1] = ge->fpoints[i][0];
- if(ISDBG(QUAD)) fprintf(stderr, "flattened zigzag at front\n");
- goto doagain;
- }
- sp[j] = sp[j+1]; np--; j--;
- if(ISDBG(QUAD)) fprintf(stderr, "(front flat) ");
- } else if(sp[j] > 0.97) { /* rear end of curve */
- if(ge->fpoints[i][1] != ge->fpoints[i][2]) {
- ge->fpoints[i][1] = ge->fpoints[i][2];
- if(ISDBG(QUAD)) fprintf(stderr, "flattened at rear\n");
- goto doagain;
- }
- if( ge->fpoints[i][0] != ge->fpoints[i][1]
- && fsign(ge->prev->fpoints[i][2] - ge->fpoints[i][0])
- != fsign(ge->fpoints[i][0] - ge->fpoints[i][1]) ) {
- ge->fpoints[i][0] = ge->fpoints[i][1];
- if(ISDBG(QUAD)) fprintf(stderr, "flattened zigzag at rear\n");
- goto doagain;
- }
- sp[j] = sp[j+1]; np--; j--;
- if(ISDBG(QUAD)) fprintf(stderr, "(rear flat) ");
- }
- }
- if(ISDBG(QUAD)) fprintf(stderr, "\n");
- }
-
- if(np==0) /* no split points, leave it alone */
- continue;
-
- if(ISDBG(QUAD)) {
- fprintf(stderr, "%s: splitting 0x%x (%g %g) (%g %g) (%g %g) (%g %g) at %d points\n ", g->name,
- ge, ge->prev->fx3, ge->prev->fy3, ge->fx1, ge->fy1, ge->fx2, ge->fy2,
- ge->fx3, ge->fy3, np);
- for(i=0; i<np; i++)
- fprintf(stderr, "%g(%c) ", sp[i], dir[i] ? 'y':'x');
- fprintf(stderr, "\n");
- }
-
- /* sort the points ascending */
- for(i=0; i<np; i++)
- for(j=i+1; j<np; j++)
- if(sp[i] > sp[j]) {
- a = sp[i]; sp[i] = sp[j]; sp[j] = a;
- }
-
- /* now finally do the split on each point */
- for(j=0; j<np; j++) {
- double k1, k2, c;
-
- k1 = sp[j];
- k2 = 1 - k1;
-
- if(ISDBG(QUAD)) fprintf(stderr, " 0x%x %g/%g\n", ge, k1, k2);
-
- nge = newgentry(GEF_FLOAT);
- (*nge) = (*ge);
-
-#define SPLIT(pt1, pt2) ( (pt1) + k1*((pt2)-(pt1)) ) /* order is important! */
- for(i=0; i<2; i++) { /* for x and y */
- a = ge->fpoints[i][0]; /* get the middle points */
- b = ge->fpoints[i][1];
-
- /* calculate new internal points */
- c = SPLIT(a, b);
-
- ge->fpoints[i][0] = SPLIT(ge->prev->fpoints[i][2], a);
- ge->fpoints[i][1] = SPLIT(ge->fpoints[i][0], c);
-
- nge->fpoints[i][1] = SPLIT(b, nge->fpoints[i][2]);
- nge->fpoints[i][0] = SPLIT(c, nge->fpoints[i][1]);
-
- ge->fpoints[i][2] = SPLIT(ge->fpoints[i][1],
- + nge->fpoints[i][0]);
- }
-#undef SPLIT
-
- addgeafter(ge, nge);
-
- /* go to the next part, adjust remaining points */
- ge = nge;
- for(i=j+1; i<np; i++)
- sp[i] = (sp[i]-k1) / k2;
- }
- }
-
-}
-
-/* check if a curve is a zigzag */
-
-static int
-iiszigzag(
- GENTRY *ge
-)
-{
- double k, k1, k2;
- int a, b;
-
- if (ge->type != GE_CURVE)
- return 0;
-
- a = ge->iy2 - ge->iy1;
- b = ge->ix2 - ge->ix1;
- if(a == 0) {
- if(b == 0) {
- return 0;
- } else
- k = FBIGVAL;
- } else
- k = fabs((double) b / (double) a);
-
- a = ge->iy1 - ge->prev->iy3;
- b = ge->ix1 - ge->prev->ix3;
- if(a == 0) {
- if(b == 0) {
- return 0;
- } else
- k1 = FBIGVAL;
- } else
- k1 = fabs((double) b / (double) a);
-
- a = ge->iy3 - ge->iy2;
- b = ge->ix3 - ge->ix2;
- if(a == 0) {
- if(b == 0) {
- return 0;
- } else
- k2 = FBIGVAL;
- } else
- k2 = fabs((double) b / (double) a);
-
- /* if the curve is not a zigzag */
- if ((k1+0.0001 >= k && k2 <= k+0.0001) || (k1 <= k+0.0001 && k2+0.0001 >= k))
- return 0;
- else
- return 1;
-}
-
-/* check if a curve is a zigzag - floating */
-
-static int
-fiszigzag(
- GENTRY *ge
-)
-{
- double k, k1, k2;
- double a, b;
-
- if (ge->type != GE_CURVE)
- return 0;
-
- a = fabs(ge->fy2 - ge->fy1);
- b = fabs(ge->fx2 - ge->fx1);
- if(a < FEPS) {
- if(b < FEPS) {
- return 0;
- } else
- k = FBIGVAL;
- } else
- k = b / a;
-
- a = fabs(ge->fy1 - ge->prev->fy3);
- b = fabs(ge->fx1 - ge->prev->fx3);
- if(a < FEPS) {
- if(b < FEPS) {
- return 0;
- } else
- k1 = FBIGVAL;
- } else
- k1 = b / a;
-
- a = fabs(ge->fy3 - ge->fy2);
- b = fabs(ge->fx3 - ge->fx2);
- if(a < FEPS) {
- if(b < FEPS) {
- return 0;
- } else
- k2 = FBIGVAL;
- } else
- k2 = b / a;
-
- /* if the curve is not a zigzag */
- if ((k1+0.0001 >= k && k2 <= k+0.0001) || (k1 <= k+0.0001 && k2+0.0001 >= k))
- return 0;
- else
- return 1;
-}
-
-/* split the zigzag-like curves into two parts */
-
-void
-fsplitzigzags(
- GLYPH * g
-)
-{
- GENTRY *ge, *nge;
- double a, b, c, d;
-
- assertisfloat(g, "splitting zigzags");
- for (ge = g->entries; ge != 0; ge = ge->next) {
- if (ge->type != GE_CURVE)
- continue;
-
- /* if the curve is not a zigzag */
- if ( !fiszigzag(ge) ) {
- continue;
- }
-
- if(ISDBG(FCONCISE)) {
- double maxsc1, maxsc2;
- fprintf(stderr, "split a zigzag ");
- fnormalizege(ge);
- if( fcrossraysge(ge, ge, &maxsc1, &maxsc2, NULL) ) {
- fprintf(stderr, "sc1=%g sc2=%g\n", maxsc1, maxsc2);
- } else {
- fprintf(stderr, "(rays don't cross)\n");
- }
- }
- /* split the curve by t=0.5 */
- nge = newgentry(GEF_FLOAT);
- (*nge) = (*ge);
- nge->type = GE_CURVE;
-
- a = ge->prev->fx3;
- b = ge->fx1;
- c = ge->fx2;
- d = ge->fx3;
- nge->fx3 = d;
- nge->fx2 = (c + d) / 2.;
- nge->fx1 = (b + 2. * c + d) / 4.;
- ge->fx3 = (a + b * 3. + c * 3. + d) / 8.;
- ge->fx2 = (a + 2. * b + c) / 4.;
- ge->fx1 = (a + b) / 2.;
-
- a = ge->prev->fy3;
- b = ge->fy1;
- c = ge->fy2;
- d = ge->fy3;
- nge->fy3 = d;
- nge->fy2 = (c + d) / 2.;
- nge->fy1 = (b + 2. * c + d) / 4.;
- ge->fy3 = (a + b * 3. + c * 3. + d) / 8.;
- ge->fy2 = (a + 2. * b + c) / 4.;
- ge->fy1 = (a + b) / 2.;
-
- addgeafter(ge, nge);
-
- if(ISDBG(FCONCISE)) {
- dumppaths(g, ge, nge);
- }
- }
-}
-
-/* free this GENTRY, returns what was ge->next
- * (ge must be of type GE_LINE or GE_CURVE)
- * works on both float and int entries
- */
-
-static GENTRY *
-freethisge(
- GENTRY *ge
-)
-{
- GENTRY *xge;
-
- if (ge->bkwd != ge->prev) {
- /* at beginning of the contour */
-
- xge = ge->bkwd;
- if(xge == ge) { /* was the only line in contour */
- /* remove the contour completely */
- /* prev is GE_MOVE, next is GE_PATH, remove them all */
-
- /* may be the first contour, then ->bkwd points to ge->entries */
- if(ge->prev->prev == 0)
- *(GENTRY **)(ge->prev->bkwd) = ge->next->next;
- else
- ge->prev->prev->next = ge->next->next;
-
- if(ge->next->next) {
- ge->next->next->prev = ge->prev->prev;
- ge->next->next->bkwd = ge->prev->bkwd;
- }
-
- xge = ge->next->next;
- free(ge->prev); free(ge->next); free(ge);
- return xge;
- }
-
- /* move the start point of the contour */
- if(ge->flags & GEF_FLOAT) {
- ge->prev->fx3 = xge->fx3;
- ge->prev->fy3 = xge->fy3;
- } else {
- ge->prev->ix3 = xge->ix3;
- ge->prev->iy3 = xge->iy3;
- }
- } else if(ge->frwd != ge->next) {
- /* at end of the contour */
-
- xge = ge->frwd->prev;
- /* move the start point of the contour */
- if(ge->flags & GEF_FLOAT) {
- xge->fx3 = ge->bkwd->fx3;
- xge->fy3 = ge->bkwd->fy3;
- } else {
- xge->ix3 = ge->bkwd->ix3;
- xge->iy3 = ge->bkwd->iy3;
- }
- }
-
- ge->prev->next = ge->next;
- ge->next->prev = ge->prev;
- ge->bkwd->frwd = ge->frwd;
- ge->frwd->bkwd = ge->bkwd;
-
- xge = ge->next;
- free(ge);
- return xge;
-}
-
-/* inserts a new gentry (LINE or CURVE) after another (MOVE
- * or LINE or CURVE)
- * corrects the first GE_MOVE if neccessary
- */
-
-static void
-addgeafter(
- GENTRY *oge, /* after this */
- GENTRY *nge /* insert this */
-)
-{
- if(oge->type == GE_MOVE) {
- /* insert before next */
- if(oge->next->type == GE_PATH) {
- /* first and only GENTRY in path */
- nge->frwd = nge->bkwd = nge;
- } else {
- nge->frwd = oge->next;
- nge->bkwd = oge->next->bkwd;
- oge->next->bkwd->frwd = nge;
- oge->next->bkwd = nge;
- }
- } else {
- nge->frwd = oge->frwd;
- nge->bkwd = oge;
- oge->frwd->bkwd = nge;
- oge->frwd = nge;
- }
-
- nge->next = oge->next;
- nge->prev = oge;
- oge->next->prev = nge;
- oge->next = nge;
-
- if(nge->frwd->prev->type == GE_MOVE) {
- /* fix up the GE_MOVE entry */
- if(nge->flags & GEF_FLOAT) {
- nge->frwd->prev->fx3 = nge->fx3;
- nge->frwd->prev->fy3 = nge->fy3;
- } else {
- nge->frwd->prev->ix3 = nge->ix3;
- nge->frwd->prev->iy3 = nge->iy3;
- }
- }
-}
-
-/*
- * Check if this GENTRY happens to be at the end of path
- * and fix the first MOVETO accordingly
- * handles both int and float
- */
-
-static void
-fixendpath(
- GENTRY *ge
-)
-{
- GENTRY *mge;
-
- mge = ge->frwd->prev;
- if(mge->type == GE_MOVE) {
- if(ge->flags & GEF_FLOAT) {
- mge->fx3 = ge->fx3;
- mge->fy3 = ge->fy3;
- } else {
- mge->ix3 = ge->ix3;
- mge->iy3 = ge->iy3;
- }
- }
-}
-
-/*
- * This function adjusts the rest of path (the part from...to is NOT changed)
- * to cover the specified gap by the specified axis (0 - X, 1 - Y).
- * Gap is counted in direction (end_of_to - beginning_of_from).
- * Returns by how much the gap was not closed (0.0 if it was fully closed).
- * Ret contains by how much the first and last points of [from...to]
- * were moved to bring them in consistence to the rest of the path.
- * If ret==NULL then this info is not returned.
- */
-
-static double
-fclosegap(
- GENTRY *from,
- GENTRY *to,
- int axis,
- double gap,
- double *ret
-)
-{
-#define TIMESLARGER 10. /* how many times larger must be a curve to not change too much */
- double rm[2];
- double oldpos[2];
- double times, limit, df, dx;
- int j, k;
- GENTRY *xge, *pge, *nge, *bge[2];
-
- /* remember the old points to calculate ret */
- oldpos[0] = from->prev->fpoints[axis][2];
- oldpos[1] = to->fpoints[axis][2];
-
- rm[0] = rm[1] = gap / 2. ;
-
- bge[0] = from; /* this is convenient for iterations */
- bge[1] = to;
-
- /* first try to modify large curves but if have none then settle for small */
- for(times = (TIMESLARGER-1); times > 0.1; times /= 2. ) {
-
- if(rm[0]+rm[1] == 0.)
- break;
-
- /* iterate in both directions, backwards then forwards */
- for(j = 0; j<2; j++) {
-
- if(rm[j] == 0.) /* if this direction is exhausted */
- continue;
-
- limit = fabs(rm[j]) * (1.+times);
-
- for(xge = bge[j]->cntr[j]; xge != bge[!j]; xge = xge->cntr[j]) {
- dx = xge->fpoints[axis][2] - xge->prev->fpoints[axis][2];
- df = fabs(dx) - limit;
- if( df <= FEPS ) /* curve is too small to change */
- continue;
-
- if( df >= fabs(rm[j]) )
- df = rm[j];
- else
- df *= fsign(rm[j]); /* we may cover this part of rm */
-
- rm[j] -= df;
- limit = fabs(rm[j]) * (1.+times);
-
- if(xge->type == GE_CURVE) { /* correct internal points */
- double scale = ((dx+df) / dx) - 1.;
- double base;
-
- if(j)
- base = xge->fpoints[axis][2];
- else
- base = xge->prev->fpoints[axis][2];
-
- for(k = 0; k<2; k++)
- xge->fpoints[axis][k] += scale *
- (xge->fpoints[axis][k] - base);
- }
-
- /* move all the intermediate lines */
- if(j) {
- df = -df; /* absolute direction */
- pge = bge[1]->bkwd;
- nge = xge->bkwd;
- } else {
- xge->fpoints[axis][2] += df;
- pge = bge[0];
- nge = xge->frwd;
- }
- while(nge != pge) {
- if(nge->type == GE_CURVE) {
- nge->fpoints[axis][0] +=df;
- nge->fpoints[axis][1] +=df;
- }
- nge->fpoints[axis][2] += df;
- if(nge->next != nge->frwd) { /* last entry of contour */
- nge->frwd->prev->fpoints[axis][2] += df;
- }
- nge = nge->cntr[!j];
- }
-
- if(rm[j] == 0.)
- break;
- }
- }
- }
-
- /* find the difference */
- oldpos[0] -= from->prev->fpoints[axis][2];
- oldpos[1] -= to->fpoints[axis][2];
-
- if(ret) {
- ret[0] = oldpos[0] - from->prev->fpoints[axis][2];
- ret[1] = oldpos[1] - to->fpoints[axis][2];
- }
-
-#if 0
- if( rm[0]+rm[1] != gap - oldpos[1] + oldpos[0]) {
- fprintf(stderr, "** gap=%g rm[0]=%g rm[1]=%g o[0]=%g o[1]=%g rg=%g og=%g\n",
- gap, rm[0], rm[1], oldpos[0], oldpos[1], rm[0]+rm[1],
- gap - oldpos[1] + oldpos[0]);
- }
-#endif
-
- return rm[0]+rm[1];
-#undef TIMESLARGER
-}
-
-/* remove the lines or curves smaller or equal to the size limit */
-
-static void
-fdelsmall(
- GLYPH *g,
- double minlen
-)
-{
- GENTRY *ge, *nge, *pge, *xge, *next;
- int i, k;
- double dx, dy, d2, d2m;
- double minlen2;
-#define TIMESLARGER 10. /* how much larger must be a curve to not change too much */
-
- minlen2 = minlen*minlen;
-
- for (ge = g->entries; ge != 0; ge = next) {
- next = ge->next;
-
- if (ge->type != GE_CURVE && ge->type != GE_LINE)
- continue;
-
- d2m = 0;
- for(i= (ge->type==GE_CURVE? 0: 2); i<3; i++) {
- dx = ge->fxn[i] - ge->prev->fx3;
- dy = ge->fyn[i] - ge->prev->fy3;
- d2 = dx*dx + dy*dy;
- if(d2m < d2)
- d2m = d2;
- }
-
- if( d2m > minlen2 ) { /* line is not too small */
- /* XXX add more normalization here */
- continue;
- }
-
- /* if the line is too small */
-
- /* check forwards if we have a whole sequence of them */
- nge = ge;
- for(xge = ge->frwd; xge != ge; xge = xge->frwd) {
- d2m = 0;
- for(i= (xge->type==GE_CURVE? 0: 2); i<3; i++) {
- dx = xge->fxn[i] - xge->prev->fx3;
- dy = xge->fyn[i] - xge->prev->fy3;
- d2 = dx*dx + dy*dy;
- if(d2m < d2)
- d2m = d2;
- }
- if( d2m > minlen2 ) /* line is not too small */
- break;
- nge = xge;
- if(next == nge) /* move the next step past this sequence */
- next = next->next;
- }
-
- /* check backwards if we have a whole sequence of them */
- pge = ge;
- for(xge = ge->bkwd; xge != ge; xge = xge->bkwd) {
- d2m = 0;
- for(i= (xge->type==GE_CURVE? 0: 2); i<3; i++) {
- dx = xge->fxn[i] - xge->prev->fx3;
- dy = xge->fyn[i] - xge->prev->fy3;
- d2 = dx*dx + dy*dy;
- if(d2m < d2)
- d2m = d2;
- }
- if( d2m > minlen2 ) /* line is not too small */
- break;
- pge = xge;
- }
-
- /* now we have a sequence of small fragments in pge...nge (inclusive) */
-
- if(ISDBG(FCONCISE)) {
- fprintf(stderr, "glyph %s has very small fragments(%x..%x..%x)\n",
- g->name, pge, ge, nge);
- dumppaths(g, pge, nge);
- }
-
- /* reduce whole sequence to one part and remember the middle point */
- if(pge != nge) {
- while(1) {
- xge = pge->frwd;
- if(xge == nge) {
- pge->fx1 = pge->fx2 = pge->fx3;
- pge->fx3 = nge->fx3;
- pge->fy1 = pge->fy2 = pge->fy3;
- pge->fy3 = nge->fy3;
- pge->type = GE_CURVE;
- freethisge(nge);
- break;
- }
- if(xge == nge->bkwd) {
- pge->fx1 = pge->fx2 = (pge->fx3+xge->fx3)/2.;
- pge->fx3 = nge->fx3;
- pge->fy1 = pge->fy2 = (pge->fy3+xge->fy3)/2.;
- pge->fy3 = nge->fy3;
- pge->type = GE_CURVE;
- freethisge(nge);
- freethisge(xge);
- break;
- }
- freethisge(pge); pge = xge;
- xge = nge->bkwd; freethisge(nge); nge = xge;
- }
- }
- ge = pge;
-
- /* check if the whole sequence is small */
- dx = ge->fx3 - ge->prev->fx3;
- dy = ge->fy3 - ge->prev->fy3;
- d2 = dx*dx + dy*dy;
-
- if( d2 > minlen2 ) { /* no, it is not */
- double b, d;
-
- WARNING_3 fprintf(stderr, "glyph %s had a sequence of fragments < %g points each, reduced to one curve\n",
- g->name, minlen);
-
- /* check that we did not create a monstrosity spanning quadrants */
- if(fsign(ge->fx1 - ge->prev->fx1) * fsign(ge->fx3 - ge->fx1) < 0
- || fsign(ge->fy1 - ge->prev->fy1) * fsign(ge->fy3 - ge->fy1) < 0 ) {
- /* yes, we did; are both parts of this thing big enough ? */
- dx = ge->fx1 - ge->prev->fx3;
- dy = ge->fy1 - ge->prev->fy3;
- d2 = dx*dx + dy*dy;
-
- dx = ge->fx3 - ge->fx1;
- dy = ge->fy3 - ge->fy1;
- d2m = dx*dx + dy*dy;
-
- if(d2 > minlen2 && d2m > minlen2) { /* make two straights */
- nge = newgentry(GEF_FLOAT);
- *nge = *ge;
-
- for(i=0; i<2; i++) {
- ge->fpoints[i][2] = ge->fpoints[i][0];
- b = nge->fpoints[i][0];
- d = nge->fpoints[i][2] - b;
- nge->fpoints[i][0] = b + 0.1*d;
- nge->fpoints[i][1] = b + 0.9*d;
- }
- }
- for(i=0; i<2; i++) { /* make one straight or first of two straights */
- b = ge->prev->fpoints[i][2];
- d = ge->fpoints[i][2] - b;
- ge->fpoints[i][0] = b + 0.1*d;
- ge->fpoints[i][1] = b + 0.9*d;
- }
- }
- continue;
- }
-
- if(ge->frwd == ge) { /* points to itself, just remove the path completely */
- WARNING_3 fprintf(stderr, "glyph %s had a path made of fragments < %g points each, removed\n",
- g->name, minlen);
-
- next = freethisge(ge);
- continue;
- }
-
- /* now close the gap by x and y */
- for(i=0; i<2; i++) {
- double gap;
-
- gap = ge->fpoints[i][2] - ge->prev->fpoints[i][2];
- if( fclosegap(ge, ge, i, gap, NULL) != 0.0 ) {
- double scale, base;
-
- /* not good, as the last resort just scale the next line */
- gap = ge->fpoints[i][2] - ge->prev->fpoints[i][2];
-
- if(ISDBG(FCONCISE))
- fprintf(stderr, " last resort on %c: closing next by %g\n",
- (i==0 ? 'x' : 'y'), gap);
-
- nge = ge->frwd;
- base = nge->fpoints[i][2];
- dx = ge->fpoints[i][2] - base;
- if(fabs(dx) < FEPS)
- continue;
-
- scale = ((dx-gap) / dx);
-
- if(nge->type == GE_CURVE)
- for(k = 0; k<2; k++)
- nge->fpoints[i][k] = base +
- scale * (nge->fpoints[i][k] - base);
-
- ge->fpoints[i][2] -= gap;
- }
- }
-
- /* OK, the gap is closed - remove this useless GENTRY */
- freethisge(ge);
- }
-#undef TIMESLARGER
-}
-
-/* find the point where two rays continuing vectors cross
- * returns 1 if they cross, 0 if they don't
- * If they cross optionally (if the pointers are not NULL) returns
- * the maximal scales for both vectors and also optionally the point
- * where the rays cross (twice).
- * Expects that the curves are normalized.
- *
- * For convenience there are 2 front-end functions taking
- * arguments in different formats
- */
-
-struct ray {
- double x1, y1, x2, y2;
- int isvert;
- double k, b; /* lines are represented as y = k*x + b */
- double *maxp;
-};
-static struct ray ray[3];
-
-/* the back-end doing the actual work
- * the rays are defined in the static array ray[]
- */
-
-static int
-fcrossraysxx(
- double crossdot[2][2]
-)
-{
- double x, y, max;
- int i;
-
- for(i=0; i<2; i++) {
- if(ray[i].x1 == ray[i].x2)
- ray[i].isvert = 1;
- else {
- ray[i].isvert = 0;
- ray[i].k = (ray[i].y2 - ray[i].y1) / (ray[i].x2 - ray[i].x1);
- ray[i].b = ray[i].y2 - ray[i].k * ray[i].x2;
- }
- }
-
- if(ray[0].isvert && ray[1].isvert) {
- if(ISDBG(FCONCISE)) fprintf(stderr, "crossrays: both vertical\n");
- return 0; /* both vertical, don't cross */
- }
-
- if(ray[1].isvert) {
- ray[2] = ray[0]; /* exchange them */
- ray[0] = ray[1];
- ray[1] = ray[2];
- }
-
- if(ray[0].isvert) {
- x = ray[0].x1;
- } else {
- if( fabs(ray[0].k - ray[1].k) < FEPS) {
- if(ISDBG(FCONCISE)) fprintf(stderr, "crossrays: parallel lines, k = %g, %g\n",
- ray[0].k, ray[1].k);
- return 0; /* parallel lines */
- }
- x = (ray[1].b - ray[0].b) / (ray[0].k - ray[1].k) ;
- }
- y = ray[1].k * x + ray[1].b;
-
- for(i=0; i<2; i++) {
- if(ray[i].isvert)
- max = (y - ray[i].y1) / (ray[i].y2 - ray[i].y1);
- else
- max = (x - ray[i].x1) / (ray[i].x2 - ray[i].x1);
- /* check if wrong sides of rays cross */
- if( max < 0 ) {
- if(ISDBG(FCONCISE)) fprintf(stderr, "crossrays: %c scale=%g @(%g,%g) (%g,%g)<-(%g,%g)\n",
- (i?'Y':'X'), max, x, y, ray[i].x2, ray[i].y2, ray[i].x1, ray[i].y1);
- return 0;
- }
- if(ray[i].maxp)
- *ray[i].maxp = max;
- }
- if(crossdot != 0) {
- crossdot[0][0] = crossdot[1][0] = x;
- crossdot[0][1] = crossdot[1][1] = y;
- }
- return 1;
-}
-
-/* the front-end getting the arguments from 4 dots defining
- * a curve in the same format as for fapproxcurve():
- * rays are defined as beginning and end of the curve,
- * the crossdot is inserted as the two middle dots of the curve
- */
-
-int
-fcrossrayscv(
- double curve[4][2 /*X,Y*/],
- double *max1,
- double *max2
-)
-{
- ray[0].x1 = curve[0][X];
- ray[0].y1 = curve[0][Y];
- ray[0].x2 = curve[1][X];
- ray[0].y2 = curve[1][Y];
- ray[0].maxp = max1;
-
- ray[1].x1 = curve[2][X];
- ray[1].y1 = curve[2][Y];
- ray[1].x2 = curve[3][X];
- ray[1].y2 = curve[3][Y];
- ray[1].maxp = max2;
-
- return fcrossraysxx(&curve[1]);
-}
-
-/* the front-end getting the arguments from gentries:
- * rays are defined as beginning of curve1 and end of curve 2
- */
-
-int
-fcrossraysge(
- GENTRY *ge1,
- GENTRY *ge2,
- double *max1,
- double *max2,
- double crossdot[2][2]
-)
-{
- ray[0].x1 = ge1->prev->fx3;
- ray[0].y1 = ge1->prev->fy3;
- ray[0].x2 = ge1->fpoints[X][ge1->ftg];
- ray[0].y2 = ge1->fpoints[Y][ge1->ftg];
- ray[0].maxp = max1;
-
- ray[1].x1 = ge2->fx3;
- ray[1].y1 = ge2->fy3;
- if(ge2->rtg < 0) {
- ray[1].x2 = ge2->prev->fx3;
- ray[1].y2 = ge2->prev->fy3;
- } else {
- ray[1].x2 = ge2->fpoints[X][ge2->rtg];
- ray[1].y2 = ge2->fpoints[Y][ge2->rtg];
- }
- ray[1].maxp = max2;
-
- return fcrossraysxx(crossdot);
-}
-
-/* debugging printout functions */
-
-#if defined(DEBUG_DOTSEG) || defined(DEBUG_DOTCURVE) || defined(DEBUG_APPROXCV)
-
-/* for debugging */
-static
-printdot(
- double dot[2]
-)
-{
- fprintf(stderr, "(%g,%g)", dot[0], dot[1]);
-}
-
-static
-printseg(
- double seg[2][2]
-)
-{
- putc('[', stderr);
- printdot(seg[0]);
- putc(' ', stderr);
- printdot(seg[1]);
- putc(']', stderr);
-}
-
-#endif /* DEBUG_* */
-
-/*
- * Find squared distance from a dot to a line segment
- */
-
-double
-fdotsegdist2(
- double seg[2][2 /*X,Y*/],
- double dot[2 /*X,Y*/]
-)
-{
-#define x1 seg[0][X]
-#define y1 seg[0][Y]
-#define x2 seg[1][X]
-#define y2 seg[1][Y]
-#define xdot dot[X]
-#define ydot dot[Y]
-
- double dx, dy; /* segment dimensions */
- double kline, bline; /* segment line formula is y=k*x+b */
- double kperp, bperp; /* perpendicular from the dot to the line */
- double xcross, ycross; /* where the perpendicular crosses the segment */
-
-/* handle the situation where the nearest point of the segment is its end */
-#define HANDLE_LIMITS(less12, lesscr1, lesscr2) \
- if( less12 ) { \
- if( lesscr1 ) { \
- xcross = x1; \
- ycross = y1; \
- } else if( !(lesscr2) ) { \
- xcross = x2; \
- ycross = y2; \
- } \
- } else { \
- if( !(lesscr1) ) { \
- xcross = x1; \
- ycross = y1; \
- } else if( lesscr2 ) { \
- xcross = x2; \
- ycross = y2; \
- } \
- } \
- /* end of macro */
-
-
- dx = x2 - x1;
- dy = y2 - y1;
-
- if(fabs(dx) < FEPS) {
- /* special case - vertical line */
-#ifdef DEBUG_DOTSEG
- printf("vertical line!\n");
-#endif
- xcross = x1;
- ycross = ydot;
- HANDLE_LIMITS( y1 < y2, ycross < y1, ycross < y2);
- } else if(fabs(dy) < FEPS) {
- /* special case - horizontal line */
-#ifdef DEBUG_DOTSEG
- printf("horizontal line!\n");
-#endif
- xcross = xdot;
- ycross = y1;
- HANDLE_LIMITS( x1 < x2, xcross < x1, xcross < x2)
- } else {
- kline = dy/dx;
- bline = y1 - x1*kline;
- kperp = -1./kline;
- bperp = ydot - xdot*kperp;
-
- xcross = (bline-bperp) / (kperp-kline);
- ycross = kline*xcross + bline;
-
- HANDLE_LIMITS( x1 < x2, xcross < x1, xcross < x2)
- }
-#ifdef DEBUG_DOTSEG
- printf("crossover at (%g,%g)\n", xcross, ycross);
-#endif
-
- dx = xdot-xcross;
- dy = ydot-ycross;
- return dx*dx+dy*dy;
-#undef x1
-#undef y1
-#undef x2
-#undef y2
-#undef xdot
-#undef ydot
-#undef HANDLE_LIMITS
-}
-
-/* find the weighted quadratic average for the distance of a set
- * of dots from the curve; also fills out the individual distances
- * for each dot; if maxp!=NULL then returns the maximal squared
- * distance in there
- */
-
-double
-fdotcurvdist2(
- double curve[4][2 /*X,Y*/ ],
- struct dot_dist *dots,
- int ndots, /* number of entries in dots */
- double *maxp
-)
-{
- /* a curve is approximated by this many straight segments */
-#define NAPSECT 16
- /* a curve is divided into this many sections with equal weight each */
-#define NWSECT 4
- /* table of coefficients for finding the dots on the curve */
- /* tt[0] is left unused */
- static double tt[NAPSECT][4];
- static int havett = 0; /* flag: tt is initialized */
- /* dots on the curve */
- double cvd[NAPSECT+1][2 /*X,Y*/];
- /* sums by sections */
- double sum[NWSECT];
- /* counts by sections */
- double count[NWSECT];
- int d, i, j;
- int id1, id2;
- double dist1, dist2, dist3, dx, dy, x, y;
- double max = 0.;
-
- if(!havett) {
- double t, nt, t2, nt2, step;
-
- havett++;
- step = 1. / NAPSECT;
- t = 0;
- for(i=1; i<NAPSECT; i++) {
- t += step;
- nt = 1 - t;
- t2 = t*t;
- nt2 = nt*nt;
- tt[i][0] = nt2*nt; /* (1-t)^3 */
- tt[i][1] = 3*nt2*t; /* 3*(1-t)^2*t */
- tt[i][2] = 3*nt*t2; /* 3*(1-t)*t^2 */
- tt[i][3] = t2*t; /* t^3 */
- }
- }
-
- for(i=0; i<NWSECT; i++) {
- sum[i] = 0.;
- count[i] = 0;
- }
-
- /* split the curve into segments */
- for(d=0; d<2; d++) { /* X and Y */
- cvd[0][d] = curve[0][d]; /* endpoints */
- cvd[NAPSECT][d] = curve[3][d];
- for(i=1; i<NAPSECT; i++) {
- cvd[i][d] = curve[0][d] * tt[i][0]
- + curve[1][d] * tt[i][1]
- + curve[2][d] * tt[i][2]
- + curve[3][d] * tt[i][3];
- }
- }
-
- for(d=0; d<ndots; d++) {
-#ifdef DEBUG_DOTCURVE
- printf("dot %d ", d); printdot(dots[d].p); printf(":\n");
-
- /* for debugging */
- for(i=0; i< NAPSECT; i++) {
- dist1 = fdotsegdist2(&cvd[i], dots[d].p);
- printf(" seg %d ",i); printseg(&cvd[i]); printf(" dist=%g\n", sqrt(dist1));
- }
-#endif
-
- x = dots[d].p[X];
- y = dots[d].p[Y];
-
- /* find the nearest dot on the curve
- * there may be up to 2 local minimums - so we start from the
- * ends of curve and go to the center
- */
-
- id1 = 0;
- dx = x - cvd[0][X];
- dy = y - cvd[0][Y];
- dist1 = dx*dx + dy*dy;
-#ifdef DEBUG_DOTCURVE
- printf(" dot 0 "); printdot(cvd[id1]); printf(" dist=%g\n", sqrt(dist1));
-#endif
- for(i = 1; i<=NAPSECT; i++) {
- dx = x - cvd[i][X];
- dy = y - cvd[i][Y];
- dist3 = dx*dx + dy*dy;
-#ifdef DEBUG_DOTCURVE
- printf(" dot %d ",i); printdot(cvd[i]); printf(" dist=%g\n", sqrt(dist3));
-#endif
- if(dist3 < dist1) {
- dist1 = dist3;
- id1 = i;
- } else
- break;
- }
-
- if(id1 < NAPSECT-1) {
- id2 = NAPSECT;
- dx = x - cvd[NAPSECT][X];
- dy = y - cvd[NAPSECT][Y];
- dist2 = dx*dx + dy*dy;
-#ifdef DEBUG_DOTCURVE
- printf(" +dot %d ", id2); printdot(cvd[id2]); printf(" dist=%g\n", sqrt(dist2));
-#endif
- for(i = NAPSECT-1; i>id1+1; i--) {
- dx = x - cvd[i][X];
- dy = y - cvd[i][Y];
- dist3 = dx*dx + dy*dy;
-#ifdef DEBUG_DOTCURVE
- printf(" dot %d ",i); printdot(cvd[i]); printf(" dist=%g\n", sqrt(dist3));
-#endif
- if(dist3 < dist2) {
- dist2 = dist3;
- id2 = i;
- } else
- break;
- }
-
- /* now find which of the local minimums is smaller */
- if(dist2 < dist1) {
- id1 = id2;
- }
- }
-
- /* the nearest segment must include the nearest dot */
- if(id1==0) {
- dots[d].seg = 0;
- dots[d].dist2 = fdotsegdist2(&cvd[0], dots[d].p);
- } else if(id1==NAPSECT) {
- dots[d].seg = NAPSECT-1;
- dots[d].dist2 = fdotsegdist2(&cvd[NAPSECT-1], dots[d].p);
- } else {
- dist1 = fdotsegdist2(&cvd[id1], dots[d].p);
- dist2 = fdotsegdist2(&cvd[id1-1], dots[d].p);
- if(dist2 < dist1) {
- dots[d].seg = id1-1;
- dots[d].dist2 = dist2;
- } else {
- dots[d].seg = id1;
- dots[d].dist2 = dist1;
- }
- }
-
- i = dots[d].seg % NWSECT;
- sum[i] += dots[d].dist2;
- if(dots[d].dist2 > max)
- max = dots[d].dist2;
- count[i]++;
-#ifdef DEBUG_DOTCURVE
- printf(" best seg %d sect %d dist=%g\n", dots[d].seg, i, sqrt(dots[d].dist2));
-#endif
- }
-
- /* calculate the weighted average */
- id1=0;
- dist1=0.;
- for(i=0; i<NWSECT; i++) {
- if(count[i]==0)
- continue;
- id1++;
- dist1 += sum[i]/count[i];
- }
- if(maxp)
- *maxp = max;
- if(id1==0) /* no dots, strange */
- return 0.;
- else
- return dist1/id1; /* to get the average distance apply sqrt() */
-}
-
-/*
- * Approximate a curve matching the giving set of points and with
- * middle reference points going along the given segments (and no farther
- * than these segments).
- */
-
-void
-fapproxcurve(
- double cv[4][2 /*X,Y*/ ], /* points 0-3 are passed in, points 1,2 - out */
- struct dot_dist *dots, /* the dots to approximate - distances returned
- * there may be invalid */
- int ndots
-)
-{
- /* b and c are the middle control points */
-#define B 0
-#define C 1
- /* maximal number of sections on each axis - used for the first step */
-#define MAXSECT 2
- /* number of sections used for the other steps */
-#define NORMSECT 2
- /* when the steps become less than this many points, it's time to stop */
-#define STEPEPS 1.
- double from[2 /*B,C*/], to[2 /*B,C*/];
- double middf[2 /*B,C*/][2 /*X,Y*/], df;
- double coef[2 /*B,C*/][MAXSECT];
- double res[MAXSECT][MAXSECT], thisres, bestres, goodres;
- int ncoef[2 /*B,C*/], best[2 /*B,C*/], good[2 /*B,C*/];
- int i, j, k, keepsym;
- char bc[]="BC";
- char xy[]="XY";
-
-#ifdef DEBUG_APPROXCV
- fprintf(stderr, "Curve points:");
- for(i=0; i<4; i++) {
- fprintf(stderr, " ");
- printdot(cv[i]);
- }
- fprintf(stderr, "\nDots:");
- for(i=0; i<ndots; i++) {
- fprintf(stderr, " ");
- printdot(dots[i].p);
- }
- fprintf(stderr, "\n");
-#endif
-
- /* load the endpoints and calculate differences */
- for(i=0; i<2; i++) {
- /* i is X, Y */
- middf[B][i] = cv[1][i]-cv[0][i];
- middf[C][i] = cv[2][i]-cv[3][i];
-
- /* i is B, C */
- from[i] = 0.;
- to[i] = 1.;
- ncoef[i] = MAXSECT;
- }
-
- while(ncoef[B] != 1 || ncoef[C] != 1) {
- /* prepare the values of coefficients */
- for(i=0; i<2; i++) { /*B,C*/
-#ifdef DEBUG_APPROXCV
- fprintf(stderr, "Coefficients by %c(%g,%g):", bc[i], from[i], to[i]);
-#endif
- df = (to[i]-from[i]) / (ncoef[i]*2);
- for(j=0; j<ncoef[i]; j++) {
- coef[i][j] = from[i] + df*(2*j+1);
-#ifdef DEBUG_APPROXCV
- fprintf(stderr, " %g", coef[i][j]);
-#endif
- }
-#ifdef DEBUG_APPROXCV
- fprintf(stderr, "\n");
-#endif
- }
- bestres = FBIGVAL;
- /* i iterates by ncoef[B], j iterates by ncoef[C] */
- for(i=0; i<ncoef[B]; i++) {
- for(j=0; j<ncoef[C]; j++) {
- for(k=0; k<2; k++) { /*X, Y*/
- cv[1][k] = cv[0][k] + middf[B][k]*coef[B][i];
- cv[2][k] = cv[3][k] + middf[C][k]*coef[C][j];
- }
- res[i][j] = thisres = fdotcurvdist2(cv, dots, ndots, NULL);
- if(thisres < bestres) {
- goodres = bestres;
- good[B] = best[B];
- good[C] = best[C];
- bestres = thisres;
- best[B] = i;
- best[C] = j;
- } else if(thisres < goodres) {
- goodres = thisres;
- good[B] = i;
- good[C] = j;
- }
-#ifdef DEBUG_APPROXCV
- fprintf(stderr, " at (%g,%g) dist=%g %s\n", coef[B][i], coef[C][j], sqrt(thisres),
- (best[B]==i && best[C]==j)? "(BEST)":"");
-#endif
- }
- }
-#ifdef DEBUG_APPROXCV
- fprintf(stderr, " best: at (%g, %g) dist=%g\n",
- coef[B][best[B]], coef[C][best[C]], sqrt(bestres));
- fprintf(stderr, " B:%d,%d C:%d,%d -- 2nd best: at (%g, %g) dist=%g\n",
- best[B], good[B], best[C], good[C], coef[B][good[B]], coef[C][good[C]], sqrt(goodres));
-#endif
-
- if(bestres < (0.1*0.1)) { /* consider it close enough */
- /* calculate the coordinates to return */
- for(k=0; k<2; k++) { /*X, Y*/
- cv[1][k] = cv[0][k] + middf[B][k]*coef[B][best[B]];
- cv[2][k] = cv[3][k] + middf[C][k]*coef[C][best[C]];
- }
-#ifdef DEBUG_APPROXCV
- fprintf(stderr, "quick approximated middle points "); printdot(cv[1]);
- fprintf(stderr, " "); printdot(cv[2]); fprintf(stderr, "\n");
-#endif
- return;
- }
- keepsym = 0;
- if(best[B] != best[C] && best[B]-best[C] == good[C]-good[B]) {
- keepsym = 1;
-#ifdef DEBUG_APPROXCV
- fprintf(stderr, "keeping symmetry!\n");
-#endif
- }
- for(i=0; i<2; i++) { /*B,C*/
- if(ncoef[i]==1)
- continue;
- if(keepsym) {
- /* try to keep the symmetry */
- if(best[i] < good[i]) {
- from[i] = coef[i][best[i]];
- to[i] = coef[i][good[i]];
- } else {
- from[i] = coef[i][good[i]];
- to[i] = coef[i][best[i]];
- }
- } else {
- df = (to[i]-from[i]) / ncoef[i];
- from[i] += df*best[i];
- to[i] = from[i] + df;
- }
- if( fabs(df*middf[i][0]) < STEPEPS && fabs(df*middf[i][1]) < STEPEPS) {
- /* this side has converged */
- from[i] = to[i] = (from[i]+to[i]) / 2.;
- ncoef[i] = 1;
- } else
- ncoef[i] = NORMSECT;
- }
-
- }
- /* calculate the coordinates to return */
- for(k=0; k<2; k++) { /*X, Y*/
- cv[1][k] = cv[0][k] + middf[B][k]*from[B];
- cv[2][k] = cv[3][k] + middf[C][k]*from[C];
- }
-#ifdef DEBUG_APPROXCV
- fprintf(stderr, "approximated middle points "); printdot(cv[1]);
- fprintf(stderr, " "); printdot(cv[2]); fprintf(stderr, "\n");
-#endif
-#undef B
-#undef C
-#undef MAXSECT
-#undef NORMSECT
-#undef STEPEPS
-}
-
-/*
- * Find the squared value of the sinus of the angle between the
- * end of ge1 and the beginning of ge2
- * The curve must be normalized.
- */
-
-static double
-fjointsin2(
- GENTRY *ge1,
- GENTRY *ge2
-)
-{
- double d[3][2 /*X,Y*/];
- double scale1, scale2, len1, len2;
- int axis;
-
- if(ge1->rtg < 0) {
- d[1][X] = ge1->fx3 - ge1->prev->fx3;
- d[1][Y] = ge1->fy3 - ge1->prev->fy3;
- } else {
- d[1][X] = ge1->fx3 - ge1->fpoints[X][ge1->rtg];
- d[1][Y] = ge1->fy3 - ge1->fpoints[Y][ge1->rtg];
- }
- d[2][X] = ge2->fpoints[X][ge2->ftg] - ge2->prev->fx3;
- d[2][Y] = ge2->fpoints[Y][ge2->ftg] - ge2->prev->fy3;
-
- len1 = sqrt( d[1][X]*d[1][X] + d[1][Y]*d[1][Y] );
- len2 = sqrt( d[2][X]*d[2][X] + d[2][Y]*d[2][Y] );
- /* scale the 2nd segment to the length of 1
- * and to make sure that the 1st segment is longer scale it to
- * the length of 2 and extend to the same distance backwards
- */
- scale1 = 2./len1;
- scale2 = 1./len2;
-
- for(axis=0; axis <2; axis++) {
- d[0][axis] = -( d[1][axis] *= scale1 );
- d[2][axis] *= scale2;
- }
- return fdotsegdist2(d, d[2]);
-}
-
-#if 0
-/* find the area covered by the curve
- * (limited by the projections to the X axis)
- */
-
-static double
-fcvarea(
- GENTRY *ge
-)
-{
- double Ly, My, Ny, Py, Qx, Rx, Sx;
- double area;
-
- /* y = Ly*t^3 + My*t^2 + Ny*t + Py */
- Ly = -ge->prev->fy3 + 3*(ge->fy1 - ge->fy2) + ge->fy3;
- My = 3*ge->prev->fy3 - 6*ge->fy1 + 3*ge->fy2;
- Ny = 3*(-ge->prev->fy3 + ge->fy1);
- Py = ge->prev->fy3;
-
- /* dx/dt = Qx*t^2 + Rx*t + Sx */
- Qx = 3*(-ge->prev->fx3 + 3*(ge->fx1 - ge->fx2) + ge->fx3);
- Rx = 6*(ge->prev->fx3 - 2*ge->fx1 + ge->fx2);
- Sx = 3*(-ge->prev->fx3 + ge->fx1);
-
- /* area is integral[from 0 to 1]( y(t) * dx(t)/dt *dt) */
- area = 1./6.*(Ly*Qx) + 1./5.*(Ly*Rx + My*Qx)
- + 1./4.*(Ly*Sx + My*Rx + Ny*Qx) + 1./3.*(My*Sx + Ny*Rx + Py*Qx)
- + 1./2.*(Ny*Sx + Py*Rx) + Py*Sx;
-
- return area;
-}
-#endif
-
-/* find the value of point on the curve at the given parameter t,
- * along the given axis (0 - X, 1 - Y).
- */
-
-static double
-fcvval(
- GENTRY *ge,
- int axis,
- double t
-)
-{
- double t2, mt, mt2;
-
- /* val = A*(1-t)^3 + 3*B*(1-t)^2*t + 3*C*(1-t)*t^2 + D*t^3 */
- t2 = t*t;
- mt = 1-t;
- mt2 = mt*mt;
-
- return ge->prev->fpoints[axis][2]*mt2*mt
- + 3*(ge->fpoints[axis][0]*mt2*t + ge->fpoints[axis][1]*mt*t2)
- + ge->fpoints[axis][2]*t*t2;
-}
-
-/*
- * Find ndots equally spaced dots on a curve or line and fill
- * their coordinates into the dots array
- */
-
-static void
-fsampledots(
- GENTRY *ge,
- double dots[][2], /* the dots to fill */
- int ndots
-)
-{
- int i, axis;
- double t, nf, dx, d[2];
-
- nf = ndots+1;
- if(ge->type == GE_CURVE) {
- for(i=0; i<ndots; i++) {
- t = (i+1)/nf;
- for(axis=0; axis<2; axis++)
- dots[i][axis] = fcvval(ge, axis, t);
- }
- } else { /* line */
- d[0] = ge->fx3 - ge->prev->fx3;
- d[1] = ge->fy3 - ge->prev->fy3;
- for(i=0; i<ndots; i++) {
- t = (i+1)/nf;
- for(axis=0; axis<2; axis++)
- dots[i][axis] = ge->prev->fpoints[axis][2]
- + t*d[axis];
- }
- }
-}
-
-/*
- * Allocate a structure gex_con
- */
-
-static void
-alloc_gex_con(
- GENTRY *ge
-)
-{
- ge->ext = (void*)calloc(1, sizeof(GEX_CON));
- if(ge->ext == 0) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
-}
-
-/*
- * Normalize a gentry for fforceconcise() : find the points that
- * can be used to calculate the tangents.
- */
-
-static void
-fnormalizege(
- GENTRY *ge
-)
-{
- int midsame, frontsame, rearsame;
-
- if(ge->type == GE_LINE) {
- ge->ftg = 2;
- ge->rtg = -1;
- } else { /* assume it's a curve */
- midsame = (fabs(ge->fx1-ge->fx2)<FEPS && fabs(ge->fy1-ge->fy2)<FEPS);
- frontsame = (fabs(ge->fx1-ge->prev->fx3)<FEPS && fabs(ge->fy1-ge->prev->fy3)<FEPS);
- rearsame = (fabs(ge->fx3-ge->fx2)<FEPS && fabs(ge->fy3-ge->fy2)<FEPS);
-
- if(midsame && (frontsame || rearsame) ) {
- /* essentially a line */
- ge->ftg = 2;
- ge->rtg = -1;
- } else {
- if(frontsame) {
- ge->ftg = 1;
- } else {
- ge->ftg = 0;
- }
- if(rearsame) {
- ge->rtg = 0;
- } else {
- ge->rtg = 1;
- }
- }
- }
-}
-
-/* various definition for the processing of outlines */
-
-/* maximal average quadratic distance from the original curve
- * (in dots) to consider the joined curve good
- */
-#define CVEPS 1.5
-#define CVEPS2 (CVEPS*CVEPS)
-/* squared sinus of the maximal angle that we consider a smooth joint */
-#define SMOOTHSIN2 0.25 /* 0.25==sin(30 degrees)^2 */
-/* squared line length that we consider small */
-#define SMALL_LINE2 (15.*15.)
-/* how many times a curve must be bigger than a line to join, squared */
-#define TIMES_LINE2 (3.*3.)
-
-/*
- * Normalize and analyse a gentry for fforceconcise() and fill out the gex_con
- * structure
- */
-
-static void
-fanalyzege(
- GENTRY *ge
-)
-{
- int i, ix, iy;
- double avsd2, dots[3][2 /*X,Y*/];
- GEX_CON *gex;
-
- gex = X_CON(ge);
- memset(gex, 0, sizeof *gex);
-
- gex->len2 = 0;
- for(i=0; i<2; i++) {
- avsd2 = gex->d[i] = ge->fpoints[i][2] - ge->prev->fpoints[i][2];
- gex->len2 += avsd2*avsd2;
- }
- gex->sin2 = fjointsin2(ge, ge->frwd);
- if(ge->type == GE_CURVE) {
- ge->dir = fgetcvdir(ge);
- for(i=0; i<2; i++) {
- dots[0][i] = ge->prev->fpoints[i][2];
- dots[1][i] = ge->fpoints[i][2];
- dots[2][i] = fcvval(ge, i, 0.5);
- }
- avsd2 = fdotsegdist2(dots, dots[2]);
- if(avsd2 <= CVEPS2) {
- gex->flags |= GEXF_FLAT;
- }
- } else {
- ge->dir = CVDIR_FEQUAL|CVDIR_REQUAL;
- gex->flags |= GEXF_FLAT;
- }
- if(gex->flags & GEXF_FLAT) {
- if( fabs(gex->d[X]) > FEPS && fabs(gex->d[Y]) < 5.
- && fabs(gex->d[Y] / gex->d[X]) < 0.2)
- gex->flags |= GEXF_HOR;
- else if( fabs(gex->d[Y]) > FEPS && fabs(gex->d[X]) < 5.
- && fabs(gex->d[X] / gex->d[Y]) < 0.2)
- gex->flags |= GEXF_VERT;
- }
- ix = gex->isd[X] = fsign(gex->d[X]);
- iy = gex->isd[Y] = fsign(gex->d[Y]);
- if(ix <= 0) {
- if(iy <= 0)
- gex->flags |= GEXF_QDL;
- if(iy >= 0)
- gex->flags |= GEXF_QUL;
- if(gex->flags & GEXF_HOR)
- gex->flags |= GEXF_IDQ_L;
- }
- if(ix >= 0) {
- if(iy <= 0)
- gex->flags |= GEXF_QDR;
- if(iy >= 0)
- gex->flags |= GEXF_QUR;
- if(gex->flags & GEXF_HOR)
- gex->flags |= GEXF_IDQ_R;
- }
- if(gex->flags & GEXF_VERT) {
- if(iy <= 0) {
- gex->flags |= GEXF_IDQ_U;
- } else { /* supposedly there is no 0-sized entry */
- gex->flags |= GEXF_IDQ_D;
- }
- }
-}
-
-/*
- * Analyse a joint between this and following gentry for fforceconcise()
- * and fill out the corresponding parts of the gex_con structure
- * Bothe entries must be analyzed first.
- */
-
-static void
-fanalyzejoint(
- GENTRY *ge
-)
-{
- GENTRY *nge = ge->frwd;
- GENTRY tge;
- GEX_CON *gex, *ngex;
- double avsd2, dots[3][2 /*X,Y*/];
- int i;
-
- gex = X_CON(ge); ngex = X_CON(nge);
-
- /* look if they can be joined honestly */
-
- /* if any is flat, they should join smoothly */
- if( (gex->flags & GEXF_FLAT || ngex->flags & GEXF_FLAT)
- && gex->sin2 > SMOOTHSIN2)
- goto try_flatboth;
-
- if(ge->type == GE_LINE) {
- if(nge->type == GE_LINE) {
- if(gex->len2 > SMALL_LINE2 || ngex->len2 > SMALL_LINE2)
- goto try_flatboth;
- } else {
- if(gex->len2*TIMES_LINE2 > ngex->len2)
- goto try_flatboth;
- }
- } else if(nge->type == GE_LINE) {
- if(ngex->len2*TIMES_LINE2 > gex->len2)
- goto try_flatboth;
- }
-
- /* if curve changes direction */
- if( gex->isd[X]*ngex->isd[X]<0 || gex->isd[Y]*ngex->isd[Y]<0)
- goto try_idealone;
-
- /* if would create a zigzag */
- if( ((ge->dir&CVDIR_FRONT)-CVDIR_FEQUAL) * ((nge->dir&CVDIR_REAR)-CVDIR_REQUAL) < 0 )
- goto try_flatone;
-
- if( fcrossraysge(ge, nge, NULL, NULL, NULL) )
- gex->flags |= GEXF_JGOOD;
-
-try_flatone:
- /* look if they can be joined by flatting out one of the entries */
-
- /* at this point we know that the general direction of the
- * gentries is OK
- */
-
- if( gex->flags & GEXF_FLAT ) {
- tge = *ge;
- tge.fx1 = tge.fx3;
- tge.fy1 = tge.fy3;
- fnormalizege(&tge);
- if( fcrossraysge(&tge, nge, NULL, NULL, NULL) )
- gex->flags |= GEXF_JFLAT|GEXF_JFLAT1;
- }
- if( ngex->flags & GEXF_FLAT ) {
- tge = *nge;
- tge.fx2 = ge->fx3;
- tge.fy2 = ge->fy3;
- fnormalizege(&tge);
- if( fcrossraysge(ge, &tge, NULL, NULL, NULL) )
- gex->flags |= GEXF_JFLAT|GEXF_JFLAT2;
- }
-
-try_idealone:
- /* look if one of the entries can be brought to an idealized
- * horizontal or vertical position and then joined
- */
- if( gex->flags & GEXF_HOR && gex->isd[X]*ngex->isd[X]>=0 ) {
- tge = *ge;
- tge.fx1 = tge.fx3;
- tge.fy1 = ge->prev->fy3; /* force horizontal */
- fnormalizege(&tge);
- if( fcrossraysge(&tge, nge, NULL, NULL, NULL) )
- gex->flags |= GEXF_JID|GEXF_JID1;
- } else if( gex->flags & GEXF_VERT && gex->isd[Y]*ngex->isd[Y]>=0 ) {
- tge = *ge;
- tge.fx1 = ge->prev->fx3; /* force vertical */
- tge.fy1 = tge.fy3;
- fnormalizege(&tge);
- if( fcrossraysge(&tge, nge, NULL, NULL, NULL) )
- gex->flags |= GEXF_JID|GEXF_JID1;
- }
- if( ngex->flags & GEXF_HOR && gex->isd[X]*ngex->isd[X]>=0 ) {
- tge = *nge;
- tge.fx2 = ge->fx3;
- tge.fy2 = nge->fy3; /* force horizontal */
- fnormalizege(&tge);
- if( fcrossraysge(ge, &tge, NULL, NULL, NULL) )
- gex->flags |= GEXF_JID|GEXF_JID2;
- } else if( ngex->flags & GEXF_VERT && gex->isd[Y]*ngex->isd[Y]>=0 ) {
- tge = *nge;
- tge.fx2 = nge->fx3; /* force vertical */
- tge.fy2 = ge->fy3;
- fnormalizege(&tge);
- if( fcrossraysge(ge, &tge, NULL, NULL, NULL) )
- gex->flags |= GEXF_JID|GEXF_JID2;
- }
-
-try_flatboth:
- /* look if we can change them to one line */
- if(gex->flags & GEXF_FLAT && ngex->flags & GEXF_FLAT) {
- for(i=0; i<2; i++) {
- dots[0][i] = ge->prev->fpoints[i][2];
- dots[1][i] = nge->fpoints[i][2];
- dots[2][i] = ge->fpoints[i][2];
- }
- if( fdotsegdist2(dots, dots[2]) <= CVEPS2)
- gex->flags |= GEXF_JLINE;
- }
-}
-
-/*
- * Force conciseness of one contour in the glyph,
- * the contour is indicated by one entry from it.
- */
-
-static void
-fconcisecontour(
- GLYPH *g,
- GENTRY *startge
-)
-{
-/* initial maximal number of dots to be used as reference */
-#define MAXDOTS ((NREFDOTS+1)*12)
-
- GENTRY *ge, *pge, *nge, *ige;
- GEX_CON *gex, *pgex, *ngex, *nngex;
- GENTRY tpge, tnge;
- int quad, qq, i, j, ndots, maxdots;
- int found[2];
- int joinmask, pflag, nflag;
- struct dot_dist *dots;
- double avsd2, maxd2, eps2;
- double apcv[4][2];
-
- if(startge == 0) {
- fprintf(stderr, "WARNING: assertion in %s line %d, please report it to the ttf2pt1 project\n",
- __FILE__, __LINE__);
- fprintf(stderr, "Strange contour in glyph %s\n", g->name);
- dumppaths(g, NULL, NULL);
- return;
- }
-
- if(startge->type != GE_CURVE && startge->type != GE_LINE)
- return; /* probably a degenerate contour */
-
- if(ISDBG(FCONCISE))
- fprintf(stderr, "processing contour 0x%p of glyph %s\n", startge, g->name);
-
- maxdots = MAXDOTS;
- dots = (struct dot_dist *)malloc(sizeof(*dots)*maxdots);
- if(dots == NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
-
- ge = startge;
- joinmask = GEXF_JGOOD;
- while(1) {
- restart:
- gex = X_CON(ge);
- if((gex->flags & GEXF_JMASK) > ((joinmask<<1)-1)) {
- if(ISDBG(FCONCISE))
- fprintf(stderr, "found higher flag (%x>%x) at 0x%p\n",
- gex->flags & GEXF_JMASK, ((joinmask<<1)-1), ge);
- joinmask <<= 1;
- startge = ge; /* have to redo the pass */
- continue;
- }
- if(( gex->flags & joinmask )==0)
- goto next;
-
- /* if we happen to be in the middle of a string of
- * joinable entries, find its beginning
- */
- if( gex->flags & (GEXF_JCVMASK^GEXF_JID) )
- quad = gex->flags & X_CON_F(ge->frwd) & GEXF_QMASK;
- else if( gex->flags & GEXF_JID2 )
- quad = gex->flags & GEXF_QFROM_IDEAL(X_CON_F(ge->frwd)) & GEXF_QMASK;
- else /* must be GEXF_JID1 */
- quad = GEXF_QFROM_IDEAL(gex->flags) & X_CON_F(ge->frwd) & GEXF_QMASK;
-
- pge = ge;
- pgex = X_CON(pge->bkwd);
-
- if(ISDBG(FCONCISE))
- fprintf(stderr, "ge %p prev -> 0x%p ", ge, pge);
-
- while(pgex->flags & GEXF_JCVMASK) {
- if( !(pgex->flags & ((GEXF_JCVMASK^GEXF_JID)|GEXF_JID2)) )
- qq = GEXF_QFROM_IDEAL(pgex->flags);
- else
- qq = pgex->flags & GEXF_QMASK;
-
- if(ISDBG(FCONCISE))
- fprintf(stderr, "(%x?%x)", quad, qq);
-
- if( !(quad & qq) ) {
- if( !(X_CON_F(pge) & (GEXF_JCVMASK^GEXF_JID))
- && pgex->flags & (GEXF_JCVMASK^GEXF_JID) ) {
- /* the previos entry is definitely a better match */
- if(pge == ge) {
- if(ISDBG(FCONCISE))
- fprintf(stderr, "\nprev is a better match at %p\n", pge);
- startge = ge;
- goto next;
- } else
- pge = pge->frwd;
- }
- break;
- }
-
- quad &= qq;
- pge = pge->bkwd;
- pgex = X_CON(pge->bkwd);
- if(ISDBG(FCONCISE))
- fprintf(stderr, "0x%p ", pge);
- }
-
- /* collect as many entries for joining as possible */
- nge = ge->frwd;
- ngex = X_CON(nge);
- nngex = X_CON(nge->frwd);
-
- if(ISDBG(FCONCISE))
- fprintf(stderr, ": 0x%x\nnext -> 0x%p ", pge, nge);
-
- while(ngex->flags & GEXF_JCVMASK) {
- if( !(ngex->flags & ((GEXF_JCVMASK^GEXF_JID)|GEXF_JID1)) )
- qq = GEXF_QFROM_IDEAL(nngex->flags);
- else
- qq = nngex->flags & GEXF_QMASK;
-
- if(ISDBG(FCONCISE))
- fprintf(stderr, "(%x?%x)", quad, qq);
- if( !(quad & qq) ) {
- if( !(X_CON_F(nge->bkwd) & (GEXF_JCVMASK^GEXF_JID))
- && ngex->flags & (GEXF_JCVMASK^GEXF_JID) ) {
- /* the next-next entry is definitely a better match */
- if(nge == ge->frwd) {
- if(ISDBG(FCONCISE))
- fprintf(stderr, "\nnext %x is a better match than %x at %p (jmask %x)\n",
- ngex->flags & GEXF_JCVMASK, gex->flags & GEXF_JCVMASK, nge, joinmask);
- goto next;
- } else
- nge = nge->bkwd;
- }
- break;
- }
-
- quad &= qq;
- nge = nge->frwd;
- ngex = nngex;
- nngex = X_CON(nge->frwd);
- if(ISDBG(FCONCISE))
- fprintf(stderr, "0x%p ", nge);
- }
-
- if(ISDBG(FCONCISE))
- fprintf(stderr, ": 0x%x\n", nge);
-
- /* XXX add splitting of last entries if neccessary */
-
- /* make sure that all the reference dots are valid */
- for(ige = pge; ige != nge->frwd; ige = ige->frwd) {
- nngex = X_CON(ige);
- if( !(nngex->flags & GEXF_VDOTS) ) {
- fsampledots(ige, nngex->dots, NREFDOTS);
- nngex->flags |= GEXF_VDOTS;
- }
- }
-
- /* do the actual joining */
- while(1) {
- pgex = X_CON(pge);
- ngex = X_CON(nge->bkwd);
- /* now the segments to be joined are pge...nge */
-
- ndots = 0;
- for(ige = pge; ige != nge->frwd; ige = ige->frwd) {
- if(maxdots < ndots+(NREFDOTS+1)) {
- maxdots += MAXDOTS;
- dots = (struct dot_dist *)realloc((void *)dots, sizeof(*dots)*maxdots);
- if(dots == NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- }
- nngex = X_CON(ige);
- for(i=0; i<NREFDOTS; i++) {
- for(j=0; j<2; j++)
- dots[ndots].p[j] = nngex->dots[i][j];
- ndots++;
- }
- for(j=0; j<2; j++)
- dots[ndots].p[j] = ige->fpoints[j][2];
- ndots++;
- }
- ndots--; /* the last point is not interesting */
-
- tpge = *pge;
- pflag = pgex->flags;
- if(pflag & (GEXF_JGOOD|GEXF_JFLAT2|GEXF_JID2)) {
- /* nothing */
- } else if(pflag & GEXF_JFLAT) {
- tpge.fx1 = tpge.fx3;
- tpge.fy1 = tpge.fy3;
- } else if(pflag & GEXF_JID) {
- if(pflag & GEXF_HOR)
- tpge.fy1 = tpge.bkwd->fy3;
- else
- tpge.fx1 = tpge.bkwd->fx3;
- }
-
- tnge = *nge;
- nflag = ngex->flags;
- if(nflag & (GEXF_JGOOD|GEXF_JFLAT1|GEXF_JID)
- && !(nflag & GEXF_JID2)) {
- /* nothing */
- } else if(nflag & GEXF_JFLAT) {
- tnge.fx2 = tnge.bkwd->fx3;
- tnge.fy2 = tnge.bkwd->fy3;
- } else if(nflag & GEXF_JID) {
- if(X_CON_F(nge) & GEXF_HOR)
- tnge.fy2 = tnge.fy3;
- else
- tnge.fx2 = tnge.fx3;
- }
-
- fnormalizege(&tpge);
- fnormalizege(&tnge);
- if( fcrossraysge(&tpge, &tnge, NULL, NULL, &apcv[1]) ) {
- apcv[0][X] = tpge.bkwd->fx3;
- apcv[0][Y] = tpge.bkwd->fy3;
- /* apcv[1] and apcv[2] were filled by fcrossraysge() */
- apcv[3][X] = tnge.fx3;
- apcv[3][Y] = tnge.fy3;
-
- /* calculate the precision depending on the smaller dimension of the curve */
- maxd2 = apcv[3][X]-apcv[0][X];
- maxd2 *= maxd2;
- eps2 = apcv[3][Y]-apcv[0][Y];
- eps2 *= eps2;
- if(maxd2 < eps2)
- eps2 = maxd2;
- eps2 *= (CVEPS2*4.) / (400.*400.);
- if(eps2 < CVEPS2)
- eps2 = CVEPS2;
- else if(eps2 > CVEPS2*4.)
- eps2 = CVEPS2*4.;
-
- fapproxcurve(apcv, dots, ndots);
-
- avsd2 = fdotcurvdist2(apcv, dots, ndots, &maxd2);
- if(ISDBG(FCONCISE))
- fprintf(stderr, "avsd = %g, maxd = %g, ", sqrt(avsd2), sqrt(maxd2));
- if(avsd2 <= eps2 && maxd2 <= eps2*2.) {
- /* we've guessed a curve that is close enough */
- ggoodcv++; ggoodcvdots += ndots;
-
- if(ISDBG(FCONCISE)) {
- fprintf(stderr, "in %s joined %p-%p to ", g->name, pge, nge);
- for(i=0; i<4; i++) {
- fprintf(stderr, " (%g, %g)", apcv[i][X], apcv[i][Y]);
- }
- fprintf(stderr, " from\n");
- dumppaths(g, pge, nge);
- }
- for(i=0; i<3; i++) {
- pge->fxn[i] = apcv[i+1][X];
- pge->fyn[i] = apcv[i+1][Y];
- }
- pge->type = GE_CURVE;
- ge = pge;
- for(ige = pge->frwd; ; ige = pge->frwd) {
- if(ige == pge) {
- fprintf(stderr, "WARNING: assertion in %s line %d, please report it to the ttf2pt1 project\n",
- __FILE__, __LINE__);
- free(dots);
- return;
- }
- if(startge == ige)
- startge = pge;
- free(ige->ext);
- freethisge(ige);
- if(ige == nge)
- break;
- }
- fnormalizege(ge);
- if(ISDBG(FCONCISE)) {
- fprintf(stderr, "normalized ");
- for(i=0; i<3; i++) {
- fprintf(stderr, " (%g, %g)", ge->fpoints[X][i], ge->fpoints[Y][i]);
- }
- fprintf(stderr, "\n");
- }
- fanalyzege(ge);
- fanalyzejoint(ge);
- fanalyzege(ge->bkwd);
- fanalyzejoint(ge->bkwd);
-
- /* the results of this join will have to be reconsidered */
- startge = ge = ge->frwd;
- goto restart;
- } else {
- gbadcv++; gbadcvdots += ndots;
- }
- }
-
- /* if we're down to 2 entries then the join has failed */
- if(pge->frwd == nge) {
- pgex->flags &= ~joinmask;
- if(ISDBG(FCONCISE))
- fprintf(stderr, "no match\n");
- goto next;
- }
-
- /* reduce the number of entries by dropping one at some end,
- * should never drop the original ge from the range
- */
-
- if(nge->bkwd == ge
- || (pge != ge && (pgex->flags & GEXF_JCVMASK) <= (ngex->flags & GEXF_JCVMASK)) ) {
- pge = pge->frwd;
- } else {
- nge = nge->bkwd;
- }
- if(ISDBG(FCONCISE))
- fprintf(stderr, "next try: %p to %p\n", pge, nge);
- }
-
-next:
- ge = ge->frwd;
- if(ge == startge) {
- joinmask = (joinmask >> 1) & GEXF_JCVMASK;
- if(joinmask == 0)
- break;
- }
- }
-
- /* join flat segments into lines */
- /* here ge==startge */
- while(1) {
- gex = X_CON(ge);
- if( !(gex->flags & GEXF_JLINE) )
- goto next2;
-
- ndots = 0;
- dots[ndots].p[X] = ge->fx3;
- dots[ndots].p[Y] = ge->fy3;
- ndots++;
-
- pge = ge->bkwd;
- nge = ge->frwd;
-
- if(ISDBG(FCONCISE))
- fprintf(stderr, "joining LINE from %p-%p\n", ge, nge);
-
- while(pge!=nge) {
- pgex = X_CON(pge);
- ngex = X_CON(nge);
- if(ISDBG(FCONCISE))
- fprintf(stderr, "(p=%p/%x n=0x%x/%x) ", pge, pgex->flags & GEXF_JLINE,
- nge, ngex->flags & GEXF_JLINE);
- if( !((pgex->flags | ngex->flags) & GEXF_JLINE) ) {
- if(ISDBG(FCONCISE))
- fprintf(stderr, "(end p=%p n=%p) ", pge, nge);
- break;
- }
-
- if(maxdots < ndots+2) {
- maxdots += MAXDOTS;
- dots = (struct dot_dist *)realloc((void *)dots, sizeof(*dots)*maxdots);
- if(dots == NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- }
- if( pgex->flags & GEXF_JLINE ) {
- for(i=0; i<2; i++) {
- apcv[0][i] = pge->bkwd->fpoints[i][2];
- apcv[1][i] = nge->fpoints[i][2];
- dots[ndots].p[i] = pge->fpoints[i][2];
- }
- ndots++;
- for(i=0; i<ndots; i++) {
- avsd2 = fdotsegdist2(apcv, dots[i].p);
- if(avsd2 > CVEPS2)
- break;
- }
- if(i<ndots) { /* failed to join */
- if(ISDBG(FCONCISE))
- fprintf(stderr, "failed to join prev %p ", pge);
- ndots--;
- pgex->flags &= ~GEXF_JLINE;
- } else {
- pge = pge->bkwd;
- if(pge == nge) {
- if(ISDBG(FCONCISE))
- fprintf(stderr, "intersected at prev %p ", pge);
- break; /* oops, tried to self-intersect */
- }
- }
- } else if(ISDBG(FCONCISE))
- fprintf(stderr, "(p=%p) ", pge);
-
- if( ngex->flags & GEXF_JLINE ) {
- for(i=0; i<2; i++) {
- apcv[0][i] = pge->fpoints[i][2]; /* pge points before the 1st segment */
- apcv[1][i] = nge->frwd->fpoints[i][2];
- dots[ndots].p[i] = nge->fpoints[i][2];
- }
- ndots++;
- for(i=0; i<ndots; i++) {
- avsd2 = fdotsegdist2(apcv, dots[i].p);
- if(avsd2 > CVEPS2)
- break;
- }
- if(i<ndots) { /* failed to join */
- if(ISDBG(FCONCISE))
- fprintf(stderr, "failed to join next %p ", nge->frwd);
- ndots--;
- ngex->flags &= ~GEXF_JLINE;
- } else {
- nge = nge->frwd;
- }
- } else if(ISDBG(FCONCISE))
- fprintf(stderr, "(n=%p) ", nge);
- }
-
- pge = pge->frwd; /* now the limits are pge...nge inclusive */
- if(pge == nge) /* a deeply perversive contour */
- break;
-
- if(ISDBG(FCONCISE)) {
- fprintf(stderr, "\nin %s joined LINE %p-%p from\n", g->name, pge, nge);
- dumppaths(g, pge, nge);
- }
- pge->type = GE_LINE;
- for(i=0; i<2; i++) {
- pge->fpoints[i][2] = nge->fpoints[i][2];
- }
- fnormalizege(pge);
- X_CON_F(pge) &= ~GEXF_JLINE;
-
- ge = pge;
- for(ige = pge->frwd; ; ige = pge->frwd) {
- if(ige == pge) {
- fprintf(stderr, "WARNING: assertion in %s line %d, please report it to the ttf2pt1 project\n",
- __FILE__, __LINE__);
- free(dots);
- return;
- }
- if(startge == ige)
- startge = pge;
- free(ige->ext);
- freethisge(ige);
- if(ige == nge)
- break;
- }
-next2:
- ge = ge->frwd;
- if(ge == startge)
- break;
- }
-
- free(dots);
-}
-
-/* force conciseness: substitute 2 or more curves going in the
-** same quadrant with one curve
-** in floating point
-*/
-
-void
-fforceconcise(
- GLYPH * g
-)
-{
-
- GENTRY *ge, *nge, *endge, *xge;
-
- assertisfloat(g, "enforcing conciseness");
-
- fdelsmall(g, 0.05);
- assertpath(g->entries, __FILE__, __LINE__, g->name);
-
- if(ISDBG(FCONCISE))
- dumppaths(g, NULL, NULL);
-
- /* collect more information about each gentry and their joints */
- for (ge = g->entries; ge != 0; ge = ge->next)
- if (ge->type == GE_CURVE || ge->type == GE_LINE)
- fnormalizege(ge);
-
- for (ge = g->entries; ge != 0; ge = ge->next)
- if (ge->type == GE_CURVE || ge->type == GE_LINE) {
- alloc_gex_con(ge);
- fanalyzege(ge);
- }
-
- /* see what we can do about joining */
- for (ge = g->entries; ge != 0; ge = ge->next)
- if (ge->type == GE_CURVE || ge->type == GE_LINE)
- fanalyzejoint(ge);
-
- /* now do the joining */
- for (ge = g->entries; ge != 0; ge = ge->next)
- if(ge->type == GE_MOVE)
- fconcisecontour(g, ge->next);
-
- for (ge = g->entries; ge != 0; ge = ge->next)
- if (ge->type == GE_CURVE || ge->type == GE_LINE)
- free(ge->ext);
-}
-
-void
-print_glyph(
- int glyphno
-)
-{
- GLYPH *g;
- GENTRY *ge;
- int x = 0, y = 0;
- int i;
- int grp, lastgrp= -1;
-
- if(ISDBG(FCONCISE) && glyphno == 0) {
- fprintf(stderr, "Guessed curves: bad %d/%d good %d/%d\n",
- gbadcv, gbadcvdots, ggoodcv, ggoodcvdots);
- }
-
- g = &glyph_list[glyphno];
-
- fprintf(pfa_file, "/%s { \n", g->name);
-
- /* consider widths >MAXLEGALWIDTH as bugs */
- if( g->scaledwidth <= MAXLEGALWIDTH ) {
- fprintf(pfa_file, "0 %d hsbw\n", g->scaledwidth);
- } else {
- fprintf(pfa_file, "0 1000 hsbw\n");
- WARNING_2 fprintf(stderr, "glyph %s: width %d seems to be buggy, set to 1000\n",
- g->name, g->scaledwidth);
- }
-
-#if 0
- fprintf(pfa_file, "%% contours: ");
- for (i = 0; i < g->ncontours; i++)
- fprintf(pfa_file, "%s(%d,%d) ", (g->contours[i].direction == DIR_OUTER ? "out" : "in"),
- g->contours[i].xofmin, g->contours[i].ymin);
- fprintf(pfa_file, "\n");
-
- if (g->rymin < 5000)
- fprintf(pfa_file, "%d lower%s\n", g->rymin, (g->flatymin ? "flat" : "curve"));
- if (g->rymax > -5000)
- fprintf(pfa_file, "%d upper%s\n", g->rymax, (g->flatymax ? "flat" : "curve"));
-#endif
-
- if (g->hstems)
- for (i = 0; i < g->nhs; i += 2) {
- if (g->hstems[i].flags & ST_3) {
- fprintf(pfa_file, "%d %d %d %d %d %d hstem3\n",
- g->hstems[i].value,
- g->hstems[i + 1].value - g->hstems[i].value,
- g->hstems[i + 2].value,
- g->hstems[i + 3].value - g->hstems[i + 2].value,
- g->hstems[i + 4].value,
- g->hstems[i + 5].value - g->hstems[i + 4].value
- );
- i += 4;
- } else {
- fprintf(pfa_file, "%d %d hstem\n", g->hstems[i].value,
- g->hstems[i + 1].value - g->hstems[i].value);
- }
- }
-
- if (g->vstems)
- for (i = 0; i < g->nvs; i += 2) {
- if (g->vstems[i].flags & ST_3) {
- fprintf(pfa_file, "%d %d %d %d %d %d vstem3\n",
- g->vstems[i].value,
- g->vstems[i + 1].value - g->vstems[i].value,
- g->vstems[i + 2].value,
- g->vstems[i + 3].value - g->vstems[i + 2].value,
- g->vstems[i + 4].value,
- g->vstems[i + 5].value - g->vstems[i + 4].value
- );
- i += 4;
- } else {
- fprintf(pfa_file, "%d %d vstem\n", g->vstems[i].value,
- g->vstems[i + 1].value - g->vstems[i].value);
- }
- }
-
- for (ge = g->entries; ge != 0; ge = ge->next) {
- if(g->nsg>0) {
- grp=ge->stemid;
- if(grp >= 0 && grp != lastgrp) {
- fprintf(pfa_file, "%d 4 callsubr\n", grp+g->firstsubr);
- lastgrp=grp;
- }
- }
-
- switch (ge->type) {
- case GE_MOVE:
- if (absolute)
- fprintf(pfa_file, "%d %d amoveto\n", ge->ix3, ge->iy3);
- else
- rmoveto(ge->ix3 - x, ge->iy3 - y);
- if (0)
- fprintf(stderr, "Glyph %s: print moveto(%d, %d)\n",
- g->name, ge->ix3, ge->iy3);
- x = ge->ix3;
- y = ge->iy3;
- break;
- case GE_LINE:
- if (absolute)
- fprintf(pfa_file, "%d %d alineto\n", ge->ix3, ge->iy3);
- else
- rlineto(ge->ix3 - x, ge->iy3 - y);
- x = ge->ix3;
- y = ge->iy3;
- break;
- case GE_CURVE:
- if (absolute)
- fprintf(pfa_file, "%d %d %d %d %d %d arcurveto\n",
- ge->ix1, ge->iy1, ge->ix2, ge->iy2, ge->ix3, ge->iy3);
- else
- rrcurveto(ge->ix1 - x, ge->iy1 - y,
- ge->ix2 - ge->ix1, ge->iy2 - ge->iy1,
- ge->ix3 - ge->ix2, ge->iy3 - ge->iy2);
- x = ge->ix3;
- y = ge->iy3;
- break;
- case GE_PATH:
- closepath();
- break;
- default:
- WARNING_1 fprintf(stderr, "**** Glyph %s: unknown entry type '%c'\n",
- g->name, ge->type);
- break;
- }
- }
-
- fprintf(pfa_file, "endchar } ND\n");
-}
-
-/* print the subroutines for this glyph, returns the number of them */
-int
-print_glyph_subs(
- int glyphno,
- int startid /* start numbering subroutines from this id */
-)
-{
- GLYPH *g;
- int i, grp;
-
- g = &glyph_list[glyphno];
-
- if(!hints || !subhints || g->nsg<1)
- return 0;
-
- g->firstsubr=startid;
-
-#if 0
- fprintf(pfa_file, "%% %s %d\n", g->name, g->nsg);
-#endif
- for(grp=0; grp<g->nsg; grp++) {
- fprintf(pfa_file, "dup %d {\n", startid++);
- for(i= (grp==0)? 0 : g->nsbs[grp-1]; i<g->nsbs[grp]; i++)
- fprintf(pfa_file, "\t%d %d %cstem\n", g->sbstems[i].low,
- g->sbstems[i].high-g->sbstems[i].low,
- g->sbstems[i].isvert ? 'v' : 'h');
- fprintf(pfa_file, "\treturn\n\t} NP\n");
- }
-
- return g->nsg;
-}
-
-void
-print_glyph_metrics(
- int code,
- int glyphno
-)
-{
- GLYPH *g;
-
- g = &glyph_list[glyphno];
-
- if(transform)
- fprintf(afm_file, "C %d ; WX %d ; N %s ; B %d %d %d %d ;\n",
- code, g->scaledwidth, g->name,
- iscale(g->xMin), iscale(g->yMin), iscale(g->xMax), iscale(g->yMax));
- else
- fprintf(afm_file, "C %d ; WX %d ; N %s ; B %d %d %d %d ;\n",
- code, g->scaledwidth, g->name,
- g->xMin, g->yMin, g->xMax, g->yMax);
-}
-
-/*
- SB:
- An important note about the BlueValues.
-
- The Adobe documentation says that the maximal width of a Blue zone
- is connected to the value of BlueScale, which is by default 0.039625.
- The BlueScale value defines, at which point size the overshoot
- suppression be disabled.
-
- The formula for it that is given in the manual is:
-
- BlueScale=point_size/240, for a 300dpi device
-
- that makes us wonder what is this 240 standing for. Incidentally
- 240=72*1000/300, where 72 is the relation between inches and points,
- 1000 is the size of the glyph matrix, and 300dpi is the resolution of
- the output device. Knowing that we can recalculate the formula for
- the font size in pixels rather than points:
-
- BlueScale=pixel_size/1000
-
- That looks a lot simpler than the original formula, does not it ?
- And the limitation about the maximal width of zone also looks
- a lot simpler after the transformation:
-
- max_width < 1000/pixel_size
-
- that ensures that even at the maximal pixel size when the overshoot
- suppression is disabled the zone width will be less than one pixel.
- This is important, failure to comply to this limit will result in
- really ugly fonts (been there, done that). But knowing the formula
- for the pixel width, we see that in fact we can use the maximal width
- of 24, not 23 as specified in the manual.
-
-*/
-
-#define MAXBLUEWIDTH (24)
-
-/*
- * Find the indexes of the most frequent values
- * in the hystogram, sort them in ascending order, and save which one
- * was the best one (if asked).
- * Returns the number of values found (may be less than maximal because
- * we ignore the zero values)
- */
-
-#define MAXHYST (2000) /* size of the hystogram */
-#define HYSTBASE 500
-
-static int
-besthyst(
- int *hyst, /* the hystogram */
- int base, /* the base point of the hystogram */
- int *best, /* the array for indexes of best values */
- int nbest, /* its allocated size */
- int width, /* minimal difference between indexes */
- int *bestindp /* returned top point */
-)
-{
- unsigned char hused[MAXHYST / 8 + 1];
- int i, max, j, w, last = 0;
- int nf = 0;
-
- width--;
-
- memset(hused, 0 , sizeof hused);
-
- max = 1;
- for (i = 0; i < nbest && max != 0; i++) {
- best[i] = 0;
- max = 0;
- for (j = 1; j < MAXHYST - 1; j++) {
- w = hyst[j];
-
- if (w > max && (hused[j>>3] & (1 << (j & 0x07))) == 0) {
- best[i] = j;
- max = w;
- }
- }
- if (max != 0) {
- if (max < last/2) {
- /* do not pick the too low values */
- break;
- }
- for (j = best[i] - width; j <= best[i] + width; j++) {
- if (j >= 0 && j < MAXHYST)
- hused[j >> 3] |= (1 << (j & 0x07));
- }
- last = max;
- best[i] -= base;
- nf = i + 1;
- }
- }
-
- if (bestindp)
- *bestindp = best[0];
-
- /* sort the indexes in ascending order */
- for (i = 0; i < nf; i++) {
- for (j = i + 1; j < nf; j++)
- if (best[j] < best[i]) {
- w = best[i];
- best[i] = best[j];
- best[j] = w;
- }
- }
-
- return nf;
-}
-
-/*
- * Find the next best Blue zone in the hystogram.
- * Return the weight of the found zone.
- */
-
-static int
-bestblue(
- short *zhyst, /* the zones hystogram */
- short *physt, /* the points hystogram */
- short *ozhyst, /* the other zones hystogram */
- int *bluetab /* where to put the found zone */
-)
-{
- int i, j, w, max, ind, first, last;
-
- /* find the highest point in the zones hystogram */
- /* if we have a plateau, take its center */
- /* if we have multiple peaks, take the first one */
-
- max = -1;
- first = last = -10;
- for (i = 0; i <= MAXHYST - MAXBLUEWIDTH; i++) {
- w = zhyst[i];
- if (w > max) {
- first = last = i;
- max = w;
- } else if (w == max) {
- if (last == i - 1)
- last = i;
- }
- }
- ind = (first + last) / 2;
-
- if (max == 0) /* no zones left */
- return 0;
-
- /* now we reuse `first' and `last' as inclusive borders of the zone */
- first = ind;
- last = ind + (MAXBLUEWIDTH - 1);
-
- /* our maximal width is far too big, so we try to make it narrower */
- w = max;
- j = (w & 1); /* a pseudo-random bit */
- while (1) {
- while (physt[first] == 0)
- first++;
- while (physt[last] == 0)
- last--;
- if (last - first < (MAXBLUEWIDTH * 2 / 3) || (max - w) * 10 > max)
- break;
-
- if (physt[first] < physt[last]
- || (physt[first] == physt[last] && j)) {
- if (physt[first] * 20 > w) /* if weight is >5%,
- * stop */
- break;
- w -= physt[first];
- first++;
- j = 0;
- } else {
- if (physt[last] * 20 > w) /* if weight is >5%,
- * stop */
- break;
- w -= physt[last];
- last--;
- j = 1;
- }
- }
-
- /* save our zone */
- bluetab[0] = first - HYSTBASE;
- bluetab[1] = last - HYSTBASE;
-
- /* invalidate all the zones overlapping with this one */
- /* the constant of 2 is determined by the default value of BlueFuzz */
- for (i = first - (MAXBLUEWIDTH - 1) - 2; i <= last + 2; i++)
- if (i >= 0 && i < MAXHYST) {
- zhyst[i] = 0;
- ozhyst[i] = 0;
- }
- return w;
-}
-
-/*
- * Try to find the Blue Values, bounding box and italic angle
- */
-
-void
-findblues(void)
-{
- /* hystograms for upper and lower zones */
- short hystl[MAXHYST];
- short hystu[MAXHYST];
- short zuhyst[MAXHYST];
- short zlhyst[MAXHYST];
- int nchars;
- int i, j, k, w, max;
- GENTRY *ge;
- GLYPH *g;
- double ang;
-
- /* find the lowest and highest points of glyphs */
- /* and by the way build the values for FontBBox */
- /* and build the hystogram for the ItalicAngle */
-
- /* re-use hystl for the hystogram of italic angle */
-
- bbox[0] = bbox[1] = 5000;
- bbox[2] = bbox[3] = -5000;
-
- for (i = 0; i < MAXHYST; i++)
- hystl[i] = 0;
-
- nchars = 0;
-
- for (i = 0, g = glyph_list; i < numglyphs; i++, g++) {
- if (g->flags & GF_USED) {
- nchars++;
-
- g->rymin = 5000;
- g->rymax = -5000;
- for (ge = g->entries; ge != 0; ge = ge->next) {
- if (ge->type == GE_LINE) {
-
- j = ge->iy3 - ge->prev->iy3;
- k = ge->ix3 - ge->prev->ix3;
- if (j > 0)
- ang = atan2(-k, j) * 180.0 / M_PI;
- else
- ang = atan2(k, -j) * 180.0 / M_PI;
-
- k /= 100;
- j /= 100;
- if (ang > -45.0 && ang < 45.0) {
- /*
- * be careful to not overflow
- * the counter
- */
- hystl[HYSTBASE + (int) (ang * 10.0)] += (k * k + j * j) / 4;
- }
- if (ge->iy3 == ge->prev->iy3) {
- if (ge->iy3 <= g->rymin) {
- g->rymin = ge->iy3;
- g->flatymin = 1;
- }
- if (ge->iy3 >= g->rymax) {
- g->rymax = ge->iy3;
- g->flatymax = 1;
- }
- } else {
- if (ge->iy3 < g->rymin) {
- g->rymin = ge->iy3;
- g->flatymin = 0;
- }
- if (ge->iy3 > g->rymax) {
- g->rymax = ge->iy3;
- g->flatymax = 0;
- }
- }
- } else if (ge->type == GE_CURVE) {
- if (ge->iy3 < g->rymin) {
- g->rymin = ge->iy3;
- g->flatymin = 0;
- }
- if (ge->iy3 > g->rymax) {
- g->rymax = ge->iy3;
- g->flatymax = 0;
- }
- }
- if (ge->type == GE_LINE || ge->type == GE_CURVE) {
- if (ge->ix3 < bbox[0])
- bbox[0] = ge->ix3;
- if (ge->ix3 > bbox[2])
- bbox[2] = ge->ix3;
- if (ge->iy3 < bbox[1])
- bbox[1] = ge->iy3;
- if (ge->iy3 > bbox[3])
- bbox[3] = ge->iy3;
- }
- }
- }
- }
-
- /* get the most popular angle */
- max = 0;
- w = 0;
- for (i = 0; i < MAXHYST; i++) {
- if (hystl[i] > w) {
- w = hystl[i];
- max = i;
- }
- }
- ang = (double) (max - HYSTBASE) / 10.0;
- WARNING_2 fprintf(stderr, "Guessed italic angle: %f\n", ang);
- if (italic_angle == 0.0)
- italic_angle = ang;
-
- /* build the hystogram of the lower points */
- for (i = 0; i < MAXHYST; i++)
- hystl[i] = 0;
-
- for (i = 0, g = glyph_list; i < numglyphs; i++, g++) {
- if ((g->flags & GF_USED)
- && g->rymin + HYSTBASE >= 0 && g->rymin < MAXHYST - HYSTBASE) {
- hystl[g->rymin + HYSTBASE]++;
- }
- }
-
- /* build the hystogram of the upper points */
- for (i = 0; i < MAXHYST; i++)
- hystu[i] = 0;
-
- for (i = 0, g = glyph_list; i < numglyphs; i++, g++) {
- if ((g->flags & GF_USED)
- && g->rymax + HYSTBASE >= 0 && g->rymax < MAXHYST - HYSTBASE) {
- hystu[g->rymax + HYSTBASE]++;
- }
- }
-
- /* build the hystogram of all the possible lower zones with max width */
- for (i = 0; i < MAXHYST; i++)
- zlhyst[i] = 0;
-
- for (i = 0; i <= MAXHYST - MAXBLUEWIDTH; i++) {
- for (j = 0; j < MAXBLUEWIDTH; j++)
- zlhyst[i] += hystl[i + j];
- }
-
- /* build the hystogram of all the possible upper zones with max width */
- for (i = 0; i < MAXHYST; i++)
- zuhyst[i] = 0;
-
- for (i = 0; i <= MAXHYST - MAXBLUEWIDTH; i++) {
- for (j = 0; j < MAXBLUEWIDTH; j++)
- zuhyst[i] += hystu[i + j];
- }
-
- /* find the baseline */
- w = bestblue(zlhyst, hystl, zuhyst, &bluevalues[0]);
- if (0)
- fprintf(stderr, "BaselineBlue zone %d%% %d...%d\n", w * 100 / nchars,
- bluevalues[0], bluevalues[1]);
-
- if (w == 0) /* no baseline, something weird */
- return;
-
- /* find the upper zones */
- for (nblues = 2; nblues < 14; nblues += 2) {
- w = bestblue(zuhyst, hystu, zlhyst, &bluevalues[nblues]);
-
- if (0)
- fprintf(stderr, "Blue zone %d%% %d...%d\n", w * 100 / nchars,
- bluevalues[nblues], bluevalues[nblues+1]);
-
- if (w * 20 < nchars)
- break; /* don't save this zone */
- }
-
- /* find the lower zones */
- for (notherb = 0; notherb < 10; notherb += 2) {
- w = bestblue(zlhyst, hystl, zuhyst, &otherblues[notherb]);
-
- if (0)
- fprintf(stderr, "OtherBlue zone %d%% %d...%d\n", w * 100 / nchars,
- otherblues[notherb], otherblues[notherb+1]);
-
-
- if (w * 20 < nchars)
- break; /* don't save this zone */
- }
-
-}
-
-/*
- * Find the actual width of the glyph and modify the
- * description to reflect it. Not guaranteed to do
- * any good, may make character spacing too wide.
- */
-
-void
-docorrectwidth(void)
-{
- int i;
- GENTRY *ge;
- GLYPH *g;
- int xmin, xmax;
- int maxwidth, minsp;
-
- /* enforce this minimal spacing,
- * we limit the amount of the enforced spacing to avoid
- * spacing the bold wonts too widely
- */
- minsp = (stdhw>60 || stdhw<10)? 60 : stdhw;
-
- for (i = 0, g = glyph_list; i < numglyphs; i++, g++) {
- g->oldwidth=g->scaledwidth; /* save the old width, will need for AFM */
-
- if (correctwidth && g->flags & GF_USED) {
- xmin = 5000;
- xmax = -5000;
- for (ge = g->entries; ge != 0; ge = ge->next) {
- if (ge->type != GE_LINE && ge->type != GE_CURVE)
- continue;
-
- if (ge->ix3 <= xmin) {
- xmin = ge->ix3;
- }
- if (ge->ix3 >= xmax) {
- xmax = ge->ix3;
- }
- }
-
- maxwidth=xmax+minsp;
- if( g->scaledwidth < maxwidth ) {
- g->scaledwidth = maxwidth;
- WARNING_3 fprintf(stderr, "glyph %s: extended from %d to %d\n",
- g->name, g->oldwidth, g->scaledwidth );
- }
- }
- }
-
-}
-
-/*
- * Try to find the typical stem widths
- */
-
-void
-stemstatistics(void)
-{
-#define MINDIST 10 /* minimal distance between the widths */
- int hyst[MAXHYST+MINDIST*2];
- int best[12];
- int i, j, k, w;
- int nchars;
- int ns;
- STEM *s;
- GLYPH *g;
-
- /* start with typical stem width */
-
- nchars=0;
-
- /* build the hystogram of horizontal stem widths */
- memset(hyst, 0, sizeof hyst);
-
- for (i = 0, g = glyph_list; i < numglyphs; i++, g++) {
- if (g->flags & GF_USED) {
- nchars++;
- s = g->hstems;
- for (j = 0; j < g->nhs; j += 2) {
- if ((s[j].flags | s[j + 1].flags) & ST_END)
- continue;
- w = s[j + 1].value - s[j].value+1;
- if(w==20) /* split stems should not be counted */
- continue;
- if (w > 0 && w < MAXHYST - 1) {
- /*
- * handle some fuzz present in
- * converted fonts
- */
- hyst[w+MINDIST] += MINDIST-1;
- for(k=1; k<MINDIST-1; k++) {
- hyst[w+MINDIST + k] += MINDIST-1-k;
- hyst[w+MINDIST - k] += MINDIST-1-k;
- }
- }
- }
- }
- }
-
- /* find 12 most frequent values */
- ns = besthyst(hyst+MINDIST, 0, best, 12, MINDIST, &stdhw);
-
- /* store data in stemsnaph */
- for (i = 0; i < ns; i++)
- stemsnaph[i] = best[i];
- if (ns < 12)
- stemsnaph[ns] = 0;
-
- /* build the hystogram of vertical stem widths */
- memset(hyst, 0, sizeof hyst);
-
- for (i = 0, g = glyph_list; i < numglyphs; i++, g++) {
- if (g->flags & GF_USED) {
- s = g->vstems;
- for (j = 0; j < g->nvs; j += 2) {
- if ((s[j].flags | s[j + 1].flags) & ST_END)
- continue;
- w = s[j + 1].value - s[j].value+1;
- if (w > 0 && w < MAXHYST - 1) {
- /*
- * handle some fuzz present in
- * converted fonts
- */
- hyst[w+MINDIST] += MINDIST-1;
- for(k=1; k<MINDIST-1; k++) {
- hyst[w+MINDIST + k] += MINDIST-1-k;
- hyst[w+MINDIST - k] += MINDIST-1-k;
- }
- }
- }
- }
- }
-
- /* find 12 most frequent values */
- ns = besthyst(hyst+MINDIST, 0, best, 12, MINDIST, &stdvw);
-
- /* store data in stemsnaph */
- for (i = 0; i < ns; i++)
- stemsnapv[i] = best[i];
- if (ns < 12)
- stemsnapv[ns] = 0;
-
-#undef MINDIST
-}
-
-/*
- * SB
- * A funny thing: TTF paths are going in reverse direction compared
- * to Type1. So after all (because the rest of logic uses TTF
- * path directions) we have to reverse the paths.
- *
- * It was a big headache to discover that.
- */
-
-/* works on both int and float paths */
-
-void
-reversepathsfromto(
- GENTRY * from,
- GENTRY * to
-)
-{
- GENTRY *ge, *nge, *pge;
- GENTRY *cur, *next;
- int i, n, ilast[2];
- double flast[2], f;
-
- for (ge = from; ge != 0 && ge != to; ge = ge->next) {
- if(ge->type == GE_LINE || ge->type == GE_CURVE) {
- if (ISDBG(REVERSAL))
- fprintf(stderr, "reverse path 0x%x <- 0x%x, 0x%x\n", ge, ge->prev, ge->bkwd);
-
- /* cut out the path itself */
- pge = ge->prev; /* GE_MOVE */
- if (pge == 0) {
- fprintf(stderr, "**! No MOVE before line !!! Fatal. ****\n");
- exit(1);
- }
- nge = ge->bkwd->next; /* GE_PATH */
- pge->next = nge;
- nge->prev = pge;
- ge->bkwd->next = 0; /* mark end of chain */
-
- /* remember the starting point */
- if(ge->flags & GEF_FLOAT) {
- flast[0] = pge->fx3;
- flast[1] = pge->fy3;
- } else {
- ilast[0] = pge->ix3;
- ilast[1] = pge->iy3;
- }
-
- /* then reinsert them in backwards order */
- for(cur = ge; cur != 0; cur = next ) {
- next = cur->next; /* or addgeafter() will screw it up */
- if(cur->flags & GEF_FLOAT) {
- for(i=0; i<2; i++) {
- /* reverse the direction of path element */
- f = cur->fpoints[i][0];
- cur->fpoints[i][0] = cur->fpoints[i][1];
- cur->fpoints[i][1] = f;
- f = flast[i];
- flast[i] = cur->fpoints[i][2];
- cur->fpoints[i][2] = f;
- }
- } else {
- for(i=0; i<2; i++) {
- /* reverse the direction of path element */
- n = cur->ipoints[i][0];
- cur->ipoints[i][0] = cur->ipoints[i][1];
- cur->ipoints[i][1] = n;
- n = ilast[i];
- ilast[i] = cur->ipoints[i][2];
- cur->ipoints[i][2] = n;
- }
- }
- addgeafter(pge, cur);
- }
-
- /* restore the starting point */
- if(ge->flags & GEF_FLOAT) {
- pge->fx3 = flast[0];
- pge->fy3 = flast[1];
- } else {
- pge->ix3 = ilast[0];
- pge->iy3 = ilast[1];
- }
-
- ge = nge;
- }
-
- }
-}
-
-void
-reversepaths(
- GLYPH * g
-)
-{
- reversepathsfromto(g->entries, NULL);
-}
-
-/* add a kerning pair information, scales the value */
-
-void
-addkernpair(
- unsigned id1,
- unsigned id2,
- int unscval
-)
-{
- static unsigned char *bits = 0;
- static int lastid;
- GLYPH *g = &glyph_list[id1];
- int i, n;
- struct kern *p;
-
- if(unscval == 0 || id1 >= numglyphs || id2 >= numglyphs)
- return;
-
- if( (glyph_list[id1].flags & GF_USED)==0
- || (glyph_list[id2].flags & GF_USED)==0 )
- return;
-
- if(bits == 0) {
- bits = calloc( BITMAP_BYTES(numglyphs), 1);
- if (bits == NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- lastid = id1;
- }
-
- if(lastid != id1) {
- /* refill the bitmap cache */
- memset(bits, 0,BITMAP_BYTES(numglyphs));
- p = g->kern;
- for(i=g->kerncount; i>0; i--) {
- n = (p++)->id;
- SET_BITMAP(bits, n);
- }
- lastid = id1;
- }
-
- if(IS_BITMAP(bits, id2))
- return; /* duplicate */
-
- if(g->kerncount <= g->kernalloc) {
- g->kernalloc += 8;
- p = realloc(g->kern, sizeof(struct kern) * g->kernalloc);
- if(p == 0) {
- fprintf (stderr, "** realloc failed, kerning data will be incomplete\n");
- }
- g->kern = p;
- }
-
- SET_BITMAP(bits, id2);
- p = &g->kern[g->kerncount];
- p->id = id2;
- p->val = iscale(unscval) - (g->scaledwidth - g->oldwidth);
- g->kerncount++;
- kerning_pairs++;
-}
-
-/* print out the kerning information */
-
-void
-print_kerning(
- FILE *afm_file
-)
-{
- int i, j, n;
- GLYPH *g;
- struct kern *p;
-
- if( kerning_pairs == 0 )
- return;
-
- fprintf(afm_file, "StartKernData\n");
- fprintf(afm_file, "StartKernPairs %hd\n", kerning_pairs);
-
- for(i=0; i<numglyphs; i++) {
- g = &glyph_list[i];
- if( (g->flags & GF_USED) ==0)
- continue;
- p = g->kern;
- for(j=g->kerncount; j>0; j--, p++) {
- fprintf(afm_file, "KPX %s %s %d\n", g->name,
- glyph_list[ p->id ].name, p->val );
- }
- }
-
- fprintf(afm_file, "EndKernPairs\n");
- fprintf(afm_file, "EndKernData\n");
-}
-
-
-#if 0
-
-/*
-** This function is commented out because the information
-** collected by it is not used anywhere else yet. Now
-** it only collects the directions of contours. And the
-** direction of contours gets fixed already in draw_glyf().
-**
-***********************************************
-**
-** Here we expect that the paths are already closed.
-** We also expect that the contours do not intersect
-** and that curves doesn't cross any border of quadrant.
-**
-** Find which contours go inside which and what is
-** their proper direction. Then fix the direction
-** to make it right.
-**
-*/
-
-#define MAXCONT 1000
-
-void
-fixcontours(
- GLYPH * g
-)
-{
- CONTOUR cont[MAXCONT];
- short ymax[MAXCONT]; /* the highest point */
- short xofmax[MAXCONT]; /* X-coordinate of any point
- * at ymax */
- short ymin[MAXCONT]; /* the lowest point */
- short xofmin[MAXCONT]; /* X-coordinate of any point
- * at ymin */
- short count[MAXCONT]; /* count of lines */
- char dir[MAXCONT]; /* in which direction they must go */
- GENTRY *start[MAXCONT], *minptr[MAXCONT], *maxptr[MAXCONT];
- int ncont;
- int i;
- int dx1, dy1, dx2, dy2;
- GENTRY *ge, *nge;
-
- /* find the contours and their most upper/lower points */
- ncont = 0;
- ymax[0] = -5000;
- ymin[0] = 5000;
- for (ge = g->entries; ge != 0; ge = ge->next) {
- if (ge->type == GE_LINE || ge->type == GE_CURVE) {
- if (ge->iy3 > ymax[ncont]) {
- ymax[ncont] = ge->iy3;
- xofmax[ncont] = ge->ix3;
- maxptr[ncont] = ge;
- }
- if (ge->iy3 < ymin[ncont]) {
- ymin[ncont] = ge->iy3;
- xofmin[ncont] = ge->ix3;
- minptr[ncont] = ge;
- }
- }
- if (ge->frwd != ge->next) {
- start[ncont++] = ge->frwd;
- ymax[ncont] = -5000;
- ymin[ncont] = 5000;
- }
- }
-
- /* determine the directions of contours */
- for (i = 0; i < ncont; i++) {
- ge = minptr[i];
- nge = ge->frwd;
-
- if (ge->type == GE_CURVE) {
- dx1 = ge->ix3 - ge->ix2;
- dy1 = ge->iy3 - ge->iy2;
-
- if (dx1 == 0 && dy1 == 0) { /* a pathological case */
- dx1 = ge->ix3 - ge->ix1;
- dy1 = ge->iy3 - ge->iy1;
- }
- if (dx1 == 0 && dy1 == 0) { /* a more pathological
- * case */
- dx1 = ge->ix3 - ge->prev->ix3;
- dy1 = ge->iy3 - ge->prev->iy3;
- }
- } else {
- dx1 = ge->ix3 - ge->prev->ix3;
- dy1 = ge->iy3 - ge->prev->iy3;
- }
- if (nge->type == GE_CURVE) {
- dx2 = ge->ix3 - nge->ix1;
- dy2 = ge->iy3 - nge->iy1;
- if (dx1 == 0 && dy1 == 0) { /* a pathological case */
- dx2 = ge->ix3 - nge->ix2;
- dy2 = ge->iy3 - nge->iy2;
- }
- if (dx1 == 0 && dy1 == 0) { /* a more pathological
- * case */
- dx2 = ge->ix3 - nge->ix3;
- dy2 = ge->iy3 - nge->iy3;
- }
- } else {
- dx2 = ge->ix3 - nge->ix3;
- dy2 = ge->iy3 - nge->iy3;
- }
-
- /* compare angles */
- cont[i].direction = DIR_INNER;
- if (dy1 == 0) {
- if (dx1 < 0)
- cont[i].direction = DIR_OUTER;
- } else if (dy2 == 0) {
- if (dx2 > 0)
- cont[i].direction = DIR_OUTER;
- } else if (dx2 * dy1 < dx1 * dy2)
- cont[i].direction = DIR_OUTER;
-
- cont[i].ymin = ymin[i];
- cont[i].xofmin = xofmin[i];
- }
-
- /* save the information that may be needed further */
- g->ncontours = ncont;
- if (ncont > 0) {
- g->contours = malloc(sizeof(CONTOUR) * ncont);
- if (g->contours == 0) {
- fprintf(stderr, "***** Memory allocation error *****\n");
- exit(255);
- }
- memcpy(g->contours, cont, sizeof(CONTOUR) * ncont);
- }
-}
-
-#endif
-
-/*
- *
- */
-
diff --git a/nx-X11/extras/ttf2pt1/pt1.h b/nx-X11/extras/ttf2pt1/pt1.h
deleted file mode 100644
index 4f65f8847..000000000
--- a/nx-X11/extras/ttf2pt1/pt1.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * see COPYRIGHT
- */
-
-
-/* glyph entry, one drawing command */
-typedef struct gentry {
- /* this list links all GENTRYs of a GLYPH sequentially */
- struct gentry *next; /* double linked list */
- struct gentry *prev;
-
- /* this list links all GENTRYs of one contour -
- * of types GE_LINE and GE_CURVE only
- * bkwd is also reused: in the very first entry (normally
- * of type GE_MOVE) it points to g->entries
- */
- struct gentry *cntr[2]; /* double-linked circular list */
-/* convenience handles */
-#define bkwd cntr[0]
-#define frwd cntr[1]
-
- /* various extended structures used at some stage of transformation */
- void *ext;
-
- union {
- struct {
- int val[2][3]; /* integer values */
- } i;
- struct {
- double val[2][3]; /* floating values */
- } f;
- } points; /* absolute values, NOT deltas */
-/* convenience handles */
-#define ipoints points.i.val
-#define fpoints points.f.val
-#define ixn ipoints[0]
-#define iyn ipoints[1]
-#define fxn fpoints[0]
-#define fyn fpoints[1]
-#define ix1 ixn[0]
-#define ix2 ixn[1]
-#define ix3 ixn[2]
-#define iy1 iyn[0]
-#define iy2 iyn[1]
-#define iy3 iyn[2]
-#define fx1 fxn[0]
-#define fx2 fxn[1]
-#define fx3 fxn[2]
-#define fy1 fyn[0]
-#define fy2 fyn[1]
-#define fy3 fyn[2]
-
- char flags;
-#define GEF_FLOAT 0x02 /* entry contains floating point data */
-#define GEF_LINE 0x04 /* entry looks like a line even if it's a curve */
-
- unsigned char dir; /* used to temporarily store the values for
- * the directions of the ends of curves */
-/* front end */
-#define CVDIR_FUP 0x02 /* goes over the line connecting the ends */
-#define CVDIR_FEQUAL 0x01 /* coincides with the line connecting the
- * ends */
-#define CVDIR_FDOWN 0x00 /* goes under the line connecting the ends */
-#define CVDIR_FRONT 0x0F /* mask of all front directions */
-/* rear end */
-#define CVDIR_RSAME 0x30 /* is the same as for the front end */
-#define CVDIR_RUP 0x20 /* goes over the line connecting the ends */
-#define CVDIR_REQUAL 0x10 /* coincides with the line connecting the
- * ends */
-#define CVDIR_RDOWN 0x00 /* goes under the line connecting the ends */
-#define CVDIR_REAR 0xF0 /* mask of all rear directions */
-
- signed char stemid; /* connection to the substituted stem group */
- char type;
-#define GE_HSBW 'B'
-#define GE_MOVE 'M'
-#define GE_LINE 'L'
-#define GE_CURVE 'C'
-#define GE_PATH 'P'
-
- /* indexes of the points to be used for calculation of the tangents */
- signed char ftg; /* front tangent */
- signed char rtg; /* rear tangent, -1 means "idx 2 of the previous entry" */
-} GENTRY;
-
-/* stem structure, describes one [hv]stem */
-/* acually, it describes one border of a stem */
-/* the whole stem is a pair of these structures */
-
-typedef struct stem {
- short value; /* value of X or Y coordinate */
- short origin; /* point of origin for curve stems */
- GENTRY *ge; /* entry that has (value, origin) as its first dot */
- /* also for all the stems the couple (value, origin)
- * is used to determine whether a stem is relevant for a
- * line, it's considered revelant if this tuple is
- * equal to any of the ends of the line.
- * ge is also used to resolve ambiguity if there is more than
- * one line going through certain pointi, it is used to
- * distinguish these lines.
- */
-
- short from, to; /* values of other coordinate between
- * which this stem is valid */
-
- short flags;
- /* ordering of ST_END, ST_FLAT, ST_ZONE is IMPORTANT for sorting */
-#define ST_END 0x01 /* end of line, lowest priority */
-#define ST_FLAT 0x02 /* stem is defined by a flat line, not a
- * curve */
-#define ST_ZONE 0x04 /* pseudo-stem, the limit of a blue zone */
-#define ST_UP 0x08 /* the black area is to up or right from
- * value */
-#define ST_3 0x20 /* first stem of [hv]stem3 */
-#define ST_BLUE 0x40 /* stem is in blue zone */
-#define ST_TOPZONE 0x80 /* 1 - top zone, 0 - bottom zone */
-#define ST_VERT 0x100 /* vertical stem (used in substitutions) */
-} STEM;
-
-#define MAX_STEMS 2000 /* we can't have more stems than path
- * elements (or hope so) */
-#define NSTEMGRP 50 /* maximal number of the substituted stem groups */
-
-/* structure for economical representation of the
- * substituted stems
- */
-
-typedef struct stembounds {
- short low; /* low bound */
- short high; /* high bound */
- char isvert; /* 1 - vertical, 0 - horizontal */
- char already; /* temp. flag: is aleready included */
-} STEMBOUNDS;
-
-struct kern {
- unsigned id; /* ID of the second glyph */
- int val; /* kerning value */
-};
-
-typedef struct contour {
- short ymin, xofmin;
- short inside; /* inside which contour */
- char direction;
-#define DIR_OUTER 1
-#define DIR_INNER 0
-} CONTOUR;
-
-typedef struct glyph {
- int char_no;/* Encoding of glyph */
- int orig_code;/* code of glyph in the font's original encoding */
- char *name; /* Postscript name of glyph */
- int xMin, yMin, xMax, yMax; /* values from TTF dictionary */
- int lsb; /* left sidebearing */
- int ttf_pathlen; /* total length of TTF paths */
- short width;
- short flags;
-#define GF_USED 0x0001 /* whether is this glyph used in T1 font */
-#define GF_FLOAT 0x0002 /* thys glyph contains floating point entries */
-
- GENTRY *entries;/* doube linked list of entries */
- GENTRY *lastentry; /* the last inserted entry */
- GENTRY *path; /* beggining of the last path */
- int oldwidth; /* actually also scaled */
- int scaledwidth;
-#define MAXLEGALWIDTH 10000
-
- struct kern *kern; /* kerning data */
- int kerncount; /* number of kerning pairs */
- int kernalloc; /* for how many pairs we have space */
-
- STEM *hstems; /* global horiz. and vert. stems */
- STEM *vstems;
- int nhs, nvs; /* numbers of stems */
-
- STEMBOUNDS *sbstems; /* substituted stems for all the groups */
- short *nsbs; /* indexes of the group ends in the common array */
- int nsg; /* actual number of the stem groups */
- int firstsubr; /* first substistuted stems subroutine number */
-
- CONTOUR *contours; /* it is not used now */
- int ncontours;
-
- int rymin, rymax; /* real values */
- /* do we have flat surfaces on top/bottom */
- char flatymin, flatymax;
-
-} GLYPH;
-
-/* description of a dot for calculation of its distance to a curve */
-
-struct dot_dist {
- double p[2 /*X,Y*/]; /* coordinates of a dot */
- double dist2; /* squared distance from the dot to the curve */
- short seg; /* the closest segment of the curve */
-};
-
-extern int stdhw, stdvw; /* dominant stems widths */
-extern int stemsnaph[12], stemsnapv[12]; /* most typical stem width */
-
-extern int bluevalues[14];
-extern int nblues;
-extern int otherblues[10];
-extern int notherb;
-extern int bbox[4]; /* the FontBBox array */
-extern double italic_angle;
-
-extern GLYPH *glyph_list;
-extern int encoding[]; /* inverse of glyph[].char_no */
-
-/* prototypes of functions */
-void rmoveto( int dx, int dy);
-void rlineto( int dx, int dy);
-void rrcurveto( int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
-void assertpath( GENTRY * from, char *file, int line, char *name);
-
-void fg_rmoveto( GLYPH * g, double x, double y);
-void ig_rmoveto( GLYPH * g, int x, int y);
-void fg_rlineto( GLYPH * g, double x, double y);
-void ig_rlineto( GLYPH * g, int x, int y);
-void fg_rrcurveto( GLYPH * g, double x1, double y1,
- double x2, double y2, double x3, double y3);
-void ig_rrcurveto( GLYPH * g, int x1, int y1,
- int x2, int y2, int x3, int y3);
-void g_closepath( GLYPH * g);
-
-void pathtoint( GLYPH *g);
-void ffixquadrants( GLYPH *g);
-void flattencurves( GLYPH * g);
-int checkcv( GENTRY * ge, int dx, int dy);
-void iclosepaths( GLYPH * g);
-void fclosepaths( GLYPH * g);
-void smoothjoints( GLYPH * g);
-void buildstems( GLYPH * g);
-void fstraighten( GLYPH * g);
-void istraighten( GLYPH * g, int zigonly);
-void isplitzigzags( GLYPH * g);
-void fsplitzigzags( GLYPH * g);
-void fforceconcise( GLYPH * g);
-void iforceconcise( GLYPH * g);
-void reversepathsfromto( GENTRY * from, GENTRY * to);
-void reversepaths( GLYPH * g);
-void dumppaths( GLYPH * g, GENTRY *start, GENTRY *end);
-void print_glyph( int glyphno);
-int print_glyph_subs( int glyphno, int startid);
-void print_glyph_metrics( int code, int glyphno);
-void findblues(void);
-void stemstatistics(void);
-void docorrectwidth(void);
-void addkernpair( unsigned id1, unsigned id2, int unscval);
-void print_kerning( FILE *afm_file);
-
-int fcrossrayscv( double curve[4][2], double *max1, double *max2);
-int fcrossraysge( GENTRY *ge1, GENTRY *ge2, double *max1, double *max2,
- double crossdot[2][2]);
-double fdotsegdist2( double seg[2][2], double dot[2]);
-double fdotcurvdist2( double curve[4][2], struct dot_dist *dots, int ndots, double *maxp);
-void fapproxcurve( double cv[4][2], struct dot_dist *dots, int ndots);
diff --git a/nx-X11/extras/ttf2pt1/runt1asm.c b/nx-X11/extras/ttf2pt1/runt1asm.c
deleted file mode 100644
index 58c4cad8c..000000000
--- a/nx-X11/extras/ttf2pt1/runt1asm.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Wrap-around code to either compile in t1asm or call it externally
- *
- * Copyright (C) 2000 by Sergey Babkin
- * Copyright (C) 2000 by The TTF2PT1 Project
- *
- * See COPYRIGHT for full license
- */
-
-#ifdef EXTERNAL_T1ASM
-
-#include <stdio.h>
-#include <errno.h>
-
-FILE *ifp;
-FILE *ofp;
-
-int
-runt1asm(
- int pfbflag
-)
-{
- char *cmd;
- int id, od;
- int error;
-
- /* first make a copy in case some of then is already stdin/stdout */
- if(( id = dup(fileno(ifp)) )<0) {
- perror("** Re-opening input file for t1asm");
- exit(1);
- }
- if(( od = dup(fileno(ofp)) )<0) {
- perror("** Re-opening output file for t1asm");
- exit(1);
- }
- fclose(ifp); fclose(ofp);
- close(0);
- if(( dup(id) )!=0) {
- perror("** Re-directing input file for t1asm");
- exit(1);
- }
- close(1);
- if(( dup(od) )!=1) {
- perror("** Re-directing output file for t1asm");
- exit(1);
- }
- close(id); close(od);
-
- if(pfbflag)
- error = execlp("t1asm", "t1asm", "-b", NULL);
- else
- error = execlp("t1asm", "t1asm", NULL);
-
- perror("** Calling t1asm");
-
- exit(1);
-}
-
-#else
-# include "t1asm.c"
-#endif
diff --git a/nx-X11/extras/ttf2pt1/t1asm.c b/nx-X11/extras/ttf2pt1/t1asm.c
deleted file mode 100644
index cf13f2005..000000000
--- a/nx-X11/extras/ttf2pt1/t1asm.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/* t1asm
- *
- * This program `assembles' Adobe Type-1 font programs in pseudo-PostScript
- * form into either PFB or PFA format. The human readable/editable input is
- * charstring- and eexec-encrypted as specified in the `Adobe Type 1 Font
- * Format' version 1.1 (the `black book'). There is a companion program,
- * t1disasm, which `disassembles' PFB and PFA files into a pseudo-PostScript
- * file.
- *
- * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.
- *
- * Permission is hereby granted to use, modify, and distribute this program
- * for any purpose provided this copyright notice and the one below remain
- * intact.
- *
- * I. Lee Hetherington (ilh@lcs.mit.edu)
- *
- * Revision 1.2 92/05/22 11:54:45 ilh
- * Fixed bug where integers larger than 32000 could not be encoded in
- * charstrings. Now integer range is correct for four-byte
- * twos-complement integers: -(1<<31) <= i <= (1<<31)-1. Bug detected by
- * Piet Tutelaers (rcpt@urc.tue.nl).
- *
- * Revision 1.1 92/05/22 11:48:46 ilh
- * initial version
- *
- * Ported to Microsoft C/C++ Compiler and MS-DOS operating system by
- * Kai-Uwe Herbing (herbing@netmbx.netmbx.de) on June 12, 1992. Code
- * specific to the MS-DOS version is encapsulated with #ifdef _MSDOS
- * ... #endif, where _MSDOS is an identifier, which is automatically
- * defined, if you compile with the Microsoft C/C++ Compiler.
- *
- */
-
-#ifndef lint
-static char copyright[] =
- "@(#) Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.";
-#ifdef _MSDOS
-static char portnotice[] =
- "@(#) Ported to MS-DOS by Kai-Uwe Herbing (herbing@netmbx.netmbx.de).";
-#endif
-#endif
-
-/* Note: this is ANSI C. */
-
-#ifdef _MSDOS
- #include <fcntl.h>
- #include <getopt.h>
- #include <io.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-
-#ifdef WINDOWS
-# ifdef STANDALONE
-# define WINDOWS_FUNCTIONS
-# include "windows.h"
-# endif
-#endif
-
-/* int32 must be at least 32-bit and uint16 must be at least 16-bit */
-#ifndef AIXV3
-#if INT_MAX >= 0x7FFFFFFFUL
-typedef int int32;
-#else
-typedef long int32;
-#endif
-#endif /* !AIXV3 */
-#if USHRT_MAX >= 0xFFFFUL
-typedef unsigned short uint16;
-#else
-typedef unsigned int uint16;
-#endif
-
-#define LINESIZE 256
-
-#define MAXBLOCKLEN ((1L<<17)-6)
-#define MINBLOCKLEN ((1L<<8)-6)
-
-#define MARKER 128
-#define ASCII 1
-#define BINARY 2
-#define DONE 3
-
-typedef unsigned char byte;
-
-/* must be visible from outside */
-FILE *ifp;
-FILE *ofp;
-
-/* flags */
-static int pfb = 0;
-static int active = 0;
-static int start_charstring = 0;
-static int in_eexec = 0;
-
-static char line[LINESIZE];
-
-/* lenIV and charstring start command */
-static int lenIV = 4;
-static char cs_start[10];
-
-/* for charstring buffering */
-static byte charstring_buf[65535];
-static byte *charstring_bp;
-
-/* for PFB block buffering */
-static byte blockbuf[MAXBLOCKLEN];
-static int32 blocklen = MAXBLOCKLEN;
-static int32 blockpos = -1;
-static int blocktyp = ASCII;
-
-/* decryption stuff */
-static uint16 er, cr;
-static uint16 c1 = 52845, c2 = 22719;
-
-/* table of charstring commands */
-static struct command {
- char *name;
- int one, two;
-} command_table[] = {
- { "callothersubr", 12, 16 },
- { "callsubr", 10, -1 },
- { "closepath", 9, -1 },
- { "div", 12, 12 },
- { "dotsection", 12, 0 },
- { "endchar", 14, -1 },
- { "hlineto", 6, -1 },
- { "hmoveto", 22, -1 },
- { "hsbw", 13, -1 },
- { "hstem", 1, -1 },
- { "hstem3", 12, 2 },
- { "hvcurveto", 31, -1 },
- { "pop", 12, 17 },
- { "return", 11, -1 },
- { "rlineto", 5, -1 },
- { "rmoveto", 21, -1 },
- { "rrcurveto", 8, -1 },
- { "sbw", 12, 7 },
- { "seac", 12, 6 },
- { "setcurrentpoint", 12, 33 },
- { "vhcurveto", 30, -1 },
- { "vlineto", 7, -1 },
- { "vmoveto", 4, -1 },
- { "vstem", 3, -1 },
- { "vstem3", 12, 1 },
-}; /* alphabetical */
-
-/* Two separate encryption functions because eexec and charstring encryption
- must proceed in parallel. */
-
-static byte eencrypt(byte plain)
-{
- byte cipher;
-
- cipher = (byte) (plain ^ (er >> 8));
- er = (uint16) ((cipher + er) * c1 + c2);
- return cipher;
-}
-
-static byte cencrypt(byte plain)
-{
- byte cipher;
-
- cipher = (byte) (plain ^ (cr >> 8));
- cr = (uint16) ((cipher + cr) * c1 + c2);
- return cipher;
-}
-
-/* This function flushes a buffered PFB block. */
-
-static void output_block()
-{
- int32 i;
-
- /* output four-byte block length */
- fputc((int) (blockpos & 0xff), ofp);
- fputc((int) ((blockpos >> 8) & 0xff), ofp);
- fputc((int) ((blockpos >> 16) & 0xff), ofp);
- fputc((int) ((blockpos >> 24) & 0xff), ofp);
-
- /* output block data */
- for (i = 0; i < blockpos; i++)
- fputc(blockbuf[i], ofp);
-
- /* mark block buffer empty and uninitialized */
- blockpos = -1;
-}
-
-/* This function outputs a single byte. If output is in PFB format then output
- is buffered through blockbuf[]. If output is in PFA format, then output
- will be hexadecimal if in_eexec is set, ASCII otherwise. */
-
-static void output_byte(byte b)
-{
- static char *hexchar = "0123456789ABCDEF";
- static int hexcol = 0;
-
- if (pfb) {
- /* PFB */
- if (blockpos < 0) {
- fputc(MARKER, ofp);
- fputc(blocktyp, ofp);
- blockpos = 0;
- }
- blockbuf[blockpos++] = b;
- if (blockpos == blocklen)
- output_block();
- } else {
- /* PFA */
- if (in_eexec) {
- /* trim hexadecimal lines to 64 columns */
- if (hexcol >= 64) {
- fputc('\n', ofp);
- hexcol = 0;
- }
- fputc(hexchar[(b >> 4) & 0xf], ofp);
- fputc(hexchar[b & 0xf], ofp);
- hexcol += 2;
- } else {
- fputc(b, ofp);
- }
- }
-}
-
-/* This function outputs a byte through possible eexec encryption. */
-
-static void eexec_byte(byte b)
-{
- if (in_eexec)
- output_byte(eencrypt(b));
- else
- output_byte(b);
-}
-
-/* This function outputs a null-terminated string through possible eexec
- encryption. */
-
-static void eexec_string(char *string)
-{
- while (*string)
- eexec_byte((byte) *string++);
-}
-
-/* This function gets ready for the eexec-encrypted data. If output is in
- PFB format then flush current ASCII block and get ready for binary block.
- We start encryption with four random (zero) bytes. */
-
-static void eexec_start()
-{
- eexec_string(line);
- if (pfb) {
- output_block();
- blocktyp = BINARY;
- }
-
- in_eexec = 1;
- er = 55665;
- eexec_byte(0);
- eexec_byte(0);
- eexec_byte(0);
- eexec_byte(0);
-}
-
-/* This function wraps-up the eexec-encrypted data.
- If output is in PFB format then this entails flushing binary block and
- starting an ASCII block. */
-
-static void eexec_end()
-{
- int i, j;
-
- if (pfb) {
- output_block();
- blocktyp = ASCII;
- } else {
- fputc('\n', ofp);
- }
- in_eexec = 0;
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 64; j++)
- eexec_byte('0');
- eexec_byte('\n');
- }
-#if 0
- eexec_string("cleartomark\n");
-#endif
-}
-
-/* This function writes ASCII trailer.
- If output is in PFB format then this entails flushing binary block and
- starting an ASCII block. */
-
-static void file_end()
-{
- if (pfb) {
- output_block();
- fputc(MARKER, ofp);
- fputc(DONE, ofp);
- }
-}
-/* This function returns an input line of characters. A line is terminated by
- length (including terminating null) greater than LINESIZE, a newline \n, or
- when active (looking for charstrings) by '{'. When terminated by a newline
- the newline is put into line[]. When terminated by '{', the '{' is not put
- into line[], and the flag start_charstring is set to 1. */
-
-static void t1asm_getline()
-{
- int c;
- char *p = line;
- int comment = 0;
-
- start_charstring = 0;
- while (p < line + LINESIZE) {
- c = fgetc(ifp);
- if (c == EOF)
- break;
- if (c == '%')
- comment = 1;
- if (active && !comment && c == '{') {
- start_charstring = 1;
- break;
- }
- *p++ = (char) c;
- if (c == '\n')
- break;
- }
- *p = '\0';
-}
-
-/* This function is used by the binary search, bsearch(), for command names in
- the command table. */
-
-static int command_compare(const void *key, const void *item)
-{
- return strcmp((char *) key, ((struct command *) item)->name);
-}
-
-/* This function returns 1 if the string is an integer and 0 otherwise. */
-
-static int is_integer(char *string)
-{
- if (isdigit(string[0]) || string[0] == '-' || string[0] == '+') {
- while (*++string && isdigit(*string))
- ; /* deliberately empty */
- if (!*string)
- return 1;
- }
- return 0;
-}
-
-/* This function initializes charstring encryption. Note that this is called
- at the beginning of every charstring. */
-
-static void charstring_start()
-{
- int i;
-
- charstring_bp = charstring_buf;
- cr = 4330;
- for (i = 0; i < lenIV; i++)
- *charstring_bp++ = cencrypt((byte) 0);
-}
-
-/* This function encrypts and buffers a single byte of charstring data. */
-
-static void charstring_byte(int v)
-{
- byte b = (byte) (v & 0xff);
-
- if (charstring_bp - charstring_buf > sizeof(charstring_buf)) {
- fprintf(stderr, "error: charstring_buf full (%d bytes)\n",
- sizeof(charstring_buf));
- exit(1);
- }
- *charstring_bp++ = cencrypt(b);
-}
-
-/* This function outputs buffered, encrypted charstring data through possible
- eexec encryption. */
-
-static void charstring_end()
-{
- byte *bp;
-
- sprintf(line, "%d ", charstring_bp - charstring_buf);
- eexec_string(line);
- sprintf(line, "%s ", cs_start);
- eexec_string(line);
- for (bp = charstring_buf; bp < charstring_bp; bp++)
- eexec_byte(*bp);
-}
-
-/* This function generates the charstring representation of an integer. */
-
-static void charstring_int(int num)
-{
- int x;
-
- if (num >= -107 && num <= 107) {
- charstring_byte(num + 139);
- } else if (num >= 108 && num <= 1131) {
- x = num - 108;
- charstring_byte(x / 256 + 247);
- charstring_byte(x % 256);
- } else if (num >= -1131 && num <= -108) {
- x = abs(num) - 108;
- charstring_byte(x / 256 + 251);
- charstring_byte(x % 256);
- } else if (num >= (-2147483647-1) && num <= 2147483647) {
- charstring_byte(255);
- charstring_byte(num >> 24);
- charstring_byte(num >> 16);
- charstring_byte(num >> 8);
- charstring_byte(num);
- } else {
- fprintf(stderr,
- "error: cannot format the integer %d, too large\n", num);
- exit(1);
- }
-}
-
-/* This function parses an entire charstring into integers and commands,
- outputting bytes through the charstring buffer. */
-
-static void parse_charstring()
-{
- struct command *cp;
-
- charstring_start();
- while (fscanf(ifp, "%s", line) == 1) {
- if (line[0] == '%') {
- /* eat comment to end of line */
- while (fgetc(ifp) != '\n' && !feof(ifp))
- ; /* deliberately empty */
- continue;
- }
- if (line[0] == '}')
- break;
- if (is_integer(line)) {
- charstring_int(atoi(line));
- } else {
- cp = (struct command *)
- bsearch((void *) line, (void *) command_table,
- sizeof(command_table) / sizeof(struct command),
- sizeof(struct command),
- command_compare);
- if (cp) {
- charstring_byte(cp->one);
- if (cp->two >= 0)
- charstring_byte(cp->two);
- } else {
- fprintf(stderr, "error: cannot use `%s' in charstring\n",line);
- exit(1);
- }
- }
- }
- charstring_end();
-}
-
-static void usage()
-{
- fprintf(stderr,
- "usage: t1asm [-b] [-l block-length] [input [output]]\n");
- fprintf(stderr,
- "\n-b means output in PFB format, otherwise PFA format.\n");
- fprintf(stderr,
- "The block length applies to the length of blocks in the\n");
- fprintf(stderr,
- "PFB output file; the default is to use the largest possible.\n");
- exit(1);
-}
-
-static void print_banner()
-{
- static char rcs_revision[] = ""; /* removed RCS */
- static char revision[20];
-
- if (sscanf(rcs_revision, "$Revision: %19s", revision) != 1)
- revision[0] = '\0';
- fprintf(stderr, "This is t1asm %s.\n", revision);
-}
-
-#ifdef STANDALONE
-int main(int argc, char **argv)
-{
- char *p, *q, *r;
- int c;
-
- extern char *optarg;
- extern int optind;
-
- ifp = stdin;
- ofp = stdout;
-
- print_banner();
-
- /* interpret command line arguments using getopt */
- while ((c = getopt(argc, argv, "bl:")) != -1)
- switch (c) {
- case 'b':
- pfb = 1;
- break;
- case 'l':
- blocklen = atoi(optarg);
- if (blocklen < MINBLOCKLEN) {
- blocklen = MINBLOCKLEN;
- fprintf(stderr,
- "warning: using minimum block length of %d\n",
- blocklen);
- } else if (blocklen > MAXBLOCKLEN) {
- blocklen = MAXBLOCKLEN;
- fprintf(stderr,
- "warning: using maximum block length of %d\n",
- blocklen);
- }
- break;
- default:
- usage();
- break;
- }
- if (argc - optind > 2)
- usage();
-
- /* possibly open input & output files */
- if (argc - optind >= 1) {
- ifp = fopen(argv[optind], "r");
- if (!ifp) {
- fprintf(stderr, "error: cannot open %s for reading\n", argv[1]);
- exit(1);
- }
- }
- if (argc - optind >= 2) {
- ofp = fopen(argv[optind + 1], "w");
- if (!ofp) {
- fprintf(stderr, "error: cannot open %s for writing\n", argv[2]);
- exit(1);
- }
- }
-
-#else
-int runt1asm(int pfbflag)
-{
- char *p, *q, *r;
-
- pfb = pfbflag;
-#endif
-
- #ifdef _MSDOS
- /* If we are processing a PFB (binary) output */
- /* file, we must set its file mode to binary. */
- if (pfb)
- _setmode(_fileno(ofp), _O_BINARY);
- #endif
-
- /* Finally, we loop until no more input. Some special things to look for
- are the `currentfile eexec' line, the beginning of the `/Subrs'
- definition, the definition of `/lenIV', and the definition of the
- charstring start command which has `...string currentfile...' in it. */
-
- while (!feof(ifp) && !ferror(ifp)) {
- t1asm_getline();
- if (strcmp(line, "currentfile eexec\n") == 0) {
- eexec_start();
- continue;
- } else if (strstr(line, "/Subrs") && isspace(line[6])) {
- active = 1;
- } else if ((p = strstr(line, "/lenIV"))) {
- sscanf(p, "%*s %d", &lenIV);
- } else if ((p = strstr(line, "string currentfile"))) {
- /* locate the name of the charstring start command */
- *p = '\0'; /* damage line[] */
- q = strrchr(line, '/');
- if (q) {
- r = cs_start;
- ++q;
- while (!isspace(*q) && *q != '{')
- *r++ = *q++;
- *r = '\0';
- }
- *p = 's'; /* repair line[] */
- }
- /* output line data */
- eexec_string(line);
- if ((p = strstr(line, "currentfile closefile"))) {
- eexec_end();
- }
- if (start_charstring) {
- if (!cs_start[0]) {
- fprintf(stderr, "error: couldn't find charstring start command\n");
- exit(1);
- }
- parse_charstring();
- }
- }
- file_end();
-
- fclose(ifp);
- fclose(ofp);
-
- return 0;
-}
diff --git a/nx-X11/extras/ttf2pt1/ttf.c b/nx-X11/extras/ttf2pt1/ttf.c
deleted file mode 100644
index b5cc5bdf8..000000000
--- a/nx-X11/extras/ttf2pt1/ttf.c
+++ /dev/null
@@ -1,1480 +0,0 @@
-/*
- * True Type Font to Adobe Type 1 font converter
- * By Mark Heath <mheath@netspace.net.au>
- * Based on ttf2pfa by Andrew Weeks <ccsaw@bath.ac.uk>
- * With help from Frank M. Siegert <fms@this.net>
- *
- * see COPYRIGHT
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <time.h>
-#include <ctype.h>
-#include <math.h>
-
-#ifndef WINDOWS
-# include <unistd.h>
-# include <netinet/in.h>
-#else
-# include "windows.h"
-#endif
-
-#include "ttf.h"
-#include "pt1.h"
-#include "global.h"
-
-/* prototypes of call entries */
-static void openfont(char *fname, char *arg);
-static void closefont( void);
-static int getnglyphs ( void);
-static int glnames( GLYPH *glyph_list);
-static void glmetrics( GLYPH *glyph_list);
-static int glenc( GLYPH *glyph_list, int *encoding, int *unimap);
-static void fnmetrics( struct font_metrics *fm);
-static void glpath( int glyphno, GLYPH *glyph_list);
-static void kerning( GLYPH *glyph_list);
-
-/* globals */
-
-/* front-end descriptor */
-struct frontsw ttf_sw = {
- /*name*/ "ttf",
- /*descr*/ "built-in TTF support",
- /*suffix*/ { "ttf" },
- /*open*/ openfont,
- /*close*/ closefont,
- /*nglyphs*/ getnglyphs,
- /*glnames*/ glnames,
- /*glmetrics*/ glmetrics,
- /*glenc*/ glenc,
- /*fnmetrics*/ fnmetrics,
- /*glpath*/ glpath,
- /*kerning*/ kerning,
-};
-
-/* statics */
-
-static FILE *ttf_file;
-static int ttf_nglyphs, long_offsets;
-
-static TTF_DIRECTORY *directory;
-static TTF_DIR_ENTRY *dir_entry;
-static char *filebuffer;
-static char *filebuffer_end;
-static TTF_NAME *name_table = NULL;
-static TTF_NAME_REC *name_record;
-static TTF_HEAD *head_table = NULL;
-static TTF_HHEA *hhea_table = NULL;
-static TTF_KERN *kern_table = NULL;
-static TTF_CMAP *cmap_table = NULL;
-static LONGHORMETRIC *hmtx_table = NULL;
-static TTF_GLYF *glyf_table;
-static BYTE *glyf_start = NULL;
-static TTF_MAXP *maxp_table = NULL;
-static TTF_POST_HEAD *post_table = NULL;
-static union {
- USHORT *sp;
- ULONG *lp;
-} loca_table;
-#define short_loca_table loca_table.sp
-#define long_loca_table loca_table.lp
-
-static short cmap_n_segs;
-static USHORT *cmap_seg_start, *cmap_seg_end;
-static short *cmap_idDelta, *cmap_idRangeOffset;
-static TTF_CMAP_FMT0 *encoding0;
-static int enc_type;
-
-static char name_buffer[2000];
-static char *name_fields[8];
-
-static int enc_found_ms, enc_found_mac;
-
-static char *mac_glyph_names[258] = {
- ".notdef", ".null", "CR",
- "space", "exclam", "quotedbl", "numbersign",
- "dollar", "percent", "ampersand", "quotesingle",
- "parenleft", "parenright", "asterisk", "plus",
- "comma", "hyphen", "period", "slash",
- "zero", "one", "two", "three",
- "four", "five", "six", "seven",
- "eight", "nine", "colon", "semicolon",
- "less", "equal", "greater", "question",
- "at", "A", "B", "C",
- "D", "E", "F", "G",
- "H", "I", "J", "K",
- "L", "M", "N", "O",
- "P", "Q", "R", "S",
- "T", "U", "V", "W",
- "X", "Y", "Z", "bracketleft",
- "backslash", "bracketright", "asciicircum", "underscore",
- "grave", "a", "b", "c",
- "d", "e", "f", "g",
- "h", "i", "j", "k",
- "l", "m", "n", "o",
- "p", "q", "r", "s",
- "t", "u", "v", "w",
- "x", "y", "z", "braceleft",
- "bar", "braceright", "asciitilde", "Adieresis",
- "Aring", "Ccedilla", "Eacute", "Ntilde",
- "Odieresis", "Udieresis", "aacute", "agrave",
- "acircumflex", "adieresis", "atilde", "aring",
- "ccedilla", "eacute", "egrave", "ecircumflex",
- "edieresis", "iacute", "igrave", "icircumflex",
- "idieresis", "ntilde", "oacute", "ograve",
- "ocircumflex", "odieresis", "otilde", "uacute",
- "ugrave", "ucircumflex", "udieresis", "dagger",
- "degree", "cent", "sterling", "section",
- "bullet", "paragraph", "germandbls", "registered",
- "copyright", "trademark", "acute", "dieresis",
- "notequal", "AE", "Oslash", "infinity",
- "plusminus", "lessequal", "greaterequal", "yen",
- "mu", "partialdiff", "summation", "product",
- "pi", "integral", "ordfeminine", "ordmasculine",
- "Omega", "ae", "oslash", "questiondown",
- "exclamdown", "logicalnot", "radical", "florin",
- "approxequal", "increment", "guillemotleft", "guillemotright",
- "ellipsis", "nbspace", "Agrave", "Atilde",
- "Otilde", "OE", "oe", "endash",
- "emdash", "quotedblleft", "quotedblright", "quoteleft",
- "quoteright", "divide", "lozenge", "ydieresis",
- "Ydieresis", "fraction", "currency", "guilsinglleft",
- "guilsinglright", "fi", "fl", "daggerdbl",
- "periodcentered", "quotesinglbase", "quotedblbase", "perthousand",
- "Acircumflex", "Ecircumflex", "Aacute", "Edieresis",
- "Egrave", "Iacute", "Icircumflex", "Idieresis",
- "Igrave", "Oacute", "Ocircumflex", "applelogo",
- "Ograve", "Uacute", "Ucircumflex", "Ugrave",
- "dotlessi", "circumflex", "tilde", "macron",
- "breve", "dotaccent", "ring", "cedilla",
- "hungarumlaut", "ogonek", "caron", "Lslash",
- "lslash", "Scaron", "scaron", "Zcaron",
- "zcaron", "brokenbar", "Eth", "eth",
- "Yacute", "yacute", "Thorn", "thorn",
- "minus", "multiply", "onesuperior", "twosuperior",
- "threesuperior", "onehalf", "onequarter", "threequarters",
- "franc", "Gbreve", "gbreve", "Idot",
- "Scedilla", "scedilla", "Cacute", "cacute",
- "Ccaron", "ccaron", "dmacron"
-};
-
-/* other prototypes */
-static void draw_composite_glyf( GLYPH *g, GLYPH *glyph_list, int glyphno,
- double *matrix, int level);
-static void draw_simple_glyf( GLYPH *g, GLYPH *glyph_list, int glyphno,
- double *matrix);
-static double f2dot14( short x);
-
-/* get the TTF description table address and length for this index */
-
-static void
-get_glyf_table(
- int glyphno,
- TTF_GLYF **tab,
- int *len
-)
-{
- if(tab!=NULL) {
- if (long_offsets) {
- *tab = (TTF_GLYF *) (glyf_start + ntohl(long_loca_table[glyphno]));
- } else {
- *tab = (TTF_GLYF *) (glyf_start + (ntohs(short_loca_table[glyphno]) << 1));
- }
- }
- if(len!=NULL) {
- if (long_offsets) {
- *len = ntohl(long_loca_table[glyphno + 1]) - ntohl(long_loca_table[glyphno]);
- } else {
- *len = (ntohs(short_loca_table[glyphno + 1]) - ntohs(short_loca_table[glyphno])) << 1;
- }
- }
-}
-
-static void
-handle_name(void)
-{
- int j, k, lang, len, platform;
- char *p, *string_area;
- char *nbp = name_buffer;
- int found3 = 0;
-
- string_area = (char *) name_table + ntohs(name_table->offset);
- name_record = &(name_table->nameRecords);
-
- for (j = 0; j < 8; j++) {
- name_fields[j] = "";
- }
-
- for (j = 0; j < ntohs(name_table->numberOfNameRecords); j++) {
-
- platform = ntohs(name_record->platformID);
-
- if (platform == 3) {
-
- found3 = 1;
- lang = ntohs(name_record->languageID) & 0xff;
- len = ntohs(name_record->stringLength);
- if (lang == 0 || lang == 9) {
- k = ntohs(name_record->nameID);
- if (k < 8) {
- name_fields[k] = nbp;
-
- p = string_area + ntohs(name_record->stringOffset);
- for (k = 0; k < len; k++) {
- if (p[k] != '\0') {
- if (p[k] == '(') {
- *nbp = '[';
- } else if (p[k] == ')') {
- *nbp = ']';
- } else {
- *nbp = p[k];
- }
- nbp++;
- }
- }
- *nbp = '\0';
- nbp++;
- }
- }
- }
- name_record++;
- }
-
- string_area = (char *) name_table + ntohs(name_table->offset);
- name_record = &(name_table->nameRecords);
-
- if (!found3) {
- for (j = 0; j < ntohs(name_table->numberOfNameRecords); j++) {
-
- platform = ntohs(name_record->platformID);
-
- if (platform == 1) {
-
- found3 = 1;
- lang = ntohs(name_record->languageID) & 0xff;
- len = ntohs(name_record->stringLength);
- if (lang == 0 || lang == 9) {
- k = ntohs(name_record->nameID);
- if (k < 8) {
- name_fields[k] = nbp;
-
- p = string_area + ntohs(name_record->stringOffset);
- for (k = 0; k < len; k++) {
- if (p[k] != '\0') {
- if (p[k] == '(') {
- *nbp = '[';
- } else if (p[k] == ')') {
- *nbp = ']';
- } else {
- *nbp = p[k];
- }
- nbp++;
- }
- }
- *nbp = '\0';
- nbp++;
- }
- }
- }
- name_record++;
- }
- }
- if (!found3) {
- fprintf(stderr, "**** Cannot decode font name fields ****\n");
- exit(1);
- }
- if (name_fields[4][0] == 0) { /* Full Name empty, use Family Name */
- name_fields[4] = name_fields[1];
- }
- if (name_fields[6][0] == 0) { /* Font Name empty, use Full Name */
- name_fields[6] = name_fields[4];
- if (name_fields[6][0] == 0) { /* oops, empty again */
- WARNING_1 fprintf(stderr, "Font name is unknown, setting to \"Unknown\"\n");
- name_fields[6] = "Unknown";
- }
- }
- p = name_fields[6];
- /* must not start with a digit */
- if(isdigit(*p))
- *p+= 'A'-'0'; /* change to a letter */
- while (*p != '\0') {
- if (!isalnum(*p) || *p=='_') {
- *p = '-';
- }
- p++;
- }
-}
-
-static void
-handle_head(void)
-{
- long_offsets = ntohs(head_table->indexToLocFormat);
- if (long_offsets != 0 && long_offsets != 1) {
- fprintf(stderr, "**** indexToLocFormat wrong ****\n");
- exit(1);
- }
-}
-
-/* limit the recursion level to avoid cycles */
-#define MAX_COMPOSITE_LEVEL 20
-
-static void
-draw_composite_glyf(
- GLYPH *g,
- GLYPH *glyph_list,
- int glyphno,
- double *orgmatrix,
- int level
-)
-{
- int len;
- short ncontours;
- USHORT flagbyte, glyphindex;
- double arg1, arg2;
- BYTE *ptr;
- char *bptr;
- SHORT *sptr;
- double matrix[6], newmatrix[6];
-
- get_glyf_table(glyphno, &glyf_table, &len);
-
- if(len<=0) /* nothing to do */
- return;
-
- ncontours = ntohs(glyf_table->numberOfContours);
- if (ncontours >= 0) { /* simple case */
- draw_simple_glyf(g, glyph_list, glyphno, orgmatrix);
- return;
- }
-
- if(ISDBG(COMPOSITE) && level ==0)
- fprintf(stderr, "* %s [ %.2f %.2f %.2f %.2f %.2f %.2f ]\n", g->name,
- orgmatrix[0], orgmatrix[1], orgmatrix[2], orgmatrix[3],
- orgmatrix[4], orgmatrix[5]);
-
- /* complex case */
- if(level >= MAX_COMPOSITE_LEVEL) {
- WARNING_1 fprintf(stderr,
- "*** Glyph %s: stopped (possibly infinite) recursion at depth %d\n",
- g->name, level);
- return;
- }
-
- ptr = ((BYTE *) glyf_table + sizeof(TTF_GLYF));
- sptr = (SHORT *) ptr;
- do {
- flagbyte = ntohs(*sptr);
- sptr++;
- glyphindex = ntohs(*sptr);
- sptr++;
-
- if (flagbyte & ARG_1_AND_2_ARE_WORDS) {
- arg1 = (short)ntohs(*sptr);
- sptr++;
- arg2 = (short)ntohs(*sptr);
- sptr++;
- } else {
- bptr = (char *) sptr;
- arg1 = (signed char) bptr[0];
- arg2 = (signed char) bptr[1];
- sptr++;
- }
- matrix[1] = matrix[2] = 0.0;
-
- if (flagbyte & WE_HAVE_A_SCALE) {
- matrix[0] = matrix[3] = f2dot14(*sptr);
- sptr++;
- } else if (flagbyte & WE_HAVE_AN_X_AND_Y_SCALE) {
- matrix[0] = f2dot14(*sptr);
- sptr++;
- matrix[3] = f2dot14(*sptr);
- sptr++;
- } else if (flagbyte & WE_HAVE_A_TWO_BY_TWO) {
- matrix[0] = f2dot14(*sptr);
- sptr++;
- matrix[2] = f2dot14(*sptr);
- sptr++;
- matrix[1] = f2dot14(*sptr);
- sptr++;
- matrix[3] = f2dot14(*sptr);
- sptr++;
- } else {
- matrix[0] = matrix[3] = 1.0;
- }
-
- /*
- * See *
- * http://fonts.apple.com/TTRefMan/RM06/Chap6g
- * lyf.html * matrix[0,1,2,3,4,5]=a,b,c,d,m,n
- */
-
- if (fabs(matrix[0]) > fabs(matrix[1]))
- matrix[4] = fabs(matrix[0]);
- else
- matrix[4] = fabs(matrix[1]);
- if (fabs(fabs(matrix[0]) - fabs(matrix[2])) <= 33. / 65536.)
- matrix[4] *= 2.0;
-
- if (fabs(matrix[2]) > fabs(matrix[3]))
- matrix[5] = fabs(matrix[2]);
- else
- matrix[5] = fabs(matrix[3]);
- if (fabs(fabs(matrix[2]) - fabs(matrix[3])) <= 33. / 65536.)
- matrix[5] *= 2.0;
-
- /*
- * fprintf (stderr,"Matrix Opp %hd
- * %hd\n",arg1,arg2);
- */
-#if 0
- fprintf(stderr, "Matrix: %f %f %f %f %f %f\n",
- matrix[0], matrix[1], matrix[2], matrix[3],
- matrix[4], matrix[5]);
- fprintf(stderr, "Offset: %f %f (%s)\n",
- arg1, arg2,
- ((flagbyte & ARGS_ARE_XY_VALUES) ? "XY" : "index"));
-#endif
-
- if (flagbyte & ARGS_ARE_XY_VALUES) {
- matrix[4] *= arg1;
- matrix[5] *= arg2;
- } else {
- WARNING_1 fprintf(stderr,
- "*** Glyph %s: reusing scale from another glyph is unsupported\n",
- g->name);
- /*
- * must extract values from a glyph
- * but it seems to be too much pain
- * and it's not clear now that it
- * would be really used in any
- * interesting font
- */
- }
-
- /* at this point arg1,arg2 contain what logically should be matrix[4,5] */
-
- /* combine matrices */
-
- newmatrix[0] = orgmatrix[0]*matrix[0] + orgmatrix[2]*matrix[1];
- newmatrix[1] = orgmatrix[0]*matrix[2] + orgmatrix[2]*matrix[3];
-
- newmatrix[2] = orgmatrix[1]*matrix[0] + orgmatrix[3]*matrix[1];
- newmatrix[3] = orgmatrix[1]*matrix[2] + orgmatrix[3]*matrix[3];
-
- newmatrix[4] = orgmatrix[0]*matrix[4] + orgmatrix[2]*matrix[5] + orgmatrix[4];
- newmatrix[5] = orgmatrix[1]*matrix[4] + orgmatrix[3]*matrix[5] + orgmatrix[5];
-
- if(ISDBG(COMPOSITE)) {
- fprintf(stderr, "%*c+-> %2d %s [ %.2f %.2f %.2f %.2f %.2f %.2f ]\n",
- level+1, ' ', level, glyph_list[glyphindex].name,
- matrix[0], matrix[1], matrix[2], matrix[3],
- matrix[4], matrix[5]);
- fprintf(stderr, "%*c = [ %.2f %.2f %.2f %.2f %.2f %.2f ]\n",
- level+1, ' ',
- newmatrix[0], newmatrix[1], newmatrix[2], newmatrix[3],
- newmatrix[4], newmatrix[5]);
- }
- draw_composite_glyf(g, glyph_list, glyphindex, newmatrix, level+1);
-
- } while (flagbyte & MORE_COMPONENTS);
-}
-
-static void
-draw_simple_glyf(
- GLYPH *g,
- GLYPH *glyph_list,
- int glyphno,
- double *matrix
-)
-{
- int i, j, k, k1, len, first, cs, ce;
- /* We assume that hsbw always sets to(0, 0) */
- double xlast = 0, ylast = 0;
- int finished, nguide, contour_start, contour_end;
- short ncontours, n_inst, last_point;
- USHORT *contour_end_pt;
- BYTE *ptr;
-#define GLYFSZ 2000
- short xabs[GLYFSZ], yabs[GLYFSZ], xrel[GLYFSZ], yrel[GLYFSZ];
- double xcoord[GLYFSZ], ycoord[GLYFSZ];
- BYTE flags[GLYFSZ];
- double tx, ty;
- int needreverse = 0; /* transformation may require
- * that */
- GENTRY *lge;
-
- lge = g->lastentry;
-
- get_glyf_table(glyphno, &glyf_table, &len);
-
- if (len <= 0) {
- WARNING_1 fprintf(stderr,
- "**** Composite glyph %s refers to non-existent glyph %s, ignored\n",
- g->name,
- glyph_list[glyphno].name);
- return;
- }
- ncontours = ntohs(glyf_table->numberOfContours);
- if (ncontours < 0) {
- WARNING_1 fprintf(stderr,
- "**** Composite glyph %s refers to composite glyph %s, ignored\n",
- g->name,
- glyph_list[glyphno].name);
- return;
- }
- contour_end_pt = (USHORT *) ((char *) glyf_table + sizeof(TTF_GLYF));
-
- last_point = ntohs(contour_end_pt[ncontours - 1]);
- n_inst = ntohs(contour_end_pt[ncontours]);
-
- ptr = ((BYTE *) contour_end_pt) + (ncontours << 1) + n_inst + 2;
- j = k = 0;
- while (k <= last_point) {
- flags[k] = ptr[j];
-
- if (ptr[j] & REPEAT) {
- for (k1 = 0; k1 < ptr[j + 1]; k1++) {
- k++;
- flags[k] = ptr[j];
- }
- j++;
- }
- j++;
- k++;
- }
-
- for (k = 0; k <= last_point; k++) {
- if (flags[k] & XSHORT) {
- if (flags[k] & XSAME) {
- xrel[k] = ptr[j];
- } else {
- xrel[k] = -ptr[j];
- }
- j++;
- } else if (flags[k] & XSAME) {
- xrel[k] = 0.0;
- } else {
- xrel[k] = (short)( ptr[j] * 256 + ptr[j + 1] );
- j += 2;
- }
- if (k == 0) {
- xabs[k] = xrel[k];
- } else {
- xabs[k] = xrel[k] + xabs[k - 1];
- }
-
- }
-
- for (k = 0; k <= last_point; k++) {
- if (flags[k] & YSHORT) {
- if (flags[k] & YSAME) {
- yrel[k] = ptr[j];
- } else {
- yrel[k] = -ptr[j];
- }
- j++;
- } else if (flags[k] & YSAME) {
- yrel[k] = 0;
- } else {
- yrel[k] = ptr[j] * 256 + ptr[j + 1];
- j += 2;
- }
- if (k == 0) {
- yabs[k] = yrel[k];
- } else {
- yabs[k] = yrel[k] + yabs[k - 1];
- }
- }
-
- if (matrix) {
- for (i = 0; i <= last_point; i++) {
- tx = xabs[i];
- ty = yabs[i];
- xcoord[i] = fscale(matrix[0] * tx + matrix[2] * ty + matrix[4]);
- ycoord[i] = fscale(matrix[1] * tx + matrix[3] * ty + matrix[5]);
- }
- } else {
- for (i = 0; i <= last_point; i++) {
- xcoord[i] = fscale(xabs[i]);
- ycoord[i] = fscale(yabs[i]);
- }
- }
-
- i = j = 0;
- first = 1;
-
- while (i <= ntohs(contour_end_pt[ncontours - 1])) {
- contour_end = ntohs(contour_end_pt[j]);
-
- if (first) {
- fg_rmoveto(g, xcoord[i], ycoord[i]);
- xlast = xcoord[i];
- ylast = ycoord[i];
- contour_start = i;
- first = 0;
- } else if (flags[i] & ONOROFF) {
- fg_rlineto(g, xcoord[i], ycoord[i]);
- xlast = xcoord[i];
- ylast = ycoord[i];
- } else {
- cs = i - 1;
- finished = nguide = 0;
- while (!finished) {
- if (i == contour_end + 1) {
- ce = contour_start;
- finished = 1;
- } else if (flags[i] & ONOROFF) {
- ce = i;
- finished = 1;
- } else {
- i++;
- nguide++;
- }
- }
-
- switch (nguide) {
- case 0:
- fg_rlineto(g, xcoord[ce], ycoord[ce]);
- xlast = xcoord[ce];
- ylast = ycoord[ce];
- break;
-
- case 1:
- fg_rrcurveto(g,
- (xcoord[cs] + 2.0 * xcoord[cs + 1]) / 3.0,
- (ycoord[cs] + 2.0 * ycoord[cs + 1]) / 3.0,
- (2.0 * xcoord[cs + 1] + xcoord[ce]) / 3.0,
- (2.0 * ycoord[cs + 1] + ycoord[ce]) / 3.0,
- xcoord[ce],
- ycoord[ce]
- );
- xlast = xcoord[ce];
- ylast = ycoord[ce];
-
- break;
-
- case 2:
- fg_rrcurveto(g,
- (-xcoord[cs] + 4.0 * xcoord[cs + 1]) / 3.0,
- (-ycoord[cs] + 4.0 * ycoord[cs + 1]) / 3.0,
- (4.0 * xcoord[cs + 2] - xcoord[ce]) / 3.0,
- (4.0 * ycoord[cs + 2] - ycoord[ce]) / 3.0,
- xcoord[ce],
- ycoord[ce]
- );
- xlast = xcoord[ce];
- ylast = ycoord[ce];
- break;
-
- case 3:
- fg_rrcurveto(g,
- (xcoord[cs] + 2.0 * xcoord[cs + 1]) / 3.0,
- (ycoord[cs] + 2.0 * ycoord[cs + 1]) / 3.0,
- (5.0 * xcoord[cs + 1] + xcoord[cs + 2]) / 6.0,
- (5.0 * ycoord[cs + 1] + ycoord[cs + 2]) / 6.0,
- (xcoord[cs + 1] + xcoord[cs + 2]) / 2.0,
- (ycoord[cs + 1] + ycoord[cs + 2]) / 2.0
- );
-
- fg_rrcurveto(g,
- (xcoord[cs + 1] + 5.0 * xcoord[cs + 2]) / 6.0,
- (ycoord[cs + 1] + 5.0 * ycoord[cs + 2]) / 6.0,
- (5.0 * xcoord[cs + 2] + xcoord[cs + 3]) / 6.0,
- (5.0 * ycoord[cs + 2] + ycoord[cs + 3]) / 6.0,
- (xcoord[cs + 3] + xcoord[cs + 2]) / 2.0,
- (ycoord[cs + 3] + ycoord[cs + 2]) / 2.0
- );
-
- fg_rrcurveto(g,
- (xcoord[cs + 2] + 5.0 * xcoord[cs + 3]) / 6.0,
- (ycoord[cs + 2] + 5.0 * ycoord[cs + 3]) / 6.0,
- (2.0 * xcoord[cs + 3] + xcoord[ce]) / 3.0,
- (2.0 * ycoord[cs + 3] + ycoord[ce]) / 3.0,
- xcoord[ce],
- ycoord[ce]
- );
- ylast = ycoord[ce];
- xlast = xcoord[ce];
-
- break;
-
- default:
- k1 = cs + nguide;
- fg_rrcurveto(g,
- (xcoord[cs] + 2.0 * xcoord[cs + 1]) / 3.0,
- (ycoord[cs] + 2.0 * ycoord[cs + 1]) / 3.0,
- (5.0 * xcoord[cs + 1] + xcoord[cs + 2]) / 6.0,
- (5.0 * ycoord[cs + 1] + ycoord[cs + 2]) / 6.0,
- (xcoord[cs + 1] + xcoord[cs + 2]) / 2.0,
- (ycoord[cs + 1] + ycoord[cs + 2]) / 2.0
- );
-
- for (k = cs + 2; k <= k1 - 1; k++) {
- fg_rrcurveto(g,
- (xcoord[k - 1] + 5.0 * xcoord[k]) / 6.0,
- (ycoord[k - 1] + 5.0 * ycoord[k]) / 6.0,
- (5.0 * xcoord[k] + xcoord[k + 1]) / 6.0,
- (5.0 * ycoord[k] + ycoord[k + 1]) / 6.0,
- (xcoord[k] + xcoord[k + 1]) / 2.0,
- (ycoord[k] + ycoord[k + 1]) / 2.0
- );
-
- }
-
- fg_rrcurveto(g,
- (xcoord[k1 - 1] + 5.0 * xcoord[k1]) / 6.0,
- (ycoord[k1 - 1] + 5.0 * ycoord[k1]) / 6.0,
- (2.0 * xcoord[k1] + xcoord[ce]) / 3.0,
- (2.0 * ycoord[k1] + ycoord[ce]) / 3.0,
- xcoord[ce],
- ycoord[ce]
- );
- xlast = xcoord[ce];
- ylast = ycoord[ce];
-
- break;
- }
- }
- if (i >= contour_end) {
- g_closepath(g);
- first = 1;
- i = contour_end + 1;
- j++;
- } else {
- i++;
- }
- }
-
- if (matrix) {
- /* guess whether do we need to reverse the results */
-
- double x[3], y[3];
- int max = 0, from, to;
-
- /* transform a triangle going in proper direction */
- /*
- * the origin of triangle is in (0,0) so we know it in
- * advance
- */
-
- x[0] = y[0] = 0;
- x[1] = matrix[0] * 0 + matrix[2] * 300;
- y[1] = matrix[1] * 0 + matrix[3] * 300;
- x[2] = matrix[0] * 300 + matrix[2] * 0;
- y[2] = matrix[1] * 300 + matrix[3] * 0;
-
- /* then find the topmost point */
- for (i = 0; i < 3; i++)
- if (y[i] > y[max])
- max = i;
- from = (max + 3 - 1) % 3;
- to = (max + 1) % 3;
-
- needreverse = 0;
-
- /* special cases for horizontal lines */
- if (y[max] == y[from]) {
- if (x[max] < y[from])
- needreverse = 1;
- } else if (y[to] == y[from]) {
- if (x[to] < x[max])
- needreverse = 1;
- } else { /* generic case */
- if ((x[to] - x[max]) * (y[max] - y[from])
- > (x[max] - x[from]) * (y[to] - y[max]))
- needreverse = 1;
- }
-
- if (needreverse) {
- if (lge) {
- assertpath(lge->next, __FILE__, __LINE__, g->name);
- reversepathsfromto(lge->next, NULL);
- } else {
- assertpath(g->entries, __FILE__, __LINE__, g->name);
- reversepaths(g);
- }
- }
- }
-}
-
-static double
-f2dot14(
- short x
-)
-{
- short y = ntohs(x);
- return (y >> 14) + ((y & 0x3fff) / 16384.0);
-}
-
-
-/* check that the pointer points within the file */
-/* returns 0 if pointer is good, 1 if bad */
-static int
-badpointer(
- void *ptr
-)
-{
- return (ptr < (void *)filebuffer || ptr >= (void *)filebuffer_end);
-}
-
-/*
- * Externally accessible methods
- */
-
-/*
- * Open font and prepare to return information to the main driver.
- * May print error and warning messages.
- * Exit on error.
- */
-
-static void
-openfont(
- char *fname,
- char *arg /* unused now */
-)
-{
- int i, j;
- struct stat statbuf;
- static struct {
- void **tbpp; /* pointer to pointer to the table */
- char name[5]; /* table name */
- char optional; /* flag: table may be missing */
- } tables[] = {
- { (void **)&name_table, "name", 0 },
- { (void **)&head_table, "head", 0 },
- { (void **)&hhea_table, "hhea", 0 },
- { (void **)&post_table, "post", 0 },
- { (void **)&glyf_start, "glyf", 0 },
- { (void **)&cmap_table, "cmap", 0 },
- { (void **)&kern_table, "kern", 1 },
- { (void **)&maxp_table, "maxp", 0 },
- { (void **)&hmtx_table, "hmtx", 0 },
- { (void **)&long_loca_table, "loca", 0 },
- { NULL, "", 0 } /* end of table */
- };
-
- if (stat(fname, &statbuf) == -1) {
- fprintf(stderr, "**** Cannot access %s ****\n", fname);
- exit(1);
- }
- if ((filebuffer = malloc(statbuf.st_size)) == NULL) {
- fprintf(stderr, "**** Cannot malloc space for file ****\n");
- exit(1);
- }
-
- filebuffer_end = filebuffer + statbuf.st_size;
-
- if ((ttf_file = fopen(fname, "rb")) == NULL) {
- fprintf(stderr, "**** Cannot open file '%s'\n", fname);
- exit(1);
- } else {
- WARNING_2 fprintf(stderr, "Processing file %s\n", fname);
- }
-
- if (fread(filebuffer, 1, statbuf.st_size, ttf_file) != statbuf.st_size) {
- fprintf(stderr, "**** Could not read whole file \n");
- exit(1);
- }
- fclose(ttf_file);
-
- directory = (TTF_DIRECTORY *) filebuffer;
-
- if (ntohl(directory->sfntVersion) != 0x00010000) {
- fprintf(stderr,
- "**** Unknown File Version number [%x], or not a TrueType file\n",
- directory->sfntVersion);
- exit(1);
- }
-
- /* clear the tables */
- for(j=0; tables[j].tbpp != NULL; j++)
- *(tables[j].tbpp) = NULL;
-
- dir_entry = &(directory->list);
-
- for (i = 0; i < ntohs(directory->numTables); i++) {
-
- for(j=0; tables[j].tbpp != NULL; j++)
- if (memcmp(dir_entry->tag, tables[j].name, 4) == 0) {
- *(tables[j].tbpp) = (void *) (filebuffer + ntohl(dir_entry->offset));
- break;
- }
-
- if (memcmp(dir_entry->tag, "EBDT", 4) == 0 ||
- memcmp(dir_entry->tag, "EBLC", 4) == 0 ||
- memcmp(dir_entry->tag, "EBSC", 4) == 0) {
- WARNING_1 fprintf(stderr, "Font contains bitmaps\n");
- }
- dir_entry++;
- }
-
- for(j=0; tables[j].tbpp != NULL; j++)
- if(!tables[j].optional && badpointer( *(tables[j].tbpp) )) {
- fprintf(stderr, "**** File contains no required table '%s'\n", tables[j].name);
- exit(1);
- }
-
- handle_name();
-
- handle_head();
-
- ttf_nglyphs = ntohs(maxp_table->numGlyphs);
-
- enc_found_ms = enc_found_mac = 0;
-}
-
-/*
- * Close font.
- * Exit on error.
- */
-
-static void
-closefont(
- void
-)
-{
- return; /* empty operation */
-}
-
-/*
- * Get the number of glyphs in font.
- */
-
-static int
-getnglyphs (
- void
-)
-{
- return ttf_nglyphs;
-}
-
-/*
- * Get the names of the glyphs.
- * Returns 0 if the names were assigned, non-zero if the font
- * provides no glyph names.
- */
-
-static int
-glnames(
- GLYPH *glyph_list
-)
-{
- int i, len, n, npost;
- unsigned int format;
- USHORT *name_index;
- char *ptr, *p;
- char **ps_name_ptr = (char **) malloc(ttf_nglyphs * sizeof(char *));
- int n_ps_names;
- int ps_fmt_3 = 0;
-
- format = ntohl(post_table->formatType);
-
- if (format == 0x00010000) {
- for (i = 0; i < 258 && i < ttf_nglyphs; i++) {
- glyph_list[i].name = mac_glyph_names[i];
- }
- } else if (format == 0x00020000) {
- npost = ntohs(post_table->numGlyphs);
- if (ttf_nglyphs != npost) {
- /* This is an error in the font, but we can now cope */
- WARNING_1 fprintf(stderr, "**** Postscript table size mismatch %d/%d ****\n",
- npost, ttf_nglyphs);
- }
- n_ps_names = 0;
- name_index = &(post_table->glyphNameIndex);
-
- /* This checks the integrity of the post table */
- for (i=0; i<npost; i++) {
- n = ntohs(name_index[i]);
- if (n > n_ps_names + 257) {
- n_ps_names = n - 257;
- }
- }
-
- ptr = (char *) post_table + 34 + (ttf_nglyphs << 1);
- i = 0;
- while (*ptr > 0 && i < n_ps_names) {
- len = *ptr;
- /* previously the program wrote nulls into the table. If the table
- was corrupt, this could put zeroes anywhere, leading to obscure bugs,
- so now I malloc space for the names. Yes it is much less efficient */
-
- if ((p = malloc(len+1)) == NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
-
- ps_name_ptr[i] = p;
- strncpy(p, ptr+1, len);
- p[len] = '\0';
- i ++;
- ptr += len + 1;
- }
-
- if (i != n_ps_names)
- {
- WARNING_2 fprintf (stderr, "** Postscript Name mismatch %d != %d **\n",
- i, n_ps_names);
- n_ps_names = i;
- }
-
- /*
- * for (i=0; i<n_ps_names; i++) { fprintf(stderr, "i=%d,
- * len=%d, name=%s\n", i, ps_name_len[i], ps_name_ptr[i]); }
- */
-
- for (i = 0; i < npost; i++) {
- n = ntohs(name_index[i]);
- if (n < 258) {
- glyph_list[i].name = mac_glyph_names[n];
- } else if (n < 258 + n_ps_names) {
- glyph_list[i].name = ps_name_ptr[n - 258];
- } else {
- glyph_list[i].name = malloc(16);
- sprintf(glyph_list[i].name, "_g_%d", i);
- WARNING_2 fprintf(stderr,
- "Glyph No. %d has no postscript name, becomes %s\n",
- i, glyph_list[i].name);
- }
- }
- /* Now fake postscript names for all those beyond the end of the table */
- if (npost < ttf_nglyphs) {
- for (i=npost; i<ttf_nglyphs; i++) {
- if ((glyph_list[i].name = malloc(16)) == NULL)
- {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- sprintf(glyph_list[i].name, "_g_%d", i);
- WARNING_2 fprintf(stderr,
- "Glyph No. %d has no postscript name, becomes %s\n",
- i, glyph_list[i].name);
- }
- }
- } else if (format == 0x00030000) {
- WARNING_3 fputs("No postscript table, using default\n", stderr);
- ps_fmt_3 = 1;
- } else if (format == 0x00028000) {
- ptr = (char *) &(post_table->numGlyphs);
- for (i = 0; i < ttf_nglyphs; i++) {
- glyph_list[i].name = mac_glyph_names[i + ptr[i]];
- }
- } else {
- fprintf(stderr,
- "**** Postscript table in wrong format %x ****\n",
- format);
- exit(1);
- }
-
- return ps_fmt_3;
-}
-
-/*
- * Get the metrics of the glyphs.
- */
-
-static void
-glmetrics(
- GLYPH *glyph_list
-)
-{
- int i;
- int n_hmetrics = ntohs(hhea_table->numberOfHMetrics);
- GLYPH *g;
- LONGHORMETRIC *hmtx_entry = hmtx_table;
- FWORD *lsblist;
-
- for (i = 0; i < n_hmetrics; i++) {
- g = &(glyph_list[i]);
- g->width = ntohs(hmtx_entry->advanceWidth);
- g->lsb = ntohs(hmtx_entry->lsb);
- hmtx_entry++;
- }
-
- lsblist = (FWORD *) hmtx_entry;
- hmtx_entry--;
-
- for (i = n_hmetrics; i < ttf_nglyphs; i++) {
- g = &(glyph_list[i]);
- g->width = ntohs(hmtx_entry->advanceWidth);
- g->lsb = ntohs(lsblist[i - n_hmetrics]);
- }
-
- for (i = 0; i < ttf_nglyphs; i++) {
- g = &(glyph_list[i]);
- get_glyf_table(i, &glyf_table, &g->ttf_pathlen);
-
- g->xMin = (short)ntohs(glyf_table->xMin);
- g->xMax = (short)ntohs(glyf_table->xMax);
- g->yMin = (short)ntohs(glyf_table->yMin);
- g->yMax = (short)ntohs(glyf_table->yMax);
- }
-
-}
-
-
-static void
-handle_ms_encoding(
- GLYPH *glyph_list,
- int *encoding,
- int *unimap
-)
-{
- int j, k, kk, set_ok;
- USHORT start, end, ro;
- short delta, n;
-
- for (j = 0; j < cmap_n_segs - 1; j++) {
- start = ntohs(cmap_seg_start[j]);
- end = ntohs(cmap_seg_end[j]);
- delta = ntohs(cmap_idDelta[j]);
- ro = ntohs(cmap_idRangeOffset[j]);
-
- for (k = start; k <= end; k++) {
- if (ro == 0) {
- n = k + delta;
- } else {
- n = ntohs(*((ro >> 1) + (k - start) +
- &(cmap_idRangeOffset[j])));
- if (delta != 0)
- {
- /* Not exactly sure how to deal with this circumstance,
- I suspect it never occurs */
- n += delta;
- fprintf (stderr,
- "rangeoffset and delta both non-zero - %d/%d",
- ro, delta);
- }
- }
- if(n<0 || n>=ttf_nglyphs) {
- WARNING_1 fprintf(stderr, "Font contains a broken glyph code mapping, ignored\n");
- continue;
- }
- if (glyph_list[n].orig_code != -1) {
-#if 0
- if (strcmp(glyph_list[n].name, ".notdef") != 0) {
- WARNING_2 fprintf(stderr,
- "Glyph %s has >= two encodings (A), %4.4x & %4.4x\n",
- glyph_list[n].name,
- glyph_list[n].orig_code,
- k);
- }
-#endif
- set_ok = 0;
- } else {
- set_ok = 1;
- }
- if (enc_type==1 || forcemap) {
- kk = unicode_rev_lookup(k);
- if(ISDBG(UNICODE))
- fprintf(stderr, "Unicode %s - 0x%04x\n",glyph_list[n].name,k);
- if (set_ok) {
- glyph_list[n].orig_code = k;
- /* glyph_list[n].char_no = kk; */
- }
- if (kk >= 0 && kk < ENCTABSZ && encoding[kk] == -1)
- encoding[kk] = n;
- } else {
- if ((k & 0xff00) == 0xf000) {
- if( encoding[k & 0x00ff] == -1 ) {
- encoding[k & 0x00ff] = n;
- if (set_ok) {
- /* glyph_list[n].char_no = k & 0x00ff; */
- glyph_list[n].orig_code = k;
- }
- }
- } else {
- if (set_ok) {
- /* glyph_list[n].char_no = k; */
- glyph_list[n].orig_code = k;
- }
- WARNING_2 fprintf(stderr,
- "Glyph %s has non-symbol encoding %4.4x\n",
- glyph_list[n].name,
- k & 0xffff);
- /*
- * just use the code
- * as it is
- */
- if ((k & ~0xff) == 0 && encoding[k] == -1 )
- encoding[k] = n;
- }
- }
- }
- }
-}
-
-static void
-handle_mac_encoding(
- GLYPH *glyph_list,
- int *encoding,
- int *unimap
-)
-{
- short n;
- int j, size;
-
- size = ntohs(encoding0->length) - 6;
- for (j = 0; j < size; j++) {
- n = encoding0->glyphIdArray[j];
- if (glyph_list[n].char_no != -1) {
- WARNING_2 fprintf(stderr,
- "Glyph %s has >= two encodings (B), %4.4x & %4.4x\n",
- glyph_list[n].name,
- glyph_list[n].char_no,
- j);
- } else {
- if (j < ENCTABSZ) {
- if(encoding[j] == -1) {
- glyph_list[n].char_no = j;
- encoding[j] = n;
- }
- }
- }
- }
-}
-
-/*
- * Get the original encoding of the font.
- * Returns 1 for if the original encoding is Unicode, 2 if the
- * original encoding is other 16-bit, 0 if 8-bit.
- */
-
-static int
-glenc(
- GLYPH *glyph_list,
- int *encoding,
- int *unimap
-)
-{
- int num_tables = ntohs(cmap_table->numberOfEncodingTables);
- BYTE *ptr;
- int i, format, offset, seg_c2, found;
- int platform, encoding_id;
- TTF_CMAP_ENTRY *table_entry;
- TTF_CMAP_FMT4 *encoding4;
-
- if(enc_found_ms) {
- handle_ms_encoding(glyph_list, encoding, unimap);
- return enc_type;
- } else if(enc_found_mac) {
- handle_mac_encoding(glyph_list, encoding, unimap);
- return 0;
- }
-
- if(force_pid != -1 && force_pid != 3) {
- fputs("*** Only platform ID == 3 is supported\n", stderr);
- exit(1);
- }
-
- enc_type = 0;
- found = 0;
-
- for (i = 0; i < num_tables && !found; i++) {
- table_entry = &(cmap_table->encodingTable[i]);
- offset = ntohl(table_entry->offset);
- encoding4 = (TTF_CMAP_FMT4 *) ((BYTE *) cmap_table + offset);
- format = ntohs(encoding4->format);
- platform = ntohs(table_entry->platformID);
- encoding_id = ntohs(table_entry->encodingID);
-
- if (platform == 3 && format == 4) {
- if(force_pid == 3) {
- if(encoding_id != force_eid)
- continue;
- WARNING_1 fprintf(stderr, "Found Encoding PID=%d/EID=%d\n",
- force_pid, force_eid);
- enc_type = 1;
- } else {
- switch (encoding_id) {
- case 0:
- WARNING_1 fputs("Found Symbol Encoding\n", stderr);
- break;
- case 1:
- WARNING_1 fputs("Found Unicode Encoding\n", stderr);
- enc_type = 1;
- break;
- default:
- WARNING_1 {
- fprintf(stderr,
- "****MS Encoding ID %d not supported****\n",
- encoding_id);
- fputs("Treating it like Symbol encoding\n", stderr);
- }
- break;
- }
- }
-
- found = 1;
- seg_c2 = ntohs(encoding4->segCountX2);
- cmap_n_segs = seg_c2 >> 1;
- ptr = (BYTE *) encoding4 + 14;
- cmap_seg_end = (USHORT *) ptr;
- cmap_seg_start = (USHORT *) (ptr + seg_c2 + 2);
- cmap_idDelta = (short *) (ptr + (seg_c2 * 2) + 2);
- cmap_idRangeOffset = (short *) (ptr + (seg_c2 * 3) + 2);
- enc_found_ms = 1;
-
- handle_ms_encoding(glyph_list, encoding, unimap);
- }
- }
-
- if (!found) {
- if(force_pid != -1) {
- fprintf(stderr, "*** TTF encoding table PID=%d/EID=%d not found\n",
- force_pid, force_eid);
- exit(1);
- }
-
- WARNING_1 fputs("No Microsoft encoding, looking for MAC encoding\n", stderr);
- for (i = 0; i < num_tables && !found; i++) {
- table_entry = &(cmap_table->encodingTable[i]);
- offset = ntohl(table_entry->offset);
- encoding0 = (TTF_CMAP_FMT0 *) ((BYTE *) cmap_table + offset);
- format = ntohs(encoding0->format);
- platform = ntohs(table_entry->platformID);
- encoding_id = ntohs(table_entry->encodingID);
-
- if (format == 0) {
- found = 1;
- enc_found_mac = 1;
-
- handle_mac_encoding(glyph_list, encoding, unimap);
- }
- }
- }
- if (!found) {
- fprintf(stderr, "**** No Recognised Encoding Table ****\n");
- exit(1);
- }
-
- return enc_type;
-}
-
-/*
- * Get the font metrics
- */
-static void
-fnmetrics(
- struct font_metrics *fm
-)
-{
- char *str;
- static int fieldstocheck[]= {2,4,6};
- int i, j, len;
-
- fm->italic_angle = (short) (ntohs(post_table->italicAngle.upper)) +
- ((short) ntohs(post_table->italicAngle.lower) / 65536.0);
- fm->underline_position = (short) ntohs(post_table->underlinePosition);
- fm->underline_thickness = (short) ntohs(post_table->underlineThickness);
- fm->is_fixed_pitch = ntohl(post_table->isFixedPitch);
-
- fm->ascender = (short)ntohs(hhea_table->ascender);
- fm->descender = (short)ntohs(hhea_table->descender);
-
- fm->units_per_em = ntohs(head_table->unitsPerEm);
-
- fm->bbox[0] = (short) ntohs(head_table->xMin);
- fm->bbox[1] = (short) ntohs(head_table->yMin);
- fm->bbox[2] = (short) ntohs(head_table->xMax);
- fm->bbox[3] = (short) ntohs(head_table->yMax);
-
- fm->name_copyright = name_fields[0];
- fm->name_family = name_fields[1];
- fm->name_style = name_fields[2];
- fm->name_full = name_fields[4];
- fm->name_version = name_fields[5];
- fm->name_ps = name_fields[6];
-
- /* guess the boldness from the font names */
- fm->force_bold=0;
-
- for(i=0; !fm->force_bold && i<sizeof fieldstocheck /sizeof(int); i++) {
- str = name_fields[fieldstocheck[i]];
- len = strlen(str);
- for(j=0; j<len; j++) {
- if( (str[j]=='B'
- || str[j]=='b'
- && ( j==0 || !isalpha(str[j-1]) )
- )
- && !strncmp("old",&str[j+1],3)
- && (j+4 >= len || !islower(str[j+4]))
- ) {
- fm->force_bold=1;
- break;
- }
- }
- }
-}
-
-/*
- * Get the path of contrours for a glyph.
- */
-
-static void
-glpath(
- int glyphno,
- GLYPH *glyf_list
-)
-{
- double matrix[6];
- GLYPH *g;
-
- g = &glyph_list[glyphno];
-
- matrix[0] = matrix[3] = 1.0;
- matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0.0;
- draw_composite_glyf(g, glyf_list, glyphno, matrix, 0 /*level*/);
-}
-
-/*
- * Get the kerning data.
- */
-
-static void
-kerning(
- GLYPH *glyph_list
-)
-{
- TTF_KERN_SUB *subtable;
- TTF_KERN_ENTRY *kern_entry;
- int i, j;
- int ntables;
- int npairs;
- char *ptr;
-
- if(kern_table == NULL) {
- WARNING_1 fputs("No Kerning data\n", stderr);
- return;
- }
- if(badpointer(kern_table)) {
- fputs("**** Defective Kerning table, ignored\n", stderr);
- return;
- }
-
- ntables = ntohs(kern_table->nTables);
- ptr = (char *) kern_table + 4;
-
- for (i = 0; i < ntables; i++) {
- subtable = (TTF_KERN_SUB *) ptr;
- if ((ntohs(subtable->coverage) & 0xff00) == 0) {
- npairs = (short) ntohs(subtable->nPairs);
- kern_entry = (TTF_KERN_ENTRY *) (ptr + sizeof(TTF_KERN_SUB));
-
- kern_entry = (TTF_KERN_ENTRY *) (ptr + sizeof(TTF_KERN_SUB));
- for (j = 0; j < npairs; j++) {
- if( kern_entry->value != 0)
- addkernpair(ntohs(kern_entry->left),
- ntohs(kern_entry->right), (short)ntohs(kern_entry->value));
- kern_entry++;
- }
- }
- ptr += subtable->length;
- }
-}
-
diff --git a/nx-X11/extras/ttf2pt1/ttf.h b/nx-X11/extras/ttf2pt1/ttf.h
deleted file mode 100644
index 297dcaf10..000000000
--- a/nx-X11/extras/ttf2pt1/ttf.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * see COPYRIGHT
- */
-
-/* these definitions are mostly taken from Microsoft's True Type
- documentation.
-*/
-
-#ifdef XP_PSTEXT
-typedef unsigned char BYTE;
-typedef signed char CHAR;
-typedef unsigned short USHORT;
-typedef signed short SHORT;
-typedef unsigned int ULONG;
-typedef signed int LONG;
-typedef SHORT FWORD;
-typedef USHORT UFWORD;
-#else
-#define BYTE unsigned char
-#define CHAR signed char
-#define USHORT unsigned short
-#define SHORT signed short
-#define ULONG unsigned int
-#define LONG signed int
-#define FWORD SHORT
-#define UFWORD USHORT
-#endif /* XP_PSTEXT */
-
-#define ONOROFF 0x01
-#define XSHORT 0x02
-#define YSHORT 0x04
-#define REPEAT 0x08
-#define XSAME 0x10
-#define YSAME 0x20
-
-#define ARG_1_AND_2_ARE_WORDS 0x0001
-#define ARGS_ARE_XY_VALUES 0x0002
-#define XY_BOUND_TO_GRID 0x0004
-#define WE_HAVE_A_SCALE 0x0008
-#define MORE_COMPONENTS 0x0020
-#define WE_HAVE_AN_X_AND_Y_SCALE 0x0040
-#define WE_HAVE_A_TWO_BY_TWO 0x0080
-#define WE_HAVE_INSTRUCTIONS 0x0100
-#define USE_MY_METRICS 0x0200
-
-typedef struct short_2 {
- SHORT upper;
- USHORT lower;
-} FIXED ;
-
-typedef struct longhormetric {
- UFWORD advanceWidth;
- FWORD lsb;
-} LONGHORMETRIC;
-
-typedef struct ttf_hhea {
- BYTE version[4];
- SHORT ascender, descender, lineGap;
- USHORT advnaceWidthMax;
- SHORT minLSB, minRSB, xMaxExtent;
- SHORT caretSlopeRise, caretSlopeRun;
- SHORT reserved[5];
- SHORT metricDataFormat;
- USHORT numberOfHMetrics;
-} TTF_HHEA;
-
-typedef struct ttf_dir_entry {
- char tag[4];
- ULONG checksum;
- ULONG offset;
- ULONG length;
-} TTF_DIR_ENTRY ;
-
-typedef struct ttf_directory {
- ULONG sfntVersion;
- USHORT numTables;
- USHORT searchRange;
- USHORT entrySelector;
- USHORT rangeShift;
- TTF_DIR_ENTRY list;
-} TTF_DIRECTORY ;
-
-typedef struct ttf_name_rec {
- USHORT platformID;
- USHORT encodingID;
- USHORT languageID;
- USHORT nameID;
- USHORT stringLength;
- USHORT stringOffset;
-} TTF_NAME_REC;
-
-typedef struct ttf_name {
- USHORT format;
- USHORT numberOfNameRecords;
- USHORT offset;
- TTF_NAME_REC nameRecords;
-} TTF_NAME ;
-
-typedef struct ttf_head {
- ULONG version;
- ULONG fontRevision;
- ULONG checksumAdjust;
- ULONG magicNo;
- USHORT flags;
- USHORT unitsPerEm;
- BYTE created[8];
- BYTE modified[8];
- FWORD xMin, yMin, xMax, yMax;
- USHORT macStyle, lowestRecPPEM;
- SHORT fontDirection, indexToLocFormat, glyphDataFormat;
-} TTF_HEAD ;
-
-typedef struct ttf_kern {
- USHORT version, nTables;
-} TTF_KERN ;
-
-typedef struct ttf_kern_sub {
- USHORT version, length, coverage;
- USHORT nPairs, searchRange, entrySelector, rangeShift;
-} TTF_KERN_SUB;
-
-typedef struct ttf_kern_entry {
- USHORT left, right;
- FWORD value;
-} TTF_KERN_ENTRY;
-
-typedef struct ttf_cmap_fmt0 {
- USHORT format;
- USHORT length;
- USHORT version;
- BYTE glyphIdArray[256];
-} TTF_CMAP_FMT0;
-
-typedef struct ttf_cmap_fmt4 {
- USHORT format;
- USHORT length;
- USHORT version;
- USHORT segCountX2;
- USHORT searchRange;
- USHORT entrySelector;
- USHORT rangeShift;
-} TTF_CMAP_FMT4;
-
-typedef struct ttf_cmap_entry {
- USHORT platformID;
- USHORT encodingID;
- ULONG offset;
-} TTF_CMAP_ENTRY;
-
-typedef struct ttf_cmap {
- USHORT version;
- USHORT numberOfEncodingTables;
- TTF_CMAP_ENTRY encodingTable[1];
-} TTF_CMAP ;
-
-typedef struct ttf_glyf {
- SHORT numberOfContours;
- FWORD xMin, yMin, xMax, yMax;
-} TTF_GLYF ;
-
-typedef struct ttf_maxp {
- ULONG version;
- USHORT numGlyphs, maxPoints, maxContours;
- USHORT maxCompositePoints, maxCompositeContours;
- USHORT maxZones, maxTwilightPoints, maxStorage;
- USHORT maxFunctionDefs, maxInstructionsDefs;
- USHORT maxSizeOfInstructions, maxComponentElements;
- USHORT maxComponentDepth;
-} TTF_MAXP ;
-
-typedef struct ttf_post_head {
- ULONG formatType;
- FIXED italicAngle;
- FWORD underlinePosition;
- FWORD underlineThickness;
- ULONG isFixedPitch;
- ULONG minMemType42;
- ULONG maxMemType42;
- ULONG minMemType1;
- ULONG maxMemType1;
- USHORT numGlyphs;
- USHORT glyphNameIndex;
-} TTF_POST_HEAD ;
diff --git a/nx-X11/extras/ttf2pt1/ttf2pt1.1 b/nx-X11/extras/ttf2pt1/ttf2pt1.1
deleted file mode 100644
index 500a7d2ec..000000000
--- a/nx-X11/extras/ttf2pt1/ttf2pt1.1
+++ /dev/null
@@ -1,832 +0,0 @@
-.rn '' }`
-''' $RCSfile: ttf2pt1.1,v $$Revision: 1.2 $$Date: 2004/04/23 18:42:57 $
-'''
-''' $Log: ttf2pt1.1,v $
-''' Revision 1.2 2004/04/23 18:42:57 eich
-''' 2004-04-23 Egbert Eich <eich@freedesktop.org>
-''' Merging XORG-CURRENT into trunk
-'''
-''' Revision 1.1.4.1 2004/04/21 10:03:13 gisburn
-''' Fix for http://pdx.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=530 - Land XPRINT branch on XORG-CURRENT
-'''
-''' Revision 1.1 2003/06/04 00:33:54 roland
-''' Fix for http://xprint.mozdev.org/bugs/show_bug.cgi?id=3846 - RFE: Upload Freetype --> PS Type1 font converter "ttf2pt1" ...
-'''
-'''
-.de Sh
-.br
-.if t .Sp
-.ne 5
-.PP
-\fB\\$1\fR
-.PP
-..
-.de Sp
-.if t .sp .5v
-.if n .sp
-..
-.de Ip
-.br
-.ie \\n(.$>=3 .ne \\$3
-.el .ne 3
-.IP "\\$1" \\$2
-..
-.de Vb
-.ft CW
-.nf
-.ne \\$1
-..
-.de Ve
-.ft R
-
-.fi
-..
-'''
-'''
-''' Set up \*(-- to give an unbreakable dash;
-''' string Tr holds user defined translation string.
-''' Bell System Logo is used as a dummy character.
-'''
-.tr \(*W-|\(bv\*(Tr
-.ie n \{\
-.ds -- \(*W-
-.ds PI pi
-.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
-.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
-.ds L" ""
-.ds R" ""
-''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of
-''' \*(L" and \*(R", except that they are used on ".xx" lines,
-''' such as .IP and .SH, which do another additional levels of
-''' double-quote interpretation
-.ds M" """
-.ds S" """
-.ds N" """""
-.ds T" """""
-.ds L' '
-.ds R' '
-.ds M' '
-.ds S' '
-.ds N' '
-.ds T' '
-'br\}
-.el\{\
-.ds -- \(em\|
-.tr \*(Tr
-.ds L" ``
-.ds R" ''
-.ds M" ``
-.ds S" ''
-.ds N" ``
-.ds T" ''
-.ds L' `
-.ds R' '
-.ds M' `
-.ds S' '
-.ds N' `
-.ds T' '
-.ds PI \(*p
-'br\}
-.\" If the F register is turned on, we'll generate
-.\" index entries out stderr for the following things:
-.\" TH Title
-.\" SH Header
-.\" Sh Subsection
-.\" Ip Item
-.\" X<> Xref (embedded
-.\" Of course, you have to process the output yourself
-.\" in some meaninful fashion.
-.if \nF \{
-.de IX
-.tm Index:\\$1\t\\n%\t"\\$2"
-..
-.nr % 0
-.rr F
-.\}
-.TH TTF2PT1 1 "version 3.4.4-SNAP-030526" "May 26, 2003" "TTF2PT1 Font Converter"
-.UC
-.if n .hy 0
-.if n .na
-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
-.de CQ \" put $1 in typewriter font
-.ft CW
-'if n "\c
-'if t \\&\\$1\c
-'if n \\&\\$1\c
-'if n \&"
-\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7
-'.ft R
-..
-.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2
-. \" AM - accent mark definitions
-.bd B 3
-. \" fudge factors for nroff and troff
-.if n \{\
-. ds #H 0
-. ds #V .8m
-. ds #F .3m
-. ds #[ \f1
-. ds #] \fP
-.\}
-.if t \{\
-. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
-. ds #V .6m
-. ds #F 0
-. ds #[ \&
-. ds #] \&
-.\}
-. \" simple accents for nroff and troff
-.if n \{\
-. ds ' \&
-. ds ` \&
-. ds ^ \&
-. ds , \&
-. ds ~ ~
-. ds ? ?
-. ds ! !
-. ds /
-. ds q
-.\}
-.if t \{\
-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
-. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'
-. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'
-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
-. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10'
-.\}
-. \" troff and (daisy-wheel) nroff accents
-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
-.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
-.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#]
-.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'
-.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'
-.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#]
-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
-.ds ae a\h'-(\w'a'u*4/10)'e
-.ds Ae A\h'-(\w'A'u*4/10)'E
-.ds oe o\h'-(\w'o'u*4/10)'e
-.ds Oe O\h'-(\w'O'u*4/10)'E
-. \" corrections for vroff
-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
-. \" for low resolution devices (crt and lpr)
-.if \n(.H>23 .if \n(.V>19 \
-\{\
-. ds : e
-. ds 8 ss
-. ds v \h'-1'\o'\(aa\(ga'
-. ds _ \h'-1'^
-. ds . \h'-1'.
-. ds 3 3
-. ds o a
-. ds d- d\h'-1'\(ga
-. ds D- D\h'-1'\(hy
-. ds th \o'bp'
-. ds Th \o'LP'
-. ds ae ae
-. ds Ae AE
-. ds oe oe
-. ds Oe OE
-.\}
-.rm #[ #] #H #V #F C
-.SH "NAME"
-TTF2PT1 \- A True Type to PostScript Type 1 Font Converter
-.SH "SYNOPSIS"
-\f(CWttf2pt1 \fI[-options] ttffont.ttf [Fontname]\fR\fR
-.PP
-or
-.PP
-\f(CWttf2pt1 \fI[-options] ttffont.ttf -\fR\fR
-.SH "DESCRIPTION"
-Ttf2pt1 is a font converter from the True Type format (and some other formats
-supported by the FreeType library as well) to the Adobe Type1 format.
-.PP
-The versions 3.0 and later got rather extensive post-processing algorithm that
-brings the converted fonts to the requirements of the Type1 standard, tries to
-correct the rounding errors introduced during conversions and some simple
-kinds of bugs that are typical for the public domain TTF fonts. It
-also generates the hints that enable much better rendering of fonts in
-small sizes that are typical for the computer displays. But everything
-has its price, and some of the optimizations may not work well for certain
-fonts. That's why the options were added to the converter, to control
-the performed optimizations.
-.SH "OPTIONS"
-The first variant creates the file \f(CWFontname.pfa\fR (or \f(CWFontname.pfb\fR if the
-option \*(L'\fB\-b\fR\*(R' was used) with the converted font and \f(CWFontname.afm\fR with the
-font metrics, the second one prints the font or another file (if the option
-\&\*(R'\fB\-G\fR\*(R' was used) on the standard output from where it can be immediately
-piped through some filter. If no \f(CWFontname\fR is specified for the first
-variant, the name is generated from \f(CWttffont\fR by replacing the \f(CW.ttf\fR
-filename suffix.
-.PP
-Most of the time no options are neccessary (with a possible exception
-of \*(L'\fB\-e\fR'). But if there are some troubles with the resulting font, they
-may be used to control the conversion.
-The \fBoptions\fR are:
-.Ip "\(bu" 2
-\f(CW\fB-a\fR\fR \- Include all the glyphs from the source file into the converted
-file. If this option is not specified then only the glyphs that have
-been assigned some encoding are included, because the rest of glyphs
-would be inaccessible anyway and would only consume the disk space.
-But some applications are clever enough to change the encoding on
-the fly and thus use the other glyphs, in this case they could
-benefit from using this option. But there is a catch: the X11 library
-has rather low limit for the font size. Including more glyphs increases
-the file size and thus increases the chance of hitting this limit.
-See \f(CWapp/X11/README\fR for the description of a
-patch to X11 which fixes this problem.
-.Ip "\(bu" 2
-\f(CW\fB-b\fR\fR \- Encode the resulting font to produce a ready \f(CW.pfb\fR file.
-.Ip "\(bu" 2
-\f(CW\fB-d \fIsuboptions\fR\fR\fR \- Debugging options. The suboptions are:
-.Sp
-\f(CW\fBa\fR\fR \- Print out the absolute coordinates of dots in outlines. Such
-a font can not be used by any program (that's why this option is
-incompatible with \*(L'\fB\-e\fR') but it has proven to be a valuable debuging
-information.
-.Sp
-\f(CW\fBr\fR\fR \- Do not reverse the direction of outlines. The \s-1TTF\s0 fonts have
-the standard direction of outlines opposite to the Type1 fonts. So
-they should be reversed during proper conversion. This option
-may be used for debugging or to handle a \s-1TTF\s0 font with wrong
-direction of outlines (possibly, converted in a broken way from
-a Type1 font). The first signs of the wrong direction are the
-letters like \*(L"P\*(R" or \*(L"B\*(R" without the unpainted \*(L"holes\*(R" inside.
-.Ip "\(bu" 2
-\f(CW\fB-e\fR\fR \- Assemble the resulting font to produce a ready \f(CW.pfa\fR file.
-.Sp
-[ S.B.: Personally I don't think that this option is particularly useful.
-The same result may be achieved by piping the unassembled data
-through t1asm, the Type 1 assembler. And, anyways, it's good to
-have the t1utils package handy. But Mark and many users think that
-this functionality is good and it took not much time to add this option. ]
-.Ip "\(bu" 2
-\f(CW\fB-F\fR\fR \- Force the Unicode encoding: any type of \s-1MS\s0 encoding specified
-in the font is ignored and the font is treated like it has Unicode
-encoding. \fB\s-1WARNING\s0:\fR this option is intended for buggy fonts
-which actually are in Unicode but are marked as something else. The
-effect on the other fonts is unpredictable.
-.Ip "\(bu" 2
-\f(CW\fB-G \fIsuboptions\fR\fR\fR \- File generation options. The suboptions may be lowercase
-or uppercase, the lowercase ones disable the generation of particular
-files, the corresponding uppercase suboptions enable the generation of the
-same kind of files. If the result of ttf2pt1 is requested to be printed on
-the standard output, the last enabling suboption of \fB\-G\fR determines
-which file will be written to the standard output and the rest of files
-will be discarded. For example, \fB\-G A\fR will request the \s-1AFM\s0 file.
-The suboptions to disable/enable the generation of the files are:
-.Sp
-\f(CW\fBf/F\fR\fR \- The font file. Depending on the other options this file
-will have one of the suffixes \f(CW.t1a\fR, \f(CW.pfa\fR or \f(CW.pfb\fR. If the conversion result
-is requested on the standard output ('\f(CW-\fR\*(R' is used as the output file name)
-then the font file will also be written there by default, if not overwritten
-by another suboption of \fB\-G\fR.
-\fBDefault: enabled\fR
-.Sp
-\f(CW\fBa/A\fR\fR \- The Adobe font metrics file (\f(CW.afm\fR).
-\fBDefault: enabled\fR
-.Sp
-\f(CW\fBe/E\fR\fR \- The dvips encoding file (\f(CW.enc\fR).
-\fBDefault: disabled\fR
-.Ip "\(bu" 2
-\f(CW\fB-l \fIlanguage\fR[+\fIargument\fR]\fR\fR \- Extract the fonts for the specified language from a
-multi-language Unicode font. If this option is not used the converter
-tries to guess the language by the values of the shell variable \s-1LANG\s0.
-If it is not able to guess the language by \s-1LANG\s0 it tries all the
-languages in the order they are listed.
-.Sp
-After the plus sign an optional argument for the language extractor
-may be specified. The format of the argument is absolutely up to
-the particular language converter. The primary purpose of the
-argument is to support selection of planes for the multi-plane
-Eastern encodings but it can also be used in any other way. The
-language extractor may decide to add the plane name in some form
-to the name of the resulting font. None of the currently supported
-languages make any use of the argument yet.
-.Sp
-As of now the following languages are supported:
-.Sp
-\ \ \f(CWlatin1\fR \- for all the languages using the Latin-1 encoding
-.Sp
-\ \ \f(CWlatin2\fR \- for the Central European languages
-.Sp
-\ \ \f(CWlatin4\fR \- for the Baltic languages
-.Sp
-\ \ \f(CWlatin5\fR \- for the Turkish language
-.Sp
-\ \ \f(CWcyrillic\fR \- for the languages with Cyrillic alphabet
-.Sp
-\ \ \f(CWrussian\fR \- historic synonym for cyrillic
-.Sp
-\ \ \f(CWbulgarian\fR \- historic synonym for cyrillic
-.Sp
-\ \ \f(CWadobestd\fR \- for the AdobeStandard encoding used by TeX
-.Sp
-\ \ \f(CWplane+\fIargument\fR\fR \- to select one plane from a multi-byte encoding
-.Sp
-The argument of the \*(L"\f(CWplane\fR\*(R" language may be in one of three forms:
-.Sp
-\ \ \f(CWplane+\fBpid=\fR\fI<pid>\fR\fB,eid=\fR\fI<eid>\fR\fR
-.Sp
-\ \ \f(CWplane+\fBpid=\fR\fI<pid>\fR\fB,eid=\fR\fI<eid>\fR\fB,\fR\fI<plane_number>\fR\fR
-.Sp
-\ \ \f(CWplane+\fI<plane_number>\fR\fR
-.Sp
-Pid (\s-1TTF\s0 platform id) and eid (\s-1TTF\s0 encoding id) select a particular
-\s-1TTF\s0 encoding table in the original font. They are specified as decimal
-numbers. If this particular encoding table is not present in the font
-file then the conversion fails. The native ("ttf") front-end parser supports
-only pid=3 (Windows platform), the FreeType-based ("ft") front-end supports
-any platform. If pid/eid is not specified then the \s-1TTF\s0 encoding table is
-determined as usual: Unicode encoding if it's first or an 8-bit encoding
-if not (and for an 8-bit encoding the plane number is silently ignored).
-To prevent the converter from falling back to an 8-bit encoding, specify
-the Unicode pid/eid value explicitly.
-.Sp
-Plane_number is a hexadecimal (if starts with \*(L"\fB0x\fR") or decimal number.
-It gives the values of upper bytes for which 256 characters will be
-selected. If not specified, defaults to 0. It is also used as a font
-name suffix (the leading \*(L"0x\*(R" is not included into the suffix).
-.Sp
-\fB\s-1NOTE\s0:\fR
-You may notice that the language names are not uniform: some are the
-names of particular languages and some are names of encodings. This
-is because of the different approaches. The original idea was to
-implement a conversion from Unicode to the appropriate Windows
-encoding for a given language. And then use the translation tables
-to generate the fonts in whatever final encodings are needed. This
-would allow to pile together the Unicode fonts and the non-Unicode
-Windows fonts for that language and let the program to sort them out
-automatically. And then generate fonts in all the possible encodings
-for that language. An example of this approach is the Russian language
-support. But if there is no multiplicity of encodings used for some
-languages and if the non-Unicode fonts are not considered important
-by the users, another way would be simpler to implement: just provide
-only one table for extraction of the target encoding from Unicode
-and don't bother with the translation tables. The latin* \*(L"languages\*(R"
-are examples of this approach. If somebody feels that he needs the
-Type1 fonts both in Latin-* and Windows encodings he or she is absolutely
-welcome to submit the code to implement it.
-.Sp
-\fB\s-1WARNING\s0:\fR
-Some of the glyphs included into the AdobeStandard encoding are not
-included into the Unicode standard. The most typical examples of such
-glyphs are ligatures like \*(L'fi\*(R', \*(L'fl\*(R' etc. Because of this the font
-designers may place them at various places. The converter tries to
-do its best, if the glyphs have honest Adobe names and/or are
-placed at the same codes as in the Microsoft fonts they will be
-picked up. Otherwise a possible solution is to use the option \*(L'\fB\-L\fR\*(R'
-with an external map.
-.Ip "\(bu" 2
-\f(CW\fB-L \fIfile\fR[+[pid=\fI<pid>\fR,eid=\fI<eid>\fR,][\fIplane\fR]]\fR\fR \- Extract the fonts for the specified
-language from a multi-language font using the map from this file. This is
-rather like the option \*(L'\fB\-l\fR\*(R' but the encoding map is not
-compiled into the program, it's taken from that file, so it's
-easy to edit. Examples of such files are provided in
-\f(CWmaps/adobe-standard-encoding.map\fR, \f(CWCP1250.map\fR. (\fB\s-1NOTE\s0:\fR
-the \*(L'standard encoding\*(R' map does not include all the glyphs of the
-AdobeStandard encoding, it's provided only as an example.) The
-description of the supported map formats is in the file
-\f(CWmaps/unicode-sample.map\fR.
-.Sp
-Likewise to \*(L'\fB\-l\fR\*(R', an argument may be specified after the map file
-name. But in this case the argument has fixed meaning: it selects the
-original \s-1TTF\s0 encoding table (the syntax is the same as in \*(L'\fB\-l plane\fR')
-and/or a plane of the map file. The plane name also gets added after dash
-to the font name. The plane is a concept used in the Eastern fonts with big
-number of glyphs: one \s-1TTF\s0 font gets divided into multiple Type1 fonts,
-each containing one plane of up to 256 glyphs. But with a little
-creativity this concept may be used for other purposes of combining
-multiple translation maps into one file. To extract multiple planes
-from a \s-1TTF\s0 font \f(CWttf2pt1\fR must be run multiple times, each time with
-a different plane name specified.
-.Sp
-The default original \s-1TTF\s0 encoding table used for the option \*(L'\fB\-L\fR\*(R' is
-Unicode. The map files may include directives to specify different original
-\s-1TTF\s0 encodings. However if the pid/eid pair is specified with
-it overrides any original encoding specified in the map file.
-.Ip "\(bu" 2
-\f(CW\fB-m \fItype\fR=\fIvalue\fR\fR\fR \- Set maximal or minimal limits of resources.
-These limits control the the font generation by limiting the resources
-that the font is permitted to require from the PostScript interpreter.
-The currently supported types of limits are:
-.Sp
-\f(CW\fBh\fR\fR \- the maximal hint stack depth for the substituted hints.
-The default value is 128, according to the limitation in X11. This seems to
-be the lowest (and thus the safest) widespread value. To display the
-hint stack depth required by each glyph in a \f(CW.t1a\fR file use the script
-\f(CWscripts/cntstems.pl\fR.
-.Ip "\(bu" 2
-\f(CW\fB-O \fIsuboptions\fR\fR\fR \- Outline processing options. The suboptions
-may be lowercase or uppercase, the lowercase ones disable the features,
-the corresponding uppercase suboptions enable the same features.
-The suboptions to disable/enable features are:
-.Sp
-\f(CW\fBb/B\fR\fR \- Guessing of the ForceBold parameter. This parameter helps
-the Type1 engine to rasterize the bold fonts properly at small sizes.
-But the algorithm used to guess the proper value of this flag makes
-that guess based solely on the font name. In rare cases that may cause
-errors, in these cases you may want to disable this guessing.
-\fBDefault: enabled\fR
-.Sp
-\f(CW\fBh/H\fR\fR \- Autogeneration of hints. The really complex outlines
-may confuse the algorithm, so theoretically it may be useful
-sometimes to disable them. Although up to now it seems that
-even bad hints are better than no hints at all.
-\fBDefault: enabled\fR
-.Sp
-\f(CW\fBu/U\fR\fR \- Hint substitution. Hint substitution is a technique
-permitting generation of more detailed hints for the rasterizer. It allows
-to use different sets of hints for different parts of a glyph and change
-these sets as neccessary during rasterization (that's why \*(L"substituted").
-So it should improve the quality of the fonts rendered at small sizes.
-But there are two catches: First, the X11 library has rather low limit for
-the font size. More detailed hints increase the file size and thus increase
-the chance of hitting this limit (that does not mean that you shall hit it
-but you may if your fonts are particularly big). This is especially
-probable for Unicode fonts converted with option \*(L'\fB\-a\fR\*(R', so you may want to
-use \*(L'\fB\-a\fR\*(R' together with \*(L'\fB\-Ou\fR\*(R'. See \f(CWapp/X11/README\fR for the description of
-a patch to X11 which fixes this problem. Second, some rasterizers (again,
-X11 is the typical example) have a limitation for total number of hints
-used when drawing a glyph (also known as the hint stack depth). If that
-stack overflows the glyph is ignored. Starting from version 3.22 \f(CWttf2pt1\fR
-uses algorithms to minimizing this depth, with the trade-off of slightly
-bigger font files. The glyphs which still exceed the limit set by option
-\&\*(R'\fB\-mh\fR\*(R' have all the substituted hints removed and only base hints left.
-The algorithms seem to have been refined far enough to make the fonts with
-substituted hints look better than the fonts without them or at least the
-same. Still if the original fonts are not well-designed the detailed
-hinting may emphasize the defects of the design, such as non-even thickness
-of lines. So provided that you are not afraid of the X11 bug the best idea
-would be to generate a font with this feature and without it, then compare
-the results using the program \f(CWother/cmpf\fR (see the description
-in \f(CWother/README\fR) and decide which one looks better.
-\fBDefault: enabled\fR
-.Sp
-\f(CW\fBo/O\fR\fR \- Space optimization of the outlines\*(R' code. This kind of optimization
-never hurts, and the only reason to disable this feature is for comparison
-of the generated fonts with the fonts generated by the previous versions of
-converter. Well, it _almost_ never hurts. As it turned out there exist
-some brain-damaged printers which don't understand it. Actually this
-feature does not change the outlines at all. The Type 1 font manual
-provides a set of redundant operators that make font description shorter,
-such as \*(L'10 hlineto\*(R' instead of \*(L'0 10 rlineto\*(R' to describe a horizontal
-line. This feature enables use of these operators.
-\fBDefault: enabled\fR
-.Sp
-\f(CW\fBs/S\fR\fR \- Smoothing of outlines. If the font is broken in some
-way (even the ones that are not easily noticeable), such smoothing
-may break it further. So disabling this feature is the first thing to be
-tried if some font looks odd. But with smoothing off the hint generation
-algorithms may not work properly too.
-\fBDefault: enabled\fR
-.Sp
-\f(CW\fBt/T\fR\fR \- Auto-scaling to the 1000x1000 Type1 standard matrix. The
-\s-1TTF\s0 fonts are described in terms of an arbitrary matrix up to
-4000x4000. The converted fonts must be scaled to conform to
-the Type1 standard. But the scaling introduces additional rounding
-errors, so it may be curious sometimes to look at the font in its
-original scale.
-\fBDefault: enabled\fR
-.Sp
-\f(CW\fBv/V\fR\fR \- Do vectorization on the bitmap fonts. Functionally
-\*(L"vectorization\*(R" is the same thing as \*(L"autotracing\*(R", a different word is
-used purely to differentiate it from the Autotrace library. It tries to
-produce nice smooth outlines from bitmaps. This feature is still a work
-in progress though the results are already mostly decent.
-\fBDefault: disabled\fR
-.Sp
-\f(CW\fBw/W\fR\fR \- Glyphs\*(R' width corection. This option is designed to be
-used on broken fonts which specify too narrow widths for the
-letters. You can tell that a font can benefit from this option
-if you see that the characters are smashed together without
-any whitespace between them. This option causes the converter
-to set the character widths to the actual width of this character
-plus the width of a typical vertical stem. But on the other hand
-the well-designed fonts may have characters that look better if
-their widths are set slightly narrower. Such well-designed fonts
-will benefit from disabling this feature. You may want to convert
-a font with and without this feature, compare the results and
-select the better one. This feature may be used only on proportional
-fonts, it has no effect on the fixed-width fonts.
-\fBDefault: disabled\fR
-.Sp
-\f(CW\fBz/Z\fR\fR \- Use the Autotrace library on the bitmap fonts. The results
-are horrible and \fBthe use of this option is not recommended\fR. This option is
-present for experimental purposes. It may change or be removed in the
-future. The working tracing can be achieved with option \f(CW\fB-OV\fR\fR.
-\fBDefault: disabled\fR
-.Ip "\(bu" 2
-\f(CW\fB-p \fIparser_name\fR\fR\fR \- Use the specified front-end parser to read the font file.
-If this option is not used, ttf2pt1 selects the parser automatically based
-on the suffix of the font file name, it uses the first parser in its
-list that supports this font type. Now two parsers are supported:
-.Sp
-\ \ \f(CWttf\fR \- built-in parser for the ttf files (suffix \f(CW.ttf\fR)
-.Sp
-\ \ \f(CWbdf\fR \- built-in parser for the \s-1BDF\s0 files (suffix \f(CW.bdf\fR)
-.Sp
-\ \ \f(CWft\fR \- parser based on the FreeType-2 library (suffixes \f(CW.ttf\fR,
-\&\f(CW.otf\fR, \f(CW.pfa\fR, \f(CW.pfb\fR)
-.Sp
-The parser \f(CWft\fR is \fB\s-1NOT\s0\fR linked in by default. See \f(CWMakefile\fR
-for instructions how to enable it. We do no support this parser on
-Windows: probably it will work but nobody tried and nobody knows how
-to build it.
-.Sp
-The conversion of the bitmap fonts (such as \s-1BDF\s0) is simplistic yet,
-producing jagged outlines. When converting such fonts, it might be
-a good idea to turn off the hint substitution (using option \fB\-Ou\fR)
-because the hints produced will be huge but not adding much to the
-quality of the fonts.
-.Ip "\(bu" 2
-\f(CW\fB-u \fInumber\fR\fR\fR \- Mark the font with this value as its
-UniqueID. The UniqueID is used by the printers with the hard disks
-to cache the rasterized characters and thus significantly
-speed-up the printing. Some of those printers just can't
-store the fonts without UniqueID on their disk.The problem
-is that the \s-1ID\s0 is supposed to be unique, as it name says. And
-there is no easy way to create a guaranteed unique \s-1ID\s0. Adobe specifies
-the range 4000000-4999999 for private IDs but still it's difficult
-to guarantee the uniqueness within it. So if you don't really need the
-UniqueID don't use it, it's optional. Luckily there are a few millions of
-possible IDs, so the chances of collision are rather low.
-If instead of the number a special value \*(L'\f(CW\fBA\fR\fR\*(R' is given
-then the converter generates the value of UniqueID automatically,
-as a hash of the font name. (\fB\s-1NOTE\s0:\fR in the version 3.22 the
-algorithm for autogeneration of UniqueID was changed to fit the values
-into the Adobe-spacified range. This means that if UniqueIDs were used
-then the printer's cache may need to be flushed before replacing the
-fonts converted by an old version with fonts converted by a newer version).
-A simple way to find if any of the fonts in a given directory have
-duplicated UniqueIDs is to use the command:
-.Sp
-\f(CW\ \ cat *.pf[ab] | grep UniqueID | sort | uniq -c | grep -v ' 1 '\fR
-.Sp
-Or if you use \f(CWscripts/convert\fR it will do that for you automatically
-plus it will also give the exact list of files with duplicate UIDs.
-.Ip "\(bu" 2
-\f(CW\fB-v \fIsize\fR\fR\fR \- Re-scale the font to get the size of a typical uppercase
-letter somewhere around the specified size. Actually, it re-scales
-the whole font to get the size of one language-dependent letter to be
-at least of the specified size. Now this letter is \*(L"A\*(R" in all the
-supported languages. The size is specified in the points of the
-Type 1 coordinate grids, the maximal value is 1000. This is an
-experimental option and should be used with caution. It tries to
-increase the visible font size for a given point size and thus make
-the font more readable. But if overused it may cause the fonts to
-look out of scale. As of now the interesting values of size for
-this option seem to be located mostly between 600 and 850. This
-re-scaling may be quite useful but needs more experience to
-understand the balance of its effects.
-.Ip "\(bu" 2
-\f(CW\fB-W \fIlevel\fR\fR\fR \- Select the verbosity level of the warnings.
-Currently the levels from 0 to 4 are supported. Level 0 means no warnings
-at all, level 4 means all the possible warnings. The default level is 3.
-Other levels may be added in the future, so using the level number 99 is
-recommended to get all the possible warnings. Going below level 2 is
-not generally recommended because you may miss valuable information about
-the problems with the fonts being converted.
-.Ip "\(bu" 2
-\fBObsolete option:\fR
-\f(CW\fB-A\fR\fR \- Print the font metrics (.afm file) instead of the font on \s-1STDOUT\s0.
-Use \fB\-\s-1GA\s0\fR instead.
-.Ip "\(bu" 2
-\fBVery obsolete option:\fR
-.Sp
-The algorithm that implemented the forced fixed width had major
-flaws, so it was disabled. The code is still in the program and
-some day it will be refined and returned back. Meanwhile the
-option name \*(L'\fB\-f\fR\*(R' was reused for another option. The old version was:
-.Sp
-\f(CW\fB-f\fR\fR \- Don't try to force the fixed width of font. Normally the converter
-considers the fonts in which the glyph width deviates by not more
-than 5% as buggy fixed width fonts and forces them to have really
-fixed width. If this is undesirable, it can be disabled by this option.
-.PP
-The \f(CW.pfa\fR font format supposes that the description of the characters
-is binary encoded and encrypted. This converter does not encode or
-encrypt the data by default, you have to specify the option \*(L'\fB\-e\fR\*(R'
-or use the \f(CWt1asm\fR program to assemble (that means, encode and
-encrypt) the font program. The \f(CWt1asm\fR program that is included with
-the converter is actually a part of the \f(CWt1utils\fR package, rather old
-version of which may be obtained from
-.PP
-http://ttf2pt1.sourceforge.net/t1utils.tar.gz
-.PP
-Note that \f(CWt1asm\fR from the old version of that package won't work properly
-with the files generated by \f(CWttf2pt1\fR version 3.20 and later. Please use
-\f(CWt1asm\fR packaged with \f(CWttf2pt1\fR or from the new version \f(CWt1utils\fR
-instead. For a newer version of \f(CWt1utils\fR please look at
-.PP
-http://www.lcdf.org/~eddietwo/type/
-.SH "EXAMPLES"
-So, the following command lines:
-.PP
-\f(CWttf2pt1 -e ttffont.ttf t1font\fR
-.PP
-\f(CWttf2pt1 ttffont.ttf - | t1asm >t1font.pfa\fR
-.PP
-represent two ways to get a working font. The benefit of the second form
-is that other filters may be applied to the font between the converter
-and assembler.
-.SH "FILES"
-.Ip "\(bu" 2
-\s-1TTF2PT1_LIBXDIR/\s0t1asm
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR\s0/*
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/\s0scripts/*
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/\s0other/*
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/README\s0
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/FONTS\s0
-.SH "SEE ALSO"
-.Ip "\(bu" 4
-the \fIttf2pt1_convert(1)\fR manpage
-.Ip "\(bu" 4
-the \fIttf2pt1_x2gs(1)\fR manpage
-.Ip "\(bu" 4
-the \fIt1asm(1)\fR manpage
-.Ip "\(bu" 4
-ttf2pt1-announce@lists.sourceforge.net
-.Sp
-The mailing list with announcements about ttf2pt1. It is a moderated mailing
-with extremely low traffic. Everyone is encouraged to subscribe to keep in
-touch with the current status of project. To subscribe use the Web interface
-at http://lists.sourceforge.net/mailman/listinfo/ttf2pt1-announce.
-If you have only e-mail access to the Net then send a subscribe request to
-the development mailing list ttf2pt1-devel@lists.sourceforge.net and somebody
-will help you with subscription.
-.Ip "\(bu" 4
-ttf2pt1-devel@lists.sourceforge.net
-.Sp
-ttf2pt1-users@lists.sourceforge.net
-.Sp
-The ttf2pt1 mailing lists for development and users issues. They have not
-that much traffic either. To subscribe use the Web interface at
-http://lists.sourceforge.net/mailman/listinfo/ttf2pt1-devel
-and http://lists.sourceforge.net/mailman/listinfo/ttf2pt1-users.
-If you have only e-mail access to the Net then send a subscribe request to
-the development mailing list ttf2pt1-devel@lists.sourceforge.net and somebody
-will help you with subscription.
-.Ip "\(bu" 4
-http://ttf2pt1.sourceforge.net
-.Sp
-The main page of the project.
-.Sp
-http://www.netspace.net.au/~mheath/ttf2pt1/
-.Sp
-The old main page of the project.
-.SH "BUGS"
-It seems that many Eastern fonts use features of the TTF format that are
-not supported by the ttf2pt1's built-in front-end parser. Because of
-this for now we recommend using the FreeType-based parser (option
-\&\*(R'\fB\-p ft\fR') with the \*(L"\f(CWplane\fR\*(R" language.
-.Sh "Troubleshooting and bug reports"
-Have problems with conversion of some font ? The converter dumps core ? Or your
-printer refuses to understand the converted fonts ? Or some characters are
-missing ? Or some characters look strange ?
-.PP
-Send the bug reports to the ttf2pt1 development mailing list at
-ttf2pt1-devel@lists.sourceforge.net.
-.PP
-Try to collect more information about the problem and include it into
-the bug report. (Of course, even better if you would provide a ready
-fix, but just a detailed bug report is also good). Provide detailed
-information about your problem, this will speed up the response greatly.
-Don't just write \*(L"this font looks strange after conversion\*(R" but describe
-what's exactly wrong with it: for example, what characters look wrong
-and what exactly is wrong about their look. Providing a link to the
-original font file would be also a good idea. Try to do a little
-troublehooting and report its result. This not only would help with
-the fix but may also give you a temporary work-around for the bug.
-.PP
-First, enable full warnings with option \*(L'\fB\-W99\fR\*(R', save them to
-a file and read carefully. Sometimes the prolem is with a not implemented
-feature which is reported in the warnings. Still, reporting about such
-problems may be a good idea: some features were missed to cut corners,
-in hope that no real font is using them. So a report about a font using
-such a feature may motivate someone to implement it. Of course, you
-may be the most motivated person: after all, you are the one wishing
-to convert that font. ;\-) Seriously, the philosophy \*(L"scrath your own itch\*(R"
-seems to be the strongest moving force behind the Open Source software.
-.PP
-The next step is playing with the options. This serves a dual purpose:
-on one hand, it helps to localize the bug, on the other hand you may be
-able to get a working version of the font for the meantime while the
-bug is being fixed. The typical options to try out are: first \*(L'\fB\-Ou\fR\*(R', if
-it does not help then \*(L'\fB\-Os\fR\*(R', then \*(L'\fB\-Oh\fR\*(R', then \*(L'\fB\-Oo\fR\*(R'.
-They are described in a bit more detail above. Try them one by one
-and in combinations. See if with them the resulting fonts look better.
-.PP
-On some fonts ttf2pt1 just crashes. Commonly that happens because the
-font being converted is highly defective (although sometimes the bug
-is in ttf2pt1 itself). In any case it should not crash, so the reports
-about such cases will help to handle these defects properly in future.
-.PP
-We try to respond to the bug reports in a timely fashion but alas, this
-may not always be possible, especially if the problem is complex.
-This is a volunteer project and its resources are limited. Because
-of this we would appreciate bug reports as detailed as possible,
-and we would appreciate the ready fixes and contributions even more.
-.SH "HISTORY"
-Based on ttf2pfa by Andrew Weeks, and help from Frank Siegert.
-.PP
-Modification by Mark Heath.
-.PP
-Further modification by Sergey Babkin.
-.PP
-The Type1 assembler by I. Lee Hetherington with modifications by
-Kai-Uwe Herbing.
-
-.rn }` ''
-.IX Title "TTF2PT1 1"
-.IX Name "TTF2PT1 - A True Type to PostScript Type 1 Font Converter"
-
-.IX Header "NAME"
-
-.IX Header "SYNOPSIS"
-
-.IX Header "DESCRIPTION"
-
-.IX Header "OPTIONS"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Header "EXAMPLES"
-
-.IX Header "FILES"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Header "SEE ALSO"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Header "BUGS"
-
-.IX Subsection "Troubleshooting and bug reports"
-
-.IX Header "HISTORY"
-
diff --git a/nx-X11/extras/ttf2pt1/ttf2pt1.c b/nx-X11/extras/ttf2pt1/ttf2pt1.c
deleted file mode 100644
index a85a41658..000000000
--- a/nx-X11/extras/ttf2pt1/ttf2pt1.c
+++ /dev/null
@@ -1,2722 +0,0 @@
-/*
- * True Type Font to Adobe Type 1 font converter
- * By Mark Heath <mheath@netspace.net.au>
- * Based on ttf2pfa by Andrew Weeks <ccsaw@bath.ac.uk>
- * With help from Frank M. Siegert <fms@this.net>
- *
- * see COPYRIGHT for full copyright notice
- *
-***********************************************************************
- *
- * Sergey Babkin <babkin@users.sourceforge.net>, <sab123@hotmail.com>
- *
- * Added post-processing of resulting outline to correct the errors
- * both introduced during conversion and present in the original font,
- * autogeneration of hints (has yet to be improved though) and BlueValues,
- * scaling to 1000x1000 matrix, option to print the result on STDOUT,
- * support of Unicode to CP1251 conversion, optimization of the
- * resulting font code by space (that improves the speed too). Excluded
- * the glyphs that are unaccessible through the encoding table from
- * the output file. Added the built-in Type1 assembler (taken from
- * the `t1utils' package).
- *
-***********************************************************************
- *
- * Thomas Henlich <thenlich@rcs.urz.tu-dresden.de>
- *
- * Added generation of .afm file (font metrics)
- * Read encoding information from encoding description file
- * Fixed bug in error message about unknown language ('-l' option)
- * Added `:' after %%!PS-AdobeFont-1.0
- * changed unused entries in ISOLatin1Encoding[] from .notdef to c127,c128...
- *
-***********************************************************************
- *
- * Thomas Henlich <thenlich@rcs.urz.tu-dresden.de>
- *
- * Added generation of .afm file (font metrics)
- *
-***********************************************************************
- *
- * Bug Fixes:
-************************************************************************
- *
- * Sun, 21 Jun 1998 Thomas Henlich <thenlich@Rcs1.urz.tu-dresden.de>
- * 1. "width" should be "short int" because otherwise:
- * characters with negative widths (e.g. -4) become *very* wide (65532)
- * 2. the number of /CharStrings is numglyphs and not numglyphs+1
- *
-***********************************************************************
- *
- *
- *
- * The resultant font file produced by this program still needs to be ran
- * through t1asm (from the t1utils archive) to produce a completely valid
- * font.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <time.h>
-#include <ctype.h>
-#include <math.h>
-
-#ifdef _GNU_SOURCE
-#include <getopt.h>
-#endif
-
-#ifndef WINDOWS
-# include <unistd.h>
-# include <netinet/in.h>
-# define BITBUCKET "/dev/null"
-# include <sys/wait.h>
-#else
-# define WINDOWS_FUNCTIONS /* ask to define functions - in one file only */
-# include "windows.h"
-# define BITBUCKET "NUL"
-# define snprintf _snprintf
-#endif
-
-#ifdef XP_PSTEXT
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TRUETYPE_TABLES_H
-#include FT_BBOX_H
-#include FT_GLYPH_H
-
-#include FT_CONFIG_CONFIG_H
-#include FT_CONFIG_OPTIONS_H
-#include FT_ERRORS_H
-#include FT_SYSTEM_H
-#include FT_IMAGE_H
-#include FT_TYPES_H
-#include FT_OUTLINE_H
-#include FT_MODULE_H
-#include FT_RENDER_H
-#include FT_TYPE1_TABLES_H
-#include FT_TRUETYPE_IDS_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_MULTIPLE_MASTERS_H
-#include FT_SFNT_NAMES_H
-
-#include "os.h"
-#include "Xproto.h"
-#include "font.h"
-#include "fontstruct.h"
-#include "fntfilst.h"
-#include "fontutil.h"
-#include "fontenc.h"
-#include "ft.h"
-#define NOT_IN_FTFUNCS
-#include "ftfuncs.h"
-#endif /* XP_PSTEXT */
-
-#include "pt1.h"
-#include "global.h"
-#include "version.h"
-
-/* globals */
-
-/* table of front-ends */
-
-#ifdef USE_TTF
-extern struct frontsw ttf_sw;
-#endif /* USE_TTF */
-#ifdef USE_BDF
-extern struct frontsw bdf_sw;
-#endif /* USE_BDF */
-#if defined(USE_FREETYPE)
- extern struct frontsw freetype_sw;
-#endif
-
-struct frontsw *frontswtab[] = {
-#ifdef USE_BDF
- &bdf_sw,
-#endif /* USE_BDF */
-#if defined(USE_FREETYPE) && defined(PREFER_FREETYPE)
- &freetype_sw,
-#endif
-#ifdef USE_TTF
- &ttf_sw,
-#endif /* USE_TTF */
-#if defined(USE_FREETYPE) && !defined(PREFER_FREETYPE)
- &freetype_sw,
-#endif
- NULL /* end of table */
-};
-
-struct frontsw *cursw=0; /* the active front end */
-char *front_arg=""; /* optional argument */
-
-/* options */
-int encode = 0; /* encode the resulting file */
-int pfbflag = 0; /* produce compressed file */
-int wantafm=0; /* want to see .afm instead of .t1a on stdout */
-int correctvsize=0; /* try to correct the vertical size of characters */
-int wantuid = 0; /* user wants UniqueID entry in the font */
-int allglyphs = 0; /* convert all glyphs, not only 256 of them */
-int warnlevel = 3; /* the level of permitted warnings */
-int forcemap = 0; /* do mapping even on non-Unicode fonts */
-/* options - maximal limits */
-int max_stemdepth = 128; /* maximal depth of stem stack in interpreter (128 - limit from X11) */
-/* options - debugging */
-int absolute = 0; /* print out in absolute values */
-int reverse = 1; /* reverse font to Type1 path directions */
-/* options - suboptions of Outline Processing, defaults are set in table */
-int optimize; /* enables space optimization */
-int smooth; /* enable smoothing of outlines */
-int transform; /* enables transformation to 1000x1000 matrix */
-int hints; /* enables autogeneration of hints */
-int subhints; /* enables autogeneration of substituted hints */
-int trybold; /* try to guess whether the font is bold */
-int correctwidth; /* try to correct the character width */
-int vectorize; /* vectorize the bitmaps */
-int use_autotrace; /* use the autotrace library on bitmap */
-/* options - suboptions of File Generation, defaults are set in table */
-int gen_pfa; /* generate the font file */
-int gen_afm; /* generate the metrics file */
-int gen_dvienc; /* generate the dvips encoding file */
-
-/* not quite options to select a particular source encoding */
-int force_pid = -1; /* specific platform id */
-int force_eid = -1; /* specific encoding id */
-
-/* structure to define the sub-option lists controlled by the
- * case: uppercase enables them, lowercase disables
- */
-struct subo_case {
- char disbl; /* character to disable - enforced lowercase */
- char enbl; /* character to enable - auto-set as toupper(disbl) */
- int *valp; /* pointer to the actual variable containing value */
- int dflt; /* default value */
- char *descr; /* description */
-};
-
-#ifdef DEBUG
-int debug = DEBUG; /* debugging flag */
-#else
-int debug = 0;
-#endif /* DEBUG */
-
-FILE *null_file, *pfa_file, *afm_file, *dvienc_file;
-int numglyphs;
-struct font_metrics fontm;
-
-/* non-globals */
-static char *strUID = 0; /* user-supplied UniqueID */
-static unsigned long numUID; /* auto-generated UniqueID */
-
-static int ps_fmt_3 = 0;
-static double scale_factor, original_scale_factor;
-
-static char *glyph_rename[ENCTABSZ];
-
-/* the names assigned if the original font
- * does not specify any
- */
-
-static char *Fmt3Encoding[256] = {
- "c0", "c1", "c2", "c3",
- "c4", "c5", "c6", "c7",
- "c8", "c9", "c10", "c11",
- "c12", "CR", "c14", "c15",
- "c16", "c17", "c18", "c19",
- "c20", "c21", "c22", "c23",
- "c24", "c25", "c26", "c27",
- "c28", "c29", "c30", "c31",
- "space", "exclam", "quotedbl", "numbersign",
- "dollar", "percent", "ampersand", "quotesingle",
- "parenleft", "parenright", "asterisk", "plus",
- "comma", "hyphen", "period", "slash",
- "zero", "one", "two", "three",
- "four", "five", "six", "seven",
- "eight", "nine", "colon", "semicolon",
- "less", "equal", "greater", "question",
- "at", "A", "B", "C",
- "D", "E", "F", "G",
- "H", "I", "J", "K",
- "L", "M", "N", "O",
- "P", "Q", "R", "S",
- "T", "U", "V", "W",
- "X", "Y", "Z", "bracketleft",
- "backslash", "bracketright", "asciicircum", "underscore",
- "grave", "a", "b", "c",
- "d", "e", "f", "g",
- "h", "i", "j", "k",
- "l", "m", "n", "o",
- "p", "q", "r", "s",
- "t", "u", "v", "w",
- "x", "y", "z", "braceleft",
- "bar", "braceright", "asciitilde", "c127",
- "c128", "c129", "quotesinglbase", "florin",
- "quotedblbase", "ellipsis", "dagger", "daggerdbl",
- "circumflex", "perthousand", "Scaron", "guilsinglleft",
- "OE", "c141", "c142", "c143",
- "c144", "quoteleft", "quoteright", "quotedblleft",
- "quotedblright", "bullet", "endash", "emdash",
- "tilde", "trademark", "scaron", "guilsinglright",
- "oe", "c157", "c158", "Ydieresis",
- "nbspace", "exclamdown", "cent", "sterling",
- "currency", "yen", "brokenbar", "section",
- "dieresis", "copyright", "ordfeminine", "guillemotleft",
- "logicalnot", "sfthyphen", "registered", "macron",
- "degree", "plusminus", "twosuperior", "threesuperior",
- "acute", "mu", "paragraph", "periodcentered",
- "cedilla", "onesuperior", "ordmasculine", "guillemotright",
- "onequarter", "onehalf", "threequarters", "questiondown",
- "Agrave", "Aacute", "Acircumflex", "Atilde",
- "Adieresis", "Aring", "AE", "Ccedilla",
- "Egrave", "Eacute", "Ecircumflex", "Edieresis",
- "Igrave", "Iacute", "Icircumflex", "Idieresis",
- "Eth", "Ntilde", "Ograve", "Oacute",
- "Ocircumflex", "Otilde", "Odieresis", "multiply",
- "Oslash", "Ugrave", "Uacute", "Ucircumflex",
- "Udieresis", "Yacute", "Thorn", "germandbls",
- "agrave", "aacute", "acircumflex", "atilde",
- "adieresis", "aring", "ae", "ccedilla",
- "egrave", "eacute", "ecircumflex", "edieresis",
- "igrave", "iacute", "icircumflex", "idieresis",
- "eth", "ntilde", "ograve", "oacute",
- "ocircumflex", "otilde", "odieresis", "divide",
- "oslash", "ugrave", "uacute", "ucircumflex",
- "udieresis", "yacute", "thorn", "ydieresis"
-};
-
-#ifdef notdef /* { */
-/* This table is not used anywhere in the code
- * so it's ifdef-ed out by default but left in
- * the source code for reference purposes (and
- * possibly for future use)
- */
-
-static char *ISOLatin1Encoding[256] = {
- ".null", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "CR", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- "space", "exclam", "quotedbl", "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",
- "less", "equal", "greater", "question",
- "at", "A", "B", "C",
- "D", "E", "F", "G",
- "H", "I", "J", "K",
- "L", "M", "N", "O",
- "P", "Q", "R", "S",
- "T", "U", "V", "W",
- "X", "Y", "Z", "bracketleft",
- "backslash", "bracketright", "asciicircum", "underscore",
- "grave", "a", "b", "c",
- "d", "e", "f", "g",
- "h", "i", "j", "k",
- "l", "m", "n", "o",
- "p", "q", "r", "s",
- "t", "u", "v", "w",
- "x", "y", "z", "braceleft",
- "bar", "braceright", "asciitilde", "c127",
- "c128", "c129", "quotesinglbase", "florin",
- "quotedblbase", "ellipsis", "dagger", "daggerdbl",
- "circumflex", "perthousand", "Scaron", "guilsinglleft",
- "OE", "c141", "c142", "c143",
- "c144", "quoteleft", "quoteright", "quotedblleft",
- "quotedblright", "bullet", "endash", "emdash",
- "tilde", "trademark", "scaron", "guilsinglright",
- "oe", "c157", "c158", "Ydieresis",
- "nbspace", "exclamdown", "cent", "sterling",
- "currency", "yen", "brokenbar", "section",
- "dieresis", "copyright", "ordfeminine", "guillemotleft",
- "logicalnot", "sfthyphen", "registered", "macron",
- "degree", "plusminus", "twosuperior", "threesuperior",
- "acute", "mu", "paragraph", "periodcentered",
- "cedilla", "onesuperior", "ordmasculine", "guillemotright",
- "onequarter", "onehalf", "threequarters", "questiondown",
- "Agrave", "Aacute", "Acircumflex", "Atilde",
- "Adieresis", "Aring", "AE", "Ccedilla",
- "Egrave", "Eacute", "Ecircumflex", "Edieresis",
- "Igrave", "Iacute", "Icircumflex", "Idieresis",
- "Eth", "Ntilde", "Ograve", "Oacute",
- "Ocircumflex", "Otilde", "Odieresis", "multiply",
- "Oslash", "Ugrave", "Uacute", "Ucircumflex",
- "Udieresis", "Yacute", "Thorn", "germandbls",
- "agrave", "aacute", "acircumflex", "atilde",
- "adieresis", "aring", "ae", "ccedilla",
- "egrave", "eacute", "ecircumflex", "edieresis",
- "igrave", "iacute", "icircumflex", "idieresis",
- "eth", "ntilde", "ograve", "oacute",
- "ocircumflex", "otilde", "odieresis", "divide",
- "oslash", "ugrave", "uacute", "ucircumflex",
- "udieresis", "yacute", "thorn", "ydieresis"
-};
-
-#endif /* } notdef */
-
-static char *adobe_StandardEncoding[256] = {
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- "space", "exclam", "quotedbl", "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",
- "less", "equal", "greater", "question",
- "at", "A", "B", "C", "D", "E", "F", "G",
- "H", "I", "J", "K", "L", "M", "N", "O",
- "P", "Q", "R", "S", "T", "U", "V", "W",
- "X", "Y", "Z", "bracketleft",
- "backslash", "bracketright", "asciicircum", "underscore",
- "quoteleft", "a", "b", "c", "d", "e", "f", "g",
- "h", "i", "j", "k", "l", "m", "n", "o",
- "p", "q", "r", "s", "t", "u", "v", "w",
- "x", "y", "z", "braceleft",
- "bar", "braceright", "asciitilde", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "exclamdown", "cent", "sterling",
- "fraction", "yen", "florin", "section",
- "currency", "quotesingle", "quotedblleft", "guillemotleft",
- "guilsinglleft", "guilsinglright", "fi", "fl",
- ".notdef", "endash", "dagger", "daggerdbl",
- "periodcentered", ".notdef", "paragraph", "bullet",
- "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright",
- "ellipsis", "perthousand", ".notdef", "questiondown",
- ".notdef", "grave", "acute", "circumflex",
- "tilde", "macron", "breve", "dotaccent",
- "dieresis", ".notdef", "ring", "cedilla",
- ".notdef", "hungarumlaut", "ogonek", "caron",
- "emdash", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "AE", ".notdef", "ordfeminine",
- ".notdef", ".notdef", ".notdef", ".notdef",
- "Lslash", "Oslash", "OE", "ordmasculine",
- ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "ae", ".notdef", ".notdef",
- ".notdef", "dotlessi", ".notdef", ".notdef",
- "lslash", "oslash", "oe", "germandbls",
- ".notdef", ".notdef", ".notdef", ".notdef"
-};
-
-/*
- * Decription of the supported conversions from Unicode
- *
- * SB
- * Yes, I know that the compiled-in conversion is stupid but
- * it is simple to implement and allows not to worry about the
- * filesystem context. After all, the source is always available
- * and adding another language to it is easy.
- *
- * The language name is expected to be the same as the subdirectory name
- * in the `encodings' directory (for possible future extensions).
- * The primary use of the aliases is for guessing based on the current
- * locale.
- */
-
-#define MAXUNIALIAS 10
-#define MAXUNITABLES 3
-
-/* the character used as the language argument separator */
-#define LANG_ARG_SEP '+'
-
-
-/*
- * Types of language-related routines. Arguments are:
- * name is the glyph name
- * arg is the user-specified language-dependent argument
- * which can for example select the subfont plane for Eastern fonts.
- * If none is supplied by user then an empty string ("") is passed.
- * If no language is specified by user and auto-guessing happens
- * then NULL is passed.
- * when shows if the conversion by name was called before conversion by
- * map or after (it's called twice)
- */
-
-/* type of the Unicode map initialization routine */
-typedef void uni_init_t(char *arg);
-
-/* type of Unicode converter-by-name function
- * it's called for each glyph twice: one time for each glyph
- * before doing conversion by map and one time after
- */
-typedef int uni_conv_t(char *name, char *arg, int when);
-#define UNICONV_BYNAME_BEFORE 0
-#define UNICONV_BYNAME_AFTER 1
-
-struct uni_language {
- uni_init_t *init[MAXUNITABLES]; /* map initialization routines */
- uni_conv_t *convbyname; /* the name-based conversion function */
- char *name; /* the language name */
- char *descr; /* description */
- char *alias[MAXUNIALIAS]; /* aliases of the language name */
- int sample_upper; /* code of some uppercase character for correctvsize() */
-};
-
-/* the converter routines have an option of adding this suffix to the font name */
-static char *uni_font_name_suffix = ""; /* empty by default */
-/* this buffer may be used to store the suffix */
-#define UNI_MAX_SUFFIX_LEN 100
-static char uni_suffix_buf[UNI_MAX_SUFFIX_LEN+1];
-
-/*
- * Prototypes of the conversion routines
- */
-
-static uni_init_t unicode_latin1;
-static uni_init_t unicode_latin2;
-static uni_init_t unicode_latin4;
-static uni_init_t unicode_latin5;
-static uni_init_t unicode_cyrillic;
-static uni_init_t unicode_adobestd;
-static uni_init_t unicode_plane;
-static uni_conv_t unicode_adobestd_byname;
-
-static uni_init_t unicode_init_user;
-
-/*
- * The order of descriptions is important: if we can't guess the
- * language we just call all the conversion routines in order until
- * we find one that understands this glyph.
- */
-static struct uni_language uni_lang[]= {
- /* pseudo-language for all the languages using Latin1 */
- {
- { unicode_latin1 },
- 0, /* no name-based mapping */
- "latin1",
- "works for most of the Western languages",
- { "en_", "de_", "fr_", "nl_", "no_", "da_", "it_" },
- 'A'
- },
- { /* by Szalay Tamas <tomek@elender.hu> */
- { unicode_latin2 },
- 0, /* no name-based mapping */
- "latin2",
- "works for Central European languages",
- { "hu_","pl_","cz_","si_","sk_" },
- 'A'
- },
- { /* by Rièardas Èepas <rch@WriteMe.Com> */
- { unicode_latin4 },
- 0, /* no name-based mapping */
- "latin4",
- "works for Baltic languages",
- { "lt_", "lv_" }, /* doubt about ee_ */
- 'A'
- },
- { /* by Turgut Uyar <uyar@cs.itu.edu.tr> */
- { unicode_latin5 },
- 0, /* no name-based mapping */
- "latin5",
- "for Turkish",
- { "tr_" },
- 'A'
- },
- { /* by Zvezdan Petkovic <z.petkovic@computer.org> */
- { unicode_cyrillic, unicode_latin1 },
- 0, /* no name-based mapping */
- "cyrillic",
- "in Windows encoding",
- { "bg_", "be_", "mk_", "ru_", "sr_", "su_", "uk_" },
- 'A'
- },
- {
- { unicode_cyrillic, unicode_latin1 },
- 0, /* no name-based mapping */
- "russian",
- "obsolete, use cyrillic instead",
- { 0 },
- 'A'
- },
- {
- { unicode_cyrillic, unicode_latin1 },
- 0, /* no name-based mapping */
- "bulgarian",
- "obsolete, use cyrillic instead",
- { 0 },
- 'A'
- },
- {
- { unicode_adobestd },
- unicode_adobestd_byname,
- "adobestd",
- "Adobe Standard, expected by TeX",
- { NULL },
- 'A'
- },
- {
- { unicode_plane },
- 0, /* no name-based mapping */
- "plane",
- "one plane of Unicode or other multi-byte encoding as is",
- { NULL },
- 0 /* no easy way to predict the capital letters */
- },
-};
-
-static struct uni_language uni_lang_user = {
- { unicode_init_user },
- 0, /* no name-based mapping */
- 0, /* no name */
- 0, /* no description */
- { 0 },
- 0 /* no sample */
-};
-
-static struct uni_language *uni_lang_selected=0; /* 0 means "unknown, try all" */
-static int uni_sample='A'; /* sample of an uppercase character */
-static char *uni_lang_arg=""; /* user-supplied language-dependent argument */
-
-extern int runt1asm(int);
-
-/*
- * user-defined loadable maps
- */
-
-
-/* The idea begind buckets is to avoid comparing every code with all ENCTABSZ codes in table.
- * All the 16-bit unicode space is divided between a number of equal-sized buckets.
- * Initially all the buckets are marked with 0. Then if any code in the bucket is
- * used it's marked with 1. Later during translation we check the code's bucket first
- * and it it's 0 then return failure right away. This may be useful for
- * Chinese fonts with many thousands of glyphs.
- */
-
-#define BUCKET_ID_BITS 11
-#define MARK_UNI_BUCKET(unicode) SET_BITMAP(uni_user_buckets, (unicode)>>(16-BUCKET_ID_BITS))
-#define IS_UNI_BUCKET(unicode) IS_BITMAP(uni_user_buckets, (unicode)>>(16-BUCKET_ID_BITS))
-
-static DEF_BITMAP(uni_user_buckets, 1<<BUCKET_ID_BITS);
-
-static unsigned int unicode_map[ENCTABSZ]; /* font-encoding to unicode map */
-static int enctabsz = 256; /* actual number of codes used */
-
-static void
-unicode_init_user(
- char *path
-)
-{
- FILE *unicode_map_file;
-#define UNIBFSZ 256
- char buffer[UNIBFSZ];
- unsigned code, unicode, curpos, unicode2;
- char *arg, *p;
- int enabled, found, sawplane;
- int lineno, cnt, n, nchars;
- char next;
- int pid, eid, overid=0;
-
- /* check if we have an argument (plane name) */
- arg = strrchr(path, LANG_ARG_SEP);
- if(arg != 0) {
- *arg++ = 0;
- if( sscanf(arg, "pid=%d,eid=%d%n", &pid, &eid, &nchars) == 2 ) {
- force_pid = pid; force_eid = eid; overid = 1;
- WARNING_1 fprintf(stderr, "User override of the source encoding: pid=%d eid=%d\n", pid, eid);
- forcemap = 1;
- arg += nchars;
- if(*arg == ',')
- arg++;
- }
- if( *arg == 0 || strlen(arg) > UNI_MAX_SUFFIX_LEN-1)
- arg = NULL;
- else {
- sprintf(uni_suffix_buf, "-%s", arg);
- uni_font_name_suffix = uni_suffix_buf;
- }
- }
-
- /* now read in the encoding description file, if requested */
- if ((unicode_map_file = fopen(path, "r")) == NULL) {
- fprintf(stderr, "**** Cannot access map file '%s' ****\n", path);
- exit(1);
- }
-
- sawplane = 0;
- if(arg==NULL)
- enabled = found = 1;
- else
- enabled = found = 0;
-
- lineno=0; curpos=0;
- while (fgets (buffer, UNIBFSZ, unicode_map_file) != NULL) {
- char name[UNIBFSZ];
-
- lineno++;
-
- if(sscanf(buffer, "plane %s", name)==1) {
- sawplane = 1;
- if(arg == 0) {
- fprintf(stderr, "**** map file '%s' requires plane name\n", path);
- fprintf(stderr, "for example:\n");
- fprintf(stderr, " ttf2pt1 -L %s%c[pid=N,eid=N,]%s ...\n",
- path, LANG_ARG_SEP, name);
- fprintf(stderr, "to select plane '%s'\n", name);
- exit(1);
- }
- if( !strcmp(arg, name) ) {
- enabled = found = 1;
- curpos = 0;
- } else {
- enabled = 0;
- if(found) /* no need to read further */
- break;
- }
- continue;
- }
-
- if(sscanf(buffer, "id %d %d", &pid, &eid)==2) {
- if( !overid /* only if the user has not overriden */
- && (enabled || !sawplane) ) {
- force_pid = pid; force_eid = eid;
- forcemap = 1;
- }
- continue;
- }
-
- if( !enabled )
- continue; /* skip to the next plane */
-
- if( sscanf(buffer, "at %i", &curpos) == 1 ) {
- if(curpos > 255) {
- fprintf(stderr, "**** map file '%s' line %d: code over 255\n", path, lineno);
- exit(1);
- }
- if(ISDBG(EXTMAP)) fprintf(stderr, "=== at 0x%x\n", curpos);
- continue;
- }
-
- /* try the format of Roman Czyborra's files */
- if ( sscanf (buffer, " =%x U+%4x", &code, &unicode) == 2
- /* try the format of Linux locale charmap file */
- || sscanf (buffer, " <%*s /x%x <U%4x>", &code, &unicode) == 2 ) {
- if (code < ENCTABSZ) {
- if(code >= enctabsz) enctabsz=code+1;
- unicode_map[code] = unicode;
- glyph_rename[code] = NULL;
- }
- }
- /* try the format with glyph renaming */
- else if (sscanf (buffer, " !%x U+%4x %128s", &code,
- &unicode, name) == 3) {
- if (code < ENCTABSZ) {
- if(code >= enctabsz) enctabsz=code+1;
- unicode_map[code] = unicode;
- glyph_rename[code] = strdup(name);
- }
- }
- /* try the compact sequence format */
- else if( (n=sscanf(buffer, " %i%n", &unicode, &cnt)) == 1 ) {
- p = buffer;
- do {
- if(curpos > 255) {
- fprintf(stderr, "**** map file '%s' line %d: code over 255 for unicode 0x%x\n",
- path, lineno, unicode);
- exit(1);
- }
- if(ISDBG(EXTMAP)) fprintf(stderr, "=== 0x%d -> 0x%x\n", curpos, unicode);
- unicode_map[curpos++] = unicode;
- p += cnt;
- if( sscanf(p, " %[,-]%n", &next,&cnt) == 1 ) {
- if(ISDBG(EXTMAP)) fprintf(stderr, "=== next: '%c'\n", next);
- p += cnt;
- if( next == '-' ) { /* range */
- if ( sscanf(p, " %i%n", &unicode2, &cnt) != 1 ) {
- fprintf(stderr, "**** map file '%s' line %d: missing end of range\n", path, lineno);
- exit(1);
- }
- p += cnt;
- if(ISDBG(EXTMAP)) fprintf(stderr, "=== range 0x%x to 0x%x\n", unicode, unicode2);
- for(unicode++; unicode <= unicode2; unicode++) {
- if(curpos > 255) {
- fprintf(stderr, "**** map file '%s' line %d: code over 255 in unicode range ...-0x%x\n",
- path, lineno, unicode2);
- exit(1);
- }
- if(ISDBG(EXTMAP)) fprintf(stderr, "=== 0x%x -> 0x%x\n", curpos, unicode);
- unicode_map[curpos++] = unicode;
- }
- }
- }
- } while ( sscanf(p, " %i%n", &unicode, &cnt) == 1 );
- }
-
- }
-
- fclose (unicode_map_file);
-
- if( !found ) {
- fprintf(stderr, "**** map file '%s' has no plane '%s'\n", path, arg);
- exit(1);
- }
-
- if(unicode_map['A'] == 'A')
- uni_sample = 'A'; /* seems to be compatible with Latin */
- else
- uni_sample = 0; /* don't make any assumptions */
-}
-
-/*
- * by Zvezdan Petkovic <z.petkovic@computer.org>
- */
-static void
-unicode_cyrillic(
- char *arg
-)
-{
- int i;
- static unsigned int cyrillic_unicode_map[] = {
- 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, /* 80 */
- 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, /* 88 */
- 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, /* 90 */
- 0x02dc, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, /* 98 */
- 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, /* A0 */
- 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, /* A8 */
- 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, /* B0 */
- 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, /* B8 */
- };
-
- for(i=0; i<=0x7F; i++)
- unicode_map[i] = i;
-
- for(i=0x80; i<=0xBF; i++)
- unicode_map[i] = cyrillic_unicode_map[i-0x80];
-
- for(i=0xC0; i<=0xFF; i++)
- unicode_map[i] = i+0x350;
-
-}
-
-static void
-unicode_latin1(
- char *arg
-)
-{
- int i;
- static unsigned int latin1_unicode_map[] = {
- 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, /* 80 */
- 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x017d, 0x008f, /* 88 */
- 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, /* 90 */
- 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x017e, 0x0178, /* 98 */
- };
-
- for(i=0; i<=0x7F; i++)
- unicode_map[i] = i;
-
- for(i=0x80; i<=0x9F; i++)
- unicode_map[i] = latin1_unicode_map[i-0x80];
-
- for(i=0xA0; i<=0xFF; i++)
- unicode_map[i] = i;
-}
-
-static void
-unicode_adobestd(
- char *arg
-)
-{
- int i;
- static unsigned int adobestd_unicode_map[] = {
- -1, 0x00a1, 0x00a2, 0x00a3, 0x2215, 0x00a5, 0x0192, 0x00a7, /* A0 */
- 0x00a4, 0x0027, 0x201c, 0x00ab, 0x2039, 0x203a, 0xfb01, 0xfb02, /* A8 */
- -1, 0x2013, 0x2020, 0x2021, 0x2219, -1, 0x00b6, 0x2022, /* B0 */
- 0x201a, 0x201e, 0x201d, 0x00bb, 0x2026, 0x2030, -1, 0x00bf, /* B8 */
- -1, 0x0060, 0x00b4, 0x02c6, 0x02dc, 0x02c9, 0x02d8, 0x02d9, /* C0 */
- 0x00a8, -1, 0x02da, 0x00b8, -1, 0x02dd, 0x02db, 0x02c7, /* C8 */
- 0x2014, -1, -1, -1, -1, -1, -1, -1, /* D0 */
- -1, -1, -1, -1, -1, -1, -1, -1, /* D8 */
- -1, 0x00c6, -1, 0x00aa, -1, -1, -1, -1, /* E0 */
- 0x0141, 0x00d8, 0x0152, 0x00ba, -1, -1, -1, -1, /* E8 */
- -1, 0x00e6, -1, -1, -1, 0x0131, -1, -1, /* F0 */
- 0x0142, 0x00f8, 0x0153, 0x00df, -1, -1, -1, -1, /* F8 */
- };
-
- for(i=0; i<=0x7F; i++)
- unicode_map[i] = i;
-
- unicode_map[0x27] = 0x2019;
- unicode_map[0x60] = -1;
-
- /* 0x80 to 0x9F is a hole */
-
- for(i=0xA0; i<=0xFF; i++)
- unicode_map[i] = adobestd_unicode_map[i-0xA0];
-}
-
-/*
- * Not all of the Adobe glyphs are in the Unicode
- * standard maps, so the font creators have
- * different ideas about their codes. Because
- * of this we try to map based on the glyph
- * names instead of Unicode codes. If there are
- * no glyph names (ps_fmt_3!=0) we fall back
- * to the code-based scheme.
- */
-
-static int
-unicode_adobestd_byname(
- char *name,
- char *arg,
- int where
-)
-{
- int i;
-
- /* names always take precedence over codes */
- if(where == UNICONV_BYNAME_AFTER)
- return -1;
-
- for(i=32; i<256; i++) {
- if(!strcmp(name, adobe_StandardEncoding[i]))
- return i;
- }
- return -1;
-
-}
-
-static void
-unicode_latin2(
- char *arg
-)
-{
- int i;
- static unsigned int latin2_unicode_map[] = {
- 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, /* A0 */
- 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, /* A8 */
- 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, /* B0 */
- 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* B8 */
- 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, /* C0 */
- 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, /* C8 */
- 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, /* D0 */
- 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, /* D8 */
- 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, /* E0 */
- 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, /* E8 */
- 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, /* F0 */
- 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9, /* F8 */
- };
-
- for(i=0; i<=0x7E; i++)
- unicode_map[i] = i;
-
- /* 7F-9F are unused */
-
- for(i=0xA0; i<=0xFF; i++)
- unicode_map[i] = latin2_unicode_map[i-0xA0];
-}
-
-static void
-unicode_latin4(
- char *arg
-)
-{
- int i;
- static unsigned int latin4_unicode_map[] = {
- 0x0080, 0x0081, 0x201a, 0x0192, -1, 0x2026, 0x2020, 0x2021, /* 80 */
- 0x02c6, 0x2030, -1, 0x2039, 0x0152, 0x008d, 0x008e, 0x008f, /* 88 */
- 0x201e, 0x201c, 0x2019, -1, 0x201d, 0x2022, 0x2013, 0x2014, /* 90 */
- 0x02dc, 0x2122, -1, 0x203a, 0x0153, 0x009d, 0x009e, 0x0178, /* 98 */
- 0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7, /* A0 */
- 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, /* A8 */
- 0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, /* B0 */
- 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b, /* B8 */
- 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, /* C0 */
- 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a, /* C8 */
- 0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, /* D0 */
- 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df, /* D8 */
- 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, /* E0 */
- 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, /* E8 */
- 0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, /* F0 */
- 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9, /* F8 */
- };
-
- for(i=0; i<=0x7F; i++)
- unicode_map[i] = i;
-
- for(i=0x80; i<=0xFF; i++)
- unicode_map[i] = latin4_unicode_map[i-0x80];
-
-#if 0 /* for documentation purposes only */
- case 0x201e: return 0x90; /* these two quotes are a hack only */
- case 0x201c: return 0x91; /* these two quotes are a hack only */
- case 0x00A0: return 0xA0; /* NO-BREAK SPACE */
- case 0x0104: return 0xA1; /* LATIN CAPITAL LETTER A WITH OGONEK */
- case 0x0138: return 0xA2; /* LATIN SMALL LETTER KRA */
- case 0x0156: return 0xA3; /* LATIN CAPITAL LETTER R WITH CEDILLA */
- case 0x00A4: return 0xA4; /* CURRENCY SIGN */
- case 0x0128: return 0xA5; /* LATIN CAPITAL LETTER I WITH TILDE */
- case 0x013B: return 0xA6; /* LATIN CAPITAL LETTER L WITH CEDILLA */
- case 0x00A7: return 0xA7; /* SECTION SIGN */
- case 0x00A8: return 0xA8; /* DIAERESIS */
- case 0x0160: return 0xA9; /* LATIN CAPITAL LETTER S WITH CARON */
- case 0x0112: return 0xAA; /* LATIN CAPITAL LETTER E WITH MACRON */
- case 0x0122: return 0xAB; /* LATIN CAPITAL LETTER G WITH CEDILLA */
- case 0x0166: return 0xAC; /* LATIN CAPITAL LETTER T WITH STROKE */
- case 0x00AD: return 0xAD; /* SOFT HYPHEN */
- case 0x017D: return 0xAE; /* LATIN CAPITAL LETTER Z WITH CARON */
- case 0x00AF: return 0xAF; /* MACRON */
- case 0x00B0: return 0xB0; /* DEGREE SIGN */
- case 0x0105: return 0xB1; /* LATIN SMALL LETTER A WITH OGONEK */
- case 0x02DB: return 0xB2; /* OGONEK */
- case 0x0157: return 0xB3; /* LATIN SMALL LETTER R WITH CEDILLA */
- case 0x00B4: return 0xB4; /* ACUTE ACCENT */
- case 0x0129: return 0xB5; /* LATIN SMALL LETTER I WITH TILDE */
- case 0x013C: return 0xB6; /* LATIN SMALL LETTER L WITH CEDILLA */
- case 0x02C7: return 0xB7; /* CARON */
- case 0x00B8: return 0xB8; /* CEDILLA */
- case 0x0161: return 0xB9; /* LATIN SMALL LETTER S WITH CARON */
- case 0x0113: return 0xBA; /* LATIN SMALL LETTER E WITH MACRON */
- case 0x0123: return 0xBB; /* LATIN SMALL LETTER G WITH CEDILLA */
- case 0x0167: return 0xBC; /* LATIN SMALL LETTER T WITH STROKE */
- case 0x014A: return 0xBD; /* LATIN CAPITAL LETTER ENG */
- case 0x017E: return 0xBE; /* LATIN SMALL LETTER Z WITH CARON */
- case 0x014B: return 0xBF; /* LATIN SMALL LETTER ENG */
- case 0x0100: return 0xC0; /* LATIN CAPITAL LETTER A WITH MACRON */
- case 0x00C1: return 0xC1; /* LATIN CAPITAL LETTER A WITH ACUTE */
- case 0x00C2: return 0xC2; /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
- case 0x00C3: return 0xC3; /* LATIN CAPITAL LETTER A WITH TILDE */
- case 0x00C4: return 0xC4; /* LATIN CAPITAL LETTER A WITH DIAERESIS */
- case 0x00C5: return 0xC5; /* LATIN CAPITAL LETTER A WITH RING ABOVE */
- case 0x00C6: return 0xC6; /* LATIN CAPITAL LIGATURE AE */
- case 0x012E: return 0xC7; /* LATIN CAPITAL LETTER I WITH OGONEK */
- case 0x010C: return 0xC8; /* LATIN CAPITAL LETTER C WITH CARON */
- case 0x00C9: return 0xC9; /* LATIN CAPITAL LETTER E WITH ACUTE */
- case 0x0118: return 0xCA; /* LATIN CAPITAL LETTER E WITH OGONEK */
- case 0x00CB: return 0xCB; /* LATIN CAPITAL LETTER E WITH DIAERESIS */
- case 0x0116: return 0xCC; /* LATIN CAPITAL LETTER E WITH DOT ABOVE */
- case 0x00CD: return 0xCD; /* LATIN CAPITAL LETTER I WITH ACUTE */
- case 0x00CE: return 0xCE; /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
- case 0x012A: return 0xCF; /* LATIN CAPITAL LETTER I WITH MACRON */
- case 0x0110: return 0xD0; /* LATIN CAPITAL LETTER D WITH STROKE */
- case 0x0145: return 0xD1; /* LATIN CAPITAL LETTER N WITH CEDILLA */
- case 0x014C: return 0xD2; /* LATIN CAPITAL LETTER O WITH MACRON */
- case 0x0136: return 0xD3; /* LATIN CAPITAL LETTER K WITH CEDILLA */
- case 0x00D4: return 0xD4; /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
- case 0x00D5: return 0xD5; /* LATIN CAPITAL LETTER O WITH TILDE */
- case 0x00D6: return 0xD6; /* LATIN CAPITAL LETTER O WITH DIAERESIS */
- case 0x00D7: return 0xD7; /* MULTIPLICATION SIGN */
- case 0x00D8: return 0xD8; /* LATIN CAPITAL LETTER O WITH STROKE */
- case 0x0172: return 0xD9; /* LATIN CAPITAL LETTER U WITH OGONEK */
- case 0x00DA: return 0xDA; /* LATIN CAPITAL LETTER U WITH ACUTE */
- case 0x00DB: return 0xDB; /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
- case 0x00DC: return 0xDC; /* LATIN CAPITAL LETTER U WITH DIAERESIS */
- case 0x0168: return 0xDD; /* LATIN CAPITAL LETTER U WITH TILDE */
- case 0x016A: return 0xDE; /* LATIN CAPITAL LETTER U WITH MACRON */
- case 0x00DF: return 0xDF; /* LATIN SMALL LETTER SHARP S */
- case 0x0101: return 0xE0; /* LATIN SMALL LETTER A WITH MACRON */
- case 0x00E1: return 0xE1; /* LATIN SMALL LETTER A WITH ACUTE */
- case 0x00E2: return 0xE2; /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
- case 0x00E3: return 0xE3; /* LATIN SMALL LETTER A WITH TILDE */
- case 0x00E4: return 0xE4; /* LATIN SMALL LETTER A WITH DIAERESIS */
- case 0x00E5: return 0xE5; /* LATIN SMALL LETTER A WITH RING ABOVE */
- case 0x00E6: return 0xE6; /* LATIN SMALL LIGATURE AE */
- case 0x012F: return 0xE7; /* LATIN SMALL LETTER I WITH OGONEK */
- case 0x010D: return 0xE8; /* LATIN SMALL LETTER C WITH CARON */
- case 0x00E9: return 0xE9; /* LATIN SMALL LETTER E WITH ACUTE */
- case 0x0119: return 0xEA; /* LATIN SMALL LETTER E WITH OGONEK */
- case 0x00EB: return 0xEB; /* LATIN SMALL LETTER E WITH DIAERESIS */
- case 0x0117: return 0xEC; /* LATIN SMALL LETTER E WITH DOT ABOVE */
- case 0x00ED: return 0xED; /* LATIN SMALL LETTER I WITH ACUTE */
- case 0x00EE: return 0xEE; /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
- case 0x012B: return 0xEF; /* LATIN SMALL LETTER I WITH MACRON */
- case 0x0111: return 0xF0; /* LATIN SMALL LETTER D WITH STROKE */
- case 0x0146: return 0xF1; /* LATIN SMALL LETTER N WITH CEDILLA */
- case 0x014D: return 0xF2; /* LATIN SMALL LETTER O WITH MACRON */
- case 0x0137: return 0xF3; /* LATIN SMALL LETTER K WITH CEDILLA */
- case 0x00F4: return 0xF4; /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
- case 0x00F5: return 0xF5; /* LATIN SMALL LETTER O WITH TILDE */
- case 0x00F6: return 0xF6; /* LATIN SMALL LETTER O WITH DIAERESIS */
- case 0x00F7: return 0xF7; /* DIVISION SIGN */
- case 0x00F8: return 0xF8; /* LATIN SMALL LETTER O WITH STROKE */
- case 0x0173: return 0xF9; /* LATIN SMALL LETTER U WITH OGONEK */
- case 0x00FA: return 0xFA; /* LATIN SMALL LETTER U WITH ACUTE */
- case 0x00FB: return 0xFB; /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
- case 0x00FC: return 0xFC; /* LATIN SMALL LETTER U WITH DIAERESIS */
- case 0x0169: return 0xFD; /* LATIN SMALL LETTER U WITH TILDE */
- case 0x016B: return 0xFE; /* LATIN SMALL LETTER U WITH MACRON */
- case 0x02D9: return 0xFF; /* DOT ABOVE */
-#endif
-}
-
-static void
-unicode_latin5(
- char *arg
-)
-{
- int i;
- static unsigned int latin5_unicode_map1[] = {
- 0x0080, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, /* 80 */
- 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x008e, 0x008f, /* 88 */
- 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, /* 90 */
- 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x009e, 0x0178, /* 98 */
- };
- static unsigned int latin5_unicode_map2[] = {
- 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, /* D0 */
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, /* D8 */
- 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, /* E0 direct */
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, /* E8 direct */
- 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, /* F0 */
- 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff, /* F8 */
- };
-
- for(i=0; i<=0x7F; i++)
- unicode_map[i] = i;
-
- for(i=0x80; i<=0x9F; i++)
- unicode_map[i] = latin5_unicode_map1[i-0x80];
-
- for(i=0xA0; i<=0xCF; i++)
- unicode_map[i] = i;
-
- for(i=0xD0; i<=0xFF; i++)
- unicode_map[i] = latin5_unicode_map2[i-0xD0];
-}
-
-/* a way to select one 256-character plane from Unicode
- * or other multi-byte encoding
- */
-
-static void
-unicode_plane(
- char *arg
-)
-{
- static unsigned plane;
- int nchars;
- int c1, c2, i;
-
- if(uni_lang_selected == 0)
- return; /* don't participate in auto-guessing */
-
- plane = 0; force_pid = force_eid = -1;
-
- c1 = sscanf(arg, "pid=%d,eid=%d%n", &force_pid, &force_eid, &nchars);
- if(c1 == 2) {
- arg += nchars;
- if(*arg == ',')
- arg++;
- }
- if(arg[0] == '0' && (arg[1]=='x' || arg[1]=='X') ) {
- arg += 2;
- c2 = sscanf(arg, "%x", &plane);
- } else {
- c2 = sscanf(arg, "%d", &plane);
- }
-
- if( (c1!=2 && c1!=0) || (c1==0 && c2==0) ) {
- fprintf(stderr, "**** option -l plane expects one of the following formats:\n");
- fprintf(stderr, " -l plane+0xNN - select hexadecimal number of plane of Unicode\n");
- fprintf(stderr, " -l plane+NN - select decimal number of plane of Unicode\n");
- fprintf(stderr, " -l plane+pid=N,eid=N - select plane 0 of specified encoding\n");
- fprintf(stderr, " -l plane+pid=N,eid=N,0xNN - select hex plane of TTF encoding with this PID/EID\n");
- fprintf(stderr, " -l plane+pid=N,eid=N,NN - select decimal plane of TTF encoding with this PID/EID\n");
- exit(1);
- }
-
- if(c2!=0) {
- if(strlen(arg) > sizeof(uni_suffix_buf)-2) {
- fprintf(stderr, "**** plane number is too large\n");
- }
-
- sprintf(uni_suffix_buf, "-%s", arg);
- uni_font_name_suffix = uni_suffix_buf;
- } else {
- uni_font_name_suffix = "";
- }
-
- plane <<= 8;
- for(i=0; i<=0xFF; i++)
- unicode_map[i] = plane | i;
-}
-
-/* look up the 8-bit code by unicode */
-
-int
-unicode_rev_lookup(
- int unival
-)
-{
- int res;
-
- if( ! IS_UNI_BUCKET(unival) )
- return -1;
-
- for (res = 0; res < enctabsz; res++)
- if (unicode_map[res] == unival)
- return res;
- return -1;
-}
-
-/* mark the buckets for quick lookup */
-
-static void
-unicode_prepare_buckets(
- void
-)
-{
- int i;
-
- memset(uni_user_buckets, 0, sizeof uni_user_buckets);
- for(i=0; i<enctabsz; i++) {
- if(unicode_map[i] != (unsigned) -1)
- MARK_UNI_BUCKET(unicode_map[i]);
- }
-}
-
-/*
- * When we print errors about bad names we want to print these names in
- * some decent-looking form
- */
-
-static char *
-nametoprint(
- unsigned char *s
-)
-{
- static char res[50];
- int c, i;
-
- for(i=0; ( c =* s )!=0 && i<sizeof(res)-8; s++) {
- if(c < ' ' || c > 126) {
- sprintf(res+i, "\\x%02X", c);
- i+=4;
- } else {
- res[i++] = c;
- }
- }
- if(*s != 0) {
- res[i++] = '.';
- res[i++] = '.';
- res[i++] = '.';
- }
- res[i++] = 0;
- return res;
-}
-
-/*
- * Scale the values according to the scale_factor
- */
-
-double
-fscale(
- double val
-)
-{
- return scale_factor * val;
-}
-
-int
-iscale(
- int val
-)
-{
- return (int) (val > 0 ? scale_factor * val + 0.5
- : scale_factor * val - 0.5);
-}
-
-/*
- * Try to force fixed width of characters
- */
-
-static void
-alignwidths(void)
-{
- int i;
- int n = 0, avg, max = 0, min = 3000, sum = 0, x;
-
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED) {
- x = glyph_list[i].width;
-
- if (x != 0) {
- if (x < min)
- min = x;
- if (x > max)
- max = x;
-
- sum += x;
- n++;
- }
- }
- }
-
- if (n == 0)
- return;
-
- avg = sum / n;
-
- WARNING_3 fprintf(stderr, "widths: max=%d avg=%d min=%d\n", max, avg, min);
-
- /* if less than 5% variation from average */
- /* force fixed width */
- if (20 * (avg - min) < avg && 20 * (max - avg) < avg) {
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED)
- glyph_list[i].width = avg;
- }
- fontm.is_fixed_pitch = 1;
- }
-}
-
-static void
-convert_glyf(
- int glyphno
-)
-{
- GLYPH *g;
- int ncurves;
-
- g = &glyph_list[glyphno];
-
-
- g->scaledwidth = iscale(g->width);
-
- g->entries = 0;
- g->lastentry = 0;
- g->path = 0;
- if (g->ttf_pathlen != 0) {
- cursw->glpath(glyphno, glyph_list);
- g->lastentry = 0;
-
- if(ISDBG(BUILDG))
- dumppaths(g, NULL, NULL);
-
- assertpath(g->entries, __FILE__, __LINE__, g->name);
-
- fclosepaths(g);
- assertpath(g->entries, __FILE__, __LINE__, g->name);
-
- /* float processing */
- if(smooth) {
- ffixquadrants(g);
- assertpath(g->entries, __FILE__, __LINE__, g->name);
-
- fsplitzigzags(g);
- assertpath(g->entries, __FILE__, __LINE__, g->name);
-
- fforceconcise(g);
- assertpath(g->entries, __FILE__, __LINE__, g->name);
-
- fstraighten(g);
- assertpath(g->entries, __FILE__, __LINE__, g->name);
- }
-
- pathtoint(g);
- /* all processing past this point expects integer path */
- assertpath(g->entries, __FILE__, __LINE__, g->name);
-
-#if 0
- fixcontours(g);
- testfixcvdir(g);
-#endif
-
- /* int processing */
- if (smooth) {
- smoothjoints(g);
- assertpath(g->entries, __FILE__, __LINE__, g->name);
- }
-
- ncurves = 0;
- {
- GENTRY *ge;
- for(ge = g->entries; ge; ge = ge->next)
- ncurves++;
- }
- if (ncurves > 200) {
- WARNING_3 fprintf(stderr,
- "** Glyph %s is too long, may display incorrectly\n",
- g->name);
- }
- } else {
- /* for buildstems */
- g->flags &= ~GF_FLOAT;
- }
-}
-
-static void
-handle_gnames(void)
-{
- int i, n, found, c, type;
-
- /* get the names from the font file */
- ps_fmt_3 = cursw->glnames(glyph_list);
-
-/* These checks are not required by Xprt's PS DDX... */
-#ifndef XP_PSTEXT
- /* check for names with wrong characters */
- for (n = 0; n < numglyphs; n++) {
- int c;
- for (i = 0; (c = glyph_list[n].name[i]) != 0; i++) {
- if (!(isalnum(c) || c == '.' || c == '_' || c == '-')
- || i==0 && isdigit(c)) { /* must not start with a digit */
- WARNING_3 fprintf(stderr, "Glyph %d %s (%s), ",
- n, isdigit(c) ? "name starts with a digit" :
- "has bad characters in name",
- nametoprint(glyph_list[n].name));
- glyph_list[n].name = malloc(16);
- sprintf(glyph_list[n].name, "_b_%d", n);
- WARNING_3 fprintf(stderr, "changing to %s\n", glyph_list[n].name);
- break;
- }
- }
- }
-
- if( !ps_fmt_3 ) {
- /* check for duplicate names */
- for (n = 0; n < numglyphs; n++) {
- found = 0;
- for (i = 0; i < n && !found; i++) {
- if (strcmp(glyph_list[i].name, glyph_list[n].name) == 0) {
- if (( glyph_list[n].name = malloc(16) )==0) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- sprintf(glyph_list[n].name, "_d_%d", n);
-
- /* if the font has no names in it (what the native parser
- * recognises as ps_fmt_3), FreeType returns all the
- * names as .notdef, so don't complain in this case
- */
- if(strcmp(glyph_list[i].name, ".notdef")) {
- WARNING_3 fprintf(stderr,
- "Glyph %d has the same name as %d: (%s), changing to %s\n",
- n, i,
- glyph_list[i].name,
- glyph_list[n].name);
- }
- found = 1;
- }
- }
- }
-
- }
-#endif /* !XP_PSTEXT */
-
- /* start the encoding stuff */
- for (i = 0; i < ENCTABSZ; i++) {
- encoding[i] = -1;
- }
-
- /* do the 1st round of encoding by name */
- if(!ps_fmt_3 && uni_lang_selected && uni_lang_selected->convbyname) {
- for (n = 0; n < numglyphs; n++) {
- c = uni_lang_selected->convbyname(glyph_list[n].name,
- uni_lang_arg, UNICONV_BYNAME_BEFORE);
- if(c>=0 && c<ENCTABSZ && encoding[c] == -1)
- encoding[c] = n;
- }
- }
-
- /* now do the encoding by table */
- if(uni_lang_selected) {
- for(i=0; i < MAXUNITABLES && uni_lang_selected->init[i]; i++) {
- for (n = 0; n < ENCTABSZ; n++)
- unicode_map[n] = -1;
- uni_lang_selected->init[i](uni_lang_arg);
- unicode_prepare_buckets();
- type = cursw->glenc(glyph_list, encoding, unicode_map);
- if( type == 0 )
- /* if we have an 8-bit encoding we don't need more tries */
- break;
- }
- } else {
- /* language is unknown, try the first table of each */
- for(i=0; i < sizeof uni_lang/(sizeof uni_lang[0]); i++) {
- if(uni_lang[i].init[0] == NULL)
- continue;
- for (n = 0; n < ENCTABSZ; n++)
- unicode_map[n] = -1;
- uni_lang[i].init[0](uni_lang_arg);
- unicode_prepare_buckets();
- type = cursw->glenc(glyph_list, encoding, unicode_map);
- if( type == 0 )
- /* if we have an 8-bit encoding we don't need more tries */
- break;
- }
- }
-
- if (ps_fmt_3) {
- /* get rid of the old names, they are all "UNKNOWN" anyawy */
- for (i = 0; i < numglyphs; i++) {
- glyph_list[i].name = 0;
- }
- if(type == 0) {
- /* 8-bit - give 8859/1 names to the first 256 glyphs */
- for (i = 0; i < 256; i++) { /* here 256, not ENCTABSZ */
- if (encoding[i] > 0) {
- glyph_list[encoding[i]].name = Fmt3Encoding[i];
- }
- }
- } else if(type == 1) {
- /* Unicode - give 8859/1 names to the first 256 glyphs of Unicode */
- for (n = 0; n < 256; n++) { /* here 256, not ENCTABSZ */
- i = unicode_rev_lookup(n);
- if (i>=0 && encoding[i] > 0) {
- glyph_list[encoding[i]].name = Fmt3Encoding[i];
- }
- }
- } /* for other types of encodings just give generated names */
- /* assign unique names to the rest of the glyphs */
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].name == 0) {
- if (( glyph_list[i].name = malloc(16) )==0) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- sprintf(glyph_list[i].name, "_d_%d", i);
- }
- }
- }
-
- /* do the 2nd round of encoding by name */
- if(uni_lang_selected && uni_lang_selected->convbyname) {
- for (n = 0; n < numglyphs; n++) {
- c = uni_lang_selected->convbyname(glyph_list[n].name,
- uni_lang_arg, UNICONV_BYNAME_AFTER);
- if(c>=0 && c<ENCTABSZ && encoding[c] == -1)
- encoding[c] = n;
- }
- }
- /* all the encoding things are done */
-
- for (i = 0; i < ENCTABSZ; i++)
- if(encoding[i] == -1) {
- /* check whether this character might be a duplicate
- * (in which case it would be missed by unicode_rev_lookup())
- */
- c = unicode_map[i];
- if((type != 0 || forcemap) && c != -1) {
- for(n = 0; n < i; n++) {
- if(unicode_map[n] == c) {
- encoding[i] = encoding[n];
- }
- }
- }
- if(encoding[i] == -1) /* still not found, defaults to .notdef */
- encoding[i] = 0;
- }
-
- for (i = 0; i < 256; i++) /* here 256, not ENCTABSZ */
- glyph_list[encoding[i]].char_no = i;
-
-#ifndef XP_PSTEXT
- /* enforce two special cases defined in TTF manual */
- if(numglyphs > 0)
- glyph_list[0].name = ".notdef";
- if(numglyphs > 1)
- glyph_list[1].name = ".null";
-#endif /* !XP_PSTEXT */
-
- for (i = 0; i < ENCTABSZ; i++) {
- if ((encoding[i] != 0) && glyph_rename[i]) {
- glyph_list[encoding[i]].name = glyph_rename[i];
- }
- }
-}
-
-static void
-usage(void)
-{
-
-#ifdef XP_PSTEXT
- fputs("ft2pt1: Internal startup error\n", stderr);
-#else
-
-#ifdef _GNU_SOURCE
-# define fplop(txt) fputs(txt, stderr);
-#else
-# define fplop(txt)
-#endif
-
- fputs("Use:\n", stderr);
- fputs("ttf2pt1 [-<opts>] [-l language | -L file] <ttf-file> [<fontname>]\n", stderr);
- fputs(" or\n", stderr);
- fputs("ttf2pt1 [-<opts>] [-l language | -L file] <ttf-file> -\n", stderr);
- fputs(" or\n", stderr);
- fputs("ttf2pt1 [-<opts>] [-l language | -L file] <ttf-file> - | t1asm > <pfa-file>\n", stderr);
-
- fplop("\n");
- fplop("This build supports both short and long option names,\n");
- fplop("the long options are listed before corresponding short ones\n");
-
- fplop(" --all-glyphs\n");
- fputs(" -a - include all glyphs, even those not in the encoding table\n", stderr);
- fplop(" --pfb\n");
- fputs(" -b - produce a compressed .pfb file\n", stderr);
- fplop(" --debug dbg_suboptions\n");
- fputs(" -d dbg_suboptions - debugging options, run ttf2pt1 -d? for help\n", stderr);
- fplop(" --encode\n");
- fputs(" -e - produce a fully encoded .pfa file\n", stderr);
- fplop(" --force-unicode\n");
- fputs(" -F - force use of Unicode encoding even if other MS encoding detected\n", stderr);
- fplop(" --generate suboptions\n");
- fputs(" -G suboptions - control the file generation, run ttf2pt1 -G? for help\n", stderr);
- fplop(" --language language\n");
- fputs(" -l language - convert Unicode to specified language, run ttf2pt1 -l? for list\n", stderr);
- fplop(" --language-map file\n");
- fputs(" -L file - convert Unicode according to encoding description file\n", stderr);
- fplop(" --limit <type>=<value>\n");
- fputs(" -m <type>=<value> - set maximal limit of given type to value, types:\n", stderr);
- fputs(" h - maximal hint stack depth in the PostScript interpreter\n", stderr);
- fplop(" --processing suboptions\n");
- fputs(" -O suboptions - control outline processing, run ttf2pt1 -O? for help\n", stderr);
- fplop(" --parser name\n");
- fputs(" -p name - use specific front-end parser, run ttf2pt1 -p? for list\n", stderr);
- fplop(" --uid id\n");
- fputs(" -u id - use this UniqueID, -u A means autogeneration\n", stderr);
- fplop(" --vertical-autoscale size\n");
- fputs(" -v size - scale the font to make uppercase letters >size/1000 high\n", stderr);
- fplop(" --version\n");
- fputs(" -V - print ttf2pt1 version number\n", stderr);
- fplop(" --warning number\n");
- fputs(" -W number - set the level of permitted warnings (0 - disable)\n", stderr);
- fputs("Obsolete options (will be removed in future releases):\n", stderr);
- fplop(" --afm\n");
- fputs(" -A - write the .afm file to STDOUT instead of the font, now -GA\n", stderr);
- fputs(" -f - don't try to guess the value of the ForceBold hint, now -Ob\n", stderr);
- fputs(" -h - disable autogeneration of hints, now -Oh\n", stderr);
- fputs(" -H - disable hint substitution, now -Ou\n", stderr);
- fputs(" -o - disable outline optimization, now -Oo\n", stderr);
- fputs(" -s - disable outline smoothing, now -Os\n", stderr);
- fputs(" -t - disable auto-scaling to 1000x1000 standard matrix, now -Ot\n", stderr);
- fputs(" -w - correct the glyph widths (use only for buggy fonts), now -OW\n", stderr);
- fputs("With no <fontname>, write to <ttf-file> with suffix replaced.\n", stderr);
- fputs("The last '-' means 'use STDOUT'.\n", stderr);
-
-#undef fplop
-
-#endif /* XP_PSTEXT */
-}
-
-static void
-printversion(void)
-{
- fprintf(stderr, "ttf2pt1 %s\n", TTF2PT1_VERSION);
-}
-
-/* initialize a table of suboptions */
-static void
-init_subo_tbl(
- struct subo_case *tbl
-)
-{
- int i;
-
- for(i=0; tbl[i].disbl != 0; i++) {
- tbl[i].disbl = tolower(tbl[i].disbl);
- tbl[i].enbl = toupper(tbl[i].disbl);
- *(tbl[i].valp) = tbl[i].dflt;
- }
-}
-
-/* print the default value of the suboptions */
-static void
-print_subo_dflt(
- FILE *f,
- struct subo_case *tbl
-)
-{
- int i;
-
- for(i=0; tbl[i].disbl != 0; i++) {
- if(tbl[i].dflt)
- putc(tbl[i].enbl, f);
- else
- putc(tbl[i].disbl, f);
- }
-}
-
-/* print the usage message for the suboptions */
-static void
-print_subo_usage(
- FILE *f,
- struct subo_case *tbl
-)
-{
-#ifdef XP_PSTEXT
- fputs("ft2pt1: Internal startup error\n", stderr);
-#else
- int i;
-
- fprintf(f,"The lowercase suboptions disable features, corresponding\n");
- fprintf(f,"uppercase suboptions enable them. The supported suboptions,\n");
- fprintf(f,"their default states and the features they control are:\n");
- for(i=0; tbl[i].disbl != 0; i++) {
- fprintf(f," %c/%c - [%s] %s\n", tbl[i].disbl, tbl[i].enbl,
- tbl[i].dflt ? "enabled" : "disabled", tbl[i].descr);
- }
-#endif /* XP_PSTEXT */
-}
-
-/* find and set the entry according to suboption,
- * return the found entry (or if not found return NULL)
- */
-struct subo_case *
-set_subo(
- struct subo_case *tbl,
- int subopt
-)
-{
- int i;
-
- for(i=0; tbl[i].disbl != 0; i++) {
- if(subopt == tbl[i].disbl) {
- *(tbl[i].valp) = 0;
- return &tbl[i];
- } else if(subopt == tbl[i].enbl) {
- *(tbl[i].valp) = 1;
- return &tbl[i];
- }
- }
- return NULL;
-}
-
-
-#ifdef XP_PSTEXT
-FT_Face xp_pstext_ft_face = NULL; /* used by ft.c */
-FTFontPtr xp_xtf = NULL;
-const char *xp_psfontname = NULL;
-unsigned long xp_font_block_offset = 0UL;
-
-int
-ft2pt1_main(
- int argc,
- char **argv,
- FTFontPtr tf,
- const char *download_psfontname,
- unsigned long download_font_block_offset
-)
-#else
-int
-main(
- int argc,
- char **argv
-)
-#endif /* XP_PSTEXT */
-{
- long i, j;
- time_t now;
- char filename[4096];
- int c,nchars,nmetrics;
- int ws;
- int forcebold= -1; /* -1 means "don't know" */
- char *lang;
- int oc;
- int subid;
- char *cmdline;
-#ifdef _GNU_SOURCE
-# define ttf2pt1_getopt(a, b, c, d, e) getopt_long(a, b, c, d, e)
- static struct option longopts[] = {
- { "afm", 0, NULL, 'A' },
- { "all-glyphs", 0, NULL, 'a' },
- { "pfb", 0, NULL, 'b' },
- { "debug", 1, NULL, 'd' },
- { "encode", 0, NULL, 'e' },
- { "force-unicode", 0, NULL, 'F' },
- { "generate", 1, NULL, 'G' },
- { "language", 1, NULL, 'l' },
- { "language-map", 1, NULL, 'L' },
- { "limit", 1, NULL, 'm' },
- { "processing", 1, NULL, 'O' },
- { "parser", 1, NULL, 'p' },
- { "uid", 1, NULL, 'u' },
- { "vertical-autoscale", 1, NULL, 'v' },
- { "version", 0, NULL, 'V' },
- { "warning", 1, NULL, 'W' },
- { NULL, 0, NULL, 0 }
- };
-#else
-# define ttf2pt1_getopt(a, b, c, d, e) getopt(a, b, c)
-#endif
- /* table of Outline Processing (may think also as Optimization) options */
- static struct subo_case opotbl[] = {
- { 'b', 0/*auto-set*/, &trybold, 1, "guessing of the ForceBold hint" },
- { 'h', 0/*auto-set*/, &hints, 1, "autogeneration of hints" },
- { 'u', 0/*auto-set*/, &subhints, 1, "hint substitution technique" },
- { 'o', 0/*auto-set*/, &optimize, 1, "space optimization of font files" },
- { 's', 0/*auto-set*/, &smooth, 1, "smoothing and repair of outlines" },
- { 't', 0/*auto-set*/, &transform, 1, "auto-scaling to the standard matrix 1000x1000" },
- { 'w', 0/*auto-set*/, &correctwidth, 0, "correct the glyph widths (use only for buggy fonts)" },
- { 'v', 0/*auto-set*/, &vectorize, 0, "vectorize (trace) the bitmaps" },
-#ifdef USE_AUTOTRACE
- { 'z', 0/*auto-set*/, &use_autotrace, 0, "use the autotrace library on bitmaps (works badly)" },
-#endif /*USE_AUTOTRACE*/
- { 0, 0, 0, 0, 0} /* terminator */
- };
- /* table of the File Generation options */
- static struct subo_case fgotbl[] = {
- { 'f', 0/*auto-set*/, &gen_pfa, 1, "generate the font file (.t1a, .pfa or .pfb)" },
- { 'a', 0/*auto-set*/, &gen_afm, 1, "generate the Adobe metrics file (.afm)" },
- { 'e', 0/*auto-set*/, &gen_dvienc, 0, "generate the dvips encoding file (.enc)" },
- { 0, 0, 0, 0, 0} /* terminator */
- };
- int *genlast = NULL;
-
-#ifdef XP_PSTEXT
- xp_pstext_ft_face = tf->instance->face->face;
- xp_xtf = tf;
- xp_psfontname = download_psfontname;
- xp_font_block_offset = download_font_block_offset;
-#endif /* XP_PSTEXT */
-
- init_subo_tbl(opotbl); /* initialize sub-options of -O */
- init_subo_tbl(fgotbl); /* initialize sub-options of -G */
-
- /* save the command line for the record
- * (we don't bother about escaping the shell special characters)
- */
-
- j = 0;
- for(i=1; i<argc; i++) {
- j += strlen(argv[i])+1;
- }
- if ((cmdline = malloc(j+1)) == NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- cmdline[0] = 0;
- for(i=1; i<argc; i++) {
- strcat(cmdline, argv[i]);
- strcat(cmdline, " ");
- }
- for(i=0; (j=cmdline[i])!=0; i++)
- if(j == '\n')
- cmdline[i] = ' ';
-
-
- while(( oc=ttf2pt1_getopt(argc, argv, "FaoebAsthHfwVv:p:l:d:u:L:m:W:O:G:",
- longopts, NULL) )!= -1) {
- switch(oc) {
- case 'W':
- if(sscanf(optarg, "%d", &warnlevel) < 1 || warnlevel < 0) {
- fprintf(stderr, "**** warning level must be a positive number\n");
- exit(1);
- }
- break;
- case 'F':
- forcemap = 1;
- break;
- case 'o':
- fputs("Warning: option -o is obsolete, use -Oo instead\n", stderr);
- optimize = 0;
- break;
- case 'e':
- encode = 1;
- break;
- case 'b':
- encode = pfbflag = 1;
- break;
- case 'A':
- fputs("Warning: option -A is obsolete, use -GA instead\n", stderr);
- wantafm = 1;
- break;
- case 'a':
- allglyphs = 1;
- break;
- case 's':
- fputs("Warning: option -s is obsolete, use -Os instead\n", stderr);
- smooth = 0;
- break;
- case 't':
- fputs("Warning: option -t is obsolete, use -Ot instead\n", stderr);
- transform = 0;
- break;
- case 'd':
- for(i=0; optarg[i]!=0; i++)
- switch(optarg[i]) {
- case 'a':
- absolute = 1;
- break;
- case 'r':
- reverse = 0;
- break;
- default:
- if (optarg[i] != '?')
- fprintf(stderr, "**** Unknown debugging option '%c' ****\n", optarg[i]);
- fputs("The recognized debugging options are:\n", stderr);
- fputs(" a - enable absolute coordinates\n", stderr);
- fputs(" r - do not reverse font outlines directions\n", stderr);
- exit(1);
- break;
- };
- break;
- case 'm':
- {
- char subopt;
- int val;
-
- if(sscanf(optarg, "%c=%d", &subopt, &val) !=2) {
- fprintf(stderr, "**** Misformatted maximal limit ****\n");
- fprintf(stderr, "spaces around the equal sign are not allowed\n");
- fprintf(stderr, "good examples: -mh=100 -m h=100\n");
- fprintf(stderr, "bad examples: -mh = 100 -mh= 100\n");
- exit(1);
- break;
- }
- switch(subopt) {
- case 'h':
- max_stemdepth = val;
- break;
- default:
- if (subopt != '?')
- fprintf(stderr, "**** Unknown limit type '%c' ****\n", subopt);
- fputs("The recognized limit types are:\n", stderr);
- fputs(" h - maximal hint stack depth in the PostScript interpreter\n", stderr);
- exit(1);
- break;
- }
- break;
- }
- case 'O':
- {
- char *p;
- for(p=optarg; *p != 0; p++) {
- if(set_subo(opotbl, *p) == NULL) { /* found no match */
- if (*p != '?')
- fprintf(stderr, "**** Unknown outline processing suboption '%c' ****\n", *p);
- fprintf(stderr,"The general form of the outline processing option is:\n");
- fprintf(stderr," -O suboptions\n");
- fprintf(stderr,"(To remember easily -O may be also thought of as \"optimization\").\n");
- print_subo_usage(stderr, opotbl);
- fprintf(stderr, "The default state corresponds to the option -O ");
- print_subo_dflt(stderr, opotbl);
- fprintf(stderr, "\n");
- exit(1);
- }
- }
- break;
- }
- case 'G':
- {
- char *p;
- struct subo_case *s;
-
- for(p=optarg; *p != 0; p++) {
- if(( s = set_subo(fgotbl, *p) )==NULL) { /* found no match */
- if (*p != '?')
- fprintf(stderr, "**** Unknown outline processing suboption '%c' ****\n", *p);
- fprintf(stderr,"The general form of the file generation option is:\n");
- fprintf(stderr," -G suboptions\n");
- print_subo_usage(stderr, fgotbl);
- fprintf(stderr, "The default state corresponds to the option -G ");
- print_subo_dflt(stderr, fgotbl);
- fprintf(stderr, "\n");
- fprintf(stderr, "If the result is written to STDOUT, the last specified enabling suboption of -G\n");
- fprintf(stderr, "selects the file to be written to STDOUT (the font file by default).\n");
- exit(1);
- }
- if( *(s->valp) )
- genlast = s->valp;
- }
- break;
- }
- case 'h':
- fputs("Warning: option -h is obsolete, use -Oh instead\n", stderr);
- hints = 0;
- break;
- case 'H':
- fputs("Warning: meaning of option -H has been changed to its opposite\n", stderr);
- fputs("Warning: option -H is obsolete, use -Ou instead\n", stderr);
- subhints = 0;
- break;
- case 'f':
- fputs("Warning: option -f is obsolete, use -Ob instead\n", stderr);
- trybold = 0;
- break;
- case 'w':
- fputs("Warning: option -w is obsolete, use -OW instead\n", stderr);
- correctwidth = 1;
- break;
- case 'u':
- if(wantuid) {
- fprintf(stderr, "**** UniqueID may be specified only once ****\n");
- exit(1);
- }
- wantuid = 1;
- if(optarg[0]=='A' && optarg[1]==0)
- strUID=0; /* will be generated automatically */
- else {
- strUID=optarg;
- for(i=0; optarg[i]!=0; i++)
- if( !isdigit(optarg[i]) ) {
- fprintf(stderr, "**** UniqueID must be numeric or A for automatic ****\n");
- exit(1);
- }
- }
- break;
- case 'v':
- correctvsize = atoi(optarg);
- if(correctvsize <= 0 && correctvsize > 1000) {
- fprintf(stderr, "**** wrong vsize '%d', ignored ****\n", correctvsize);
- correctvsize=0;
- }
- break;
- case 'p':
- if(cursw!=0) {
- fprintf(stderr, "**** only one front-end parser be used ****\n");
- exit(1);
- }
-
- { /* separate parser from parser-specific argument */
- char *p = strchr(optarg, LANG_ARG_SEP);
- if(p != 0) {
- *p = 0;
- front_arg = p+1;
- } else
- front_arg = "";
- }
- for(i=0; frontswtab[i] != NULL; i++)
- if( !strcmp(frontswtab[i]->name, optarg) ) {
- cursw = frontswtab[i];
- break;
- }
-
- if(cursw==0) {
- if (strcmp(optarg, "?"))
- fprintf(stderr, "**** unknown front-end parser '%s' ****\n", optarg);
- fputs("the following front-ends are supported now:\n", stderr);
- for(i=0; frontswtab[i] != NULL; i++) {
- fprintf(stderr," %s (%s)\n file suffixes: ",
- frontswtab[i]->name,
- frontswtab[i]->descr ? frontswtab[i]->descr : "no description"
- );
- for(j=0; j<MAXSUFFIX; j++)
- if(frontswtab[i]->suffix[j])
- fprintf(stderr, "%s ", frontswtab[i]->suffix[j]);
- fprintf(stderr, "\n");
- }
- exit(1);
- }
- break;
- case 'l':
- if(uni_lang_selected!=0) {
- fprintf(stderr, "**** only one language option may be used ****\n");
- exit(1);
- }
-
- { /* separate language from language-specific argument */
- char *p = strchr(optarg, LANG_ARG_SEP);
- if(p != 0) {
- *p = 0;
- uni_lang_arg = p+1;
- } else
- uni_lang_arg = "";
- }
- for(i=0; i < sizeof uni_lang/(sizeof uni_lang[0]); i++)
- if( !strcmp(uni_lang[i].name, optarg) ) {
- uni_lang_selected = &uni_lang[i];
- uni_sample = uni_lang[i].sample_upper;
- break;
- }
-
- if(uni_lang_selected==0) {
- if (strcmp(optarg, "?"))
- fprintf(stderr, "**** unknown language '%s' ****\n", optarg);
- fputs(" the following languages are supported now:\n", stderr);
- for(i=0; i < sizeof uni_lang/(sizeof uni_lang[0]); i++)
- fprintf(stderr," %s (%s)\n",
- uni_lang[i].name,
- uni_lang[i].descr ? uni_lang[i].descr : "no description"
- );
- exit(1);
- }
- break;
- case 'L':
- if(uni_lang_selected!=0) {
- fprintf(stderr, "**** only one language option may be used ****\n");
- exit(1);
- }
- uni_lang_selected = &uni_lang_user;
- uni_lang_arg = optarg;
- break;
- case 'V':
- printversion();
- exit(0);
- break;
- default:
- usage();
- exit(1);
- break;
- }
- }
- argc-=optind-1; /* the rest of code counts from argv[0] */
- argv+=optind-1;
-
- if (absolute && encode) {
- fprintf(stderr, "**** options -a and -e are incompatible ****\n");
- exit(1);
- }
- if ((argc != 2) && (argc != 3)) {
- usage();
- exit(1);
- }
-
- /* try to guess the language by the locale used */
- if(uni_lang_selected==0 && (lang=getenv("LANG"))!=0 ) {
- for(i=0; i < sizeof uni_lang/sizeof(struct uni_language); i++) {
- if( !strncmp(uni_lang[i].name, lang, strlen(uni_lang[i].name)) ) {
- uni_lang_selected = &uni_lang[i];
- goto got_a_language;
- }
- }
- /* no full name ? try aliases */
- for(i=0; i < sizeof uni_lang/sizeof(struct uni_language); i++) {
- for(c=0; c<MAXUNIALIAS; c++)
- if( uni_lang[i].alias[c]!=0
- && !strncmp(uni_lang[i].alias[c], lang, strlen(uni_lang[i].alias[c])) ) {
- uni_lang_selected = &uni_lang[i];
- goto got_a_language;
- }
- }
- got_a_language:
- if(uni_lang_selected!=0) {
- WARNING_1 fprintf(stderr, "Using language '%s' for Unicode fonts\n", uni_lang[i].name);
- uni_sample = uni_lang[i].sample_upper;
- }
- }
-
- /* try to guess the front-end parser by the file name suffix */
- if(cursw==0) {
- char *p = strrchr(argv[1], '.');
- char *s;
-
- if(p!=0 && (s = strdup(p+1))!=0) {
- for(p=s; *p; p++)
- *p = tolower(*p);
- p = s;
-
- for(i=0; frontswtab[i] != 0 && cursw == 0; i++) {
- for(j=0; j<MAXSUFFIX; j++)
- if(frontswtab[i]->suffix[j]
- && !strcmp(p, frontswtab[i]->suffix[j]) ) {
- cursw = frontswtab[i];
- WARNING_1 fprintf(stderr, "Auto-detected front-end parser '%s'\n",
- cursw->name);
- WARNING_1 fprintf(stderr, " (use ttf2pt1 -p? to get the full list of available front-ends)\n");
- break;
- }
- }
- free(s);
- }
-
- if(cursw==0) {
- cursw = frontswtab[0];
- WARNING_1 fprintf(stderr, "Can't detect front-end parser, using '%s' by default\n",
- cursw->name);
- WARNING_1 fprintf(stderr, " (use ttf2pt1 -p? to get the full list of available front-ends)\n");
- }
- }
-
- /* open the input file */
- cursw->open(argv[1], front_arg);
-
- /* Get base name of output file (if not specified)
- * by removing (known) suffixes
- */
- if (argc == 2) {
- char *p;
- argv[2] = strdup (argv[1]);
- p = strrchr(argv[2], '.');
- if (p != NULL)
- for (j = 0; (j < MAXSUFFIX) && (cursw->suffix[j]); j++)
- if (!strcmp(p+1, cursw->suffix[j])) {
- *p = '\0';
- break;
- }
- }
-
- if ((null_file = fopen(BITBUCKET, "w")) == NULL) {
- fprintf(stderr, "**** Cannot open %s ****\n",
- BITBUCKET);
- exit(1);
- }
-
- if (argv[2][0] == '-' && argv[2][1] == 0) {
-#ifdef WINDOWS
- if(encode) {
- fprintf(stderr, "**** can't write encoded file to stdout ***\n");
- exit(1);
- }
-#endif /* WINDOWS */
- pfa_file = afm_file = dvienc_file = null_file;
-
- if(wantafm || genlast == &gen_afm) { /* print .afm instead of .pfa */
- afm_file=stdout;
- } else if(genlast == &gen_dvienc) { /* print .enc instead of .pfa */
- dvienc_file=stdout;
- } else {
- pfa_file=stdout;
- }
- } else {
-#ifndef WINDOWS
- snprintf(filename, sizeof filename, "%s.%s", argv[2], encode ? (pfbflag ? "pfb" : "pfa") : "t1a" );
-#else /* WINDOWS */
- snprintf(filename, sizeof filename, "%s.t1a", argv[2]);
-#endif /* WINDOWS */
- if(gen_pfa) {
- if ((pfa_file = fopen(filename, "w+b")) == NULL) {
- fprintf(stderr, "**** Cannot create %s ****\n", filename);
- exit(1);
- } else {
- WARNING_2 fprintf(stderr, "Creating file %s\n", filename);
- }
- } else
- pfa_file = null_file;
-
- if(gen_afm) {
- snprintf(filename, sizeof filename, "%s.afm", argv[2]) ;
- if ((afm_file = fopen(filename, "w+")) == NULL) {
- fprintf(stderr, "**** Cannot create %s ****\n", filename);
- exit(1);
- }
- } else
- afm_file = null_file;
-
- if(gen_dvienc) {
- snprintf(filename, sizeof filename, "%s.enc", argv[2]) ;
- if ((dvienc_file = fopen(filename, "w+")) == NULL) {
- fprintf(stderr, "**** Cannot create %s ****\n", filename);
- exit(1);
- }
- } else
- dvienc_file = null_file;
- }
-
- /*
- * Now check whether we want a fully encoded .pfa file
- */
-#ifndef WINDOWS
- if (encode && pfa_file != null_file) {
- int p[2];
- extern FILE *ifp, *ofp; /* from t1asm.c */
-
- ifp=stdin;
- ofp=stdout;
-
- if (pipe(p) < 0) {
- perror("**** Cannot create pipe ****\n");
- exit(1);
- }
- ofp = pfa_file;
- ifp = fdopen(p[0], "r");
- if (ifp == NULL) {
- perror("**** Cannot use pipe for reading ****\n");
- exit(1);
- }
- pfa_file = fdopen(p[1], "w");
- if (pfa_file == NULL) {
- perror("**** Cannot use pipe for writing ****\n");
- exit(1);
- }
- switch (fork()) {
- case -1:
- perror("**** Cannot fork the assembler process ****\n");
- exit(1);
- case 0: /* child */
- fclose(pfa_file);
- exit(runt1asm(pfbflag));
- default: /* parent */
- fclose(ifp); fclose(ofp);
- }
- }
-#endif /* WINDOWS */
-
- numglyphs = cursw->nglyphs();
-
- WARNING_3 fprintf(stderr, "numglyphs = %d\n", numglyphs);
-
- glyph_list = (GLYPH *) calloc(numglyphs, sizeof(GLYPH));
-
- /* initialize non-0 fields */
- for (i = 0; i < numglyphs; i++) {
- GLYPH *g;
-
- g = &glyph_list[i];
- g->char_no = -1;
- g->orig_code = -1;
- g->name = "UNKNOWN";
- g->flags = GF_FLOAT; /* we start with float representation */
- }
-
- handle_gnames();
-
- cursw->glmetrics(glyph_list);
- cursw->fnmetrics(&fontm);
-
- original_scale_factor = 1000.0 / (double) fontm.units_per_em;
-
- if(transform == 0)
- scale_factor = 1.0; /* don't transform */
- else
- scale_factor = original_scale_factor;
-
- if(correctvsize && uni_sample!=0) { /* only for known languages */
- /* try to adjust the scale factor to make a typical
- * uppercase character of hight at least (correctvsize), this
- * may improve the appearance of the font but also
- * make it weird, use with caution
- */
- int ysz;
-
- ysz = iscale(glyph_list[encoding[uni_sample]].yMax);
- if( ysz<correctvsize ) {
- scale_factor *= (double)correctvsize / ysz;
- }
- }
-
-#ifdef XP_ONLY_BLOCKS
- /* All glyphs from |xp_font_block_offset| to |xp_font_block_offset+255|*/
- for( i = xp_font_block_offset ; i < (xp_font_block_offset+256) ; i++ ) {
- unsigned long ftindex;
-
- /* Remap X11 font index to FreeType font index */
- ftindex = FTRemap(xp_pstext_ft_face, &xp_xtf->mapping, i);
-
- if( ftindex < numglyphs ) {
- glyph_list[ftindex].flags |= GF_USED;
- }
- }
-
- /* also always include .notdef */
- {
- int notdef_found = FALSE;
-
- for (i = 0; i < numglyphs; i++) {
- if(!strcmp(glyph_list[i].name, ".notdef")) {
- glyph_list[i].flags |= GF_USED;
- notdef_found = TRUE;
- break;
- }
- }
-
- if( !notdef_found )
- {
- /* No ".notdef" found ?
- * Then copy outlines of char 0 to the first "free" slot and make
- * it our ".notdef" char.
- */
- for (i = 0; i < numglyphs; i++) {
- if((glyph_list[i].flags & GF_USED) == 0) {
- glyph_list[i] = glyph_list[0];
- glyph_list[i].flags |= GF_USED;
- glyph_list[i].name = ".notdef";
- notdef_found = TRUE;
- break;
- }
- }
- }
-
- if( !notdef_found )
- {
- /* This shoudl never happen... */
- fprintf(stderr, "ft2pt1: '.notdef' missing in generated font.\n");
- }
- }
-#else
- if(allglyphs) {
- for (i = 0; i < numglyphs; i++) {
- glyph_list[i].flags |= GF_USED;
- }
- } else {
- for (i = 0; i < ENCTABSZ; i++) {
- glyph_list[encoding[i]].flags |= GF_USED;
- }
-
- /* also always include .notdef */
- for (i = 0; i < numglyphs; i++)
- if(!strcmp(glyph_list[i].name, ".notdef")) {
- glyph_list[i].flags |= GF_USED;
- break;
- }
- }
-#endif /* XP_ONLY_BLOCKS */
-
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED) {
- DBG_TO_GLYPH(&glyph_list[i]);
- convert_glyf(i);
- DBG_FROM_GLYPH(&glyph_list[i]);
- }
- }
-
- italic_angle = fontm.italic_angle;
-
- if (italic_angle > 45.0 || italic_angle < -45.0)
- italic_angle = 0.0; /* consider buggy */
-
- if (hints) {
- findblues();
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED) {
- DBG_TO_GLYPH(&glyph_list[i]);
- buildstems(&glyph_list[i]);
- assertpath(glyph_list[i].entries, __FILE__, __LINE__, glyph_list[i].name);
- DBG_FROM_GLYPH(&glyph_list[i]);
- }
- }
- stemstatistics();
- } else {
- for(i=0; i<4; i++)
- bbox[i] = iscale(fontm.bbox[i]);
- }
- /* don't touch the width of fixed width fonts */
- if( fontm.is_fixed_pitch )
- correctwidth=0;
- docorrectwidth(); /* checks correctwidth inside */
- if (reverse)
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED) {
- DBG_TO_GLYPH(&glyph_list[i]);
- reversepaths(&glyph_list[i]);
- assertpath(glyph_list[i].entries, __FILE__, __LINE__, glyph_list[i].name);
- DBG_FROM_GLYPH(&glyph_list[i]);
- }
- }
-
-
-#if 0
- /*
- ** It seems to bring troubles. The problem is that some
- ** styles of the font may be recognized as fixed-width
- ** while other styles of the same font as proportional.
- ** So it's better to be commented out yet.
- */
- if (tryfixed)
- alignwidths();
-#endif
-
- if(trybold) {
- forcebold = fontm.force_bold;
- }
-
-#ifdef XP_PSTEXT
- fprintf(pfa_file, "%%!PS-AdobeFont-1.0: %s\n", fontm.name_ps);
-#else
- fprintf(pfa_file, "%%!PS-AdobeFont-1.0: %s %s\n", fontm.name_ps, fontm.name_copyright);
- time(&now);
- fprintf(pfa_file, "%%%%CreationDate: %s", ctime(&now));
- fprintf(pfa_file, "%% Converted by ttf2pt1 %s/%s\n", TTF2PT1_VERSION, cursw->name);
- fprintf(pfa_file, "%% Args: %s\n", cmdline);
- fprintf(pfa_file, "%%%%EndComments\n");
-#endif /* XP_PSTEXT */
- fprintf(pfa_file, "12 dict begin\n/FontInfo 9 dict dup begin\n");
-
- WARNING_3 fprintf(stderr, "FontName %s%s\n", fontm.name_ps, uni_font_name_suffix);
-
-
- fprintf(pfa_file, " /version (%s) readonly def\n", fontm.name_version);
-
- fprintf(pfa_file, " /Notice (%s) readonly def\n", fontm.name_copyright);
-
- fprintf(pfa_file, " /FullName (%s) readonly def\n", fontm.name_full);
- fprintf(pfa_file, " /FamilyName (%s) readonly def\n", fontm.name_family);
-
- if(wantuid) {
- if(strUID)
- fprintf(pfa_file, " /UniqueID %s def\n", strUID);
- else {
- numUID=0;
- for(i=0; fontm.name_full[i]!=0; i++) {
- numUID *= 37; /* magic number, good for hash */
- numUID += fontm.name_full[i]-' ';
- /* if the name is long the first chars
- * may be lost forever, so re-insert
- * them thus making kind of CRC
- */
- numUID += (numUID>>24) & 0xFF;
- }
- /* the range for private UIDs is 4 000 000 - 4 999 999 */
- fprintf(pfa_file, " /UniqueID %lu def\n", numUID%1000000+4000000);
- }
- }
-
- fprintf(pfa_file, " /Weight (%s) readonly def\n", fontm.name_style);
-
- fprintf(pfa_file, " /ItalicAngle %f def\n", italic_angle);
- fprintf(pfa_file, " /isFixedPitch %s def\n",
- fontm.is_fixed_pitch ? "true" : "false");
-
- /* we don't print out the unused glyphs */
- nchars = 0;
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED) {
- nchars++;
- }
- }
-
- fprintf(afm_file, "StartFontMetrics 4.1\n");
- fprintf(afm_file, "FontName %s%s\n", fontm.name_ps, uni_font_name_suffix);
- fprintf(afm_file, "FullName %s\n", fontm.name_full);
- fprintf(afm_file, "Notice %s\n", fontm.name_copyright);
- fprintf(afm_file, "EncodingScheme FontSpecific\n");
- fprintf(afm_file, "FamilyName %s\n", fontm.name_family);
- fprintf(afm_file, "Weight %s\n", fontm.name_style);
- fprintf(afm_file, "Version %s\n", fontm.name_version);
- fprintf(afm_file, "Characters %d\n", nchars);
- fprintf(afm_file, "ItalicAngle %.1f\n", italic_angle);
-
- fprintf(afm_file, "Ascender %d\n", iscale(fontm.ascender));
- fprintf(afm_file, "Descender %d\n", iscale(fontm.descender));
-
- fprintf(pfa_file, " /UnderlinePosition %d def\n",
- iscale(fontm.underline_position));
-
- fprintf(pfa_file, " /UnderlineThickness %hd def\n",
- iscale(fontm.underline_thickness));
-
- fprintf(pfa_file, "end readonly def\n");
-
- fprintf(afm_file, "UnderlineThickness %d\n",
- iscale(fontm.underline_thickness));
-
- fprintf(afm_file, "UnderlinePosition %d\n",
- iscale(fontm.underline_position));
-
- fprintf(afm_file, "IsFixedPitch %s\n",
- fontm.is_fixed_pitch ? "true" : "false");
- fprintf(afm_file, "FontBBox %d %d %d %d\n",
- bbox[0], bbox[1], bbox[2], bbox[3]);
-
- fprintf(pfa_file, "/FontName /%s%s def\n", fontm.name_ps, uni_font_name_suffix);
- fprintf(pfa_file, "/PaintType 0 def\n/StrokeWidth 0 def\n");
- /* I'm not sure if these are fixed */
- fprintf(pfa_file, "/FontType 1 def\n");
-
- if (transform) {
- fprintf(pfa_file, "/FontMatrix [0.001 0 0 0.001 0 0] def\n");
- } else {
- fprintf(pfa_file, "/FontMatrix [%9.7f 0 0 %9.7f 0 0] def\n",
- original_scale_factor / 1000.0, original_scale_factor / 1000.0);
- }
-
- fprintf(pfa_file, "/FontBBox {%d %d %d %d} readonly def\n",
- bbox[0], bbox[1], bbox[2], bbox[3]);
-
- fprintf(pfa_file, "/Encoding 256 array\n");
- /* determine number of elements for metrics table */
- nmetrics = 256;
- for (i = 0; i < numglyphs; i++) {
- if( glyph_list[i].flags & GF_USED
- && glyph_list[i].char_no == -1 ) {
- nmetrics++;
- }
- }
- fprintf(afm_file, "StartCharMetrics %d\n", nmetrics);
-
- fprintf(dvienc_file, "/%s%sEncoding [\n",
- fontm.name_ps, uni_font_name_suffix);
-
-#ifdef XP_PSTEXT
- {
- int linewidth = 0;
- for (i = 0; i < 256; i++) { /* here 256, not ENCTABSZ */
- linewidth += strlen(glyph_list[encoding[i]].name) + 14 + 8;
- fprintf(pfa_file, "dup %d /%s put%s",
- i,
- glyph_list[encoding[i]].name,
- (linewidth > 70 || i == 255)?(linewidth = 0, "\n"):("\t"));
- if( glyph_list[encoding[i]].flags & GF_USED ) {
- print_glyph_metrics(i, encoding[i]);
- }
- if (encoding[i])
- fprintf (dvienc_file, "/index0x%04X\n", encoding[i]);
- else
- fprintf (dvienc_file, "/.notdef\n");
- }
- }
-#else
- for (i = 0; i < 256; i++) { /* here 256, not ENCTABSZ */
- fprintf(pfa_file,
- "dup %d /%s put\n", i, glyph_list[encoding[i]].name);
- if( glyph_list[encoding[i]].flags & GF_USED ) {
- print_glyph_metrics(i, encoding[i]);
- }
- if (encoding[i])
- fprintf (dvienc_file, "/index0x%04X\n", encoding[i]);
- else
- fprintf (dvienc_file, "/.notdef\n");
- }
-#endif /* XP_PSTEXT */
- /* print the metrics for glyphs not in encoding table */
- for(i=0; i<numglyphs; i++) {
- if( (glyph_list[i].flags & GF_USED)
- && glyph_list[i].char_no == -1 ) {
- print_glyph_metrics(-1, i);
- }
- }
-
- fprintf(pfa_file, "readonly def\ncurrentdict end\ncurrentfile eexec\n");
- fprintf(pfa_file, "dup /Private 16 dict dup begin\n");
-
- fprintf(pfa_file, "/RD{string currentfile exch readstring pop}executeonly def\n");
- fprintf(pfa_file, "/ND{noaccess def}executeonly def\n");
- fprintf(pfa_file, "/NP{noaccess put}executeonly def\n");
-
- /* UniqueID must be shown twice, in both font and Private dictionary */
- if(wantuid) {
- if(strUID)
- fprintf(pfa_file, "/UniqueID %s def\n", strUID);
- else
- /* the range for private UIDs is 4 000 000 - 4 999 999 */
- fprintf(pfa_file, "/UniqueID %lu def\n", numUID%1000000+4000000);
- }
-
- if(forcebold==0)
- fprintf(pfa_file, "/ForceBold false def\n");
- else if(forcebold==1)
- fprintf(pfa_file, "/ForceBold true def\n");
-
- fprintf(pfa_file, "/BlueValues [ ");
- for (i = 0; i < nblues; i++)
- fprintf(pfa_file, "%d ", bluevalues[i]);
- fprintf(pfa_file, "] def\n");
-
- fprintf(pfa_file, "/OtherBlues [ ");
- for (i = 0; i < notherb; i++)
- fprintf(pfa_file, "%d ", otherblues[i]);
- fprintf(pfa_file, "] def\n");
-
- if (stdhw != 0)
- fprintf(pfa_file, "/StdHW [ %d ] def\n", stdhw);
- if (stdvw != 0)
- fprintf(pfa_file, "/StdVW [ %d ] def\n", stdvw);
- fprintf(pfa_file, "/StemSnapH [ ");
- for (i = 0; i < 12 && stemsnaph[i] != 0; i++)
- fprintf(pfa_file, "%d ", stemsnaph[i]);
- fprintf(pfa_file, "] def\n");
- fprintf(pfa_file, "/StemSnapV [ ");
- for (i = 0; i < 12 && stemsnapv[i] != 0; i++)
- fprintf(pfa_file, "%d ", stemsnapv[i]);
- fprintf(pfa_file, "] def\n");
-
- fprintf(pfa_file, "/MinFeature {16 16} def\n");
- /* Are these fixed also ? */
- fprintf(pfa_file, "/password 5839 def\n");
-
- /* calculate the number of subroutines */
-
- subid=5;
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED) {
- subid+=glyph_list[i].nsg;
- }
- }
-
- fprintf(pfa_file, "/Subrs %d array\n", subid);
- /* standard subroutines */
- fprintf(pfa_file, "dup 0 {\n\t3 0 callothersubr pop pop setcurrentpoint return\n\t} NP\n");
- fprintf(pfa_file, "dup 1 {\n\t0 1 callothersubr return\n\t} NP\n");
- fprintf(pfa_file, "dup 2 {\n\t0 2 callothersubr return\n\t} NP\n");
- fprintf(pfa_file, "dup 3 {\n\treturn\n\t} NP\n");
- /* our sub to make the hint substitution code shorter */
- fprintf(pfa_file, "dup 4 {\n\t1 3 callothersubr pop callsubr return\n\t} NP\n");
-
- if(pfa_file != null_file) { /* save time if the output would be wasted */
- /* print the hinting subroutines */
- subid=5;
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED) {
- subid+=print_glyph_subs(i, subid);
- }
- }
-
- fprintf(pfa_file, "ND\n");
-
- fprintf(pfa_file, "2 index /CharStrings %d dict dup begin\n", nchars);
-
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED) {
- print_glyph(i);
- }
- }
- }
-
-
- fprintf(pfa_file, "end\nend\nreadonly put\n");
- fprintf(pfa_file, "noaccess put\n");
- fprintf(pfa_file, "dup/FontName get exch definefont pop\n");
- fprintf(pfa_file, "mark currentfile closefile\n");
- fprintf(pfa_file, "cleartomark\n");
- if(pfa_file != null_file)
- fclose(pfa_file);
-
- fprintf(afm_file, "EndCharMetrics\n");
-
- if(afm_file != null_file) { /* save time if the output would be wasted */
- /* print the kerning data if present */
- cursw->kerning(glyph_list);
- print_kerning(afm_file);
- }
-
- fprintf(afm_file, "EndFontMetrics\n");
- if(afm_file != null_file)
- fclose(afm_file);
-
- fprintf(dvienc_file, "] def\n");
- if(dvienc_file != null_file)
- fclose(dvienc_file);
-
- WARNING_1 fprintf(stderr, "Finished - font files created\n");
-
- cursw->close();
-
-#ifndef WINDOWS
- while (wait(&ws) > 0) {
- }
-#else
- if (encode && pfa_file != null_file) {
- extern FILE *ifp, *ofp; /* from t1asm.c */
-
- snprintf(filename, sizeof filename, "%s.%s", argv[2], pfbflag ? "pfb" : "pfa" );
-
- if ((ofp = fopen(filename, "w+b")) == NULL) {
- fprintf(stderr, "**** Cannot create %s ****\n", filename);
- exit(1);
- } else {
- WARNING_2 fprintf(stderr, "Creating file %s\n", filename);
- }
-
- snprintf(filename, sizeof filename, "%s.t1a", argv[2]);
-
- if ((ifp = fopen(filename, "rb")) == NULL) {
- fprintf(stderr, "**** Cannot read %s ****\n", filename);
- exit(1);
- } else {
- WARNING_2 fprintf(stderr, "Converting file %s\n", filename);
- }
-
- runt1asm(pfbflag);
-
- WARNING_2 fprintf(stderr, "Removing file %s\n", filename);
- if(unlink(filename) < 0)
- WARNING_1 fprintf(stderr, "Unable to remove file %s\n", filename);
- }
-#endif /* WINDOWS */
-
- fclose(null_file);
- return 0;
-}
diff --git a/nx-X11/extras/ttf2pt1/ttf2pt1_convert.1 b/nx-X11/extras/ttf2pt1/ttf2pt1_convert.1
deleted file mode 100644
index 8e07150aa..000000000
--- a/nx-X11/extras/ttf2pt1/ttf2pt1_convert.1
+++ /dev/null
@@ -1,516 +0,0 @@
-.rn '' }`
-''' $RCSfile: ttf2pt1_convert.1,v $$Revision: 1.2 $$Date: 2004/04/23 18:42:57 $
-'''
-''' $Log: ttf2pt1_convert.1,v $
-''' Revision 1.2 2004/04/23 18:42:57 eich
-''' 2004-04-23 Egbert Eich <eich@freedesktop.org>
-''' Merging XORG-CURRENT into trunk
-'''
-''' Revision 1.1.4.1 2004/04/21 10:03:13 gisburn
-''' Fix for http://pdx.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=530 - Land XPRINT branch on XORG-CURRENT
-'''
-''' Revision 1.1 2003/06/04 00:33:54 roland
-''' Fix for http://xprint.mozdev.org/bugs/show_bug.cgi?id=3846 - RFE: Upload Freetype --> PS Type1 font converter "ttf2pt1" ...
-'''
-'''
-.de Sh
-.br
-.if t .Sp
-.ne 5
-.PP
-\fB\\$1\fR
-.PP
-..
-.de Sp
-.if t .sp .5v
-.if n .sp
-..
-.de Ip
-.br
-.ie \\n(.$>=3 .ne \\$3
-.el .ne 3
-.IP "\\$1" \\$2
-..
-.de Vb
-.ft CW
-.nf
-.ne \\$1
-..
-.de Ve
-.ft R
-
-.fi
-..
-'''
-'''
-''' Set up \*(-- to give an unbreakable dash;
-''' string Tr holds user defined translation string.
-''' Bell System Logo is used as a dummy character.
-'''
-.tr \(*W-|\(bv\*(Tr
-.ie n \{\
-.ds -- \(*W-
-.ds PI pi
-.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
-.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
-.ds L" ""
-.ds R" ""
-''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of
-''' \*(L" and \*(R", except that they are used on ".xx" lines,
-''' such as .IP and .SH, which do another additional levels of
-''' double-quote interpretation
-.ds M" """
-.ds S" """
-.ds N" """""
-.ds T" """""
-.ds L' '
-.ds R' '
-.ds M' '
-.ds S' '
-.ds N' '
-.ds T' '
-'br\}
-.el\{\
-.ds -- \(em\|
-.tr \*(Tr
-.ds L" ``
-.ds R" ''
-.ds M" ``
-.ds S" ''
-.ds N" ``
-.ds T" ''
-.ds L' `
-.ds R' '
-.ds M' `
-.ds S' '
-.ds N' `
-.ds T' '
-.ds PI \(*p
-'br\}
-.\" If the F register is turned on, we'll generate
-.\" index entries out stderr for the following things:
-.\" TH Title
-.\" SH Header
-.\" Sh Subsection
-.\" Ip Item
-.\" X<> Xref (embedded
-.\" Of course, you have to process the output yourself
-.\" in some meaninful fashion.
-.if \nF \{
-.de IX
-.tm Index:\\$1\t\\n%\t"\\$2"
-..
-.nr % 0
-.rr F
-.\}
-.TH TTF2PT1_CONVERT 1 "version 3.4.4-SNAP-030526" "May 26, 2003" "TTF2PT1 Font Converter"
-.UC
-.if n .hy 0
-.if n .na
-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
-.de CQ \" put $1 in typewriter font
-.ft CW
-'if n "\c
-'if t \\&\\$1\c
-'if n \\&\\$1\c
-'if n \&"
-\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7
-'.ft R
-..
-.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2
-. \" AM - accent mark definitions
-.bd B 3
-. \" fudge factors for nroff and troff
-.if n \{\
-. ds #H 0
-. ds #V .8m
-. ds #F .3m
-. ds #[ \f1
-. ds #] \fP
-.\}
-.if t \{\
-. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
-. ds #V .6m
-. ds #F 0
-. ds #[ \&
-. ds #] \&
-.\}
-. \" simple accents for nroff and troff
-.if n \{\
-. ds ' \&
-. ds ` \&
-. ds ^ \&
-. ds , \&
-. ds ~ ~
-. ds ? ?
-. ds ! !
-. ds /
-. ds q
-.\}
-.if t \{\
-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
-. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'
-. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'
-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
-. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10'
-.\}
-. \" troff and (daisy-wheel) nroff accents
-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
-.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
-.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#]
-.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'
-.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'
-.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#]
-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
-.ds ae a\h'-(\w'a'u*4/10)'e
-.ds Ae A\h'-(\w'A'u*4/10)'E
-.ds oe o\h'-(\w'o'u*4/10)'e
-.ds Oe O\h'-(\w'O'u*4/10)'E
-. \" corrections for vroff
-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
-. \" for low resolution devices (crt and lpr)
-.if \n(.H>23 .if \n(.V>19 \
-\{\
-. ds : e
-. ds 8 ss
-. ds v \h'-1'\o'\(aa\(ga'
-. ds _ \h'-1'^
-. ds . \h'-1'.
-. ds 3 3
-. ds o a
-. ds d- d\h'-1'\(ga
-. ds D- D\h'-1'\(hy
-. ds th \o'bp'
-. ds Th \o'LP'
-. ds ae ae
-. ds Ae AE
-. ds oe oe
-. ds Oe OE
-.\}
-.rm #[ #] #H #V #F C
-.SH "NAME"
-\fBttf2pt1_convert\fR \- convenience font conversion script
-.SH "SYNOPSIS"
-ttf2pt1_convert \fB[config-file]\fR
-.SH "DESCRIPTION"
-`\fBConvert\fR\*(R' is the master conversion script provided with ttf2pt1.
-When installed into a public directory it's named `\fBttf2pt1_convert\fR\*(R'
-to avoid name collisions with the other programs.
-.PP
-If the configuration file is not specified as an argument then the file
-`\f(CWconvert.cfg\fR\*(R' in the current directory is used. This file contains
-a set of configuration variables. The distribution contains a sample file
-file `\f(CWconvert.cfg.sample\fR\*(R'. Please copy it to `\f(CWconvert.cfg\fR\*(R',
-look inside it and change the configuration variables. The more stable
-configuration variables, such as the path names of the scripts and
-encoding files are located in `\f(CWconvert\fR\*(R' itself, they are
-automatically updated when installing \fBttf2pt1\fR.
-.PP
-Put all the TTF fonts you want to convert into some directory (this
-may be just the directory that already contains all the Windows
-fonts on a mounted FAT filesystem). If you have fonts in different
-source encoding then put the fonts in each of the encodings
-into a separate directory. Up to 10 source directories are
-supported. If you (in a rather unlikely case) have more source
-directories then you can make two separate runs of the converter,
-converting up to 10 directories at a time.
-.PP
-The variables in the configuration file are:
-.Ip "\(bu" 2
-\fB\f(CWSRCDIRS\fR\fR \- the list of directories (with absolute paths) with
-\s-1TTF\s0 fonts. Each line contains at least 3 fields: the name of the directory,
-the language of the fonts in it (if you have fonts for different
-languages you have to put them into the separate directories) and the
-encoding of the fonts. Again, if you have some of the \s-1TTF\s0 typefaces in
-one encoding, and some in another (say, \s-1CP\s0\-1251 and \s-1KOI\s0\-8), you have
-to put them into the separate source directories. Some lines may contain
-4 fields. Then the fourth field is the name of the external map to
-convert the Unicode fonts into the desirable encoding. This map is
-used instead of the built-in map for the specified language.
-.Sp
-*8*
-An interesting thing is that some languages have more than one
-widely used character encodings. For example, the widely used
-encodings for Russian are \s-1IBM\s0 \s-1CP\s0\-866 (\s-1MS\s0\-\s-1DOS\s0 and Unix), \s-1KOI\s0\-8
-(Unix and \s-1VAX\s0, also the standard Internet encoding), \s-1IBM\s0 \s-1CP\s0\-1251 (\s-1MS\s0 Windows).
-That's why I have provided the means to generate the converted fonts
-in more than one encoding. See the file encodings/\s-1README\s0 for
-details about the encoding tables. Actually, if you plan to use
-these fonts with Netscape Navigator better use the aliases
-cp-866 instead of ibm-866 and windows-1251 instead of ibm-1251
-because that's what Netscape wants.
-.Ip "\(bu" 2
-\fB\f(CWDSTDIR\fR\fR \- directory for the resulting Type1 fonts. Be careful!
-This directory gets completely wiped out before conversion,
-so don't use any already existing directory for this purpose.
-.Ip "\(bu" 2
-\fB\f(CWDSTENC\fI{language}\fR\fR\fR \- the list of encodings in which the destination
-fonts will be generated for each language. Each font of that
-language will be generated in each of the specified
-encodings. If you don't want any translation, just specify both
-\f(CWSRCENC\fR and \f(CWDSTENC\fR as iso8859-1 (or if you want any other encoding
-specified in the fonts.dir, copy the description of 8859-1 with
-new name and use this new name for \f(CWSRCENC\fR and \f(CWDSTENC\fR).
-.Ip "\(bu" 2
-\fB\f(CWFOUNDRY\fR\fR \- the foundry name to be used in the fonts.dir file. I have
-set it to `fromttf\*(R' to avoid name conflicts with any existing font for
-sure. But this foundry name is not registered in X11 standards and
-if you want to get the full standard compliance or have a font server
-that enforces such a compliance, use `misc\*(R'.
-.PP
-The next few parameters control the general behavior of the converter.
-They default values are set to something reasonable.
-.Ip "\(bu" 2
-\fB\f(CWCORRECTWIDTH\fR\fR \- if the value is set to \fB\f(CWYES\fR\fR then use the
-converter option \f(CW\fB-w\fR\fR, otherwise don't use it. See the description of
-this option in the \s-1README\s0 file.
-.Ip "\(bu" 2
-\fB\f(CWREMOVET1A\fR\fR \- if the value is set to \fB\f(CWYES\fR\fR then after
-conversion remove the un-encoded \f(CW.t1a\fR font files and the
-intermediate \f(CW.xpfa\fR font metric files.
-.Ip "\(bu" 2
-\fB\f(CWINSTALLFONTMAP\fR\fR \- a Ghostscript parameter, if the value is set to
-\fB\f(CWYES\fR\fR then install the entries for the new fonts
-right into the main \f(CWFontmap\fR file. Otherwise just leave
-the file \f(CWFontmap.ttf\fR in the Ghostscript configuration
-directory.
-.Ip "\(bu" 2
-\fB\f(CWHINTSUBST\fR\fR \- if the value is set to \fB\f(CWYES\fR\fR use the option
-\f(CW\fB-H\fR\fR, otherwise don't use it. This option enables the
-hint substitution technique. If you have not installed the X11 patch
-described above, use this option with great caution. See further
-description of this option in the \s-1README\s0 file.
-.Ip "\(bu" 2
-\fB\f(CWENFORCEISO\fR\fR \- if the value is set to \fB\f(CWYES\fR\fR then
-disguise the resulting fonts as the fonts in ISOLatin1 encoding. Historically
-this was neccessary due to the way the installer scripts created the
-X11 font configuration files. It is not neccessary any more for this
-purpose. But if you plan to use these fonts with some other application
-that expects ISOLatin1 encoding then better enable this option.
-.Ip "\(bu" 2
-\fB\f(CWALLGLYPHS\fR\fR \- if the value is set to \fB\f(CWYES\fR\fR then
-include all the glyphs from the source fonts into the resulting fonts, even
-if these glyphs are inaccessible. If it's set to \fB\f(CWNO\fR\fR then
-include only the glyphs which have codes assigned to them. The glyphs
-without codes can not be used directly. But some clever programs,
-such as the Type 1 library from XFree86 3.9 and higher can change
-the encoding on the fly and use another set of glyphs. If you have not
-installed the X11 patch described above, use this option with great
-caution. See further description of the option option \f(CW\fB-a\fR\fR in the
-\s-1README\s0 file.
-.Ip "\(bu" 2
-\fB\f(CWGENUID\fR\fR \- if the value is set to \fB\f(CWYES\fR\fR then use
-the option \f(CW\fB-uA\fR\fR of the converter to generate UniqueIDs for
-the converted fonts. The standard X11 Type 1 library does not use
-this \s-1ID\s0, so it may only be neccessary for the other applications.
-The script is clever enough to generate different UniqueID for the
-same font converted to multiple encodings. Also after conversion it
-checks all the fonts generacted during the session for duplicated
-UniqueID and shows those. Still, this does not quarantee that these
-UniqueIDs won't overlap with some other fonts. The UniqueIDs are
-generated as hash values from the font names, so it's guaranteed
-that if the `\f(CWconvert\fR\*(R' script runs multiple times it will
-generate the same UniqueIDs during each run. See further description
-of this option in the \s-1README\s0 file.
-.Ip "\(bu" 2
-\fB\f(CWGENUID\fR\fR \- if the value is set to \fB\f(CWYES\fR\fR then create
-the \f(CW.pfb\fR files, otherwise the \f(CW.pfa\fR files. The \f(CW.pfb\fR
-files are more compact but contain binary data, so you may experience some
-troubles when transferring them through the network.
-.PP
-The following parameters are used to locate the other scripts and
-configuration files. By default the scripts do a bit of guessing for them:
-they search in the \fBttf2pt1\fR installation directory if \fBttf2pt1\fR
-was installed or otherwise suppose that you are running `\f(CWconvert\fR\*(R' with
-`\f(CWscripts\fR\*(R' subdirectory being the current directory.
-.Ip "\(bu" 2
-\fB\f(CWENCDIR\fR\fR \- directory containing the descriptions of encodings
-.Ip "\(bu" 2
-\fB\f(CWMAPDIR\fR\fR \- directory containing the external map files
-.PP
-Besides that a few parameters are built into the `\f(CWconvert\fR\*(R' script itself.
-You probably won't need to change them:
-.Ip "\(bu" 2
-\f(CW\fBT1ASM\fR\fR, \f(CW\fBTTF2PT1\fR\fR, \f(CW\fBTRANS\fR\fR, \f(CW\fBT1FDIR\fR\fR, \f(CW\fBFORCEISO\fR\fR \- paths to the other script
-.PP
-Also there are a few parameters controlling the installation of
-fonts for Ghostscript. Please look at their description in the
-Ghostscript section of documentation or in the \fBttf2pt1_x2gs(1)\fR
-manual page before running `\f(CWconvert\fR\*(R'. If these parameters are
-set, `\f(CWconvert\fR\*(R' will call the `\f(CWx2gs\fR\*(R' script automatically
-to install the newly converted fonts in Ghostscript.
-.PP
-After creating the configuration file run the `\f(CWconvert\fR\*(R' script. Look at
-the result and the log file in \f(CWDSTDIR\fR.
-.PP
-Add the directory with newly converted fonts to the configuration
-of X server or font server. For most of the systems this step is
-very straightforward. For \s-1HP\s0\-\s-1UX\s0 it's rather tricky and poorly
-documented, so the file \s-1FONTS\s0.hpux gives a short description.
-.PP
-If you don't have the privileges of the root user, you still can
-configure your private font server. Just use some non-standard
-port number (see \s-1FONTS\s0.hpux for an example, exept that you won't
-need all the \s-1HP\s0\-related stuff on any other system).
-.SH "FILES"
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/\s0scripts/convert.cfg.sample
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/\s0scripts/*
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/README\s0
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/FONTS\s0
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR\s0/*
-.Ip "\(bu" 2
-\s-1TTF2PT1_BINDIR/\s0ttf2pt1
-.SH "SEE ALSO"
-.Ip "\(bu" 4
-the \fIttf2pt1(1)\fR manpage
-.Ip "\(bu" 4
-the \fIttf2pt1_x2gs(1)\fR manpage
-.Ip "\(bu" 4
-the \fIt1asm(1)\fR manpage
-.SH "BUGS"
-.Sh "Known problems"
-.Ip "\(bu" 4
-One catch is that the X11 Type 1 font library has a rather low limit
-on the font size. Because of this the fonts with more complicated
-outlines and the enabled hint substitution may not fit into
-this limit. The same applies to the fonts with very complicated
-outlines or with very many glyphs (especially the fonts with
-over 256 glyphs). So you will need to excercise caution with
-these options if you plan using these fonts with X11. Some vendors
-such as \s-1HP\s0 provide the Type 1 implementation licensed from Adobe
-which should have no such problem.
-.Sp
-But there is a solution even for the generic X11. A patch located
-in the subdirectory `\f(CWapp/X11\fR\*(R' fixes this problem as well
-as some other minor problems. Its description is provided in
-app/X11/\s-1README\s0.
-.Sp
-To fix the X11 font library, you have to get the X11 sources. I
-can recommend the ftp sites of the XFree86 project ftp://ftp.xfree86.org
-or of the Open Group ftp://ftp.x.org. This patch was made on the sources
-of XFree86 so you may have better success with applying it to the
-XFree86 distribution. After you have got the sources, make sure
-that you can compile them. Then apply the patch as described.
-Make sure that it was applied properly. Compile the sources again
-(actually, you need only the fonts library, the fonts server, and
-possibly the X server). It would be prudent now to save your old
-font library, font server and, possibly, X server. Then install
-the new recently compiled versions of these files. Of course,
-if you know someone who already has compiled these files for the
-same \s-1OS\s0 as yours, you can just copy the binary fles from him.
-.Sp
-Alas, building the X11 system from the source code is not the
-easiest thing in the world and if you have no experience it
-can be quite difficult. In this case just avoid the aforementioned
-features or check each converted font to make sure that it
-works properly.
-.Ip "\(bu" 4
-The Type1 font library from the standard X11 distribution
-does not work on \s-1HP\s0\-\s-1UX\s0 (at least, up to 10.01). The font server
-supplied with \s-1HP\s0\-\s-1UX\s0 up to 10.01 is also broken. Starting from
-\s-1HP\s0\-\s-1UX\s0 10.20 (I don't know about 10.10) they supply a proprietary font
-library and the converted fonts work fine with it, provided that
-they are configured properly (see the file \s-1FONTS\s0.hpux).
-.Ip "\(bu" 4
-The \f(CWfonts.scale\fR files created by the older versions of the
-\f(CWttf2pt1\fR installation program (up to release 3.1) have conflicted
-with the language definitions of the \f(CWXfsft\fR font server and
-parts of it included into XFree86. To overcome this incompatibility
-the never versions creats the \f(CWfonts.scale\fR file describing all the
-fonts as belonging to the \f(CWadobe-fontspecific\fR encoding and
-the \f(CWfonts.alias\fR file with the proper names. The drawback of
-this solution is that \f(CWxlsfonts\fR gives the list of twice more
-fonts. But as a side effect the option \f(CW\fBENFORCEISO\fR\fR in
-`\f(CWconvert.cfg\fR\*(R' is not required for X11 any more.
-.Ip "\(bu" 4
-The conversion script has no support for Eastern multi-plane fonts.
-Contribution of such a support would be welcome.
-
-.rn }` ''
-.IX Title "TTF2PT1_CONVERT 1"
-.IX Name "B<ttf2pt1_convert> - convenience font conversion script"
-
-.IX Header "NAME"
-
-.IX Header "SYNOPSIS"
-
-.IX Header "DESCRIPTION"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Header "FILES"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Header "SEE ALSO"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Header "BUGS"
-
-.IX Subsection "Known problems"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
diff --git a/nx-X11/extras/ttf2pt1/ttf2pt1_x2gs.1 b/nx-X11/extras/ttf2pt1/ttf2pt1_x2gs.1
deleted file mode 100644
index 9ac5caad7..000000000
--- a/nx-X11/extras/ttf2pt1/ttf2pt1_x2gs.1
+++ /dev/null
@@ -1,323 +0,0 @@
-.rn '' }`
-''' $RCSfile: ttf2pt1_x2gs.1,v $$Revision: 1.2 $$Date: 2004/04/23 18:42:57 $
-'''
-''' $Log: ttf2pt1_x2gs.1,v $
-''' Revision 1.2 2004/04/23 18:42:57 eich
-''' 2004-04-23 Egbert Eich <eich@freedesktop.org>
-''' Merging XORG-CURRENT into trunk
-'''
-''' Revision 1.1.4.1 2004/04/21 10:03:13 gisburn
-''' Fix for http://pdx.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=530 - Land XPRINT branch on XORG-CURRENT
-'''
-''' Revision 1.1 2003/06/04 00:33:54 roland
-''' Fix for http://xprint.mozdev.org/bugs/show_bug.cgi?id=3846 - RFE: Upload Freetype --> PS Type1 font converter "ttf2pt1" ...
-'''
-'''
-.de Sh
-.br
-.if t .Sp
-.ne 5
-.PP
-\fB\\$1\fR
-.PP
-..
-.de Sp
-.if t .sp .5v
-.if n .sp
-..
-.de Ip
-.br
-.ie \\n(.$>=3 .ne \\$3
-.el .ne 3
-.IP "\\$1" \\$2
-..
-.de Vb
-.ft CW
-.nf
-.ne \\$1
-..
-.de Ve
-.ft R
-
-.fi
-..
-'''
-'''
-''' Set up \*(-- to give an unbreakable dash;
-''' string Tr holds user defined translation string.
-''' Bell System Logo is used as a dummy character.
-'''
-.tr \(*W-|\(bv\*(Tr
-.ie n \{\
-.ds -- \(*W-
-.ds PI pi
-.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
-.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
-.ds L" ""
-.ds R" ""
-''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of
-''' \*(L" and \*(R", except that they are used on ".xx" lines,
-''' such as .IP and .SH, which do another additional levels of
-''' double-quote interpretation
-.ds M" """
-.ds S" """
-.ds N" """""
-.ds T" """""
-.ds L' '
-.ds R' '
-.ds M' '
-.ds S' '
-.ds N' '
-.ds T' '
-'br\}
-.el\{\
-.ds -- \(em\|
-.tr \*(Tr
-.ds L" ``
-.ds R" ''
-.ds M" ``
-.ds S" ''
-.ds N" ``
-.ds T" ''
-.ds L' `
-.ds R' '
-.ds M' `
-.ds S' '
-.ds N' `
-.ds T' '
-.ds PI \(*p
-'br\}
-.\" If the F register is turned on, we'll generate
-.\" index entries out stderr for the following things:
-.\" TH Title
-.\" SH Header
-.\" Sh Subsection
-.\" Ip Item
-.\" X<> Xref (embedded
-.\" Of course, you have to process the output yourself
-.\" in some meaninful fashion.
-.if \nF \{
-.de IX
-.tm Index:\\$1\t\\n%\t"\\$2"
-..
-.nr % 0
-.rr F
-.\}
-.TH TTF2PT1_X2GS 1 "version 3.4.4-SNAP-030526" "May 26, 2003" "TTF2PT1 Font Converter"
-.UC
-.if n .hy 0
-.if n .na
-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
-.de CQ \" put $1 in typewriter font
-.ft CW
-'if n "\c
-'if t \\&\\$1\c
-'if n \\&\\$1\c
-'if n \&"
-\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7
-'.ft R
-..
-.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2
-. \" AM - accent mark definitions
-.bd B 3
-. \" fudge factors for nroff and troff
-.if n \{\
-. ds #H 0
-. ds #V .8m
-. ds #F .3m
-. ds #[ \f1
-. ds #] \fP
-.\}
-.if t \{\
-. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
-. ds #V .6m
-. ds #F 0
-. ds #[ \&
-. ds #] \&
-.\}
-. \" simple accents for nroff and troff
-.if n \{\
-. ds ' \&
-. ds ` \&
-. ds ^ \&
-. ds , \&
-. ds ~ ~
-. ds ? ?
-. ds ! !
-. ds /
-. ds q
-.\}
-.if t \{\
-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
-. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'
-. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'
-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
-. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10'
-.\}
-. \" troff and (daisy-wheel) nroff accents
-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
-.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
-.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#]
-.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'
-.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'
-.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#]
-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
-.ds ae a\h'-(\w'a'u*4/10)'e
-.ds Ae A\h'-(\w'A'u*4/10)'E
-.ds oe o\h'-(\w'o'u*4/10)'e
-.ds Oe O\h'-(\w'O'u*4/10)'E
-. \" corrections for vroff
-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
-. \" for low resolution devices (crt and lpr)
-.if \n(.H>23 .if \n(.V>19 \
-\{\
-. ds : e
-. ds 8 ss
-. ds v \h'-1'\o'\(aa\(ga'
-. ds _ \h'-1'^
-. ds . \h'-1'.
-. ds 3 3
-. ds o a
-. ds d- d\h'-1'\(ga
-. ds D- D\h'-1'\(hy
-. ds th \o'bp'
-. ds Th \o'LP'
-. ds ae ae
-. ds Ae AE
-. ds oe oe
-. ds Oe OE
-.\}
-.rm #[ #] #H #V #F C
-.SH "NAME"
-\fBttf2pt1_x2gs\fR \- font installer for Ghostscript
-.SH "SYNOPSIS"
-ttf2pt1_x2gs \fB[config-file]\fR
-.SH "DESCRIPTION"
-The fonts generated with \fBttf2pt1\fR work fine with Ghostscript by
-themselves. The script `\fBx2gs\fR\*(R' (or `\fBttf2pt1_x2gs\fR\*(R' when installed
-into a public directory, to avoid name conflicts with other
-programs) links the font files from the X11 direcotry into the Ghostscript
-directory and automatically creates the description file (\f(CWFontmap\fR)
-in Ghostscript format.
-.PP
-If the configuration file is not specified as an argument then the file
-`\f(CWconvert.cfg\fR\*(R' in the current directory is used, just like the
-`\f(CWconvert\fR\*(R' script does. Indeed, this configuration file is used for
-both scripts.
-.PP
-The Ghostscript-related parameters in the configuration file are:
-.PP
-\fB\f(CWDSTDIR\fR\fR \- the X11 font directory used by `\f(CWx2gs\fR\*(R' as the
-source of the fonts. This parameter is common with the X11
-configuration.
-.PP
-\fB\f(CWGSDIR\fR\fR \- the base directory of Ghostsript. If this
-parameter is set to an empty string then `\f(CWconvert\fR\*(R' won't
-call `\f(CWx2gs\fR\*(R'. So if you want to get only the X11 fonts
-installed then set this parameter to an empty string. This
-directory may vary on various system, so please check your
-system and set this value accordingly before running the script.
-.PP
-\fB\f(CWGSFONTDIR\fR\fR \- the font directory of Ghostscript. In the standard
-Ghostscript installation it's a subdirectory of \f(CWGSDIR\fR
-but some systems may use completely different directories.
-.PP
-\fB\f(CWGSCONFDIR\fR\fR \- the configuration subdirectory of Ghostscript
-that contains the \f(CWFontmap\fR file.
-.PP
-\fB\f(CWINSTALLFONTMAP\fR\fR \- if the value is set to \fB\f(CWYES\fR\fR then
-install the entries for the new fonts right into the main
-\f(CWFontmap\fR file. Otherwise just leave the file \f(CWFontmap.ttf\fR
-in the Ghostscript configuration directory.
-.PP
-After preparing the configuration file run the script. It symbolicaly links
-all the font files and creates the description file \f(CWFontmap.ttf\fR in
-\f(CWGSCONDFIR\fR. After that there are two choices.
-.PP
-If the option \f(CWINSTALLFONTMAP\fR was set to \f(CWYES\fR then
-the font descriptions are also automatically installed into the
-master \f(CWFontmap\fR file. The script is clever enough to
-detect if it was run multiple times with the same directories
-and if so it replaces the old \f(CWFontmap\fR entries with
-the new ones instead of just accumulating all of them. You
-may also run it multiple times for multiple X11 directories
-and all the results will be properly collected in the \f(CWFontmap\fR.
-But it's your responsibility to watch that the names of the
-font files don't overlap. If the X11 font directory gets
-renamed then you have to remove its font entries from the
-\f(CWFontmap\fR and only after that re-run `\f(CWx2gs\fR\*(R'
-for the new directory.
-.PP
-On the other hand if the option \f(CWINSTALLFONTMAP\fR was set to
-\f(CWNO\fR then go to the \f(CWGSCONFDIR\fR directory and insert the
-contents of \f(CWFontmap.ttf\fR into the \f(CWFontmap\fR file
-manually. This step may be left manual to make the installation
-a little bit more safe.
-.PP
-After that you may also want to redefine some of the aliases in
-\f(CWFontmap\fR to refer to the newly installed fonts.
-But the redefinition of the aliases may be dangerous if the width of
-characters in the new font will be different from the old font.
-Alas, there is no visible solution of this problem yet.
-.SH "FILES"
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/\s0scripts/convert.cfg.sample
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/\s0scripts/*
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/README\s0
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR/FONTS\s0
-.Ip "\(bu" 2
-\s-1TTF2PT1_SHAREDIR\s0/*
-.Ip "\(bu" 2
-\s-1TTF2PT1_BINDIR/\s0ttf2pt1
-.SH "SEE ALSO"
-.Ip "\(bu" 4
-the \fIttf2pt1(1)\fR manpage
-.Ip "\(bu" 4
-the \fIttf2pt1_convert(1)\fR manpage
-.Ip "\(bu" 4
-the \fIt1asm(1)\fR manpage
-
-.rn }` ''
-.IX Title "TTF2PT1_X2GS 1"
-.IX Name "B<ttf2pt1_x2gs> - font installer for Ghostscript"
-
-.IX Header "NAME"
-
-.IX Header "SYNOPSIS"
-
-.IX Header "DESCRIPTION"
-
-.IX Header "FILES"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Header "SEE ALSO"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
-.IX Item "\(bu"
-
diff --git a/nx-X11/extras/ttf2pt1/version.h b/nx-X11/extras/ttf2pt1/version.h
deleted file mode 100644
index d1b3525ba..000000000
--- a/nx-X11/extras/ttf2pt1/version.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * see COPYRIGHT
- */
-
-
-/* version number */
-#define TTF2PT1_VERSION "3.4.4-SNAP-030526"
diff --git a/nx-X11/extras/ttf2pt1/winbuild.bat b/nx-X11/extras/ttf2pt1/winbuild.bat
deleted file mode 100644
index 0e8c09341..000000000
--- a/nx-X11/extras/ttf2pt1/winbuild.bat
+++ /dev/null
@@ -1,11 +0,0 @@
-rem file to build ttf2pt1 with Visual C++
-
-cl -DWINDOWS -c bdf.c
-cl -DWINDOWS -c ttf2pt1.c
-cl -DWINDOWS -c pt1.c
-cl -DWINDOWS -c ttf.c
-cl -DWINDOWS -c t1asm.c
-cl -DWINDOWS -c bitmap.c
-cl -o ttf2pt1 ttf2pt1.obj pt1.obj t1asm.obj ttf.obj bdf.obj bitmap.obj
-cl -o t1asm -DWINDOWS -DSTANDALONE t1asm.c
-
diff --git a/nx-X11/extras/ttf2pt1/windows.h b/nx-X11/extras/ttf2pt1/windows.h
deleted file mode 100644
index a90ecf7e5..000000000
--- a/nx-X11/extras/ttf2pt1/windows.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Implementation of things missing in Windows
- */
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#undef ntohs
-#undef ntohl
-#undef htonl
-
-#ifdef WINDOWS_FUNCTIONS
-/* byte order */
-
-static unsigned short StoM(unsigned short inv) {
- union iconv {
- unsigned short ui;
- unsigned char uc[2];
- } *inp, outv;
-
- inp = (union iconv *)&inv;
-
- outv.uc[0] = inp->uc[1];
- outv.uc[1] = inp->uc[0];
-
- return (outv.ui);
-}
-
-static unsigned int ItoM(unsigned int inv) {
- union iconv {
- unsigned int ui;
- unsigned char uc[4];
- } *inp, outv;
-
- inp = (union iconv *)&inv;
-
- outv.uc[0] = inp->uc[3];
- outv.uc[1] = inp->uc[2];
- outv.uc[2] = inp->uc[1];
- outv.uc[3] = inp->uc[0];
-
- return (outv.ui);
-}
-
-unsigned short ntohs(unsigned short inv) { return StoM(inv); }
-unsigned long ntohl(unsigned long inv) { return ItoM(inv); }
-unsigned long htonl(unsigned long inv) { return ItoM(inv); }
-
-char *optarg;
-int optind=1;
-
-char getopt(int argc, char **argv, char *args) {
- int n,nlen=strlen(args),nLen=0;
- char nCmd;
-
- if (argv[optind] && *argv[optind]=='-') {
- nCmd=*((argv[optind]+1));
-
- for (n=0;n<nlen;n++) {
- if (args[n] == ':') continue;
- if (args[n] == nCmd) {
- if (args[n+1]==':') {
- char retVal;
- retVal=*(argv[optind]+1);
- optarg=argv[optind+1];
- if (!optarg) optarg="";
- optind+=2;
- return retVal;
- } else {
- char retVal;
- retVal=*(argv[optind]+1);
- optarg=NULL;
- optind+=1;
- return retVal;
- }
- }
- }
- }
- return -1;
-}
-
-#else
-
-unsigned short ntohs(unsigned short inv);
-unsigned long ntohl(unsigned long inv);
-unsigned long htonl(unsigned long inv);
-
-extern char *optarg;
-extern int optind;
-
-char getopt(int argc, char **argv, char *args);
-#endif