home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / fontutils-0.6 / imageto / ifi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-23  |  5.5 KB  |  198 lines

  1. /* ifi.c: read an IFI file.  */
  2.  
  3. #include "config.h"
  4.  
  5. #include "encoding.h"
  6. #include "libfile.h"
  7.  
  8. #include "ifi.h"
  9. #include "main.h"
  10.  
  11.  
  12. /* The name of the encoding file specified by the user, and the
  13.    structure we parse it into.  (-encoding)  */
  14. string encoding_name = NULL;
  15.  
  16. /* The name of the IFI file.  (-ifi-file)  */
  17. string ifi_filename = NULL;
  18.  
  19.  
  20. static void append_image_char (image_char_list_type *l, image_char_type c);
  21. static image_char_list_type new_image_char_list (void);
  22.  
  23. /* Read the IFI file `ifi_filename' (or construct the IFI filename from
  24.    `input_name'), which gives us information about the image we are
  25.    going to read.
  26.    
  27.    See the documentation for full details and examples of IFI files.
  28.    Here we just sketch the bare bones.
  29.    
  30.    Each (non-blank, non-comment) line in this file represents a
  31.    ``character'' in the image, and has one to five entries, separated by
  32.    spaces and/or tabs.  Comments start with `%' and continue to the end
  33.    of the line.
  34.    
  35.    The first entry represents the character code.  See the documentation
  36.    for the various forms of charcodes.  We also allow `.notdef', meaning
  37.    the ``character'' should not be output in the font.  
  38.    
  39.    The second entry, if it exists, is an adjustment to the
  40.    baseline.  We move the baseline down for negative numbers, and up
  41.    for positive ones.  Default is zero.
  42.    
  43.    The third entry, if it exists, is the number of bounding boxes that
  44.    comprise this character.  If it is negative, the bounding boxes
  45.    are not consecutive in the image; instead, they alternate with
  46.    bounding boxes for some other character.
  47.    
  48.    The fourth and fifth entries, if they exist, are the left and right
  49.    side bearings, respectively.  */
  50.    
  51. image_char_list_type
  52. read_ifi_file (unsigned *total_count)
  53. {
  54.   string line;
  55.   int bb_count;
  56.   encoding_info_type *encoding_info;
  57.   int n = 0;
  58.   image_char_list_type image_char_list = new_image_char_list ();
  59.   
  60.   if (encoding_name)
  61.     {
  62.       encoding_info = XTALLOC1 (encoding_info_type);
  63.       *encoding_info = read_encoding_file (encoding_name);
  64.     }
  65.   else  
  66.     encoding_info = NULL;
  67.     
  68.   if (!ifi_filename)
  69.     ifi_filename = make_suffix (input_name, "ifi");
  70.  
  71.   libfile_start (ifi_filename, "ifi");
  72.  
  73.   *total_count = 0;
  74.  
  75.   while ((line = libfile_line ()) != NULL)
  76.     {
  77.       image_char_type c;
  78.       string baseline_adjust_str, bb_count_str, charname;
  79.       string lsb_str, rsb_str;
  80.       string save_line = line; /* So we can free it.  */
  81.       
  82.       /* The character name.  */
  83.       charname = strtok (line, " \t");
  84.       
  85.       /* `libfile_line' should never return an empty line.  */
  86.       assert (charname != NULL);
  87.       
  88.       if (STREQ (charname, ".notdef"))
  89.         IMAGE_CHAR_OMIT (c) = true;
  90.       else
  91.         {
  92.           if (encoding_info)
  93.             n = encoding_number (*encoding_info, charname);
  94.           else
  95.             n++;
  96.           
  97.           if (n == -1)
  98.             {
  99.               LIBFILE_WARN2 ("Character `%s' undefined in encoding %s",
  100.                         charname, ENCODING_SCHEME_NAME (*encoding_info));
  101.               IMAGE_CHAR_OMIT (c) = true;
  102.         }
  103.           else
  104.             {
  105.               IMAGE_CHARCODE (c) = n;
  106.               IMAGE_CHARNAME (c) = xstrdup (charname);
  107.               IMAGE_CHAR_OMIT (c) = false;
  108.         }
  109.         }
  110.  
  111.       /* The baseline adjustment.  */
  112.       baseline_adjust_str = strtok (NULL, " \t");
  113.       IMAGE_CHAR_BASELINE_ADJUST (c)
  114.         = baseline_adjust_str == NULL ? 0 : atoi (baseline_adjust_str);
  115.       
  116.       /* The bounding box count.  */
  117.       bb_count_str = strtok (NULL, " \t");
  118.       bb_count = bb_count_str == NULL ? 1 : atoi (bb_count_str);
  119.       
  120.       if (bb_count < 0)
  121.         {
  122.           IMAGE_CHAR_BB_COUNT (c) = -bb_count;
  123.           IMAGE_CHAR_BB_ALTERNATING (c) = true;
  124.         }
  125.       else
  126.         {
  127.           IMAGE_CHAR_BB_COUNT (c) = bb_count;
  128.           IMAGE_CHAR_BB_ALTERNATING (c) = false;
  129.         }
  130.  
  131.       /* The left side bearing.  */
  132.       lsb_str = strtok (NULL, " \t");
  133.       IMAGE_CHAR_LSB (c) = lsb_str == NULL ? 0 : atoi (lsb_str);
  134.       
  135.       /* The right side bearing.  */
  136.       rsb_str = strtok (NULL, " \t");
  137.       IMAGE_CHAR_RSB (c) = rsb_str == NULL ? 0 : atoi (rsb_str);
  138.       
  139.       *total_count += IMAGE_CHAR_BB_COUNT (c);
  140.       append_image_char (&image_char_list, c);
  141.       free (save_line);
  142.     }
  143.   
  144.   libfile_close ();
  145.   if (encoding_info)
  146.     free (encoding_info);
  147.   
  148.   return image_char_list;
  149. }
  150.  
  151. /* Return an initialized, empty list.  */
  152.  
  153. static image_char_list_type
  154. new_image_char_list ()
  155. {
  156.   image_char_list_type l;
  157.   
  158.   IMAGE_CHAR_LIST_LENGTH (l) = 0;
  159.   IMAGE_CHAR_LIST_DATA (l) = NULL;
  160.   
  161.   return l;
  162. }
  163.  
  164.  
  165. /* Append the character C to the list L.  */
  166.  
  167. void
  168. append_image_char (image_char_list_type *l, image_char_type c)
  169. {
  170.   IMAGE_CHAR_LIST_LENGTH (*l)++;
  171.   IMAGE_CHAR_LIST_DATA (*l)
  172.     = xrealloc (IMAGE_CHAR_LIST_DATA (*l),
  173.                   IMAGE_CHAR_LIST_LENGTH (*l) * sizeof (image_char_type));
  174.   IMAGE_CHAR (*l, IMAGE_CHAR_LIST_LENGTH (*l) - 1) = c;
  175. }
  176.  
  177.  
  178. /* Return false if the box BOX_COUNT boxes beyond FIRST_CHAR in LIST
  179.    is in the middle of a character, true otherwise.  To do this, we
  180.    add up all the box counts for characters starting at FIRST_CHAR,
  181.    until we see where we land.  */
  182.  
  183. boolean
  184. box_at_char_boundary_p (image_char_list_type list, unsigned first_char,
  185.                         unsigned box_count)
  186. {
  187.   unsigned count = 0;
  188.   
  189.   while (count < box_count && first_char < IMAGE_CHAR_LIST_LENGTH (list))
  190.     {
  191.       image_char_type c = IMAGE_CHAR (list, first_char);
  192.       count += IMAGE_CHAR_BB_COUNT (c);
  193.       first_char++;
  194.     }
  195.     
  196.   return count == box_count;
  197. }
  198.