summaryrefslogtreecommitdiff
path: root/imageto
diff options
context:
space:
mode:
authorkarl <karl>2004-04-19 22:56:26 +0000
committerkarl <karl>2004-04-19 22:56:26 +0000
commitd2ffca200655a89c5d140b66d69001e92173e3da (patch)
tree6fa1965e6e8362c5913e1554b12507a924dba7f1 /imageto
parenteb33f9ace5a3ddfe8a983866468f3352abaa6391 (diff)
downloadfontutils-d2ffca200655a89c5d140b66d69001e92173e3da.tar.gz
init
Diffstat (limited to 'imageto')
-rw-r--r--imageto/ChangeLog1113
-rw-r--r--imageto/GNUmakefile43
-rw-r--r--imageto/README46
-rw-r--r--imageto/bitmap2.c83
-rw-r--r--imageto/bitmap2.h34
-rw-r--r--imageto/extract.c239
-rw-r--r--imageto/extract.h50
-rw-r--r--imageto/ifi.c196
-rw-r--r--imageto/ifi.h91
-rw-r--r--imageto/image-char.c69
-rw-r--r--imageto/image-char.h89
-rw-r--r--imageto/image-header.h35
-rw-r--r--imageto/input-img.c159
-rw-r--r--imageto/input-img.h43
-rw-r--r--imageto/input-pbm.c88
-rw-r--r--imageto/input-pbm.h44
-rw-r--r--imageto/main.c416
-rw-r--r--imageto/main.h42
-rw-r--r--imageto/out-chars.c750
-rw-r--r--imageto/out-chars.h34
-rw-r--r--imageto/out-epsf.c166
-rw-r--r--imageto/out-epsf.h28
-rw-r--r--imageto/out-strips.c94
-rw-r--r--imageto/out-strips.h27
-rw-r--r--imageto/strips.tex85
-rw-r--r--imageto/version.c1
26 files changed, 4065 insertions, 0 deletions
diff --git a/imageto/ChangeLog b/imageto/ChangeLog
new file mode 100644
index 0000000..7870509
--- /dev/null
+++ b/imageto/ChangeLog
@@ -0,0 +1,1113 @@
+Mon Apr 8 09:25:30 1996 Kathy Hargreaves <letters@cs.umb.edu>
+
+ * out-chars.c: doc fix.
+
+Sat Dec 9 07:21:29 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * out-chars.c: (do_image_line): doc fix.
+
+Wed Dec 6 08:28:15 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * out-chars.c: (output_chars): doc fix.
+
+Tue Dec 5 09:40:23 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * out-chars.c: doc fix.
+
+Mon Dec 4 07:40:24 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * main.c (USAGE): doc fix.
+
+ * out-chars.c: doc fix. Changed image_bitmap to image_line_bitmap.
+ (do_image_line): Changed original_box_count to previous_box_count.
+
+Sun Dec 3 09:05:05 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * out-chars.c: (do_image_line): doc fix.
+
+Thu Nov 30 09:03:47 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * out-chars.c: (output_chars): doc fix.
+
+Tue Nov 28 09:47:19 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * out-chars.c: (output_chars): reconsider the current bounding box
+ if the current character is ignored.
+
+Thu Nov 23 08:36:07 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * out-chars.c: (bitmap_to_gf_char): call kpse_find_tfm instead of
+ find_tfm_filename.
+
+Thu Nov 16 09:01:31 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * out-chars.c: (bitmap_to_gf_char): Remove output_name's suffix
+ before calling find_tfm_filename with it.
+
+ * main.c: (OUTPUT_NAME): Made on-static so could do below.
+
+ * main.h: Added output_name extern declaration.
+
+ * out-chars.c: (bitmap_to_gf_char): Call kpse_find_tfm with
+ find_tfm_filename(output_name) instead of something built with
+ input_name, so that will have the design size in the name.
+
+Tue Nov 14 07:28:21 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * ifi.c: (read_ifi_file): increment n after setting the charcode,
+ not before, so first character will have charcode 0.
+
+Sat Oct 14 14:54:27 1995 Kathy Hargreaves <karl@cs.umb.edu>
+
+ * out-chars.c: (bitmap_to_gf_char): Also have to call
+ remove_suffix on input name passed to kpse_find_tfm.
+
+Thu Oct 12 10:44:23 1995 Karl Berry <karl@cs.umb.edu>
+
+ * out-chars.c (bitmap_to_gf_char): Have to call basename on the
+ input name passed to kpse_find_tfm.
+
+Sun Aug 13 18:01:11 1995 Karl Berry <karl@cs.umb.edu>
+
+ * main.c: Call kpse_set_progname.
+
+Sun May 15 11:32:54 1994 Karl Berry (karl@cs.umb.edu)
+
+ * out-chars.c (output_chars): Change `x' to `<ignored>'.
+
+Fri May 13 15:27:29 1994 Karl Berry (karl@cs.umb.edu)
+
+ * out-chars.c (bitmap_to_gf_char): Call kpse_find_tfm, now that it
+ exists.
+
+Sun Aug 22 13:32:49 1993 Karl Berry (karl@cs.umb.edu)
+
+ * out-epsf.c (PIXELS_TO_BP): No longer needed.
+
+Sat Aug 7 13:44:10 1993 Karl Berry (karl@cs.umb.edu)
+
+ * input-img.c (img_get_header): Allow grayscale images.
+
+ * *.h: types.h now in kpathsea.
+
+Tue Jul 27 09:04:12 1993 Karl Berry (karl@cs.umb.edu)
+
+ * GNUmakefile (libraries): Add tfm.
+
+Sun Jul 25 19:20:04 1993 Karl Berry (karl@cs.umb.edu)
+
+ * out-chars.c (bitmap_to_gf_char): Get TFM width from existing TFM
+ file, if we can find one. Convert for use with kpathsea.
+
+Thu May 20 17:11:25 1993 Karl Berry (karl@cs.umb.edu)
+
+ * ifi.c: Doc fix.
+
+Mon Nov 9 09:46:32 1992 Karl Berry (karl@cs.umb.edu)
+
+ * image-header.h: Doc fix.
+
+Tue Oct 27 13:02:04 1992 Karl Berry (karl@cs.umb.edu)
+
+ * Version 0.6.
+
+Sat Oct 24 05:13:02 1992 Karl Berry (karl@cs.umb.edu)
+
+ * ifi.c (read_ifi_file): Just do successive character codes if we
+ don't have an encoding file.
+ * main.c (USAGE): Change doc.
+
+Fri Oct 23 10:43:46 1992 Karl Berry (karl@cs.umb.edu)
+
+ * out-chars.c (output_chars): Free the bounding box list we construct.
+
+ * out-chars.c (output_chars): If the IFI struct says no bounding
+ boxes, don't read any of the bitmap, and reconsider the current bb.
+
+Tue Oct 20 17:17:26 1992 Karl Berry (karl@cs.umb.edu)
+
+ * GNUmakefile (install): Make the second arg a file, not a directory.
+
+Fri Oct 16 15:40:53 1992 Karl Berry (karl@cs.umb.edu)
+
+ * out-epsf.c: Doc fix.
+
+Mon Oct 5 09:31:30 1992 Karl Berry (karl@cs.umb.edu)
+
+ * main.c (read_command_line): Make -print-clean-info imply -verbose.
+ (main): Remove now-redundant test for `print_clean_info'.
+
+ * out-chars.c (write_image_chars): Only report "+" if we have to
+ keep reading vertically, not horizontally.
+ (do_image_line): Remove the report from here.
+
+Sun Oct 4 08:59:55 1992 Karl Berry (karl@cs.umb.edu)
+
+ * out-chars.c (write_image_chars): Don't keep adding to
+ `row_height' for appended image rows, just assign.
+
+ * main.c (main): Test for zero resolution here.
+ (set_input_format): Not here.
+
+ * out-chars.c (clean_threshold): Remove.
+ * out-chars.h: Likewise.
+ * main.c (USAGE, read_command_line): And here.
+
+ * out-chars.c (bb_equal_p): New fn.
+
+ * out-chars.c (offset_bb_list): Function moved here from bb-outline.c.
+
+ * out-chars.c (clean_bitmap): Rewrite to take a list of known
+ boxes, and remove those that aren't in the list.
+ (output_chars): Only call `clean_bitmap' once, after we've
+ combined everything.
+ (image_to_bitmap_bbs): New fn.
+
+Sat Oct 3 13:54:39 1992 Karl Berry (karl@cs.umb.edu)
+
+ * out-chars.c (write_image_chars): Don't abort if the image ends
+ prematurely, just give a warning and return.
+
+ * out-chars.c (OUTPUT_CHAR_P): New macro.
+ (output_chars): Use it, instead of repeating the same expr several
+ times.
+
+Fri Oct 2 16:14:03 1992 Karl Berry (karl@cs.umb.edu)
+
+ * out-chars.[ch]: New files constructed from main.[ch].
+ * main.c: Include out-chars.h.
+
+ * extract.c (REPORT_SCANLINE): use REPORT.
+
+ * main.c (-info-filename): remove this option.
+
+ * {epsf,strips}.[ch]: Rename to out-*.
+ * GNUmakefile (c_and_h): Likewise.
+
+ * ifi.[ch]: New files constructed from image-char.[ch] and main.c.
+ * main.c: include ifi.h.
+ (extract_chars): Change call to read_ifi_file.
+ * GNUmakefile (c_and_h): add `ifi', remove `image-char'.
+
+Mon Sep 28 11:11:59 1992 Karl Berry (karl@cs.umb.edu)
+
+ * main.c: change `fprintf (stderr's to use REPORT*.
+
+ * main.c (clean_bitmap): print the size of the bounding box being
+ cleaned, not that of the enclosing character. (halvers@sol.crd.ge.com)
+
+Tue Sep 22 13:01:54 1992 Karl Berry (karl@cs.umb.edu)
+
+ * main.c (read_ifi_file): call make_suffix to make the default IFI
+ filename, instead of appending to the root.
+ (input_rootname): remove.
+ (main): don't assign to input_rootname; just set output_name to
+ the fn call.
+ (input_name): new static.
+
+ * main.c (clean_bitmap): if clean_threshold is 1.0, do nothing;
+ else only clean if the gray value is > threshold, not >=.
+
+ * main.c: make diagnostic messages consistent.
+
+ * main.c (do_image_line): set `bb_offset' to just the width
+ of the previous bb, since we're already incorporating the
+ interbb whitespace in the second bb.
+
+Mon Sep 21 10:32:07 1992 Karl Berry (karl@cs.umb.edu)
+
+ * main.c (read_command_line): new option -ifi-file, a synonym for
+ -info-file.
+ (USAGE): document it.
+
+ * main.c (set_input_format): don't call strcmp on NULL if the
+ input filename lacks an extension.
+
+Thu Sep 3 09:30:54 1992 Karl Berry (karl@hayley)
+
+ * Version 0.5.
+
+Sat Aug 29 16:14:35 1992 Karl Berry (karl@hayley)
+
+ * GNUmakefile (dist, install): new targets to deal with strips.tex.
+
+Fri Aug 21 16:14:10 1992 Karl Berry (karl@hayley)
+
+ * main.c (read_ifi_file): improve warning message.
+
+Mon Jul 13 16:58:44 1992 Karl Berry (karl@hayley)
+
+ * epsf.c (write_epsf): use `width_used' for the width of image buffer.
+
+Thu Jul 2 14:06:09 1992 Kathy Hargreaves (kathy@hayley)
+
+ * main.c (BB_TO_CARTESIAN): subtract IMAGE_CHAR_BASELINE_ADJUST(.)
+ instead of adding it.
+
+ * main.c (bitmap_to_gf_char): removed `char_baseline'.
+
+Sun Jun 28 11:54:23 1992 Kathy Hargreaves (kathy@hayley)
+
+ * main.c (bitmap_to_gf_char): added cartesian_bb; fill it using
+ BB_TO_CARTESIAN and assign to the GF char. Print out the GF
+ char's rows for baseline adjustment.
+
+Fri Jun 26 13:45:20 1992 Kathy Hargreaves (kathy@hayley)
+
+ * main.c (read_ifi_file): changed warning to include encoding name.
+
+Mon Jun 15 07:37:29 1992 Karl Berry (karl@hayley)
+
+ * extract.c (get_image_row): allocate more than one row at a time.
+
+ * extract.c (get_image_row): don't realloc if we're keeping
+ leading white rows.
+
+ * main.c (extract_chars): change `nchars_per_line' to one if
+ `print_guidelines' is true.
+
+ * main.c (read_ifi_file): if the character name is undefined in
+ the encoding, omit it from the output.
+
+ * main.c (get_image_info): rename to `read_ifi_file'.
+
+ * main.c (get_image_info): make `.notdef' mean omission, instead
+ of `-1'.
+
+ * image-char.h (image_char_type): new field `charname'.
+ (IMAGE_CHARNAME): new accessor macro.
+ * main.c (bitmap_to_gf_char): print the character name, instead of
+ relying on %c.
+ (get_image_info): set it.
+
+ * main.h (print_scanline): new routine.
+ * main.c (print_scanline): define it.
+ * input-img.c (img_get_scanline): print the scanlines if
+ `trace_scanlines' is set.
+ * input-pbm.c (pbm_get_scanline): call it, instead of doing the
+ printing inline.
+
+Sat Jun 13 12:04:00 1992 Kathy Hargreaves (kathy@hayley)
+
+ * main.c (get_image_info): renamed charcode_str to charname_str.
+ Removed comment-handling stuff.
+
+ * main.c (encoding_name, encoding_info): added.
+ (get_image_info): added `encoding_info'; call `encoding_number'
+ on `charcode_str' instead of `xparse_charcode'.
+ (USAGE, read_command_line): added -encoding option.
+
+Tue Jun 9 13:45:42 1992 Kathy Hargreaves (kathy@hayley)
+
+ * main.c (output_chars): deleted clean_all_bbs.
+ (clean_bitmap): deleted CLEAN_ALL_BBS; call find_outline_bbs
+ with false instead of this. Updated doc. Now only check
+ bounding boxes which don't enclose the whole character, instead
+ of those which also are on the edge, unless clean_all_bbs is
+ true, whereupon check those also.
+ (get_image_info): don't handle CLEAN_ALL_BBS_FLAG anymore.
+
+ * image-char.h (image_char_type): deleted clean_inner_bbs field.
+ (IMAGE_CHAR_CLEAN_ALL_BBS, CLEAN_ALL_BBS_FLAG): deleted
+
+Mon Jun 8 12:33:45 1992 Kathy Hargreaves (kathy@hayley)
+
+ * input-pbm.c (pbm_get_scanline): increment scanline_count after
+ printing it.
+
+ * main.c (BB_TO_CARTESIAN): added.
+ (bitmap_to_gf_char): when print-guidelines is true, print the
+ bounding box's max and min (in that order) row in Cartesian
+ coordinates, not the GF char's min and max row.
+
+Fri Jun 5 21:18:12 1992 Kathy Hargreaves (kathy@hayley)
+
+ * main.c (output_chars): don't clean bounding boxes unless
+ outputting the character.
+
+ * main.c (get_image_info): set clean_all_bbs field of `c' false if
+ there's not a CLEAN_ALL_BBS_FLAG at the end of the character string.
+
+Fri Jun 5 09:19:48 1992 Karl Berry (karl@hayley)
+
+ * main.c (main): `return 0' instead of `exit (0)'. (From Paul Eggert)
+
+Tue Jun 2 18:03:52 1992 Kathy Hargreaves (kathy@hayley)
+
+ * main.c (output_chars): call clean_bitmap with 0's for LEFT_MARK
+ and RIGHT_MARK if clean_all_bbs is true.
+
+Mon Jun 1 11:19:46 1992 Kathy Hargreaves (kathy@hayley)
+
+ * main.c (output_chars): added clean_all_bbs to send to clean_bitmap.
+
+ * main.c (clean_bitmap): clean only those boxes which are on the
+ edges only if CLEAN_ALL_BBS is false; otherwise, clean them all.
+
+ * main.c (get_image_info): if there's a CLEAN_ALL_BBS_FLAG appended
+ to the character code, then set the clean_all_bbs field of c.
+
+ * image-char.h (image_char_type): added clean_all_bbs field.
+
+Sun May 31 13:10:48 1992 Karl Berry (karl@hayley)
+
+ * main.c: rename `design-size' option to `designsize'.
+
+ * epsf.c (write_epsf): change the EPS output to not write one
+ gigantic image.
+
+Sat May 30 11:58:02 1992 Kathy Hargreaves (kathy@hayley)
+
+ * main.c (USAGE -clean-threshold): doc fix.
+
+Fri May 29 11:34:52 1992 Karl Berry (karl@hayley)
+
+ * main.c (main): declare to return an int.
+
+Tue May 26 07:56:34 1992 Karl Berry (karl@hayley)
+
+ * main.c: simplify comments on IFI file format, since now the real
+ documentation describes it.
+
+Mon May 25 11:45:49 1992 Karl Berry (karl@hayley)
+
+ * main.c (clean_bitmap): wasn't printing clean info for bbs that
+ weren't cleared.
+
+ * main.c (read_command_line): make -print-guidelines => -verbose.
+ (USAGE): document this.
+ (main): don't bother to test `print_guidelines' anymore when we
+ doing verbose things.
+
+ * main.c (main): use `output_name', not `gf_name' (which we no
+ longer need).
+
+ * main.c (set_{pbm,img}_input_format): set `input_extension' to
+ just `pbm' or `img', omitting the leading `.'.
+
+Sun May 24 18:03:09 1992 Karl Berry (karl@hayley)
+
+ * main.c (read_command_line): in -input-format, complain if they
+ give an unrecognized input format.
+ (main): call set_input_format.
+ (set_input_format): new routine to intuit the input format from
+ the input filename if they didn't specify.
+ (set_{pbm,img}_input_format): new routines.
+
+Thu May 21 10:59:23 1992 Karl Berry (karl@hayley)
+
+ * GNUmakefile, version.c, main.c: change `imagetofont' to `imageto'.
+
+ * strips.c (write_chars_as_strips): don't bother to initialize
+ `gf_row'.
+
+Wed May 20 07:34:38 1992 Karl Berry (karl@hayley)
+
+ * strips.h: include image-header.h, not input-img.h.
+
+ * main.c (extract_chars): new fn (to shorten main).
+ (main): call it.
+
+ * main.c (do_epsf): new global.
+ (read_command_line): new option `-epsf'.
+ (main): call `write_epsf' if set.
+ * GNUmakefile (c_and_h): add epsf.
+ * epsf.[ch]: new files.
+
+Mon May 4 09:27:55 1992 Karl Berry (karl@hayley)
+
+ * main.c (main): don't lose the `<dpi>gf' from the output name.
+
+ * strips.c (write_chars_as_strips): add one to `lines_per_char' to
+ compensate for roundoff error.
+
+ * main.c (verbose): remove this, as it's defined in report.c.
+
+Sun May 3 19:31:29 1992 Karl Berry (karl@hayley)
+
+ * strips.c (write_chars_as_strips): use REPORT for the progress
+ report.
+
+Tue Apr 21 07:44:36 1992 Karl Berry (karl@hayley)
+
+ * extract.c (append_next_image_row): use XTALLOC1.
+
+Mon Apr 20 12:53:43 1992 Karl Berry (karl@hayley)
+
+ * main.c (main): simplify logic again for figuring out the output
+ filename; remove any suffix from the input filename before it is
+ used to make the IFI or output filename.
+ (get_image_info): the variable is named `input_rootname' now, not
+ `input_basename'.
+
+Wed Apr 15 15:26:53 1992 Karl Berry (karl@hayley)
+
+ * main.c (main): `make_output_filename' is now `extend_filename'.
+
+Wed Apr 8 12:28:59 1992 Karl Berry (karl@hayley)
+
+ * main.c (do_image_line): don't increment the max_col transition
+ in the horizontally concatenated block, either.
+
+ * main.c: make most of the globals static.
+ * main.h: remove declarations for unneeded globals.
+
+ * main.c (debug): add this.
+
+Mon Apr 6 16:43:39 1992 Karl Berry (karl@hayley)
+
+ * extract.c (get_image_row): count white rows in image size; free
+ the scanline storage after we've copied it.
+
+Sun Apr 5 11:46:33 1992 Karl Berry (karl@hayley)
+
+ * main.c (do_image_line): don't increment the transition which we
+ use for the maximum column.
+
+Sat Apr 4 12:57:15 1992 Karl Berry (karl@hayley)
+
+ * main.c (do_image_line): move test for enough boxes to above
+ dealing with the current bitmap, so garbage at the end doesn't
+ mess us up. (from wales@cs.ucla.edu)
+
+Wed Apr 1 16:17:18 1992 Karl Berry (karl at hayley)
+
+ * main.c (main): simplify the output name creation code.
+
+ * main.c (font_name_extension): rename to `input_extension', and
+ don't bother to initialize it.
+
+Sat Mar 28 07:48:43 1992 Karl Berry (karl at hayley)
+
+ * Version 0.4.
+
+ * Change copyright years to 1992 only.
+
+Mon Mar 9 16:46:10 1992 Kathy Hargreaves (kathy at hayley)
+
+ * main.c (main): move setting of dpi to above (and out of)
+ do_strips test.
+
+ * main.c (main): set output_name_suffix with static strings
+ and xmalloc dpi and design_size_str.
+
+ * main.c (main): if output_name has no suffix, append either
+ output_name_suffix or design_size to its stem before appending
+ a suffix.
+
+Sat Mar 7 09:55:42 1992 Karl Berry (karl at hayley)
+
+ * GNUmakefile (libraries): define again.
+ (files, headers, sources): replace with `c_and_h', etc.
+
+Thu Mar 5 06:47:26 1992 Karl Berry (karl at hayley)
+
+ * main.c (output_filename): rename to `output_name', and remove
+ the other `output_name' declaration.
+
+Wed Mar 4 17:21:32 1992 Kathy Hargreaves (kathy at hayley)
+
+ * main.c (main) changed `output_basename' to `output_name'.
+ Deleted add_suffix and add_design_size.
+ Added dpi, design_size_str, and output_name_suffix.
+ Use make_output_filename to check if output name has a suffix.
+ If output_name not given and not doing strips, set design_size_str.
+ If doing strips, set output_name_suffix to "sp".
+ Always set dpi.
+
+Mon Mar 2 12:15:52 1992 Karl Berry (karl at hayley)
+
+ * main.c (main): decrease nchars_per_line to 11.
+
+Sun Mar 1 13:03:23 1992 Karl Berry (karl at hayley)
+
+ * GNUmakefile (files): remove bb-outline.
+
+ * GNUmakefile (need_pbm_library): define.
+ (sources): remove the PBM stuff.
+
+Fri Feb 28 07:53:09 1992 Karl Berry (karl at hayley)
+
+ * extract.c (image_row_transitions): new routine.
+ (some_black_to_all_white_row): call it after getting the image row.
+ (append_next_image_row): call it after appending.
+ (get_image_row): do not compute the transitions here.
+
+ * main.c (bitmap_to_gf_char): the GF min_row is the depth, the GF
+ max_row is the height; we had it the other way around. Also,
+ `row_baseline' is one-origin, but char rows are 0-origin.
+
+Tue Feb 25 14:40:54 1992 Karl Berry (karl at hayley)
+
+ * main.c (main): decrease number of chars reported without
+ guidelines to 12.
+
+ * input-pbm.c (pbm_get_scanline): declare the test character for
+ EOF as int, not char. Also, print the scanlines if
+ trace_scanlines is set.
+ * main.c (trace_scanlines): new global.
+ (read_command_line): new option.
+
+ * bitmap2.c (bitmap_vconcat): put one blank row between the
+ bitmaps, to compensate for what some_black... removed.
+
+ * extract.c (get_image_row): don't keep leading white rows if
+ there weren't any; always append scanline, even if there were.
+
+Fri Jan 31 17:08:38 1992 Karl Berry (karl at hayley)
+
+ * main.c (read_command_line): declare `option_index' (for new
+ getopt).
+
+Tue Jan 21 11:47:26 1992 Kathy Hargreaves (kathy at hayley)
+
+ * main.c (main): wasn't putting the suffix on the gf name when
+ gave an output filename without a suffix because was finding the
+ dot in the pathname `../fonts'.
+
+ * main.c (bitmap_to_gf_char): were switching the minimum and
+ maximum rows when assigning to the gf char.
+
+ * main.c (main): malloc gf_name more precisely.
+
+ * main.c (bitmap_to_gf_char): fixed calculation of gf char's rows.
+ (main): changed how build the gf output filename: if the user
+ specifies an output file, don't ever add on a design size and don't
+ add a suffix if there's one already.
+
+ * main.c (bitmap_to_gf_char): now print gf character's (baseline-
+ adjusted) row instead of the bounding box's (unadjusted) ones.
+
+Mon Jan 20 14:46:16 1992 Kathy Hargreaves (kathy at hayley)
+
+ * main.c (main): added variable `output_basename' so user could
+ specify an output file basename.
+ (read_command_line): Added `output-file' option.
+
+Tue Jan 14 13:14:46 1992 Kathy Hargreaves (kathy at hayley)
+
+ * main.c (get_image_info): when call libfile_start with
+ info_filename, specify "ifi" as the (now-default) suffix.
+
+ * main.c [USAGE] (info-file): use <filename>.ifi if <filename>
+ doesn't have a dotted suffix; otherwise use <filename>.
+
+Thu Jan 9 08:29:52 1992 Karl Berry (karl at hayley)
+
+ * main.c (read_command_line): rename `scan_integer_list' to
+ `scan_unsigned_list'.
+
+ * *.c: do not include global.h.
+
+ * *.h: remove #pragma once.
+
+Wed Jan 8 15:28:00 1992 Karl Berry (karl at hayley)
+
+ * update copyright messages.
+
+ * change `allocate to `xmalloc', `reallocate' to `xrealloc', and
+ `string_copy' to `strdup'.
+
+Tue Jul 30 13:18:48 1991 Karl Berry (karl at ra.cs.umb.edu)
+
+ * Version 0.3.
+
+Fri Jul 26 07:02:28 1991 Karl Berry (karl at hayley)
+
+ * main.c (get_image_info): read the left and side bearings from
+ the IFI file, if present.
+ (bitmap_to_gf_char): use these numbers.
+ * image-char.h (image_char_type): new members `lsb' and `rsb'.
+ (IMAGE_CHAR_{L,R}SB): new accessor macros.
+
+Wed Jul 24 06:07:11 1991 Karl Berry (karl at hayley)
+
+ * bitmap2.c (bitmap_concat): the height of the result is the
+ height of one, not twice that.
+
+ * main.c (do_image_line): rename `concat_bitmaps' to
+ `bitmap_concat'.
+ * GNUmakefile (files): new file `bitmap2'.
+
+ * main.c (do_image_line): return a boolean saying if we need
+ another image row.
+ (main): if `do_image_line' fails, read more of the image.
+ * extract.h (append_next_image_row): declare new routine.
+ * extract.c (append_next_image_row): define it.
+ (get_image_row): new routine.
+ (some_black_to_all_white_row): call `get_image_row'.
+
+ * make-gsfont.ps (octal-value): prepend 0 to the character code.
+
+ * extract.c (some_black_to_all_white_row): use xcalloc to initialize
+ `or_of_all', not allocate. We need it to be all zeroes
+ initially.
+
+ * main.c, version.c: change `imgtogf' to `imagetofont'.
+
+ * make-gsfont.ps: remove all the if-verbose's.
+
+ * main.c: doc fix.
+
+Mon Jul 22 07:54:42 1991 Karl Berry (karl at hayley)
+
+ * make-gsfont.ps (output-encoding): set /output-encoding to the
+ dictionary.
+
+ * main.c: output ``imagetofont'' as our name in the GF file header,
+ instead of ``IMGtoGF''.
+
+ * make-gsfont.ps (print-char-dimensions-if-verbose): lose the
+ `-if-verbose'.
+
+ * make-gsfont.ps (octal-value): `get' the character name, don't
+ `load' it, so we find it in the right dictionary.
+
+ * libpbm1.c: declare parms, external functions to avoid warnings.
+
+Sat Jun 15 09:50:46 1991 Karl Berry (karl at hayley)
+
+ * input-*.c: change `checked_' to `x'.
+
+Thu Jun 6 07:29:06 1991 Karl Berry (karl at hayley)
+
+ * All files: change to version 2 of the GPL.
+
+Sat Jun 1 15:18:11 1991 Kathy Hargreaves (kathy at hayley)
+
+ * main.c (get_image_info): Now build an info filename if the
+ variable info_filename *is* NULL, not when it's not.
+ (USAGE): Deleted that resolution was set only for pbm input.
+ Stated that input-format is required and shortened comment.
+
+Fri May 31 14:30:01 1991 Kathy Hargreaves (kathy at hayley)
+
+ * imgtogf: Moved directory to `imagetofont'.
+
+ * GNUmakefile: Changed program name from `imgtogf' to `imagetofont'.
+
+ * main.c (get_image_info): Make default image info file be
+ <fontname>.ifi instead of imginf.<fontname>.
+
+ * main.[hc], input-*.[hc]: *_get_header now don't return a
+ header but rather modify the global header in main.c. Changed
+ all references to `[img, pbm]_header->' to `image_header.'.
+
+ * main.c, image-char.[hc]: Replaced all instances of `img_char'
+ with `image_char'.
+
+ * image-char.[hc]: Moved from img-char.[hc].
+
+ * main.h (image_header): Made this visible to the outside.
+
+ * input-[pbm, img].c ([pbm, img]_get_header): Set h to
+ image_header in main.c. #include main.h.
+
+ * main.c (read_command_line): Cast the assignment to
+ image_header.hres to type two_bytes.
+
+ * image-header.h, input-*.[hc], main.[hc]: Changed `img-header.h'
+ to `image-header.h'.
+
+ * main.c: Replaced all instances of `img_header*' with
+ `image_header*'. Moved `img_' and `pbm_' to the front of the
+ function names.
+
+ * img-header.h: Moved to image_header.h and replaced all
+ instances of `img_header*' with `image_header*'.
+
+ * input-img.[hc] (*_img_*): Moved `img_' to the front of the
+ variable names. Replaced instances of `img_header_type' with
+ `image_header_type'.
+
+ * input-pbm.[hc] (*_pbm_*): Moved `pbm_' to the front of the
+ variable names.
+
+ * extract.c, strips.c: (ptr_get_scanline): Removed `ptr_' from in
+ front of this function's name and replaced it with `image'.
+ Replaced instances of `img_header*' with `image_header*', if any.
+
+ * main.h (ptr_open_input_file, ptr_close_input_file, ptr_get_header,
+ ptr_get_scanline): Removed `ptr_' from the front of all these
+ names and replaced it with `image'. Replaced `img_header_type'
+ with `image_header_type'.
+
+ * main.c (ptr_open_input_file, ptr_close_input_file, ptr_get_header,
+ ptr_get_scanline): Moved and set all to NULL.
+ Removed `ptr_' from the front of all these names and replaced it
+ with `image'.
+ (read_command_line): Remove "img-input-format" from option
+ structure.
+ Removed variable need_resolutions, as don't need it.
+ Force them to specify the input format on the command line
+ rather than having a default.
+
+Wed May 29 16:19:57 1991 Kathy Hargreaves (kathy at hayley)
+
+ * input-pbm.c (line_in_bytes): Deleted this global variable, as
+ don't need it. (pbm_readpbmrow reads right into line_in_bits in
+ get_pbm_scanline.)
+
+ * pbm.h: Took out #include for types.h.
+
+ * input-pbm.c (get_pbm_scanline): Check if at EOF before calling
+ pbm_readpbmrow.
+
+ * libpbm2.c (pbm_readpbmrow): Restored to original; can test if at
+ EOF in the wrapper get_pbm_scanline.
+ Took out #include for types.h.
+
+ * input-pbm.c (get_pbm_scanline): Hooked up to libpbm2.c routine.
+
+ * main.c (read_command_line): Combined some options and changed
+ their names and their input.
+ Make input-format take an argument.
+
+Mon May 27 14:52:45 1991 Kathy Hargreaves (kathy at hayley)
+
+ * main.c (read_commandline): If both resolutions are missing and
+ are required on the commandline, print that they both are, not
+ just that the horizontal one is.
+
+ * bb-outline.c (is_outline_edge): Changed VALID_LOCATION to
+ BITMAP_VALID_PIXEL.
+
+ * pbmplus.h: Commented out malloc, etc. declarations.
+
+ * libpbm2.c (pbmreadpbmrow): Make it return a boolean instead of a
+ void, so will fit into our code.
+ Make it return false instead of an error message.
+
+ * pbm.h (top): pbmplus.h is in the current directory, so take out
+ the `../' before it in the #include.
+ (pbmreadpbmrow): Make it return a boolean instead of a void, so
+ will fit into our code.
+
+ * extract.c (top): Now #include input-pbm.h.
+ (some_black_to_all_white_row): Changed all instances of
+ get_img_scanline to get_scanline.
+
+ * input-img.c (top): Now #include img-header.h.
+ (get_img_header): Got rid of variable format, as now put that in
+ the header.
+
+ * main.c: (open_input_file, close_input_file, get_header,
+ get_scanline): Declared these pointers to functions so could set
+ them to a set of routines belonging to the type of input we're
+ using. Set them to .pbm input format routines as a default.
+ (font_name_extension): Added this static variable so could set
+ it when get read the input format on the command line. Set to
+ `.pbm' by default.
+ (main): Initialize img_header to all zeros so will know if the
+ user set them using the command line.
+ Changed call to open_img_input_file to open_input_file and
+ concat font_name_extension instead of ".img" for the argument.
+ Changed some comments.
+ Changed the call to get_img_header to get_header.
+ Changed the call to close_img_input_file to close_input_file.
+ (USAGE): Added horz-resolution, img-input-format,
+ pbm-input-format, and vert-resolution.
+ (read_command_line): Added boolean variable need_resolutions to
+ keep track of whether or not the user needs to input the
+ horizontal and vertical resolutions on the command line.
+ Added horz-resolution, img-input-format, pbm-input-format, and
+ vert-resolution to the option variable long_options.
+ If the argument is horz-resolution or vert-resolution, then set
+ the appropriate field in the header.
+ If the argument if img-input-format or pbm-input-format, the set
+ the input function pointers in main to the appropriate set of
+ functions that belong to the input format. If the argument is
+ the former, then set needs_resolution to false; if it's the latter,
+ set it to true.
+ If the user wants .pbm input format, then check that the header's
+ resolutions are set; if not, issue an error message and exit.
+
+ * main.h (open_input_file, close_input_file, get_header, get_scanline):
+ Added these function pointer declarations so extract.c and strips.c
+ could use them.
+
+ * strips.c (top): Now #include input-pbm.h.
+ (write_chars_as_strips): Changed the call to get_img_scanline to
+ a call to get_scanline.
+
+Sat Apr 13 17:13:51 1991 Karl Berry (karl at hayley)
+
+ * main.c (get_image_info): use the libfile routines to read the
+ image info files.
+
+ * main.c, input-img.c: new includes from the library
+ rearrangements.
+
+Mon Feb 25 16:32:45 1991 Karl Berry (karl at hayley)
+
+ * main.c, strips.c: use `gf_...' instead of `..._gf_...'.
+
+Sun Feb 17 09:39:20 1991 Karl Berry (karl at hayley)
+
+ * *.c: include config.h.
+
+Tue Jan 22 15:43:19 1991 Karl Berry (karl at hayley)
+
+ * extract.[ch] (extract_subimage): move to kbase.
+
+Thu Jan 17 10:32:09 1991 Karl Berry (karl at hayley)
+
+ * main.c (main): don't put the day of the week in the font comment.
+
+Tue Oct 9 09:07:02 1990 Karl Berry (karl at hayley)
+
+ * main.c (scan_baseline_list): move to kbase.
+ (baseline_list): make a vector of ints, not unsigneds.
+ (main): test for the end of the baseline list being -1, not 0.
+
+Mon Oct 8 16:37:07 1990 Karl Berry (karl at hayley)
+
+ * main.c: #include cmdline.h.
+ (read_command_line): call FINISH_COMMAND_LINE.
+
+Sun Sep 30 09:15:25 1990 Karl Berry (karl at hayley)
+
+ * main.c (do_image_line): don't give a report when we read part of
+ the line, after all.
+
+Fri Sep 28 13:47:15 1990 Karl Berry (karl at hayley)
+
+ * main.c (scan_integer_list): use strtok, instead of doing the
+ work ourselves.
+
+Sat Sep 22 06:16:49 1990 Karl Berry (karl at hayley)
+
+ * main.c (output_chars): don't increment `current_char' if we've
+ already seen the box.
+
+Fri Sep 21 08:40:49 1990 Karl Berry (karl at hayley)
+
+ * img-char.h (img_char_type): new element, `alternating'.
+ (IMG_CHAR_BB_ALTERNATING): macro to access it.
+ * main.c (get_image_info): if the bb count is negative, set
+ `alternating' (and make it positive).
+ (output_chars): handle the bounding boxes alternating.
+
+ * main.c (do_image_line): give a progress report when we read part
+ of the line.
+
+ * main.c (read_command_line): return NULL at the end; the POSIX
+ include files don't declare `exit' as volatile, more's the pity.
+ * bb-output.c (is_outline_edge): return false at the end, for the
+ same reason.
+
+Sun Sep 16 11:13:43 1990 Karl Berry (karl at hayley)
+
+ * main.c: include "getopt.h" instead of <getopt.h>.
+
+ * main.c (read_command_line): change call of PARSE_CHAR_CODE to
+ xparse_char_code.
+
+ * main.c (main): make the default info filename `imginf.<name>',
+ not `imginfo.<name>'.
+
+Sat Sep 8 10:06:19 1990 Karl Berry (karl at hayley)
+
+ * main.c (read_command_line): remove any suffix on the font name
+ before returning it.
+
+ * main.c (read_command_line): use GET_RANGE.
+
+ * main.c (get_image_info): use PARSE_CHAR_CODE to get the
+ character code from the file.
+
+Thu Sep 6 06:16:29 1990 Karl Berry (karl at hayley)
+
+ * main.c (scan_integer_list): doc fix.
+
+Wed Sep 5 06:19:53 1990 Karl Berry (karl at hayley)
+
+ * main.c (USAGE): doc fix in -range.
+
+Tue Sep 4 09:33:49 1990 Karl Berry (karl at hayley)
+
+ * main.c (do_image_line): pass the current character to
+ output_chars, not the current box count.
+
+ * extract.c (REPORT_SCANLINE): output to stderr instead of stdout.
+
+ * main.c (get_image_info): always assign to the character code and
+ omit fields.
+
+Mon Sep 3 16:57:02 1990 Karl Berry (karl at hayley)
+
+ * main.c (get_image_info): use NULL in subsequent calls to strtok.
+
+ * main.c (get_encoding): replace with get_image_info; change
+ callers.
+ * img-char.[ch]: new files to support the data structure.
+
+Thu Aug 16 08:00:19 1990 Karl Berry (karl at hayley)
+
+ * bb-outline.c (free_bounding_box_list): check if the list is
+ allocated before freeing it.
+
+ * main.c (do_image_line): only say that we've read too many boxes
+ once.
+
+Wed Aug 8 08:06:53 1990 Karl Berry (karl at hayley)
+
+ * main.c (read_command_line): change `encoding-file' to
+ `info-file'.
+
+Tue Aug 7 08:53:13 1990 Karl Berry (karl at hayley)
+
+ * main.c (main): use the basename of the image filename to
+ construct the output name, instead of the full name.
+
+ * main.c (USAGE): explain `-baselines' better.
+
+Thu Jul 26 06:54:56 1990 Karl Berry (karl at hayley)
+
+ * extract.c (find_transitions): move to kbase.
+
+Tue Jul 24 13:09:38 1990 Karl Berry (karl at hayley)
+
+ * main.c: don't include time.h.
+
+Thu Jul 19 15:22:29 1990 Karl Berry (karl at aten)
+
+ * main.c (main): don't dereference baseline_list if it's null.
+
+Mon Jul 16 08:56:41 1990 Karl Berry (karl at hayley)
+
+ * main.c (clean_bitmap): only print the `. ' if we're printing the
+ cleaning info.
+
+Sun Jul 15 08:27:52 1990 Karl Berry (karl at hayley)
+
+ * bb-outline.c (append_bounding_box_list): don't change anything
+ if we're appending a list of length zero.
+
+Fri Jul 13 11:35:15 1990 Karl Berry (karl at hayley)
+
+ * main.c (clean_bitmap): also potentially clean bounding boxes on
+ the bottom edge.
+
+ * main.c (SET_EDGES): make coordinates relative to the bitmap of
+ the character.
+
+ * main.c (clean_bitmap): only test the gray value for bounding
+ boxes that are on the edge.
+
+ * main.c (output_chars): return the number of characters actually
+ output, omitting the ones out of range.
+
+ * main.c (clean_bitmap): print gray values for the bounding boxes
+ if requested.
+ (read_command_line): new option, `print_clean_info'.
+
+Thu Jul 12 06:08:33 1990 Karl Berry (karl at hayley)
+
+ * extract.c (some_black_to_all_white_row): don't output a newline
+ after reading the scanlines.
+
+ * main.h: new file.
+ * extract.c: include it, remove declaration of verbose.
+
+ * strips.[ch]: new files.
+ * main.c (main): cut the image into strips if requested.
+ (read_command_line): new option `strips'.
+
+ * extract.c (find_transitions): new routine.
+ (some_black_to_all_white_row): call it, at the end, with a new
+ variable that is the logical or of all the rows we read.
+ (some_black_to_all_white_column, found_color_in_column): these
+ routines aren't needed any more.
+ * main.c (do_image_line): use the transition vector to set
+ `char_bitmap'.
+
+ * main.c (scan_integer_list): increment length after checking the
+ exit condition.
+
+ * main.c (do_image_line): new routine, consisting of a lot of the
+ main loop.
+
+ * main.c (bitmap_to_gf_char): determine the baseline.
+ (read_command_line): new option `baselines' to set the baselines.
+ (scan_integer_list): new routine.
+
+ * extract.c (found_color_in_column): start halfway down the
+ bitmap.
+
+Wed Jul 11 06:19:51 1990 Karl Berry (karl at hayley)
+
+ * main.c (bitmap_to_gf_char): take another argument, the character
+ code, to consolidate where the GF char is set.
+
+ * main.c (nchars_per_line): new static to say how many characters
+ we can report on per line; different for `print_guidelines' being
+ set and not set.
+
+ * main.c (print_guidelines): new global.
+ (read_command_line): new option to set it.
+ (bitmap_to_gf_char): print the row numbers if it's set.
+
+ * bb-outline.c (find_outline_bbs): take two additional arguments:
+ column numbers between which we don't look.
+ * bb-outline.h (find_outline_bbs): change the declaration.
+ * main.c (main), (clean_bitmap): change the calls.
+
+ * bb-outline.c (append_bounding_box_list): reallocate based on the
+ element size, not the list size.
+
+ * bb-outline.c (set_bounding_box_list_offset): replace by
+ `offset_bounding_box_list'.
+ (append_bb): don't offset the bounding boxes as they come in.
+ * bb-outline.h (set_bounding_box_list_offset): likewise.
+ * main.c (main): change call.
+
+ * main.c (output_chars): set char_code to *next_code at the bottom
+ of the loop, and increment next_code.
+
+Tue Jul 10 06:10:05 1990 Karl Berry (karl at hayley)
+
+ * bb-outline.c (set_bounding_box_list_offset): new routine.
+ (append_bb): move the bounding box to the right by the offset.
+ * bb-outline.h (set_bounding_box_list_offset): declare it.
+
+ * main.c (get_char_code): rename to get_encoding, and read the
+ whole file.
+
+ * bb-outline.h (init_bounding_box_list, append_bounding_box_list):
+ declare new routines.
+ bb-outline.c (same): define them.
+
+Mon Jul 9 08:10:20 1990 Karl Berry (karl at hayley)
+
+ * main.c (main): don't split each line at white columns.
+
+ * extract.c (clean_bitmap): set verbose to false before calling
+ find_outline_bbs.
+
+ * main.c (get_char_code): make sure we actually find a character
+ code.
+
+ * main.c (output_chars): don't extract or clean anything if the
+ character isn't within range.
+
+ * extract.c (REPORT_SCANLINE): report every 100 scanlines.
+
+ * main.c (output_chars): only give the status report if we
+ actually output the character.
+
+Sat Jul 7 10:43:18 1990 Karl Berry (karl at hayley)
+
+ * bb-outline.c (append_bb): changed MAX_ROW, instead of MAX_COL.
+
+ * main.c (clean_bitmap): new routine.
+ (output_gf_chars): call it.
+ * bb-outline.c (find_outline_bbs): take an additional parameter to
+ determine whether to look for inside outlines or not.
+
+ * extract.c (REPORT_SCANLINE): report every 50 scanlines, instead
+ of every 10.
+
+ * bb-outline.c (find_outline_bbs): look for outlines in
+ column-major order, instead of row-major.
+
diff --git a/imageto/GNUmakefile b/imageto/GNUmakefile
new file mode 100644
index 0000000..2fcac49
--- /dev/null
+++ b/imageto/GNUmakefile
@@ -0,0 +1,43 @@
+# Makefile for image conversion program.
+#
+# Copyright (C) 1992 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+program = imageto
+
+c_and_h = bitmap2 extract ifi input-img input-pbm main \
+ out-chars out-epsf out-strips
+h_only = image-header
+c_only = version
+
+libraries = gf pbm tfm
+
+include ../data/defs.make
+include ../data/defsprog.make
+
+check:
+ cd /w/ourfonts/dingbats ; gftopk -v g111236.1200gf
+
+
+dist::
+ ln strips.tex $(distdir)
+
+install::
+ $(INSTALL_DATA) strips.tex $(texinputdir)/strips.tex
+
+include M.depend
+
+
diff --git a/imageto/README b/imageto/README
new file mode 100644
index 0000000..31f228f
--- /dev/null
+++ b/imageto/README
@@ -0,0 +1,46 @@
+This program extracts the characters from a big image to a GF font file.
+Information about the image is given in an ``image font information''
+(IFI) file; that file format is described in the documentation.
+
+Currently the program can read the IMG files output by the Scan7650
+software, which works with the fancy Xerox 9750 scanner. (I think IMG
+output is used by other GEM applications as well.) These images are
+used by the Interleaf desktop publishing program. The image format
+isn't proprietary, though -- it doesn't have any novel features. The
+message below describes the format.
+
+It can also read PBM files.
+
+
+Date: Thu, 5 Jul 90 11:22:55 EDT
+From: rgw@hq.ileaf.com (Bob Watkins x5545)
+To: karl@cs.umb.edu
+
+The image file consists of an OPSHEADER followed by an IMGHEADER, followed
+by raster data. The version field of the OPSHEADER determines which of the
+IMGHEADER structures to use. Most likely this will be 2, but there is a
+chance that it might be 1 -- it depends on how recently the software for
+that scanner was written.
+
+When reading the headers structures, it is a good idea to read them a field
+at a time rather than all at once, since not all compilers use the same
+structure padding conventions.
+
+The resolution numbers are in pixels/inch. Their primary purpose is to
+allow TPS to scale the image to the correct physical dimensions when it is
+pasted into the document. Other than that, they aren't that useful.
+
+The flags field should be zero -- there is a stupid marketing reason why it
+is there at all, but I won't go into that.
+
+The w and h fields are the width and height of the image in pixels; the d
+field is the depth in bits/pixel. The depth is either 1 or 8, depending on
+whether the image is a lineart image or a contone image.
+
+The format field specifies the encoding of the raster data. A format of 0
+means that the data is uncompressed. The data itself is stored in scanline-
+major order. In the case of lineart image, 8 pixels are packed into each
+byte, with most-to-least significant order within the byte representing left-
+to-right order in the image. A 0 bit corresponds to a black pixel, and a 1
+bit corresponds to a white pixel. If necessary, the scanlines are padded out
+to the next 16-bit boundary.
diff --git a/imageto/bitmap2.c b/imageto/bitmap2.c
new file mode 100644
index 0000000..67d3d09
--- /dev/null
+++ b/imageto/bitmap2.c
@@ -0,0 +1,83 @@
+/* bitmap2.c: extra bitmap manipulation routines.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#include "bitmap.h"
+
+#include "bitmap2.h"
+
+
+
+/* Put B2 to the right of B1, changing B1. For example, if B1 looked
+ like `A' and B2 like `B', the result would look like `AB'. The two
+ bitmaps must have the same number of rows. */
+
+void
+bitmap_concat (bitmap_type *b1, bitmap_type b2)
+{
+ bitmap_type new;
+ dimensions_type new_dimens;
+ unsigned row;
+
+ assert (BITMAP_HEIGHT (*b1) == BITMAP_HEIGHT (b2));
+
+ DIMENSIONS_WIDTH (new_dimens) = BITMAP_WIDTH (*b1) + BITMAP_WIDTH (b2);
+ DIMENSIONS_HEIGHT (new_dimens) = BITMAP_HEIGHT (b2);
+ new = new_bitmap (new_dimens);
+
+ /* Choice of `b2' or `b1' here is arbitrary, of course. */
+ for (row = 0; row < BITMAP_HEIGHT (b2); row++)
+ {
+ one_byte *target1 = BITMAP_ROW (new, row);
+ one_byte *target2 = target1 + BITMAP_WIDTH (*b1);
+
+ memcpy (target1, BITMAP_ROW (*b1, row), BITMAP_WIDTH (*b1));
+ memcpy (target2, BITMAP_ROW (b2, row), BITMAP_WIDTH (b2));
+ }
+
+ free_bitmap (b1);
+ *b1 = new;
+}
+
+
+/* Return a bitmap which consists of B1, one blank row, and B2. The two
+ bitmaps must have the same width. (The blank row is necessary
+ because one blank row is removed the first time we call
+ some_black_to_all_white; consider the row consisting of just an `!'.)*/
+
+bitmap_type
+bitmap_vconcat (bitmap_type b1, bitmap_type b2)
+{
+ bitmap_type new;
+ dimensions_type new_dimens;
+ unsigned width = BITMAP_WIDTH (b1);
+ unsigned size1 = width * BITMAP_HEIGHT (b1);
+ unsigned size2 = width * BITMAP_HEIGHT (b2);
+
+ assert (width == BITMAP_WIDTH (b2));
+
+ DIMENSIONS_WIDTH (new_dimens) = width;
+ DIMENSIONS_HEIGHT (new_dimens) = BITMAP_HEIGHT (b1) + BITMAP_HEIGHT (b2) + 1;
+ new = new_bitmap (new_dimens);
+
+ memcpy (BITMAP_BITS (new), BITMAP_BITS (b1), size1);
+ memcpy (BITMAP_BITS (new) + size1 + width, BITMAP_BITS (b2), size2);
+
+ return new;
+}
diff --git a/imageto/bitmap2.h b/imageto/bitmap2.h
new file mode 100644
index 0000000..d643117
--- /dev/null
+++ b/imageto/bitmap2.h
@@ -0,0 +1,34 @@
+/* bitmap2.h: declare extra bitmap manipulation routines.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef BITMAP2_H
+#define BITMAP2_H
+
+#include "bitmap.h"
+
+
+/* Put B2 to the right of B1, changing B2. The two bitmaps must have
+ the same number of rows. */
+extern void bitmap_concat (bitmap_type *b1, bitmap_type b2);
+
+
+/* Put B2 below B1. The two bitmaps must have the same number of
+ columns. */
+extern bitmap_type bitmap_vconcat (bitmap_type b1, bitmap_type b2);
+
+#endif /* not BITMAP2_H */
diff --git a/imageto/extract.c b/imageto/extract.c
new file mode 100644
index 0000000..2482646
--- /dev/null
+++ b/imageto/extract.c
@@ -0,0 +1,239 @@
+/* extract.c: operations on bitmaps. These could be put in
+ lib/bitmap.c, but since they are not particularly common
+ operations, we may as well define them separately for now.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#include "bitmap.h"
+#include "bounding-box.h"
+#include "report.h"
+
+#include "bitmap2.h"
+#include "extract.h"
+#include "main.h"
+#include "input-img.h"
+#include "input-pbm.h"
+
+static bitmap_type *get_image_row (boolean, unsigned);
+static unsigned *image_row_transitions (bitmap_type);
+
+
+
+
+/* Combine the images in the bitmaps B1 and B2, returning the result in
+ B1. The relative position of the bitmaps is given by the bounding
+ boxes BB1 and BB2. We update the bounding box, also. */
+
+void
+combine_images (bitmap_type *b1, bitmap_type b2,
+ bounding_box_type *bb1, bounding_box_type bb2)
+{
+ int this_row, this_col;
+ bitmap_type whole_bitmap;
+ bounding_box_type whole_bb;
+
+ /* If either of the bitmaps are nonexistent, we have nothing
+ significant to do. */
+ if (BITMAP_BITS (b2) == NULL)
+ return;
+ if (BITMAP_BITS (*b1) == NULL)
+ {
+ *b1 = b2;
+ return;
+ }
+
+ MIN_ROW (whole_bb) = MIN (MIN_ROW (*bb1), MIN_ROW (bb2));
+ MAX_ROW (whole_bb) = MAX (MAX_ROW (*bb1), MAX_ROW (bb2));
+ MIN_COL (whole_bb) = MIN (MIN_COL (*bb1), MIN_COL (bb2));
+ MAX_COL (whole_bb) = MAX (MAX_COL (*bb1), MAX_COL (bb2));
+
+ whole_bitmap = new_bitmap (bb_to_dimensions (whole_bb));
+
+ /* First, copy the first image in. */
+ for (this_row = MIN_ROW (*bb1); this_row <= MAX_ROW (*bb1); this_row++)
+ {
+ one_byte *target_row
+ = BITMAP_BITS (whole_bitmap)
+ + (this_row - MIN_ROW (whole_bb)) * BITMAP_WIDTH (whole_bitmap)
+ + MIN_COL (*bb1) - MIN_COL (whole_bb);
+ one_byte *source_row
+ = BITMAP_BITS (*b1)
+ + (this_row - MIN_ROW (*bb1)) * BITMAP_WIDTH (*b1);
+
+ memcpy (target_row, source_row, BITMAP_WIDTH (*b1));
+ }
+
+ /* Put the second image in. */
+ for (this_row = MIN_ROW (bb2); this_row <= MAX_ROW (bb2); this_row++)
+ for (this_col = MIN_COL (bb2); this_col < MAX_COL (bb2); this_col++)
+ {
+ if (BITMAP_PIXEL (b2, this_row - MIN_ROW (bb2),
+ this_col - MIN_COL (bb2)) == BLACK)
+ BITMAP_PIXEL (whole_bitmap, this_row - MIN_ROW (whole_bb),
+ this_col - MIN_COL (whole_bb))
+ = BLACK;
+ }
+
+ free_bitmap (b1);
+ *b1 = whole_bitmap;
+ *bb1 = whole_bb;
+}
+
+/* Get the next image row of width WIDTH, ignoring leading white rows.
+ Return the columns at which there are black-to-white or white-black
+ transitions in TRANSITIONS. */
+
+bitmap_type *
+some_black_to_all_white_row (unsigned width, unsigned **transitions)
+{
+ bitmap_type *new = get_image_row (false, width);
+ if (new == NULL)
+ return NULL;
+
+ *transitions = image_row_transitions (*new);
+ return new;
+}
+
+
+/* Get the next image row, including leading blank rows, concatenating
+ it below B with one blank row between. Otherwise like
+ `some_black_to_all_white_row'. */
+
+bitmap_type *
+append_next_image_row (bitmap_type b, unsigned width, unsigned **transitions)
+{
+ bitmap_type *new = XTALLOC1 (bitmap_type);
+ bitmap_type *next = get_image_row (true, width);
+
+ if (next == NULL)
+ return NULL;
+
+ *new = bitmap_vconcat (b, *next);
+ *transitions = image_row_transitions (*new);
+ return new;
+}
+
+/* Because scanlines take a relatively long time to read, we will want
+ some kind of status report. */
+
+#define REPORT_SCANLINE() if (++scanline_count % 100 == 0) REPORT (".")
+
+/* Read scanlines of width WIDTH from the image file until we get one
+ that has at least one black pixel in it (i.e., found part of a
+ character). Then read scanlines until we get one that is entirely
+ white. If KEEP_LEADING_WHITE_ROWS, then include the white rows we
+ found at the beginning in the returned bitmap; otherwise, it's just
+ the rows from the first-black to the one before the all-white. */
+
+static bitmap_type *
+get_image_row (boolean keep_leading_white_rows, unsigned width)
+{
+ static unsigned scanline_count = 0;
+ bitmap_type *bitmap;
+ boolean found_white_row;
+ one_byte *image;
+ unsigned rows_used, rows_allocated;
+ boolean found_black_row = false;
+ one_byte *scanline = xmalloc (width);
+ unsigned white_row_count = 0;
+
+ while ((*image_get_scanline) (scanline))
+ {
+ REPORT_SCANLINE ();
+
+ found_black_row = memchr (scanline, BLACK, width) != NULL;
+ if (found_black_row)
+ break;
+
+ white_row_count++;
+ }
+
+ /* If reached end of the image before finding a black row, return NULL. */
+ if (!found_black_row)
+ return NULL;
+
+ /* Initialize the image to either the scanline with some black that we
+ just found, or to a bitmap with as many all-white rows as we've
+ seen, depending on `keep_leading_white_rows'. */
+ rows_used = 1;
+ if (keep_leading_white_rows && white_row_count > 0)
+ { /* We clear the last row unnecessarily, since the next we do is
+ memcpy into it -- but that's better than realloc-ing. */
+ image = xcalloc (white_row_count + 1, width);
+ rows_used += white_row_count;
+ memcpy (image + white_row_count * width, scanline, width);
+ free (scanline);
+ }
+ else
+ image = scanline;
+
+ /* Found the row with a black pixel; now look for the all-white row.
+ When we start off here, we've allocated exactly as much space as
+ we've used so far. */
+ rows_allocated = rows_used;
+ found_white_row = false;
+ while (!found_white_row)
+ { /* Since we only need one more row at a time, we don't need a
+ `while' loop here. */
+ if (rows_used + 1 > rows_allocated)
+ { /* Perhaps doubling is the wrong thing to do here, as it may
+ waste quite a bit of memory. But it's simple. */
+ rows_allocated += 100 /* ;<<= 1*/;
+ image = xrealloc (image, rows_allocated * width);
+ }
+
+ scanline = image + rows_used * width;
+ if (!(*image_get_scanline) (scanline))
+ break;
+ REPORT_SCANLINE ();
+ rows_used++;
+ found_white_row = memchr (scanline, BLACK, width) == NULL;
+ }
+
+ bitmap = XTALLOC1 (bitmap_type);
+ BITMAP_WIDTH (*bitmap) = width;
+ BITMAP_HEIGHT (*bitmap) = rows_used;
+ BITMAP_BITS (*bitmap) = image;
+
+ return bitmap;
+}
+
+
+/* Return a vector of the column numbers at which B changes from black
+ to white or white to black, terminated with an element which is B's
+ width + 1. */
+
+static unsigned *
+image_row_transitions (bitmap_type b)
+{
+ unsigned *transitions;
+ unsigned row, col;
+ unsigned width = BITMAP_WIDTH (b);
+ one_byte *or_of_all = xcalloc (width, 1);
+
+ for (row = 0; row < BITMAP_HEIGHT (b); row++)
+ for (col = 0; col < width; col++)
+ or_of_all[col] |= BITMAP_PIXEL (b, row, col);
+
+ /* We use `or_of_all' to find transitions: its ith column is 1
+ if any row in the image had a black pixel at the ith column. */
+ transitions = bitmap_find_transitions (or_of_all, width);
+
+ return transitions;
+}
diff --git a/imageto/extract.h b/imageto/extract.h
new file mode 100644
index 0000000..b1c29e3
--- /dev/null
+++ b/imageto/extract.h
@@ -0,0 +1,50 @@
+/* extract.h: declare operations on bitmaps.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef EXTRACT_H
+#define EXTRACT_H
+
+#include "bitmap.h"
+#include "bounding-box.h"
+
+
+/* Return the segment in B starting after the column START that begins
+ with a column with at least one black pixel, to a column that is all
+ white (or the end of the bitmap). If no such segment is found,
+ return NULL. */
+extern bitmap_type *some_black_to_all_white_column (bitmap_type b);
+
+/* Read scanlines of width WIDTH (in pixels) from the input file until
+ we find a segment starting with a row with at least one black pixel,
+ and ending with a row that is all white (or the end of the file). If
+ no such segment is found, return NULL. In TRANSITIONS we return the
+ column numbers where white changes to black or black to white. The
+ first transition is black-to-white. */
+extern bitmap_type *some_black_to_all_white_row (unsigned width,
+ unsigned **transitions);
+
+/* Like `some_black_to_all_white_row', except appends both the white
+ rows and then the black ones to B. */
+extern bitmap_type *append_next_image_row
+ (bitmap_type b, unsigned width, unsigned **transitions);
+
+/* Combine the bitmaps B1 and B2 based on the bounding boxes, returning
+ the result in B1. Also combine the bounding boxes. */
+extern void combine_images (bitmap_type *b1, bitmap_type b2,
+ bounding_box_type *, bounding_box_type);
+#endif /* not EXTRACT_H */
diff --git a/imageto/ifi.c b/imageto/ifi.c
new file mode 100644
index 0000000..45d6b4c
--- /dev/null
+++ b/imageto/ifi.c
@@ -0,0 +1,196 @@
+/* ifi.c: read an IFI file. */
+
+#include "config.h"
+
+#include "encoding.h"
+#include "libfile.h"
+
+#include "ifi.h"
+#include "main.h"
+
+
+/* The name of the encoding file specified by the user, and the
+ structure we parse it into. (-encoding) */
+string encoding_name = NULL;
+
+/* The name of the IFI file. (-ifi-file) */
+string ifi_filename = NULL;
+
+
+static void append_image_char (image_char_list_type *l, image_char_type c);
+static image_char_list_type new_image_char_list (void);
+
+/* Read the IFI file `ifi_filename' (or construct the IFI filename from
+ `input_name'), which gives us information about the image we are
+ going to read.
+
+ See the documentation for full details and examples of IFI files.
+ Here we just sketch the bare bones.
+
+ Each (non-blank, non-comment) line in this file represents a
+ ``character'' in the image, and has one to five entries, separated by
+ spaces and/or tabs. Comments start with `%' and continue to the end
+ of the line.
+
+ The first entry represents the character code. See the documentation
+ for the various forms of charcodes. We also allow `.notdef', meaning
+ the ``character'' should not be output in the font.
+
+ The second entry, if it exists, is an adjustment to the
+ baseline. We move the baseline down for negative numbers, and up
+ for positive ones. Default is zero.
+
+ The third entry, if it exists, is the number of bounding boxes that
+ comprise this character. If it is negative, the bounding boxes
+ are not consecutive in the image; instead, they alternate with
+ bounding boxes for some other character.
+
+ The fourth and fifth entries, if they exist, are the left and right
+ side bearings, respectively. */
+
+image_char_list_type
+read_ifi_file (unsigned *total_count)
+{
+ string line;
+ int bb_count;
+ encoding_info_type *encoding_info;
+ int n = 0;
+ image_char_list_type image_char_list = new_image_char_list ();
+
+ if (encoding_name)
+ {
+ encoding_info = XTALLOC1 (encoding_info_type);
+ *encoding_info = read_encoding_file (encoding_name);
+ }
+ else
+ encoding_info = NULL;
+
+ if (!ifi_filename)
+ ifi_filename = make_suffix (input_name, "ifi");
+
+ libfile_start (ifi_filename, "ifi");
+
+ *total_count = 0;
+
+ while ((line = libfile_line ()) != NULL)
+ {
+ image_char_type c;
+ string baseline_adjust_str, bb_count_str, charname;
+ string lsb_str, rsb_str;
+ string save_line = line; /* So we can free it. */
+
+ /* The character name. */
+ charname = strtok (line, " \t");
+
+ /* `libfile_line' should never return an empty line. */
+ assert (charname != NULL);
+
+ if (STREQ (charname, ".notdef"))
+ IMAGE_CHAR_OMIT (c) = true;
+ else
+ {
+ if (encoding_info)
+ n = encoding_number (*encoding_info, charname);
+ /* Otherwise, start n at 0. */
+
+ if (n == -1)
+ {
+ LIBFILE_WARN2 ("Character `%s' undefined in encoding `%s'",
+ charname, ENCODING_SCHEME_NAME (*encoding_info));
+ IMAGE_CHAR_OMIT (c) = true;
+ }
+ else
+ {
+ IMAGE_CHARCODE (c) = n++;
+ IMAGE_CHARNAME (c) = xstrdup (charname);
+ IMAGE_CHAR_OMIT (c) = false;
+ }
+ }
+
+ /* The baseline adjustment. */
+ baseline_adjust_str = strtok (NULL, " \t");
+ IMAGE_CHAR_BASELINE_ADJUST (c)
+ = baseline_adjust_str == NULL ? 0 : atoi (baseline_adjust_str);
+
+ /* The bounding box count. */
+ bb_count_str = strtok (NULL, " \t");
+ bb_count = bb_count_str == NULL ? 1 : atoi (bb_count_str);
+
+ if (bb_count < 0)
+ {
+ IMAGE_CHAR_BB_COUNT (c) = -bb_count;
+ IMAGE_CHAR_BB_ALTERNATING (c) = true;
+ }
+ else
+ {
+ IMAGE_CHAR_BB_COUNT (c) = bb_count;
+ IMAGE_CHAR_BB_ALTERNATING (c) = false;
+ }
+
+ /* The left side bearing. */
+ lsb_str = strtok (NULL, " \t");
+ IMAGE_CHAR_LSB (c) = lsb_str == NULL ? 0 : atoi (lsb_str);
+
+ /* The right side bearing. */
+ rsb_str = strtok (NULL, " \t");
+ IMAGE_CHAR_RSB (c) = rsb_str == NULL ? 0 : atoi (rsb_str);
+
+ *total_count += IMAGE_CHAR_BB_COUNT (c);
+ append_image_char (&image_char_list, c);
+ free (save_line);
+ }
+
+ libfile_close ();
+ if (encoding_info)
+ free (encoding_info);
+
+ return image_char_list;
+}
+
+/* Return an initialized, empty list. */
+
+static image_char_list_type
+new_image_char_list ()
+{
+ image_char_list_type l;
+
+ IMAGE_CHAR_LIST_LENGTH (l) = 0;
+ IMAGE_CHAR_LIST_DATA (l) = NULL;
+
+ return l;
+}
+
+
+/* Append the character C to the list L. */
+
+void
+append_image_char (image_char_list_type *l, image_char_type c)
+{
+ IMAGE_CHAR_LIST_LENGTH (*l)++;
+ IMAGE_CHAR_LIST_DATA (*l)
+ = xrealloc (IMAGE_CHAR_LIST_DATA (*l),
+ IMAGE_CHAR_LIST_LENGTH (*l) * sizeof (image_char_type));
+ IMAGE_CHAR (*l, IMAGE_CHAR_LIST_LENGTH (*l) - 1) = c;
+}
+
+
+/* Return false if the box BOX_COUNT boxes beyond FIRST_CHAR in LIST
+ is in the middle of a character, true otherwise. To do this, we
+ add up all the box counts for characters starting at FIRST_CHAR,
+ until we see where we land. */
+
+boolean
+box_at_char_boundary_p (image_char_list_type list, unsigned first_char,
+ unsigned box_count)
+{
+ unsigned count = 0;
+
+ while (count < box_count && first_char < IMAGE_CHAR_LIST_LENGTH (list))
+ {
+ image_char_type c = IMAGE_CHAR (list, first_char);
+ count += IMAGE_CHAR_BB_COUNT (c);
+ first_char++;
+ }
+
+ return count == box_count;
+}
diff --git a/imageto/ifi.h b/imageto/ifi.h
new file mode 100644
index 0000000..e013d26
--- /dev/null
+++ b/imageto/ifi.h
@@ -0,0 +1,91 @@
+/* ifi.h: information about the characters in the image.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef IFI_H
+#define IFI_H
+
+#include <kpathsea/types.h>
+
+
+/* See ifi.c. */
+extern string encoding_name, ifi_filename;
+
+
+/* A single character in the image. */
+typedef struct
+{
+ charcode_type charcode;
+ string charname;
+ boolean omit;
+ int baseline_adjust;
+ unsigned bb_count;
+ boolean alternating;
+ int lsb, rsb;
+} image_char_type;
+
+/* The character code. This is garbage if `omit' is true. */
+#define IMAGE_CHARCODE(c) ((c).charcode)
+
+/* The character name. */
+#define IMAGE_CHARNAME(c) ((c).charname)
+
+/* Says whether this character should be output. */
+#define IMAGE_CHAR_OMIT(c) ((c).omit)
+
+/* How far the baseline should be moved from the row's baseline. */
+#define IMAGE_CHAR_BASELINE_ADJUST(c) ((c).baseline_adjust)
+
+/* How many bounding boxes comprise this character. */
+#define IMAGE_CHAR_BB_COUNT(c) ((c).bb_count)
+
+/* Says whether the bounding boxes in this character are consecutive
+ (the usual case) or alternate. */
+#define IMAGE_CHAR_BB_ALTERNATING(c) ((c).alternating)
+
+/* The side bearings. */
+#define IMAGE_CHAR_LSB(c) ((c).lsb)
+#define IMAGE_CHAR_RSB(c) ((c).rsb)
+
+
+/* A list of the above. */
+typedef struct
+{
+ image_char_type *data;
+ unsigned length;
+} image_char_list_type;
+
+/* The Nth element of the list L. */
+#define IMAGE_CHAR(l, n) ((l).data[n])
+
+/* The list as a whole. */
+#define IMAGE_CHAR_LIST_DATA(l) ((l).data)
+
+/* The length of the list. */
+#define IMAGE_CHAR_LIST_LENGTH(l) ((l).length)
+
+
+/* Read the IFI file IFI_FILENAME. Return the total number of characters
+ read in TOTAL_COUNT. */
+extern image_char_list_type read_ifi_file (unsigned *total_count);
+
+/* Return false if the box BOX_COUNT boxes beyond FIRST_CHAR in LIST
+ is in the middle of a character, true otherwise. */
+extern boolean box_at_char_boundary_p
+ (image_char_list_type list, unsigned first_char, unsigned box_count);
+
+#endif /* not IFI_H */
diff --git a/imageto/image-char.c b/imageto/image-char.c
new file mode 100644
index 0000000..2f9fc56
--- /dev/null
+++ b/imageto/image-char.c
@@ -0,0 +1,69 @@
+/* image-char.c: manipulate information about the characters in the image.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#include "image-char.h"
+
+
+/* Return an initialized, empty list. */
+image_char_list_type
+new_image_char_list ()
+{
+ image_char_list_type l;
+
+ IMAGE_CHAR_LIST_LENGTH (l) = 0;
+ IMAGE_CHAR_LIST_DATA (l) = NULL;
+
+ return l;
+}
+
+
+/* Append the character C to the list L. */
+
+void
+append_image_char (image_char_list_type *l, image_char_type c)
+{
+ IMAGE_CHAR_LIST_LENGTH (*l)++;
+ IMAGE_CHAR_LIST_DATA (*l)
+ = xrealloc (IMAGE_CHAR_LIST_DATA (*l),
+ IMAGE_CHAR_LIST_LENGTH (*l) * sizeof (image_char_type));
+ IMAGE_CHAR (*l, IMAGE_CHAR_LIST_LENGTH (*l) - 1) = c;
+}
+
+
+/* Return false if the box BOX_COUNT boxes beyond CURRENT_CHAR in LIST
+ is in the middle of a character, true otherwise. To do this, we must
+ add up all the box counts for characters starting at FIRST_CHAR,
+ until we see where we land. */
+
+boolean
+box_at_char_boundary_p (image_char_list_type list, unsigned current_char,
+ unsigned box_count)
+{
+ unsigned count = 0;
+
+ while (count < box_count && current_char < IMAGE_CHAR_LIST_LENGTH (list))
+ {
+ image_char_type c = IMAGE_CHAR (list, current_char);
+ count += IMAGE_CHAR_BB_COUNT (c);
+ current_char++;
+ }
+
+ return count == box_count;
+}
diff --git a/imageto/image-char.h b/imageto/image-char.h
new file mode 100644
index 0000000..c1b2880
--- /dev/null
+++ b/imageto/image-char.h
@@ -0,0 +1,89 @@
+/* image-char.h: information about the characters in the image.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef IMAGE_CHAR_H
+#define IMAGE_CHAR_H
+
+#include "types.h"
+
+
+/* A single character in the image. */
+typedef struct
+{
+ charcode_type charcode;
+ string charname;
+ boolean omit;
+ int baseline_adjust;
+ unsigned bb_count;
+ boolean alternating;
+ int lsb, rsb;
+} image_char_type;
+
+/* The character code. This is garbage if `omit' is true. */
+#define IMAGE_CHARCODE(c) ((c).charcode)
+
+/* The character name. */
+#define IMAGE_CHARNAME(c) ((c).charname)
+
+/* Says whether this character should be output. */
+#define IMAGE_CHAR_OMIT(c) ((c).omit)
+
+/* How far the baseline should be moved from the row's baseline. */
+#define IMAGE_CHAR_BASELINE_ADJUST(c) ((c).baseline_adjust)
+
+/* How many bounding boxes comprise this character. */
+#define IMAGE_CHAR_BB_COUNT(c) ((c).bb_count)
+
+/* Says whether the bounding boxes in this character are consecutive
+ (the usual case) or alternate. */
+#define IMAGE_CHAR_BB_ALTERNATING(c) ((c).alternating)
+
+/* The side bearings. */
+#define IMAGE_CHAR_LSB(c) ((c).lsb)
+#define IMAGE_CHAR_RSB(c) ((c).rsb)
+
+
+/* A list of the above. */
+typedef struct
+{
+ image_char_type *data;
+ unsigned length;
+} image_char_list_type;
+
+/* The Nth element of the list L. */
+#define IMAGE_CHAR(l, n) ((l).data[n])
+
+/* The list as a whole. */
+#define IMAGE_CHAR_LIST_DATA(l) ((l).data)
+
+/* The length of the list. */
+#define IMAGE_CHAR_LIST_LENGTH(l) ((l).length)
+
+
+/* Return an empty list. */
+extern image_char_list_type new_image_char_list (void);
+
+/* Append the character C to the list L. */
+extern void append_image_char (image_char_list_type *l, image_char_type c);
+
+/* Return false if the box BOX_COUNT boxes beyond FIRST_CHAR in LIST
+ is in the middle of a character, true otherwise. */
+extern boolean box_at_char_boundary_p
+ (image_char_list_type list, unsigned first_char, unsigned box_count);
+
+#endif /* not IMAGE_CHAR_H */
diff --git a/imageto/image-header.h b/imageto/image-header.h
new file mode 100644
index 0000000..9d48a60
--- /dev/null
+++ b/imageto/image-header.h
@@ -0,0 +1,35 @@
+/* image-header.h: declarations for a generic image header.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef IMAGE_HEADER_H
+#define IMAGE_HEADER_H
+
+#include <kpathsea/types.h>
+
+/* The important general information about the image data.
+ See `get_{img,pbm}_header' for the full details of the headers for
+ the particular formats. */
+typedef struct
+{
+ two_bytes hres, vres; /* In pixels per inch. */
+ two_bytes width, height; /* In bits. */
+ two_bytes depth;
+ unsigned format; /* (for pbm) Whether packed or not. */
+} image_header_type;
+
+#endif /* not IMAGE_HEADER_H */
diff --git a/imageto/input-img.c b/imageto/input-img.c
new file mode 100644
index 0000000..1930350
--- /dev/null
+++ b/imageto/input-img.c
@@ -0,0 +1,159 @@
+/* input-img.c: read Interleaf .img files.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#include "file-input.h"
+
+#include "main.h"
+#include "image-header.h"
+#include "input-img.h"
+
+
+/* Where the input comes from. */
+static FILE *img_input_file;
+static string img_input_filename;
+
+/* What we'll read the raw data for each scanline into. */
+static one_byte *line_in_bytes;
+
+/* How big `line_in_bytes' is, in both bytes and pixels. */
+static unsigned byte_width;
+static unsigned pixel_width;
+static unsigned pixel_depth;
+
+/* Macros for convenient input. The routines are defined in kbase. */
+#define IMG_MATCH_BYTE(v) match_byte (v, img_input_file, img_input_filename)
+
+#define IMG_GET_TWO() get_two (img_input_file, img_input_filename)
+#define IMG_GET_FOUR() get_four (img_input_file, img_input_filename)
+
+/* Only one file can be open at a time. We do no path searching. If
+ FILENAME can't be opened, we quit. */
+
+void
+img_open_input_file (string filename)
+{
+ assert (img_input_file == NULL);
+
+ img_input_file = xfopen (filename, "r");
+ img_input_filename = filename;
+}
+
+
+/* Close the input file. If it hasn't been opened, we quit. */
+
+void
+img_close_input_file ()
+{
+ assert (img_input_file != NULL);
+
+ xfclose (img_input_file, img_input_filename);
+ img_input_file = NULL;
+}
+
+/* Read the header information.
+ Modifies the global image_header in main.c. */
+
+void
+img_get_header ()
+{
+ unsigned flags;
+ unsigned pixels_per_short;
+ unsigned short_width;
+
+ /* The ``magic number''. */
+ IMG_MATCH_BYTE (0211);
+ IMG_MATCH_BYTE ('O');
+ IMG_MATCH_BYTE ('P');
+ IMG_MATCH_BYTE ('S');
+
+ /* The version number. */
+ IMG_MATCH_BYTE (0);
+ IMG_MATCH_BYTE (2);
+
+ image_header.hres = IMG_GET_TWO ();
+ image_header.vres = IMG_GET_TWO ();
+ flags = IMG_GET_FOUR ();
+ if (flags != 0)
+ FATAL1 ("img_get_header: Expected flags to be zero, not %u", flags);
+ image_header.width = IMG_GET_TWO ();
+ image_header.height = IMG_GET_TWO ();
+ pixel_depth = image_header.depth = IMG_GET_TWO ();
+ image_header.format = IMG_GET_TWO ();
+ if (image_header.format != 0)
+ FATAL1 ("img_get_header: Expected format to be zero, not %u",
+ image_header.format);
+
+ /* Allocate the space that we will read into (since that space is the
+ same from scanline to scanline). The width is derived from the
+ header information, which must already have been read.
+ Specifically, the width in the header is given in bits. Each
+ scanline is padded to a 16-bit boundary. For example, suppose the
+ header width = 1516, that is 94.75 shorts; we round up to 95,
+ thus getting a scanline width of 1520 bits, or 190 bytes. (For
+ monochrome images.) */
+ pixel_width = image_header.width;
+ pixels_per_short = 16 / image_header.depth;
+ short_width = pixel_width / pixels_per_short
+ + (pixel_width % pixels_per_short != 0);
+ byte_width = short_width * 2;
+ line_in_bytes = xmalloc (byte_width);
+}
+
+/* Read one scanline of the image, returning each bit of the scanline in
+ a separate byte. We may use the `line_in_bytes' variable, allocated in
+ `img_get_header' just above, to read into. */
+
+boolean
+img_get_scanline (one_byte *line_in_pixels)
+{
+ /* No point in using temp. buffer if pixels and bytes are the same. */
+ if (fread (line_in_bytes, byte_width, 1, img_input_file) != 1)
+ {
+ if (feof (img_input_file))
+ return false;
+ else
+ FATAL1 ("img_get_scanline: fread of %u bytes failed", byte_width);
+ }
+
+ /* Don't handle cases other than depth 1 or 8. */
+ if (pixel_depth == 1)
+ {
+ unsigned this_bit, this_byte, mask;
+ for (this_bit = 0, this_byte = 0, mask = 0x80;
+ this_bit < pixel_width; this_bit++)
+ {
+ /* Somewhere along the line, black and white got reversed. */
+ line_in_pixels[this_bit] = (line_in_bytes[this_byte] & mask) == 0;
+ if (this_bit % 8 == 0)
+ {
+ this_byte = this_bit / 8;
+ mask = 0x80;
+ }
+ else
+ mask >>= 1;
+ }
+ }
+ else
+ memcpy (line_in_pixels, line_in_bytes, byte_width);
+
+ print_scanline (line_in_pixels, pixel_width);
+
+ return true;
+}
diff --git a/imageto/input-img.h b/imageto/input-img.h
new file mode 100644
index 0000000..afbaaeb
--- /dev/null
+++ b/imageto/input-img.h
@@ -0,0 +1,43 @@
+/* input-img.h: declarations for reading an IMG file.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef INPUT_IMG_H
+#define INPUT_IMG_H
+
+#include <kpathsea/types.h>
+#include "image-header.h"
+
+
+/* Prepare to read FILENAME. */
+extern void img_open_input_file (string filename);
+
+/* Close up gracefully. */
+extern void img_close_input_file (void);
+
+
+/* Read the header. */
+extern void img_get_header (void);
+
+
+/* Read a single scanline into P. P must point to a large-enough block
+ for one entire scanline (the width of the image is given in the
+ header). If at the end of the input file, returns false, else
+ returns true. */
+extern boolean img_get_scanline (one_byte *p);
+
+#endif /* not INPUT_IMG_H */
diff --git a/imageto/input-pbm.c b/imageto/input-pbm.c
new file mode 100644
index 0000000..9fe47ba
--- /dev/null
+++ b/imageto/input-pbm.c
@@ -0,0 +1,88 @@
+/* input-pbm.c: read PBM files.
+
+Copyright (C) 1990, 1991, 19 19ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#include "file-input.h"
+
+#include "main.h"
+#include "image-header.h"
+#include "input-pbm.h"
+
+#include "pbmplus.h"
+#include "pbm.h"
+
+
+/* Where the input comes from. */
+static FILE *pbm_input_file;
+static string pbm_input_filename;
+
+
+
+/* Only one file can be open at a time. We do no path searching. If
+ FILENAME can't be opened, we quit. */
+
+void
+pbm_open_input_file (string filename)
+{
+ assert (pbm_input_file == NULL);
+
+ pbm_input_file = xfopen (filename, "r");
+ pbm_input_filename = filename;
+}
+
+
+/* Close the input file. If it hasn't been opened, we quit. */
+
+void
+pbm_close_input_file ()
+{
+ assert (pbm_input_file != NULL);
+
+ xfclose (pbm_input_file, pbm_input_filename);
+ pbm_input_file = NULL;
+}
+
+
+
+/* Read the header information.
+ Modifies the global image_header in main.c. */
+
+void
+pbm_get_header ()
+{
+ int width, height, format;
+
+ pbm_readpbminit (pbm_input_file, &width, &height, &format);
+ image_header.width = (two_bytes) width;
+ image_header.height = (two_bytes) height;
+ image_header.depth = 0;
+ image_header.format = (two_bytes) format;
+}
+
+
+
+/* Read one scanline of the image. */
+
+boolean
+pbm_get_scanline (one_byte *line_in_bits)
+{
+ int c = getc (pbm_input_file);
+
+ if (c == EOF)
+ return false;
+
+ ungetc (c, pbm_input_file);
+ pbm_readpbmrow (pbm_input_file, line_in_bits, image_header.width,
+ image_header.format);
+
+ print_scanline (line_in_bits, image_header.width);
+ return true;
+}
diff --git a/imageto/input-pbm.h b/imageto/input-pbm.h
new file mode 100644
index 0000000..522d2de
--- /dev/null
+++ b/imageto/input-pbm.h
@@ -0,0 +1,44 @@
+/* input-pbm.h: declarations for reading an PBM file.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef INPUT_PBM_H
+#define INPUT_PBM_H
+
+#include <kpathsea/types.h>
+#include "image-header.h"
+
+
+/* Prepare to read FILENAME. */
+extern void pbm_open_input_file (string filename);
+
+/* Close up gracefully. */
+extern void pbm_close_input_file (void);
+
+
+/* Read the header. */
+extern void pbm_get_header (void);
+
+
+/* Read a single scanline into P. P must point to a large-enough block
+ for one entire scanline (the width of the image is given in the
+ header). If at the end of the input file, returns false, else
+ returns true. */
+extern boolean pbm_get_scanline (one_byte *p);
+
+#endif /* not INPUT_PBM_H */
+
diff --git a/imageto/main.c b/imageto/main.c
new file mode 100644
index 0000000..e3215c8
--- /dev/null
+++ b/imageto/main.c
@@ -0,0 +1,416 @@
+/* imageto -- convert a scanned image.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#include <kpathsea/concatn.h>
+
+#define CMDLINE_NO_DPI /* It's not in the input filename. */
+#include "cmdline.h"
+#include "encoding.h" /* For `DEFAULT_ENCODING'. */
+#include "getopt.h"
+#include "gf.h"
+#include "report.h"
+
+#include "ifi.h" /* For `encoding_name'. */
+#include "image-header.h"
+#include "input-img.h"
+#include "input-pbm.h"
+#include "main.h"
+#include "out-chars.h"
+#include "out-epsf.h"
+#include "out-strips.h"
+
+
+/* General information about the image. Set by the input routines. */
+image_header_type image_header;
+
+/* Pointers to functions based on input format. (-input-format) */
+void (*image_open_input_file) (string) = NULL;
+void (*image_close_input_file) (void) = NULL;
+void (*image_get_header) (void) = NULL;
+boolean (*image_get_scanline) (one_byte *) = NULL;
+
+/* The filename for the input image. */
+string input_name;
+
+/* Show every scanline on the terminal as we read it? (-trace-scanlines) */
+boolean trace_scanlines = false;
+
+/* Private variables. */
+
+/* The design size of the font we're creating. (-designsize) */
+static real design_size = 10.0;
+
+/* The suffix for the image file. */
+static string input_extension;
+
+/* If set, write an EPSF file. (-epsf) */
+static boolean output_epsf = false;
+
+/* The name of the file we're going to write. (-output-file) */
+string output_name;
+
+/* If set, make each ``character'' a (more or less) constant number of
+ scanlines. (-strips) */
+static boolean do_strips = false;
+
+
+static string read_command_line (int, string[]);
+static void set_img_input_format (void);
+static void set_input_format (string);
+static void set_pbm_input_format (void);
+
+/* We have three different strategies for processing the image:
+ 1) (normal) analyze the image and write out the ``true'' characters,
+ 2) (-strips) takes a constant number of scanlines as each character,
+ 3) (-epsf) write out the image as an Encapsulated PostScript file.
+
+ The output name is, correspondingly, constructed differently:
+ 1) if `output_name' was supplied, and has a suffix, that's it.
+ 2) if `output_name' was supplied, but has no suffix, append `.eps'
+ if we're doing EPSF, else append `<suffix>.<dpi>gf', where
+ <suffix> is
+ a) `sp', if we are doing strips;
+ b) the design size, if not.
+ 3) if `output_name' was not supplied, use the basename of the input
+ filename extended as in #2.
+ */
+
+int
+main (int argc, string argv[])
+{
+ boolean writing_gf;
+
+ kpse_set_progname (argv[0]);
+
+ input_name = read_command_line (argc, argv);
+ writing_gf = !output_epsf;
+
+ set_input_format (input_name);
+
+ /* If the input format is PBM, then they must also tell us the dpi. */
+ if (image_open_input_file == pbm_open_input_file
+ && image_header.hres == 0)
+ {
+ fprintf (stderr, "If you use PBM format, you must supply the dpi.\n");
+ fprintf (stderr, "For more information, use ``-help''.\n");
+ exit (1);
+ }
+
+ /* Open the main input file. */
+ (*image_open_input_file) (extend_filename (input_name, input_extension));
+
+ /* We need the horizontal resolution before we can make the GF name,
+ so, at least for IMG input, have to read the header. */
+ (*image_get_header) ();
+
+ /* If the user didn't give an output name, use the input name. */
+ if (output_name == NULL)
+ output_name = remove_suffix (basename (input_name));
+
+ /* If they didn't give an output name with a suffix, use ours. */
+ if (find_suffix (output_name) == NULL)
+ {
+ if (writing_gf)
+ {
+ char dpi[MAX_INT_LENGTH + 1];
+ string suffix = do_strips ? "sp" : itoa ((unsigned) design_size);
+
+ sprintf (dpi, "%u", image_header.hres);
+ output_name = concatn (output_name, suffix, ".", dpi, "gf", NULL);
+ }
+ else if (output_epsf)
+ output_name = concat (output_name, ".eps");
+ else
+ abort (); /* Should never happen. */
+ }
+
+ /* If necessary, open the GF file. */
+ if (writing_gf)
+ {
+ if (!gf_open_output_file (output_name))
+ FATAL_PERROR (output_name);
+
+ /* Identify ourselves in the GF comment. */
+ gf_put_preamble (concat ("imageto output ", now () + 4));
+ }
+
+ /* Do the real work, whichever the user wants. */
+ if (do_strips)
+ { /* The design size is irrelevant when we're creating strips,
+ but it should be pretty large, lest the relative dimensions in
+ the TFM file get too big. */
+ design_size = 100.0;
+ write_chars_as_strips (image_header, design_size);
+ }
+ else if (output_epsf)
+ write_epsf (output_name, image_header);
+ else
+ write_image_chars (image_header, design_size);
+
+ /* Clean up. */
+ if (verbose)
+ REPORT ("\n");
+
+ if (writing_gf)
+ {
+ /* We've read all the characters we're supposed to (or else the whole
+ image). Finish up the font. */
+ gf_put_postamble (real_to_fix (design_size),
+ (real) image_header.hres, (real) image_header.vres);
+ gf_close_output_file ();
+ }
+
+ (*image_close_input_file) ();
+
+ return 0;
+}
+
+/* We are semi-clever about printing this, for the sake of huge images. */
+
+void
+print_scanline (one_byte line[], unsigned width)
+{
+ static unsigned scanline_count = 0;
+
+ if (trace_scanlines)
+ {
+ printf ("%7d:", scanline_count++);
+
+ /* If the line is entirely white, don't print anything. */
+ if (memchr (line, BLACK, width))
+ {
+ unsigned c;
+
+ for (c = 0; c < width; c++)
+ { /* Compress eight consecutive spaces to a tab, if we're at
+ the beginning of a tab mark. This handles the usual
+ case, although we could do still better. */
+ if (c % 8 == 0 && c + 7 < width
+ && memchr (line + c, BLACK, 8) == NULL)
+ {
+ putchar ('\t');
+ c += 7;
+ }
+ else
+ putchar (line[c] ? '*' : ' ');
+ }
+ }
+
+ putchar ('\n');
+ }
+}
+
+/* Reading the options. */
+
+/* This is defined in version.c. */
+extern string version_string;
+
+#define USAGE "Options:
+<font_name> should be a base filename, e.g., `ggmr'. (More properly, it
+is an <image_name>, not a <font_name>.)" \
+ GETOPT_USAGE \
+"baselines <row1>,<row2>,...: define the baselines for each image row.
+ The baseline of the first image row is taken to be scanline <row1>, etc.
+designsize <real>: set the designsize of the font to <real>; default is 10.0.
+dpi <unsigned>: resolution (required for pbm input).
+encoding <filename>: read ligature and other encoding information
+ from `<filename>.enc'; the default is to assign successive character codes.
+epsf: write the image as an Encapsulated PostScript file, instead of a
+ bitmap font.
+help: print this message.
+ifi-file <filename>: use <filename>.ifi (if <filename doesn't have a
+ suffix; otherwise use <filename>) for the IFI filename; default is
+ `<font_name>.ifi'.
+input-format <format>: specify format of input image; <format> must be
+ one of `pbm' or `img'.
+nchars <unsigned>: only write the first <unsigned> (approximately)
+ characters to the font; default is infinity.
+output-file <filename>: write to <filename> if <filename> has a suffix.
+ If <filename> doesn't have a suffix, then if writing strips, write to
+ <filename>sp.<dpi>gf and to <filename>.<dpi>gf if not. By default,
+ use <font_name> for <filename>.
+print-clean-info: print gray values for the bounding boxes that are
+ considered for cleaning. This implies `-verbose'.
+print-guidelines: print the numbers of the top and bottom rows (in that
+ order) of each character. This implies `-verbose'.
+range <char1>-<char2>: only output characters between <char1> and
+ <char2>, inclusive.
+strips: take a constant number of scanlines as each character,
+ instead of using an IFI file to analyze the image.
+trace-scanlines: show every scanline as we read it.
+verbose: output progress reports.
+version: print the version number of this program.
+"
+
+static string
+read_command_line (int argc, string argv[])
+{
+ int g; /* `getopt' return code. */
+ int option_index;
+ boolean printed_version = false;
+ struct option long_options[]
+ = { { "baselines", 1, 0, 0 },
+ { "designsize", 1, 0, 0 },
+ { "encoding", 1, 0, 0 },
+ { "epsf", 0, (int *) &output_epsf, 1 },
+ { "help", 0, 0, 0 },
+ { "dpi", 1, 0, 0 },
+ { "ifi-file", 1, 0, 0 },
+ { "nchars", 1, 0, 0 },
+ { "input-format", 1, 0, 0 },
+ { "output-file", 1, 0, 0 },
+ { "print-clean-info", 0, (int *) &print_clean_info, 1 },
+ { "print-guidelines", 0, (int *) &print_guidelines, 1 },
+ { "range", 1, 0, 0 },
+ { "strips", 0, (int *) &do_strips, 1 },
+ { "trace-scanlines", 0, (int *) &trace_scanlines, 1 },
+ { "verbose", 0, (int *) &verbose, 1 },
+ { "version", 0, (int *) &printed_version, 1 },
+ { 0, 0, 0, 0 } };
+
+ while (true)
+ {
+ g = getopt_long_only (argc, argv, "", long_options, &option_index);
+
+ if (g == EOF)
+ break;
+
+ if (g == '?')
+ exit (1); /* Unknown option. */
+
+ assert (g == 0); /* We have no short option names. */
+
+ if (ARGUMENT_IS ("baselines"))
+ baseline_list = scan_unsigned_list (optarg);
+
+ else if (ARGUMENT_IS ("designsize"))
+ design_size = atof (optarg);
+
+ else if (ARGUMENT_IS ("dpi"))
+ {
+ image_header.hres = (two_bytes) atou (optarg);
+ image_header.vres = image_header.hres;
+ }
+
+ else if (ARGUMENT_IS ("encoding"))
+ encoding_name = optarg;
+
+ else if (ARGUMENT_IS ("help"))
+ {
+ fprintf (stderr, "Usage: %s [options] <font_name>.\n", argv[0]);
+ fprintf (stderr, USAGE);
+ exit (0);
+ }
+
+ else if (ARGUMENT_IS ("ifi-file"))
+ ifi_filename = optarg;
+
+ else if (ARGUMENT_IS ("input-format"))
+ {
+ if (STREQ ("pbm", optarg))
+ set_pbm_input_format ();
+ else if (STREQ ("img", optarg))
+ set_img_input_format ();
+ else
+ FATAL1 ("imageto: Unknown input format `%s'; expected one of \
+`img' or `pbm'", optarg);
+ }
+
+ else if (ARGUMENT_IS ("nchars"))
+ nchars_wanted = atou (optarg);
+
+ else if (ARGUMENT_IS ("output-file"))
+ output_name = optarg;
+
+ else if (ARGUMENT_IS ("print-clean-info")
+ || ARGUMENT_IS ("print-guidelines"))
+ verbose = true;
+
+ else if (ARGUMENT_IS ("range"))
+ GET_RANGE (optarg, starting_char, ending_char);
+
+ else if (ARGUMENT_IS ("version"))
+ printf ("%s.\n", version_string);
+
+ /* Else it was a flag; getopt has already done the assignment. */
+ }
+
+ if (do_strips && output_epsf)
+ FATAL ("imageto: Sorry, -strips and -epsf are mutually exclusive");
+
+ FINISH_COMMAND_LINE ();
+}
+
+/* If the input format wasn't explicitly set on the command line,
+ attempt to intuit it from FILENAME, and set the necessary variables.
+ If we can't tell what the format should be, quit. */
+
+static void
+set_input_format (string filename)
+{
+ string input_extension;
+
+ /* If it's already set, just return. */
+ if (image_open_input_file != NULL)
+ return;
+
+ /* Try to guess based on FILENAME. */
+ input_extension = find_suffix (filename) ? : "";
+
+ if (STREQ (input_extension, "img"))
+ set_img_input_format ();
+
+ else if (STREQ (input_extension, "pbm"))
+ set_pbm_input_format ();
+
+ else /* Can't guess it; quit. */
+ {
+ fprintf (stderr, "You must supply an input format.\n");
+ fprintf (stderr, "(I can't guess from the filename `%s'.)\n", filename);
+ fprintf (stderr, "For more information, use ``-help''.\n");
+ exit (1);
+ }
+}
+
+
+/* Set up for reading a PBM file. */
+
+static void
+set_pbm_input_format ()
+{
+ image_open_input_file = pbm_open_input_file;
+ image_close_input_file = pbm_close_input_file;
+ image_get_header = pbm_get_header;
+ image_get_scanline = pbm_get_scanline;
+ input_extension = "pbm";
+}
+
+
+/* Set up for reading an IMG file. */
+
+static void
+set_img_input_format ()
+{
+ image_open_input_file = img_open_input_file;
+ image_close_input_file = img_close_input_file;
+ image_get_header = img_get_header;
+ image_get_scanline = img_get_scanline;
+ input_extension = "img";
+}
diff --git a/imageto/main.h b/imageto/main.h
new file mode 100644
index 0000000..7d2f7c1
--- /dev/null
+++ b/imageto/main.h
@@ -0,0 +1,42 @@
+/* main.h: global variable declarations.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef MAIN_H
+#define MAIN_H
+
+#include <kpathsea/types.h>
+#include "image-header.h"
+
+
+/* See main.c for explanations of these globals. */
+extern boolean trace_scanlines;
+extern image_header_type image_header;
+extern string input_name;
+extern string output_name;
+
+/* Generic routines to manipulate the image. */
+extern void (*image_open_input_file) (string filename);
+extern void (*image_close_input_file) (void);
+extern void (*image_get_header) (void);
+extern boolean (*image_get_scanline) (one_byte *);
+
+
+/* Print a scanline LINE of width WIDTH, if `trace_scanlines' is true.. */
+extern void print_scanline (one_byte line[], unsigned width);
+
+#endif /* not MAIN_H */
diff --git a/imageto/out-chars.c b/imageto/out-chars.c
new file mode 100644
index 0000000..b0dc6f4
--- /dev/null
+++ b/imageto/out-chars.c
@@ -0,0 +1,750 @@
+/* out-chars.c: try to extract the real characters from the image.
+
+Copyright (C) 1992, 93 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#include <kpathsea/tex-file.h>
+#include <kpathsea/pathsearch.h>
+#include <kpathsea/paths.h>
+
+#include "bb-outline.h"
+#include "gf.h"
+#include "report.h"
+
+#include "bitmap2.h"
+#include "extract.h"
+#include "ifi.h"
+#include "image-header.h"
+#include "main.h"
+#include "out-strips.h"
+
+/*xx*/
+FILE *testfileptr;
+const char* whole_bitmap_filename = "test-whole-bitmap";
+const char* bb_whole_bitmap_filename = "test-bb-whole-bitmap";
+const char* subbitmap_filename = "test-subbitmap";
+const char* bb_subbitmap_filename = "test-bb-subbitmap";
+const char* line_subbitmap_filename = "test-line-subbitmap";
+const char* line_bb_subbitmap_filename = "test-line-bb-subbitmap";
+const char* gf_bitmap_filename = "test-gf-bitmap";
+const char* gf_bb_bitmap_filename = "test-gf-bb-bitmap";
+
+
+
+/* A list of the image rows on which the baselines occur. The end of
+ the list is marked with an element -1. (-baselines) */
+int *baseline_list = NULL;
+
+/* Find about this many characters in the image, then stop. This is
+ useful only for testing, because converting the entire image takes a long
+ time. So we might in truth output a few more characters than
+ specified here. (-nchars) */
+unsigned nchars_wanted = MAX_CHARCODE + 1;
+
+/* If set, prints diagnostics about which boxes are and aren't cleaned.
+ (-print-clean-info) */
+boolean print_clean_info = false;
+
+/* Says whether to print the row numbers of each character as we go,
+ so that the user can decide how to adjust jumping baselines.
+ (-print-guidelines) */
+boolean print_guidelines = false;
+
+/* Says which characters to output. This is independent of the
+ ordering in the font file. (-range) */
+int starting_char = 0;
+int ending_char = MAX_CHARCODE;
+
+/* The design size of the font we're creating. */
+static real design_size;
+
+/* Where the baseline of the current row is in the image. The first row
+ is #1, and so on. We start over at row 1 at each image row.*/
+static unsigned row_baseline;
+static unsigned row_height;
+
+/* How many boxes total the characters take up. */
+static unsigned total_boxes_expected;
+
+
+static boolean bb_equal_p (bounding_box_type, bounding_box_type);
+static gf_char_type bitmap_to_gf_char
+ (bitmap_type, real, bounding_box_type, image_char_type);
+static void clean_bitmap (bitmap_type *, bb_list_type);
+static boolean do_image_line
+ (bitmap_type, unsigned *, unsigned *, real, image_char_list_type);
+static void image_to_bitmap_bbs (bb_list_type *);
+extern void offset_bb_list (bb_list_type *l, int offset);
+static unsigned output_chars
+ (bb_list_type, bitmap_type, real, image_char_list_type, unsigned);
+
+/* Analyze the input image, outputting the characters we find. */
+
+void
+write_image_chars (image_header_type image_header, real ds)
+{
+ bitmap_type *image_line_bitmap;
+ unsigned nchars_done = 0;
+
+ /* Read the image information. This tells us to which character
+ each bounding box belongs, among other things. */
+ image_char_list_type image_char_list = read_ifi_file (&total_boxes_expected);
+
+ /* Remember this so we don't need to pass it through all the
+ intervening routines to the low-level output. */
+ design_size = ds;
+
+ /* The main loop also (and more commonly) exits when we've read the
+ entire image. */
+ while (nchars_done < nchars_wanted)
+ {
+ /* Vector of column numbers where the image column alternates
+ between some black to all white; used to get the bounding box
+ column min and max for each character. */
+ unsigned *transitions;
+
+ /* Read one line of characters, noting the transitions (see
+ above), in the image. After this, `image_line_bitmap' is, for
+ example, `a...z', with blank columns at the left and right.
+ Whatever is in the original image. */
+ image_line_bitmap
+ = some_black_to_all_white_row (image_header.width, &transitions);
+
+ if (image_line_bitmap == NULL)
+ break; /* We've read the whole image file. */
+
+ if (baseline_list == NULL || *baseline_list == -1)
+ {
+ if (baseline_list != NULL)
+ WARNING ("imageto: Not enough baselines specified");
+ row_baseline = 0;
+ }
+ else
+ row_baseline = *baseline_list++;
+
+ row_height = BITMAP_HEIGHT (*image_line_bitmap);
+
+ /* Process one line of characters. If `do_image_line' fails, we
+ need to read the next row in the image, and put it directly
+ below the current line to complete a character. For example,
+ if a line has only an `!' on it, we will only get the stem on
+ the first call to `some_black_to_all_white_row'. We want to
+ get the dot in there, too. */
+ while (!do_image_line (*image_line_bitmap, transitions, &nchars_done,
+ (real) image_header.hres, image_char_list))
+ {
+ bitmap_type *revised
+ = append_next_image_row (*image_line_bitmap, image_header.width,
+ &transitions);
+ if (revised == NULL)
+ {
+ WARNING ("imageto: Image ended in the midst of a character");
+ break;
+ }
+
+ /* Tell the user the image row didn't end on a character. */
+ REPORT ("+");
+
+ free_bitmap (image_line_bitmap);
+ image_line_bitmap = revised;
+ if (baseline_list == NULL)
+ row_baseline = 0;
+
+ row_height = BITMAP_HEIGHT (*image_line_bitmap);
+ }
+
+ free_bitmap (image_line_bitmap);
+ }
+}
+
+/* Analyze and output all of the bitmap IMAGE, which is one line of type
+ in the original. The resolution of the image is H_RESOLUTION, and
+ we've read NCHARS characters (including .notdefs) so far. We use
+ IMAGE_CHAR_LIST, a list of character information from the IFI file,
+ and the transition vector TRANSITIONS, which has in it how IMAGE
+ breaks into characters or character groups.
+
+ We return false if we need to be given another image row to complete
+ a character. */
+
+#define NEXT_TRANSITION() ({ \
+ if (*transitions == BITMAP_WIDTH (image) + 1) \
+ { \
+ WARNING ("imageto: Expected more transitions"); \
+ break; \
+ } \
+ *transitions++; \
+})
+
+static boolean
+do_image_line (bitmap_type image, unsigned *transitions, unsigned *nchars,
+ real h_resolution, image_char_list_type image_char_list)
+{
+ static unsigned box_count = 0;
+ bounding_box_type bb;
+
+ /* We always use the entire image line vertically. */
+ MIN_ROW (bb) = 0;
+ MAX_ROW (bb) = BITMAP_HEIGHT (image) - 1;
+
+ /* `nchars_wanted' is an option to the program, defined at the top.
+ Go through the whole line, unless we've found as many characters
+ as the user requested. */
+ while (*nchars < nchars_wanted && *transitions != BITMAP_WIDTH (image) + 1)
+ {
+ int bb_offset = 0;
+ unsigned previous_box_count = box_count;
+ bb_list_type boxes = bb_list_init ();
+ bitmap_type *char_bitmap = XTALLOC1 (bitmap_type);
+ bitmap_type *temp_bitmap = XTALLOC1 (bitmap_type);
+
+ /* The first element of TRANSITIONS is white-to-black.
+ Thereafter, they alternate. */
+ MIN_COL (bb) = NEXT_TRANSITION ();
+ MAX_COL (bb) = NEXT_TRANSITION ();
+
+ /* Get the bitmap of the first transition. `char_bitmap' is
+ either a single character (if the character didn't overlap with
+ a consecutive one in the font specimen) or more than one (if
+ the characters did overlap). For example, it might contain
+ just an `a' this time through the loop (with blank rows above
+ and below, because `a' has neither a descender nor an
+ ascender), then next time a `b', and so on. Or it might
+ contain `ij' (if they overlap in the specimen) instead of `i'
+ this time and `j' next time. */
+ *char_bitmap = extract_subbitmap (image, bb);
+ *temp_bitmap = copy_bitmap (*char_bitmap);
+/*xx*/
+if ((testfileptr = fopen(line_subbitmap_filename, "w")) != NULL)
+print_bitmap(testfileptr, *temp_bitmap);
+else
+printf("Bad file pointer for printing subbitmap.\n");
+fclose(testfileptr);
+if ((testfileptr = fopen(line_bb_subbitmap_filename, "w")) != NULL)
+print_bounded_bitmap(testfileptr, *temp_bitmap, bb);
+else
+printf("Bad file pointer for printing bb-subbitmap.\n");
+fclose(testfileptr);
+
+ /* Unless we've read enough boxes, find the ones in the current
+ character(s), and exit, either: 1) to output a character if the
+ boxes ``finish'' a character, or 2) to exit the routine with
+ false, if they don't. If don't find all the boxes needed to
+ finish a character (i.e., it has vertical white space in it,
+ loop around getting more ``transitions'' until we do. */
+ while (true)
+ {
+ bb_list_type temp_boxes;
+ bounding_box_type previous_bb;
+
+ /* If we've read all the bounding boxes specified (in the IFI
+ file), we're done. */
+ if (box_count == total_boxes_expected)
+ break;
+
+ /* If we've read more boxes than we expected to, trouble. */
+ if (box_count > total_boxes_expected)
+ {
+ WARNING2 ("imageto: Read box #%u but expected only %u",
+ box_count, total_boxes_expected);
+ /* No point in giving this message more than once. */
+ total_boxes_expected = INT_MAX;
+ }
+
+ /* Find the bounding boxes around all the shapes in `temp_bitmap'.
+ (The first time through the loop, `temp_bitmap' is the same
+ as `char_bitmap.') Continuing the above `ij' example, this
+ would result in four bounding boxes (one for the ``dotless''
+ part of the `i,' one for the ``dotless'' part of the `j'
+ and two for each of the dots). */
+ temp_boxes = find_outline_bbs (*temp_bitmap, false, 0, 0);
+
+ /* The subimages we've created all start at column zero. But
+ if there are overlapping characters (the `ij' example
+ above), we want to put the images (for, e.g., `i' and `j')
+ side-by-side instead of overlaying them. So we change the
+ bounding box numbers for `temp_boxes' by adding `bb_offset.' */
+ offset_bb_list (&temp_boxes, bb_offset);
+
+ box_count += BB_LIST_LENGTH (temp_boxes);
+ bb_list_splice (&boxes, temp_boxes);
+
+ /* Break if the number of boxes indicated for the current
+ character(s) coincide with the end of a character. This
+ translates to: if the white column was at the end of some
+ character in the list, exit the loop to output what we've got. */
+ if (box_at_char_boundary_p (image_char_list, *nchars,
+ box_count - previous_box_count))
+ break;
+
+ /* If we're at the end of the image row, return to our caller
+ that we had to quit in the middle of a character. */
+ if (*transitions == BITMAP_WIDTH (image) + 1)
+ { /* Forget that we've seen these boxes. */
+ box_count = previous_box_count;
+ return false;
+ }
+ /* If the character has white vertical space between its
+ parts, e.g., double quotes or ellipses, have to get the
+ rest of its bitmap. */
+ previous_bb = bb;
+ MIN_COL (bb) = NEXT_TRANSITION ();
+ MAX_COL (bb) = NEXT_TRANSITION ();
+
+ /* Leave in the white space between the character parts. */
+ MIN_COL (bb) = MAX_COL (previous_bb);
+
+ free_bitmap (temp_bitmap);
+ *temp_bitmap = extract_subbitmap (image, bb);
+/*xx*/
+if ((testfileptr = fopen(line_subbitmap_filename, "w")) != NULL)
+print_bitmap(testfileptr, *temp_bitmap);
+else
+printf("Bad file pointer for printing subbitmap.\n");
+fclose(testfileptr);
+if ((testfileptr = fopen(line_bb_subbitmap_filename, "w")) != NULL)
+print_bounded_bitmap(testfileptr, *temp_bitmap, bb);
+else
+printf("Bad file pointer for printing bb-subbitmap.\n");
+fclose(testfileptr);
+ if (temp_bitmap == NULL)
+ {
+ WARNING1 ("imageto: Expected more bounding boxes for `%d'",
+ IMAGE_CHARCODE (IMAGE_CHAR (image_char_list, *nchars)));
+ break;
+ }
+
+ /* Next time through the loop, the boxes `temp_bitmap' should
+ be just to the right of the bitmap we've accumulated in
+ `char_bitmap'. This happens if the character has vertical
+ white space between its parts. */
+ bb_offset = BITMAP_WIDTH (*char_bitmap);
+
+ /* When this happens, it usually means that the IFI file
+ didn't specify enough bounding boxes for some character,
+ and so things are out of sync. */
+ if (BITMAP_HEIGHT (*char_bitmap) != BITMAP_HEIGHT (*temp_bitmap))
+ {
+ WARNING ("imageto: Line ended inside a character");
+ break;
+ }
+ bitmap_concat (char_bitmap, *temp_bitmap);
+ } /* while (true) */
+
+ free_bitmap (temp_bitmap);
+
+ /* Convert the bits inside those bounding boxes into one (if not
+ overlapping with another) or more (if overlapping) characters
+ in the GF font. */
+ *nchars += output_chars (boxes, *char_bitmap, h_resolution,
+ image_char_list, *nchars);
+ free_bitmap (char_bitmap);
+ bb_list_free (&boxes);
+ } /* end while (*nchars < nchars_wanted
+ && *transitions != BITMAP_WIDTH (image) + 1) */
+
+ return true;
+}
+
+/* Move all the elements in BB_LIST to the right by OFFSET. */
+
+void
+offset_bb_list (bb_list_type *bb_list, int offset)
+{
+ unsigned this_bb;
+
+ for (this_bb = 0; this_bb < BB_LIST_LENGTH (*bb_list); this_bb++)
+ {
+ bounding_box_type *bb = &BB_LIST_ELT (*bb_list, this_bb);
+ MIN_COL (*bb) += offset;
+ MAX_COL (*bb) += offset;
+ }
+}
+
+
+/* Return true if BB1 and BB2 are equal. */
+
+static boolean
+bb_equal_p (bounding_box_type bb1, bounding_box_type bb2)
+{
+ return
+ MIN_COL (bb1) == MIN_COL (bb2)
+ && MIN_ROW (bb1) == MIN_ROW (bb2)
+ && MAX_COL (bb1) == MAX_COL (bb2)
+ && MAX_ROW (bb1) == MAX_ROW (bb2);
+}
+
+/* For each bounding box in the list BOXES, extract from IMAGE_LINE_BITMAP
+ and turn the resulting bitmap into a single character in the font.
+ The information in IMAGE_CHAR_LIST maps bounding boxes to character codes;
+ consecutive bounding boxes may belong to the same character. For
+ example, `i' will appear twice, once for the dot and once for the
+ stem. We assume that all the bounding boxes for a given character
+ will appear in IMAGE_LINE_BITMAP.
+
+ We return the number of characters (not bounding boxes) found,
+ including characters that were omitted. */
+
+/* Predicate to tell us if we want to actually write the character. */
+#define OUTPUT_CHAR_P(code, image_char) \
+ ((code) >= starting_char && (code) <= ending_char \
+ && !IMAGE_CHAR_OMIT (image_char))
+
+static unsigned
+output_chars (bb_list_type boxes, bitmap_type image_line_bitmap,
+ real h_resolution, image_char_list_type image_char_list,
+ unsigned current_char)
+{
+ static unsigned char_count = 0;
+ int this_box; /* Because we might have to subtract when it's zero. */
+ boolean done[BB_LIST_LENGTH (boxes)];
+
+ /* Since we report (a lot) more information when `print_guidelines' is
+ true, we can fit fewer characters per line. */
+ unsigned nchars_per_line = print_guidelines ? 1 : 11;
+
+ unsigned nchars_written = 0;
+
+ for (this_box = 0; this_box < BB_LIST_LENGTH (boxes); this_box++)
+ done[this_box] = false;
+
+ for (this_box = 0; this_box < BB_LIST_LENGTH (boxes); this_box++)
+ {
+ bounding_box_type bb;
+ bitmap_type bitmap;
+ image_char_type c;
+ charcode_type charcode;
+ bb_list_type bb_list = bb_list_init ();
+
+ /* `done[this_box]' will be set if we get to a bounding box that
+ has already been combined with a previous one, because of
+ an alternating combination. Since we never go backwards, we
+ don't bother to set `done' for every box we look at. */
+ if (done[this_box])
+ continue;
+
+ c = IMAGE_CHAR (image_char_list, current_char++);
+ charcode = IMAGE_CHARCODE (c);
+
+ REPORT ("[");
+
+ /* Only bother to collect the character image if we're going to
+ output it; otherwise, it just wastes a lot of time and space. */
+ if (OUTPUT_CHAR_P (charcode, c))
+ { /* A character consisting of zero bounding boxes is invisible;
+ e.g., a space. We don't want to read any of the bitmap for
+ such a thing. */
+ if (IMAGE_CHAR_BB_COUNT (c) == 0)
+ {
+ BITMAP_HEIGHT (bitmap) = 0;
+ BITMAP_WIDTH (bitmap) = 0;
+ BITMAP_BITS (bitmap) = NULL;
+ bb = (bounding_box_type) { 0, 0, 0, 0 };
+
+ /* Since we're not eating up any bounding boxes,
+ reconsider the current one. */
+ this_box--;
+ }
+ else
+ {
+ bb = BB_LIST_ELT (boxes, this_box);
+ bitmap = extract_subbitmap (image_line_bitmap, bb);
+/*xx*/
+if ((testfileptr = fopen(subbitmap_filename, "w")) != NULL)
+print_bitmap(testfileptr, bitmap);
+else
+printf("Bad file pointer for printing subbitmap.\n");
+fclose(testfileptr);
+if ((testfileptr = fopen(bb_subbitmap_filename, "w")) != NULL)
+print_bounded_bitmap(testfileptr, bitmap, bb);
+else
+printf("Bad file pointer for printing bb-subbitmap.\n");
+fclose(testfileptr);
+ bb_list_append (&bb_list, bb);
+ }
+ }
+
+ while (IMAGE_CHAR_BB_COUNT (c)-- > 1)
+ {
+ unsigned combine_box;
+
+ if (IMAGE_CHAR_BB_ALTERNATING (c))
+ {
+ /* Don't increment `this_box', since it is incremented at
+ the end of the loop, and the next box is part of
+ another character. */
+ combine_box = this_box + 2;
+ /* Don't look at the second box again in the outer loop. */
+ done[combine_box] = true;
+ }
+ else
+ /* Increment `this_box' so can keep combining nonalternating
+ bounding boxes until they are used up or we hit an
+ alternating one. */
+ combine_box = ++this_box;
+
+ /* combine_box starts at 0 and BB_LIST_LENGTH starts at 1, so... */
+ if (combine_box >= BB_LIST_LENGTH (boxes))
+ {
+ WARNING1 ("imageto: Not enough outlines for char %u",
+ (unsigned) charcode);
+ break;
+ }
+
+ if (OUTPUT_CHAR_P (charcode, c))
+ {
+ /* Get the shape to combine with `bitmap'. */
+ bounding_box_type next_bb = BB_LIST_ELT (boxes, combine_box);
+ bitmap_type next_bitmap
+ = extract_subbitmap (image_line_bitmap, next_bb);
+/*xx*/
+if ((testfileptr = fopen(subbitmap_filename, "w")) != NULL)
+print_bitmap(testfileptr, next_bitmap);
+else
+printf("Bad file pointer for printing subbitmap.\n");
+fclose(testfileptr);
+if ((testfileptr = fopen(bb_subbitmap_filename, "w")) != NULL)
+print_bounded_bitmap(testfileptr, next_bitmap, next_bb);
+else
+printf("Bad file pointer for printing bb-subbitmap.\n");
+fclose(testfileptr);
+ bb_list_append (&bb_list, next_bb);
+ combine_images (&bitmap, next_bitmap, &bb, next_bb);
+/*xx*/
+if ((testfileptr = fopen(whole_bitmap_filename, "w")) != NULL)
+print_bitmap(testfileptr, bitmap);
+else
+printf("Bad file pointer for printing whole_bitmap.\n");
+fclose(testfileptr);
+if ((testfileptr = fopen(bb_whole_bitmap_filename, "w")) != NULL)
+print_bounded_bitmap(testfileptr, bitmap, bb);
+else
+printf("Bad file pointer for printing bb_whole_bitmap.\n");
+fclose(testfileptr);
+ free_bitmap (&next_bitmap);
+ }
+ } /* while (IMAGE_CHAR_BB_COUNT (c)-- > 1) */
+
+ if (OUTPUT_CHAR_P (charcode, c))
+ {
+ gf_char_type gf_char;
+
+ if (BITMAP_BITS (bitmap) != NULL)
+ clean_bitmap (&bitmap, bb_list);
+
+ gf_char = bitmap_to_gf_char (bitmap, h_resolution, bb, c);
+ gf_put_char (gf_char);
+
+ /* This and the GF character's bitmap are the same, so we only
+ need to free one of the two. */
+ if (BITMAP_BITS (bitmap) != NULL)
+ free_bitmap (&bitmap);
+ }
+ else
+ {
+ REPORT ("<ignored>"); /* We're ignoring this character. */
+/*xx this_box--;*//* Reconsider the bounding box. */
+ }
+ REPORT1 ("]%c", ++char_count % nchars_per_line ? ' ' : '\n');
+ nchars_written++;
+
+ bb_list_free (&bb_list);
+ } /* for (this_box = 0; this_box < BB_LIST_LENGTH (boxes); this_box++) */
+
+
+ return nchars_written;
+}
+
+/* Remove bits of adjacent characters that may have crept into B because
+ of overlapping characters in the original image. KNOWN_BOXES lists
+ all the known parts of B; if we find other bounding boxes in B, we
+ remove them. */
+
+static void
+clean_bitmap (bitmap_type *b, bb_list_type known_boxes)
+{
+ unsigned test;
+ bb_list_type test_boxes = find_outline_bbs (*b, false, BITMAP_WIDTH (*b), 0);
+
+ if (print_clean_info)
+ REPORT2 ("Cleaning %ux%u bitmap:\n",
+ BITMAP_WIDTH (*b), BITMAP_HEIGHT (*b));
+
+ /* Convert KNOWN_BOXES to the same coordinates as `test_boxes'. */
+ image_to_bitmap_bbs (&known_boxes);
+
+ for (test = 0; test < BB_LIST_LENGTH (test_boxes); test++)
+ {
+ unsigned known;
+ unsigned known_length = BB_LIST_LENGTH (known_boxes);
+ bounding_box_type test_bb = BB_LIST_ELT (test_boxes, test);
+
+ if (print_clean_info)
+ REPORT4 (" checking (%d,%d)-(%d,%d) ... ",
+ MIN_COL (test_bb), MIN_ROW (test_bb),
+ MAX_COL (test_bb), MAX_ROW (test_bb));
+
+ /* If we want to keep `test_bb', it will be one of the elements of
+ BB_LIST. Otherwise, it is a piece of an adjacent character,
+ and we should erase it. */
+ for (known = 0; known < known_length && !bb_equal_p (test_bb,
+ BB_LIST_ELT (known_boxes, known));
+ known++)
+ ;
+
+ if (known == known_length)
+ {
+ unsigned r;
+ int test_bb_width = BB_WIDTH (test_bb);
+
+ assert (test_bb_width > 0);
+
+ if (print_clean_info)
+ REPORT ("clearing.\n");
+
+ for (r = MIN_ROW (test_bb); r <= MAX_ROW (test_bb); r++)
+ {
+ one_byte *row = BITMAP_ROW (*b, r);
+ memset (row + MIN_COL (test_bb), 0, test_bb_width);
+ }
+ }
+ else if (print_clean_info)
+ REPORT ("keeping.\n");
+ }
+}
+
+
+/* Translate the elements of BOXES to the origin, i.e., shift each down
+ by the minimum row and column. We use this in `clean_bitmap' to
+ change bounding boxes in the coordinates of the entire image to the
+ coordinates of the single character we are cleaning. */
+
+static void
+image_to_bitmap_bbs (bb_list_type *boxes)
+{
+ unsigned b;
+ unsigned min_col = UINT_MAX;
+ unsigned min_row = UINT_MAX;
+
+ /* First find the minimum row and column of all the bb's in BOXES. */
+ for (b = 0; b < BB_LIST_LENGTH (*boxes); b++)
+ {
+ bounding_box_type bb = BB_LIST_ELT (*boxes, b);
+
+ assert (MIN_COL (bb) >= 0 && MIN_ROW (bb) >= 0);
+
+ MIN_EQUALS (min_col, MIN_COL (bb));
+ MIN_EQUALS (min_row, MIN_ROW (bb));
+ }
+
+ /* Now translate all the bb's by those minimums. */
+ for (b = 0; b < BB_LIST_LENGTH (*boxes); b++)
+ {
+ bounding_box_type *bb = &BB_LIST_ELT (*boxes, b);
+
+ MIN_COL (*bb) -= min_col;
+ MAX_COL (*bb) -= min_col;
+ MIN_ROW (*bb) -= min_row;
+ MAX_ROW (*bb) -= min_row;
+ }
+}
+
+/* Derive the information necessary to output the font character from
+ the bitmap B, and return it. The resolution of the bitmap is given
+ in pixels per inch as H_RESOLUTION. The bounding box BB encloses the
+ character in the image coordinates. We use BB and the static
+ variables `row_baseline' and `row_height' to determine the
+ positioning of the GF character. */
+
+#define BB_TO_CARTESIAN(x) \
+ (row_height - 1 - (x) - row_baseline \
+ - IMAGE_CHAR_BASELINE_ADJUST (image_char))
+
+static gf_char_type
+bitmap_to_gf_char (bitmap_type b, real h_resolution,
+ bounding_box_type bb, image_char_type image_char)
+{
+ static boolean first = true;
+ static boolean have_tfm_file = false;
+ gf_char_type gf_char;
+ bounding_box_type cartesian_bb;
+ charcode_type charcode = IMAGE_CHARCODE (image_char);
+ boolean have_tfm_width = false;
+
+/*xx*/
+if(b.bitmap){
+if ((testfileptr = fopen(gf_bitmap_filename, "w")) != NULL)
+print_bitmap(testfileptr, b);
+else
+printf("Bad file pointer for printing gf_bitmap.\n");
+fclose(testfileptr);
+if ((testfileptr = fopen(gf_bb_bitmap_filename, "w")) != NULL)
+print_bounded_bitmap(testfileptr, b, bb);
+else
+printf("Bad file pointer for printing gf_bb_bitmap.\n");
+fclose(testfileptr);
+}
+ MIN_ROW (cartesian_bb) = BB_TO_CARTESIAN (MAX_ROW (bb));
+ MAX_ROW (cartesian_bb) = BB_TO_CARTESIAN (MIN_ROW (bb));
+
+ REPORT1 ("%u", charcode);
+
+ GF_CHARCODE (gf_char) = charcode;
+ GF_BITMAP (gf_char) = b;
+ GF_CHAR_MIN_COL (gf_char) = IMAGE_CHAR_LSB (image_char);
+ GF_CHAR_MAX_COL (gf_char) = GF_CHAR_MIN_COL (gf_char) + BITMAP_WIDTH (b);
+ GF_CHAR_MIN_ROW (gf_char) = MIN_ROW (cartesian_bb);
+ GF_CHAR_MAX_ROW (gf_char) = MAX_ROW (cartesian_bb);
+
+ GF_H_ESCAPEMENT (gf_char) = (GF_CHAR_MAX_COL (gf_char)
+ + IMAGE_CHAR_RSB (image_char));
+ if (first)
+ {
+ string tfm_name = kpse_find_tfm (remove_suffix (output_name));
+
+ if (tfm_name)
+ have_tfm_file = tfm_open_input_file (tfm_name);
+ first = false;
+ }
+
+ have_tfm_width = false;
+ if (have_tfm_file)
+ {
+ tfm_char_type *tfm_char = tfm_get_char (charcode);
+ if (tfm_char)
+ {
+ GF_TFM_WIDTH (gf_char) = TFM_FIX_WIDTH (*tfm_char);
+ have_tfm_width = true;
+ }
+ }
+
+ /* If no TFM file, or the TFM file doesn't define this character,
+ use the pixel width for the TFM value. */
+ if (!have_tfm_width)
+ {
+ real width_in_points
+ = GF_H_ESCAPEMENT (gf_char) * POINTS_PER_INCH / h_resolution;
+ GF_TFM_WIDTH (gf_char) = real_to_fix (width_in_points / design_size);
+ }
+
+ if (print_guidelines)
+ REPORT3 (" (%s) %d/%d", IMAGE_CHARNAME (image_char),
+ MIN_ROW (cartesian_bb), MAX_ROW (cartesian_bb));
+
+ return gf_char;
+}
diff --git a/imageto/out-chars.h b/imageto/out-chars.h
new file mode 100644
index 0000000..0b91ade
--- /dev/null
+++ b/imageto/out-chars.h
@@ -0,0 +1,34 @@
+/* out-chars.h: extract the characters from the image.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef OUT_CHARS_H
+#define OUT_CHARS_H
+
+#include "image-header.h"
+
+
+/* See out-chars.c. */
+extern int *baseline_list;
+extern boolean print_clean_info, print_guidelines;
+extern unsigned nchars_wanted;
+extern int starting_char, ending_char;
+
+
+extern void write_image_chars (image_header_type, real design_size);
+
+#endif /* not OUT_CHARS_H */
diff --git a/imageto/out-epsf.c b/imageto/out-epsf.c
new file mode 100644
index 0000000..564807c
--- /dev/null
+++ b/imageto/out-epsf.c
@@ -0,0 +1,166 @@
+/* out-epsf.c: output the whole image as an EPS file.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#include "hexify.h"
+#include "report.h"
+
+#include "main.h"
+#include "out-epsf.h"
+
+extern string version_string;
+
+static void pack_scanline (one_byte *, unsigned);
+
+/* Abbreviations for output to `eps_file'. */
+#define OUT_STRING(s) fprintf (eps_file, "%s", s)
+#define OUT_SIMPLE(s) fprintf (eps_file, "%%%%%s\n", s)
+#define OUT_COMMENT(s, v) fprintf (eps_file, "%%%%%s: %s\n", s, v)
+#define OUT1(s, v1) fprintf (eps_file, s, v1)
+#define OUT2(s, v1, v2) fprintf (eps_file, s, v1, v2)
+#define OUT3(s, v1, v2, v3) fprintf (eps_file, s, v1, v2, v3)
+
+/* Write an Encapsulated PostScript file corresponding to the image. */
+
+void
+write_epsf (string output_name, image_header_type image_header)
+{
+ /* Just black & white, or do we have grayscale? */
+ boolean monochrome_p = image_header.depth == 1;
+
+ /* Just for convenience. */
+ unsigned width = image_header.width;
+ unsigned height = image_header.height;
+
+ /* We pack the image tightly if it's monochrome. */
+ unsigned width_used = monochrome_p ? width / 8 + !!(width % 8) : width;
+
+ /* Buffer into which we'll read the image data. */
+ unsigned scanline_count = 0;
+ one_byte *scanline = xmalloc (width);
+
+ /* Open the output file OUTPUT_NAME. */
+ FILE *eps_file = xfopen (output_name, "w");
+
+ OUT_STRING ("%!PS-Adobe-3.0 EPSF-3.0\n");
+ OUT2 ("%%%%BoundingBox: 0 0 %u %u\n", width, height);
+ OUT_COMMENT ("Creator", version_string);
+ OUT_COMMENT ("Title", output_name);
+ OUT_COMMENT ("CreationDate", now ());
+ OUT_COMMENT ("DocumentData", "Clean7Bit");
+ OUT_SIMPLE ("EndComments");
+
+ /* We map the image to the unit square for image(mask) and scale the
+ coordinate system to get back to the original size. I can't grasp
+ how to use the matrix argument to image(mask) to avoid the scaling,
+ but I'm sure it's possible. */
+ OUT2 ("gsave\n %u %u scale\n", width, height);
+
+ /* We need a buffer to hold the string chunks as we read them. It
+ can't be of arbitrary size: it must be an exact multiple of the
+ total number of data characters. Otherwise, we will read past the
+ end of the data. */
+ OUT1 ("/image-buffer %u string def\n", width_used);
+
+ /* If we are monochrome, we use the `imagemask' operator; else `image'. */
+ OUT2 (" %u %u", width, height);
+
+ if (monochrome_p)
+ OUT_STRING (" true"); /* The `invert' argument. */
+ else
+ OUT1 (" %u", image_header.depth); /* bits/sample */
+
+ OUT3 (" [%u 0 0 -%u 0 %u]\n", width, height, height);
+ OUT_STRING ("{currentfile image-buffer readhexstring pop}\n");
+ OUT1 ("%s\n", monochrome_p ? "imagemask" : "image");
+
+ /* Read the image. */
+ while ((*image_get_scanline) (scanline))
+ {
+ string h;
+ unsigned loc;
+
+ scanline_count++;
+ if (scanline_count % 10 == 0)
+ REPORT1 (".%s", scanline_count % 790 == 0 ? "\n" : "");
+
+ /* Monochrome images are output with eight samples/byte; grayscale
+ images are output with one sample/byte. */
+ if (monochrome_p)
+ pack_scanline (scanline, width);
+
+ /* Convert binary to ASCII hexadecimal. */
+ h = hexify (scanline, width_used);
+
+ /* Adobe says lines in EPS files should be no more than 255
+ characters. How silly. */
+ for (loc = 1; loc <= 2 * width_used; loc++)
+ {
+ putc (h[loc - 1], eps_file);
+ if (loc % 255 == 0)
+ putc ('\n', eps_file);
+ }
+
+ free (h);
+ putc ('\n', eps_file);
+ }
+
+ /* Restore the ctm. */
+ OUT_STRING ("grestore\n");
+
+ if (scanline_count != image_header.height)
+ WARNING2 ("Expected %u scanlines, read %u", image_header.height,
+ scanline_count);
+
+ OUT_SIMPLE ("TRAILER");
+ OUT_SIMPLE ("EOF");
+}
+
+/* Change the one bit/byte representation (call each byte a `cell') of
+ LENGTH bits in DATA to be eight bits/byte. Pad the last byte with
+ zero. We don't change those bytes beyond the end of packed portion,
+ thus assuming they are not looked at. */
+
+static void
+pack_scanline (one_byte *data, unsigned length)
+{
+ unsigned cell; /* Which bit in the original data we're on. */
+ unsigned packing_loc = 0; /* Which byte we're currently packing. */
+ unsigned packing_bit = 8; /* How much to shift. */
+
+ /* The very first cell has to be treated specially, because we must
+ initialize it with itself shifted left (if we're going to use data
+ in place, that is.) */
+ data[0] <<= 7;
+
+ for (cell = 0; cell < length; cell++)
+ {
+ packing_bit--;
+ data[packing_loc] |= data[cell] << packing_bit;
+ if (packing_bit == 0)
+ {
+ packing_bit = 8;
+ packing_loc++;
+
+ /* After the first byte, we can just clear the byte at
+ `packing_loc', since `cell' has already moved beyond it. */
+ data[packing_loc] = 0;
+ }
+ }
+}
diff --git a/imageto/out-epsf.h b/imageto/out-epsf.h
new file mode 100644
index 0000000..c664772
--- /dev/null
+++ b/imageto/out-epsf.h
@@ -0,0 +1,28 @@
+/* out-epsf.h: output the whole image as an EPS file.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef OUT_EPSF_H
+#define OUT_EPSF_H
+
+#include "image-header.h"
+
+
+/* Output an EPS file for the image with header H to OUTPUT_NAME. */
+extern void write_epsf (string output_name, image_header_type h);
+
+#endif /* not OUT_EPSF_H */
diff --git a/imageto/out-strips.c b/imageto/out-strips.c
new file mode 100644
index 0000000..a43a411
--- /dev/null
+++ b/imageto/out-strips.c
@@ -0,0 +1,94 @@
+/* out-strips.c: cut the entire image into strips.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "config.h"
+
+#include "gf.h"
+#include "report.h"
+
+#include "main.h"
+#include "out-strips.h"
+
+/* Output a ``font'' in which each ``character'' is a constant number of
+ scanlines from the image. This might use less than resources than
+ the giant PostScript file that -epsf outputs.
+
+ We only output the GF characters here; we assume the postamble and
+ preamble are written by the caller. */
+
+void
+write_chars_as_strips (image_header_type image_header, real design_size)
+{
+ dimensions_type char_dimens;
+ gf_char_type gf_char;
+ unsigned gf_row;
+ unsigned lines_per_char;
+ one_byte *scanline;
+ real width_in_points;
+ boolean first_char = true;
+ unsigned scanline_count = 0;
+
+ /* Set up for the first character. We divide the image into 256 parts,
+ each of which will turn into one ``character''. */
+ lines_per_char = image_header.height / 256 + 1;
+ GF_CHARCODE (gf_char) = 0;
+ DIMENSIONS_WIDTH (char_dimens) = image_header.width;
+ DIMENSIONS_HEIGHT (char_dimens) = lines_per_char;
+ GF_BITMAP (gf_char) = new_bitmap (char_dimens);
+ GF_CHAR_MIN_COL (gf_char) = GF_CHAR_MIN_ROW (gf_char) = 0;
+ GF_CHAR_MAX_COL (gf_char) = DIMENSIONS_WIDTH (char_dimens);
+ GF_CHAR_MAX_ROW (gf_char) = DIMENSIONS_HEIGHT (char_dimens) - 1;
+
+ /* We aren't going to have any side bearings. */
+ GF_H_ESCAPEMENT (gf_char) = DIMENSIONS_WIDTH (char_dimens);
+ width_in_points = DIMENSIONS_WIDTH (char_dimens) * POINTS_PER_INCH
+ / (real) image_header.hres;
+ GF_TFM_WIDTH (gf_char) = real_to_fix (width_in_points / design_size);
+
+
+ /* Read the image. */
+ while (true)
+ {
+ if (scanline_count % lines_per_char == 0)
+ {
+ /* We get here when scanline_count == 0, and we haven't read
+ anything, so we can't write anything. */
+ if (!first_char)
+ {
+ gf_put_char (gf_char);
+ REPORT2 ("[%u]%c", GF_CHARCODE (gf_char),
+ (GF_CHARCODE (gf_char) + 1) % 13 ? ' ' : '\n');
+ GF_CHARCODE (gf_char)++;
+ }
+ else
+ first_char = false;
+ gf_row = 0;
+ }
+
+ scanline = BITMAP_BITS (GF_BITMAP (gf_char))
+ + gf_row * DIMENSIONS_WIDTH (char_dimens);
+ if (!(*image_get_scanline) (scanline)) break;
+
+ scanline_count++;
+ gf_row++;
+ }
+
+ if (scanline_count != image_header.height)
+ WARNING2 ("Expected %u scanlines, read %u", image_header.height,
+ scanline_count);
+}
diff --git a/imageto/out-strips.h b/imageto/out-strips.h
new file mode 100644
index 0000000..401c124
--- /dev/null
+++ b/imageto/out-strips.h
@@ -0,0 +1,27 @@
+/* out-strips.h: cut the image into strips.
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef OUT_STRIPS_H
+#define OUT_STRIPS_H
+
+#include "image-header.h"
+
+
+extern void write_chars_as_strips (image_header_type, real design_size);
+
+#endif /* not OUT_STRIPS_H */
diff --git a/imageto/strips.tex b/imageto/strips.tex
new file mode 100644
index 0000000..1b7a3ee
--- /dev/null
+++ b/imageto/strips.tex
@@ -0,0 +1,85 @@
+% TeX file to display a ``font'' made from imagetofont's -strips option.
+
+% Set up our font.
+\message{Fontname? }
+\read -1 to \testfontname
+\font\testfont = \testfontname\space
+\testfont
+
+% \monthname produces the name of the month, abbreviated to three
+% letters. The primitive \month should never be zero.
+%
+\def\monthname{%
+ \ifcase\month
+ \or Jan\or Feb\or Mar\or Apr\or May\or Jun%
+ \or Jul\or Aug\or Sep\or Oct\or Nov\or Dec%
+ \fi
+}%
+
+% \timestring produces the current time, in a format like `1:14 p.m.'.
+%
+\def\timestring{\begingroup
+ \count0 = \time
+ \divide\count0 by 60
+ \count2 = \count0 % The hour, from zero to 23.
+ %
+ \count4 = \time
+ \multiply\count0 by 60
+ \advance\count4 by -\count0 % The minute, from zero to 59.
+ % But we need the minutes with a leading zero, if necessary.
+ \ifnum\count4<10
+ \toks1 = {0}%
+ \else
+ \toks1 = {}%
+ \fi
+ %
+ % Convert the hour into `a.m.' or `p.m.', and make it mod 12.
+ \ifnum\count2<12
+ \toks0 = {a.m.}%
+ \else
+ \toks0 = {p.m.}%
+ \advance\count2 by -12
+ \fi
+ %
+ % If it's midnight, call it `12', not `0'.
+ \ifnum\count2=0
+ \count2 = 12
+ \fi
+ %
+ % Produce the output.
+ \number\count2:\the\toks1 \number\count4 \thinspace \the\toks0
+\endgroup}%
+%
+%
+% \timestamp produces a text string for the whole thing like
+% `23 Apr 1964 1:14 p.m.'.
+%
+\def\timestamp{\number\day\space\monthname\space\number\year\quad\timestring}%
+
+\nopagenumbers
+\headline = {\hfil \tt \testfontname \quad \timestamp}
+
+% Use as much of the page as we dare.
+\hoffset = -5pc \hsize = 49pc
+\voffset = -5pc \vsize = 64pc
+
+% Don't worry if there's no good place to break pages.
+\vbadness = 10000
+
+% No leading between ``lines''.
+\offinterlineskip
+
+% Don't worry if the font doesn't have exactly 256 characters, since
+% roundoff error makes this likely.
+\tracinglostchars = 0
+
+
+\count255 = 0
+\loop
+ %\setbox0 = \hbox{\char\count255}
+ \leftline{\char\count255}
+ \advance\count255 by 1
+ \ifnum\count255<256
+\repeat
+
+\end
diff --git a/imageto/version.c b/imageto/version.c
new file mode 100644
index 0000000..b39f56a
--- /dev/null
+++ b/imageto/version.c
@@ -0,0 +1 @@
+char *version_string = "imageto version REPLACE-WITH-VERSION";