]> git.donarmstrong.com Git - lilypond.git/commitdiff
patch::: 1.1.23.jcn8: tfm reader
authorJan Nieuwenhuizen <janneke@gnu.org>
Sun, 24 Jan 1999 20:33:31 +0000 (21:33 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sun, 24 Jan 1999 20:33:31 +0000 (21:33 +0100)
pl 23.jcn8
- tfm reader; revamped code from fontutils-0.6

---
Generated by janneke@gnu.org using package-diff 0.62,
>From = lilypond-1.1.23.jcn7, To = lilypond-1.1.23.jcn8

usage

    cd lilypond-source-dir; patch -E -p1 < lilypond-1.1.23.jcn8.diff

Patches do not contain automatically generated files
or (urg) empty directories,
i.e., you should rerun autoconf, configure
and possibly make outdirs.

--state
1.1.23.jcn7
1.1.23.jcn8
++state

15 files changed:
NEWS
VERSION
flower/include/fproto.hh
lib/binary-source-file.cc
lib/include/binary-source-file.hh
lib/include/proto.hh
lib/include/source-file.hh
lib/source-file.cc
lily/include/lily-proto.hh
lily/include/lily-proto.hh.orig [new file with mode: 0644]
lily/include/tfm.hh [new file with mode: 0644]
lily/main.cc
lily/tfm.cc [new file with mode: 0644]
mi2mu/include/midi-parser.hh
mi2mu/midi-score-parser.cc

diff --git a/NEWS b/NEWS
index 6209ed181a6196059c3a860a7f95c1a80947c7b0..be7d1bee97c6ebb95da056cc9d96a0782bafa421 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,12 @@
---- ../lilypond-1.1.23/NEWS    Tue Jan 19 10:29:41 1999
+--- ../lilypond-1.1.23.jcn7/NEWS       Sun Jan 24 13:35:45 1999
+++ b/NEWS      Sun Jan 24 21:29:07 1999
+@@ -1,3 +1,6 @@
+pl 23.jcn8
+       - tfm reader; revamped code from fontutils-0.6
+
+ pl 23.jcn7
+       - bf: piano-brace size (veels te simpel: kruis vingers tegen reject)
+       - crude autobeam stuff in mi2mu--- ../lilypond-1.1.23/NEWS      Tue Jan 19 10:29:41 1999
 ++ b/NEWS      Sat Jan 23 20:13:39 1999
 @@ -1,3 +1,12 @@
 pl 23.jbr1
diff --git a/VERSION b/VERSION
index 95eb4dc5417094b176a29de2d1506c7a27fa6da0..808e8329529fe9b5403b944f5bf92ac830541eff 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=1
 PATCH_LEVEL=23
-MY_PATCH_LEVEL=jbr1
+MY_PATCH_LEVEL=jcn8
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
index d149d5f0229343be0e05a61ded75d8a6e81acfe9..9983eef245f3fc9b0d82a82d7746c6baa252e136 100644 (file)
 
 char const * flower_version_sz();
 
-// what the F*** is "int" ?
-// deprecate int, long, etc., use i32, i64, remember: linux-16/linux-64 ?
-/// (i32)
-typedef int i32;
-/// (i64)
-typedef long long I64;
-
 template<class T> struct Link_array;
 template<class T> struct Array;
 template<class T> struct sstack;
@@ -70,6 +63,14 @@ struct Text_stream;
 struct Data_file;
 struct Text_db;
 struct Scalar;
+
+typedef unsigned char U8;
+typedef short I16;
+typedef unsigned short U16;
+typedef unsigned U32;
+typedef int I32;
+typedef long long I64;
+
 typedef unsigned char Byte;
 
 
index 9bcf0e5f70fa1ab4dffd161c8c12755534548494..17a712fa81c37e544a906626037421d9f115b209 100644 (file)
@@ -27,20 +27,20 @@ Binary_source_file::~Binary_source_file ()
 }
 
 String
-Binary_source_file::error_str (char const* pos_ch_c_l) const
+Binary_source_file::error_str (char const* pos_ch_C) const
 {
     assert (this);
-    if (!in_b (pos_ch_c_l))
+    if (!in_b (pos_ch_C))
        return "";
 
-    char const* begin_ch_c_l = pos_ch_c_l - 8 >? ch_C ();
-    char const* end_ch_c_l = pos_ch_c_l + 7 <? ch_C () + length_i ();
+    char const* begin_ch_C = pos_ch_C - 8 >? ch_C ();
+    char const* end_ch_C = pos_ch_C + 7 <? ch_C () + length_i ();
 
-    String pre_str ((Byte const*)begin_ch_c_l, pos_ch_c_l - begin_ch_c_l);
+    String pre_str ((Byte const*)begin_ch_C, pos_ch_C - begin_ch_C);
     pre_str = String_convert::bin2hex_str (pre_str);
     for (int i = 2; i < pre_str.length_i (); i += 3)
        pre_str = pre_str.left_str (i) + " " + pre_str.cut_str (i, INT_MAX);
-    String post_str ((Byte const*)pos_ch_c_l, end_ch_c_l - pos_ch_c_l);
+    String post_str ((Byte const*)pos_ch_C, end_ch_C - pos_ch_C);
     post_str = String_convert::bin2hex_str (post_str);
     for (int i = 2; i < post_str.length_i (); i += 3)
        post_str = post_str.left_str (i) + " " + post_str.cut_str (i, INT_MAX);
@@ -53,11 +53,11 @@ Binary_source_file::error_str (char const* pos_ch_c_l) const
 }
 
 int
-Binary_source_file::line_i (char const* pos_ch_c_l) const
+Binary_source_file::line_i (char const* pos_ch_C) const
 {
-    if (!in_b (pos_ch_c_l))
+    if (!in_b (pos_ch_C))
        return 0;
 
-    return pos_ch_c_l - ch_C ();
+    return pos_ch_C - ch_C ();
 }
 
index a6f252a1dac18ce2331311999d317b6d59bfc60f..59c35b6a83cfb2804a90e7691e20f0bd1545ee9e 100644 (file)
@@ -8,13 +8,20 @@
 
 #include "source-file.hh"
 
-class Binary_source_file : public Source_file {
+class Binary_source_file : public Source_file
+{
 public:
-       Binary_source_file (String& filename_str );
-       virtual ~Binary_source_file ();
+  Binary_source_file (String& filename_str );
+  virtual ~Binary_source_file ();
 
-       virtual String error_str (char const* pos_ch_c_l ) const;
-       virtual int line_i (char const* pos_ch_c_l ) const;
+  U8 get_U8 () { return *(U8*)forward_ch_C (1); }
+  U16 get_U16 () { return *(U16*)forward_ch_C (2); }
+  U32 get_U32 () { return *(U32*)forward_ch_C (4); }
+  Byte get_Byte () {return get_U8 (); }
+  int get_int () { return get_U32 (); }
+  
+  virtual String error_str (char const* pos_ch_C ) const;
+  virtual int line_i (char const* pos_ch_C ) const;
 };
 
-#endif // BINARY_SOURCE_FILE_HH //
+#endif // BINARY_SOURCE_FILE_HH
index 21cadf9b791e4f953c8524196b015c72a5bb8d06..540accfc4a2546468efeeff7b765fa02bb1c5c0e 100644 (file)
 struct Duration;
 struct Duration_iterator;
 struct Source_file;
+struct Binary_source_file;
 struct Sources;
 struct File_storage;
 struct Mapped_file_storage;
 struct Simple_file_storage;
+
 #endif // PROTO_HH
index ee671c785a3bfee41bffeefce3e400c13a3412cb..560ab09ed94f236b29ab9c4944ad4a9c74288951 100644 (file)
 class istream;
 
 
-/// class for reading and mapping a file. 
+/**
+  class for reading and mapping a file. 
+
+  duplicates a lot of Data_file and Text_stream.
+  should look at including Data_file's functionality:
+  get_line (), get_word () here.
+*/
+
 class Source_file
 {
 public:
   /** Ugh! filename gets changed! The path to the opened file may
     change, since it might be searched in multiple directories.  */
   Source_file (String filename_str_r );
+
   Source_file (String name_str, String data_str);
   virtual ~Source_file ();
 
   char const* ch_C () const;
-  virtual String error_str (char const* pos_ch_c_l ) const;
+  virtual String error_str (char const* pos_ch_C ) const;
   istream * istream_l ();
-  bool in_b (char const* pos_ch_c_l ) const;
+  bool in_b (char const* pos_ch_C ) const;
   int length_i () const;
-  virtual int line_i (char const* pos_ch_c_l ) const;
+  virtual int line_i (char const* pos_ch_C ) const;
   String name_str () const;
-  String file_line_column_str (char const* ch_c_l ) const;
+  String file_line_column_str (char const* ch_C ) const;
+
+  // return start + n
+  char const* seek_ch_C (int n);
+  // return here + n bytes
+  char const* forward_ch_C (int n);
+  char const* pos_ch_C () { return pos_ch_C_; }
+  String get_str (int n);
+  void set_pos (char const * pos_ch_C);
+  
+  // tbd
+  // String get_line ();
+  // String get_word ();
+  // only used in binary-source-file, currently
+
 
 protected:
   Slice line_slice (char const* pos_ch_C) const;
@@ -38,6 +60,8 @@ protected:
   int column_i (char const* pos_ch_C) const;
   int char_i (char const* pos_ch_C) const;
 
+  char const* pos_ch_C_;
+
 private:
   String name_str_;
   istream* istream_p_;
index 5403abb5179b3452b862a8305b01d469cd11182c..55e4ea63d22b19153962797fb8119fc8438247ff 100644 (file)
@@ -25,6 +25,7 @@ Source_file::Source_file (String filename_str)
   name_str_ = filename_str;
   istream_p_ = 0;
   storage_p_ = new Simple_file_storage (filename_str);
+  pos_ch_C_ = ch_C ();
 }
 
 Source_file::Source_file (String name_str, String data_str)
@@ -32,6 +33,7 @@ Source_file::Source_file (String name_str, String data_str)
   name_str_ = name_str;
   istream_p_ = 0;
   storage_p_ = new String_storage (data_str);
+  pos_ch_C_ = ch_C ();
 }
 
 istream*
@@ -198,3 +200,46 @@ Source_file::ch_C () const
 {
   return storage_p_->ch_C ();
 }
+
+void
+Source_file::set_pos (char const * pos_ch_C)
+{
+  if (in_b (pos_ch_C))
+    pos_ch_C_ = pos_ch_C;
+  else
+    error (error_str (pos_ch_C) + "invalid pos");
+}
+
+char const*
+Source_file::seek_ch_C (int n)
+{
+  char const* new_ch_C = ch_C () + n;
+  if (n < 0)
+    new_ch_C += length_i ();
+  if (in_b (new_ch_C))
+    pos_ch_C_ = new_ch_C;
+  else
+    error (error_str (new_ch_C) + "seek past eof");
+
+  return pos_ch_C_;
+}
+
+char const*
+Source_file::forward_ch_C (int n)
+{
+  char const* old_pos_C = pos_ch_C_;
+  char const* new_ch_C = pos_ch_C_ + n;
+  if (in_b (new_ch_C))
+    pos_ch_C_ = new_ch_C;
+  else
+    error (error_str (new_ch_C)  + "forward past eof");
+
+  return old_pos_C;
+}
+
+String
+Source_file::get_str (int n)
+{
+  String str ((Byte const*)forward_ch_C (n), n);
+  return str;
+}
index b44dab422342896ccb8aac43a6a438ce9bee5e02..fb8f26e12f8bd6c9129c28d6ca18b11e1d47a4ca 100644 (file)
@@ -232,6 +232,8 @@ struct Symtables;
 struct Super_element;
 struct Translation_property;
 struct Tempo_req;
+struct Tex_font_metric;
+struct Tex_font_char_metric;
 struct Text_def;
 struct Text_gob;
 struct Text_item ;
diff --git a/lily/include/lily-proto.hh.orig b/lily/include/lily-proto.hh.orig
new file mode 100644 (file)
index 0000000..b44dab4
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+  lily-proto.hh -- declare class names.
+
+  source file of the GNU LilyPond music typesetter
+
+  (c)  1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+#ifndef LILY_PROTO_HH
+#define LILY_PROTO_HH
+#include "proto.hh"
+
+struct Absolute_dynamic_req;
+struct Abbreviation;
+struct Abbreviation_beam; 
+struct Abbreviation_beam_req;
+struct Abbreviation_beam_engraver;
+struct G_staff_side_item;
+struct G_text_item;
+struct Abbreviation_req;
+struct Adobe_font_metric;
+struct Adobe_font_char_metric;
+struct All_font_metrics;
+struct Atom;
+struct Audio_element;
+struct Audio_column;
+struct Audio_item;
+struct Audio_key;
+struct Audio_time_signature;
+struct Audio_note;
+struct Audio_note_off;
+struct Audio_staff;
+struct Audio_tempo;
+struct Axis_group_element;
+struct Axis_group;
+struct Bar;
+struct Bar_column_engraver;
+struct Bar_column;
+struct Bar_engraver;
+struct Bar_req;
+struct Barcheck_req;
+struct Beam;
+struct Beam_engraver;
+struct Beam_req;
+struct Blank_req;
+struct Bow;
+struct Box;
+struct Bracket_req;
+struct Break_align_item;
+struct Break_req;
+struct Cadenza_req;
+struct Change_iterator;
+struct Change_translator;
+struct Chord_name_engraver;
+struct Clef_change_req;
+struct Clef_item;
+struct Clef_engraver;
+struct Clef_performer;
+struct Column_x_positions;
+struct Column_info;
+struct Collision;
+struct Collision_engraver;
+struct Command_req;
+struct Command_script_req;
+struct Command_tie_engraver;
+struct Command_tie_req;
+struct Compressed_music;
+struct Compressed_music_iterator;
+struct Cresc_req;
+struct Crescendo ;
+struct Decresc_req;
+struct Dots;
+struct Dot_column;
+struct Directional_spanner;
+struct Durational_req;
+struct Dynamic;
+struct Dynamic_req;
+struct Element_group;
+struct Element_group_item;
+struct Engraver;
+struct Engraver_group_engraver;
+struct Extender;
+struct Extender_req;
+struct General_script_def;
+struct Graphical_element;
+
+struct Graphical_axis_group;
+struct Global_translator;
+struct Hara_kiri_line_group_engraver;
+struct Hara_kiri_vertical_group_spanner;
+struct Head_column;
+
+struct Horizontal_align_item;
+struct Horizontal_group_element;
+struct Horizontal_group_item;
+struct Horizontal_vertical_group;
+struct Idealspacing;
+struct Identifier;
+struct Input_file;
+struct Item;
+struct Key;
+struct Key_change_req;
+struct Key_item;
+struct Key_engraver;
+struct Key_performer;
+struct Keyword;
+struct Keyword_table;
+struct Lily_stream;
+struct Line_group_engraver;
+struct Line_of_score;
+struct Line_of_staff;
+struct Line_spacer;
+struct Linestaff;
+struct Local_key;
+struct Local_key_item;
+struct Local_key_engraver;
+struct Lookup;
+struct Lyric_item;
+struct Lyric_req;
+struct Mark_req;
+struct Measure_grouping_req;
+struct Melodic_req;
+struct Midi_def;
+struct Midi_duration;
+struct Midi_header;
+struct Midi_item;
+struct Midi_key;
+struct Midi_time_signature;
+struct Midi_note;
+struct Midi_note_event;
+struct Midi_note_off;
+struct Midi_output;
+struct Midi_score;
+struct Midi_stream;
+struct Midi_tempo;
+struct Midi_track;
+struct Midi_walker;
+struct Mixed_qp;
+struct Molecule;
+struct Multi_measure_rest;
+struct Multi_measure_rest_req;
+struct Multi_measure_rest_engraver;
+struct Music;
+struct Musical_req;
+struct Musical_span_req;
+struct Musical_script_req;
+struct Music_list;
+struct Music_list_iterator;
+struct Music_output;
+struct Music_output_def;
+struct Musical_pitch;
+struct Music_sequence;
+struct Music_wrapper;
+struct Music_wrapper_iterator;
+struct My_lily_lexer;
+struct My_lily_parser;
+struct Note_column;
+struct Note_column_engraver;
+struct Note_performer;
+struct Note_req;
+struct Note_head;
+struct Note_head_engraver;
+struct Notename_table;
+struct Offset;
+struct Paper_column;
+struct Paper_def;
+struct Paper_outputter;
+struct Paper_score;
+struct Paper_stream;
+struct Partial_measure_req;
+struct Performance;
+struct Performer;
+struct Plet;
+struct Plet_engraver;
+struct Plet_req;
+struct Plet_spanner;
+struct Piano_brace;
+struct Performer;
+struct Performer_group_performer;
+struct Property_iterator;
+struct Rational;
+struct Request;
+struct Request_column;
+struct Relative_octave_music;
+struct Repeat_engraver;
+struct Repeated_music;
+struct Repeated_music_iterator;
+struct Rest;
+struct Rest_collision;
+struct Rest_collision_engraver;
+struct Rest_req;
+struct Rhythmic_grouping;
+struct Rhythmic_head;
+struct Rhythmic_grouping_req;
+struct Rhythmic_req;
+struct Scope;
+struct Separating_group_spanner;
+struct Score;
+struct Score_column;
+struct Score_element;
+struct Score_element_info;
+struct Score_performer;
+struct Script;
+struct Script_column;
+struct Script_def;
+struct Script_engraver;
+struct Script_req;
+struct Simple_music;
+struct Simultaneous_music;
+struct Single_malt_grouping_item;
+struct Skip_req;
+struct Slur;
+struct Slur_engraver;
+struct Slur_req;
+struct Spacing_req;
+struct Span_bar;
+struct Span_score_bar;
+struct Span_dynamic_req;
+struct Span_req;
+struct Spanner;
+struct Spring_spacer;
+struct Staff_bracket;
+struct Staff_performer;
+struct Staff_side;
+struct Staff_symbol;
+struct Stem;
+struct Stem_beam_engraver;
+struct Stem_req;
+struct String;
+struct Symtable;
+struct Symtables;
+struct Super_element;
+struct Translation_property;
+struct Tempo_req;
+struct Text_def;
+struct Text_gob;
+struct Text_item ;
+struct Text_engraver;
+struct Text_req;
+struct Text_spanner;
+struct Tie;
+struct Tie_engraver;
+struct Tie_req;
+struct Time_description;
+struct Time_signature;
+struct Time_signature_change_req;
+struct Time_signature_engraver;
+struct Time_signature_performer;
+struct Translator;
+struct Translator_group;
+struct Timing_req;
+struct Vertical_brace;
+struct Vertical_spanner;
+struct Vertical_group_element;
+struct Vertical_group_spanner;
+struct Vertical_align_spanner;
+struct Vertical_align_engraver;
+struct Volta_spanner;
+struct Align_element;
+struct Sequential_music;
+struct Request_chord;
+
+typedef Rational Moment;
+typedef Scope Header;
+
+#endif // LILY_PROTO_HH
diff --git a/lily/include/tfm.hh b/lily/include/tfm.hh
new file mode 100644 (file)
index 0000000..685c921
--- /dev/null
@@ -0,0 +1,168 @@
+/*   
+  tfm.hh -- declare Tex_font_metric
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+  
+ */
+
+#ifndef TFM_HH
+#define TFM_HH
+
+#include "string.hh"
+#include "array.hh"
+#include "lily-proto.hh"
+
+/* The type.  */
+typedef long Fix;
+
+/* A character code.  Perhaps someday we will allow for 16-bit
+   character codes, but for now we are restricted to 256 characters per
+   font (like TeX and PostScript).  */
+typedef unsigned char Char_code;
+
+/* Used in file formats.  */
+typedef int Byte_count;
+
+/* The restriction to 256 characters in a TFM file is part of the file
+   format, so this number should only be changed in the (very unlikely)
+   event that the file format changes.  */
+#define TFM_SIZE 256
+
+/* Fontwide information.  All real values are in printer's points:
+   72.27 points = 1 inch.  */
+
+/* TFM_MIN_DESIGNSIZE <= designsize < TFM_MAX_DESIGNSIZE.  */
+#define TFM_MIN_DESIGNSIZE 1.0
+#define TFM_MAX_DESIGNSIZE 2048
+
+/* The maximum number of global font parameters we allow.  */
+#define TFM_MAX_FONTDIMENS 30
+
+/* The maximum length of a codingscheme string.  */
+#define TFM_MAX_CODINGSCHEME_LENGTH 39
+
+/* Define symbolic names for the numbers of the parameters we
+   recognize.  Some numbers have more than one name.  */
+#define TFM_SLANT_PARAMETER 1
+#define TFM_SPACE_PARAMETER 2
+#define TFM_STRETCH_PARAMETER 3
+#define TFM_SHRINK_PARAMETER 4
+#define TFM_XHEIGHT_PARAMETER 5
+#define TFM_QUAD_PARAMETER 6
+#define TFM_EXTRASPACE_PARAMETER 7
+#define TFM_NUM1_PARAMETER 8
+#define TFM_NUM2_PARAMETER 9
+#define TFM_NUM3_PARAMETER 10
+#define TFM_DENOM1_PARAMETER 11
+#define TFM_DENOM2_PARAMETER 12
+#define TFM_SUP1_PARAMETER 13
+#define TFM_SUP2_PARAMETER 14
+#define TFM_SUP3_PARAMETER 15
+#define TFM_SUB1_PARAMETER 16
+#define TFM_SUB2_PARAMETER 17
+#define TFM_SUPDROP_PARAMETER 18
+#define TFM_SUBDROP_PARAMETER 19
+#define TFM_DELIM1_PARAMETER 20
+#define TFM_DELIM2_PARAMETER 21
+#define TFM_AXISHEIGHT_PARAMETER 22
+#define TFM_DEFAULTRULETHICKNESS_PARAMETER 8
+#define TFM_BIGOPSPACING1_PARAMETER 9
+#define TFM_BIGOPSPACING2_PARAMETER 10
+#define TFM_BIGOPSPACING3_PARAMETER 11
+#define TFM_BIGOPSPACING4_PARAMETER 12
+#define TFM_BIGOPSPACING5_PARAMETER 13
+
+/* These are not in any of the standard TeX fonts, but the information
+   is useful nevertheless.  */
+#define TFM_LEADINGHEIGHT_PARAMETER 23
+#define TFM_LEADINGDEPTH_PARAMETER 24
+#define TFM_FONTSIZE_PARAMETER 25
+#define TFM_VERSION_PARAMETER 26
+
+struct Tfm_header
+{
+  Byte_count char_info_pos;
+  Byte_count width_pos;
+  Byte_count height_pos;
+  Byte_count depth_pos;
+  Byte_count italic_correction_pos;
+  Byte_count lig_kern_pos;
+  Byte_count kern_pos;
+  unsigned param_word_count;
+};
+
+struct Tfm_info
+{
+  Char_code first_charcode, last_charcode;
+  U32 checksum;
+  Real design_size;
+  String coding_scheme;
+  unsigned parameter_count;
+  // Real parameters [Tex_font_metric::MAX_FONTDIMENS];
+  Real parameters [TFM_MAX_FONTDIMENS];
+};
+
+/* When typesetting, the current character + `character' leads to
+   `ligature'.  The TFM format was extended in 1990 to allow for more
+   complicated ligatures than this, but we do not make those
+   distinctions.  */
+struct Tfm_ligature
+{
+  Char_code character;
+  Char_code ligature;
+};
+
+/* Similarly for kerns.  */
+struct Tfm_kern
+{
+  Char_code character;
+  Real kern;
+};
+
+struct Tex_font_char_metric
+{
+  bool exists_b_;
+  Char_code code_;
+  Real width_, height_, depth_, italic_correction_;
+  Fix width_fix_, height_fix_, depth_fix_, italic_correction_fix_;
+  Array<Tfm_kern> kern_arr_;
+  Array<Tfm_ligature> ligature_arr_;
+
+  String str () const;
+  Tex_font_char_metric ();
+};
+
+
+class Tex_font_metric
+{
+public:
+  Tex_font_metric ();
+  Tex_font_char_metric find_ascii (int ascii, bool warn=true) const;
+  String str () const;
+
+  /// the reader
+  Tfm_info info_;
+  Tfm_header header_;
+  void clear (int n);
+  void read_file (String name);
+
+  Array<Tex_font_char_metric> char_metrics_;
+  Array<int> ascii_to_metric_idx_;
+
+private:
+  Real get_U32_fix_f (Binary_source_file* input);
+  Real get_U32_fix_scaled_f (Binary_source_file* input);
+  String get_bcpl_str (Binary_source_file* input);
+  void read_header (Binary_source_file* input);
+  void read_params (Binary_source_file* input);
+  void read_char_metrics (Binary_source_file* input);
+  Tex_font_char_metric read_char_metric (Binary_source_file* input, Char_code code);
+  Tex_font_char_metric read_char (Binary_source_file* input);
+  void read_lig_kern_program (Binary_source_file* input, Array <Tfm_ligature>* ligature_arr_p, Array <Tfm_kern>* kern_arr_p);
+};
+
+
+#endif /* TFM_HH */
+
index b5ca92806110ab31d99fee3302fb3d4031b9214c..4e41395e422387e42380d7efd912a29beb74ba88 100644 (file)
@@ -243,12 +243,24 @@ setup_paths ()
   }
 }
 
+#define TESTING_TFM
+#ifdef TESTING_TFM
+#include "tfm.hh"
+#endif
 
 void
 main_prog (int argc, char **argv)
 {
   default_outname_base_global = "lelie";
   all_fonts_global_p = new All_font_metrics (global_path.str ());
+
+#ifdef TESTING_TFM
+  Tex_font_metric tfm;
+  tfm.read_file ("cmr10.tfm");
+  String str = tfm.str ();
+  cout << str;
+  return;
+#endif
   
   int p=0;
   const char *arg ;
diff --git a/lily/tfm.cc b/lily/tfm.cc
new file mode 100644 (file)
index 0000000..14a83e2
--- /dev/null
@@ -0,0 +1,393 @@
+/*   
+  tfm.cc --  implement Tex_font_metric
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+  
+
+  some code shamelessly copied from GNU fontutils-0.6/tfm/tfm_input.c
+ */
+
+#include "tfm.hh"
+#include "binary-source-file.hh"
+#include "string-convert.hh"
+#include "debug.hh"
+#include "warn.hh"
+
+#define format_str String_convert::form_str
+
+#define FIX_UNITY (1 << 20)
+
+static const Real
+fix_to_real (Fix f)
+{
+  Real r = f / FIX_UNITY + ((Real) (f % FIX_UNITY) / (Real) FIX_UNITY);
+  return r;
+}
+
+#if 0 //not used
+static const Fix
+real_to_fix (Real r)
+{
+  Fix f = (Fix) (floor (r) * FIX_UNITY + (r - floor (r)) * FIX_UNITY);
+  return f;
+}
+#endif
+
+
+
+
+Tex_font_char_metric::Tex_font_char_metric ()
+{
+  exists_b_ = false;
+  code_ = 0;;
+  width_ = height_ = depth_ = italic_correction_ = 0;
+  width_fix_ = height_fix_ = depth_fix_ = italic_correction_fix_ = 0;
+}
+
+#define APPEND_CHAR_METRIC_ELT(k)  outstr += to_str (#k) + " "  + to_str (k ## _)  + "; "
+
+String
+Tex_font_char_metric::str () const
+{
+  String outstr ;
+
+  APPEND_CHAR_METRIC_ELT (exists_b);
+  APPEND_CHAR_METRIC_ELT (code);
+  APPEND_CHAR_METRIC_ELT (width);
+  APPEND_CHAR_METRIC_ELT (height);
+  APPEND_CHAR_METRIC_ELT (depth);
+  APPEND_CHAR_METRIC_ELT (italic_correction);
+  
+  return outstr + "\n";
+}
+
+Tex_font_metric::Tex_font_metric ()
+{
+}
+
+Tex_font_char_metric
+Tex_font_metric::find_ascii (int ascii, bool warn) const
+{
+  if (warn && (ascii_to_metric_idx_[ascii] == -1))
+    {
+      Tex_font_char_metric m;
+      warning (_f ("can't find ascii character `%d'", ascii));
+      return m;
+    }
+  
+  return char_metrics_[ascii_to_metric_idx_ [ascii]];
+}
+
+
+String
+Tex_font_metric::str () const
+{
+  String outstr;
+  for (int i=0; i < char_metrics_.size (); i++)
+    outstr += char_metrics_[i].str ();
+  
+  return outstr;
+}
+
+void
+Tex_font_metric::clear (int n)
+{
+  for (int i=0; i < n; i++)
+    ascii_to_metric_idx_.push (-1);
+}
+
+/* Most quantities are fixed-point fractions.  */
+
+Real
+Tex_font_metric::get_U32_fix_f (Binary_source_file* input)
+{
+  return fix_to_real (input->get_U32 ());
+}
+
+
+/* Dimensions are a `Fix' scaled by the design size.  */
+
+Real
+Tex_font_metric::get_U32_fix_scaled_f (Binary_source_file* input)
+{
+  return get_U32_fix_f (input) * info_.design_size;
+}
+
+String
+Tex_font_metric::get_bcpl_str (Binary_source_file* input)
+{
+  U8 length_u8 = input->get_U8 ();
+  String str = input->get_str (length_u8);
+  return str;
+}
+
+/* Here we read the information at the beginning of the file.  We store
+   the result into the static variables `global_info' and
+   `tfm_header'.  */
+void
+Tex_font_metric::read_header (Binary_source_file* input)
+{
+  U16 file_length = input->get_U16 ();
+  (void) file_length;
+  U16 header_length = input->get_U16 ();
+
+  info_.first_charcode = input->get_U16 ();
+  info_.last_charcode = input->get_U16 ();
+  U16 width_word_count = input->get_U16 ();
+  U16 height_word_count = input->get_U16 ();
+  U16 depth_word_count = input->get_U16 ();
+  U16 italic_correction_word_count = input->get_U16 ();
+  U16 lig_kern_word_count = input->get_U16 ();
+  U16 kern_word_count = input->get_U16 ();
+  (void)kern_word_count;
+  U16 extensible_word_count = input->get_U16 ();
+  (void)extensible_word_count;
+  
+  header_.param_word_count = input->get_U16 ();
+  info_.parameter_count = header_.param_word_count;
+
+  header_.char_info_pos = (6 + header_length) * 4;
+  header_.width_pos = header_.char_info_pos
+                         + (info_.last_charcode
+                            - info_.first_charcode + 1) * 4;
+  header_.height_pos = header_.width_pos + width_word_count * 4;
+  header_.depth_pos = header_.height_pos + height_word_count * 4;
+  header_.italic_correction_pos = header_.depth_pos
+                                     + depth_word_count * 4;
+  header_.lig_kern_pos = header_.italic_correction_pos
+    + italic_correction_word_count * 4;
+  header_.kern_pos = header_.lig_kern_pos + lig_kern_word_count * 4;
+  /* We don't care about the extensible table.  */
+
+  if (header_length < 2)
+    error (_f ("TFM header of `%s' has only %u word(s)",
+              input->name_str ().ch_C (), header_length));
+
+  info_.checksum = input->get_U32 ();
+  info_.design_size = get_U32_fix_f (input);
+
+  /* Although the coding scheme might be interesting to the caller, the
+     font family and face byte probably aren't.  So we don't read them.  */
+  info_.coding_scheme = header_length > 2
+    ? get_bcpl_str (input) : "unspecified";
+
+  DOUT << format_str ("TFM checksum = %u, design_size = %fpt, coding scheme = `%s'.\n",
+                     info_.checksum,
+                     info_.design_size,
+                     info_.coding_scheme.ch_C ());
+}
+
+void
+Tex_font_metric::read_file (String name)
+{
+  Binary_source_file input (name);
+
+  clear (TFM_SIZE);
+  read_header (&input);
+  read_params (&input);
+  read_char_metrics (&input);
+}
+
+/* Although TFM files are only usable by TeX if they have at least seven
+   parameters, that is not a requirement of the file format itself, so
+   we don't impose it.  And they can have many more than seven, of
+   course.  We do impose a limit of TFM_MAX_FONT_PARAMETERS.  We assume
+   that `tfm_header' has already been filled in.  */
+
+void
+Tex_font_metric::read_params (Binary_source_file* input)
+{
+  /* If we have no font parameters at all, we're done.  */
+  if (header_.param_word_count == 0)
+    return;
+
+  //brrr
+  /* Move to the beginning of the parameter table in the file.  */
+  input->seek_ch_C (-4 * header_.param_word_count);
+
+  /* It's unlikely but possible that this TFM file has more fontdimens
+     than we can deal with.  */
+  if (header_.param_word_count > TFM_MAX_FONTDIMENS)
+    {
+      warning (_f ("%s: TFM file has %u parameters, which is more than the
+%u I can handle",
+                  input->name_str ().ch_C (),
+                  header_.param_word_count,
+                  TFM_MAX_FONTDIMENS));
+      header_.param_word_count = TFM_MAX_FONTDIMENS;
+    }
+
+  /* The first parameter is different than all the rest, because it
+     isn't scaled by the design size.  */
+  info_.parameters[(TFM_SLANT_PARAMETER) - 1] = get_U32_fix_f (input);
+
+  for (Char_code i = 2; i <= header_.param_word_count; i++)
+    info_.parameters[i - 1] = get_U32_fix_scaled_f (input);
+
+#ifdef PRINT
+  for (Char_code i = 1; i <= header_.param_word_count; i++)
+    DOUT << format_str ("TFM parameter %d: %.3f", i, info_.parameters[i - 1]);
+#endif
+}
+
+/* Read every character in the TFM file, storing the result in the
+   static `tfm_char_table'.  We return a copy of that variable.  */
+
+void
+Tex_font_metric::read_char_metrics (Binary_source_file* input)
+{
+  for (int i = info_.first_charcode; i <= info_.last_charcode; i++)
+    {
+      Tex_font_char_metric tfm_char = read_char_metric (input, i);
+      if (tfm_char.exists_b_)
+       ascii_to_metric_idx_[tfm_char.code_] = char_metrics_.size ();
+      char_metrics_.push (tfm_char);
+    }
+}
+
+/* Read the character CODE.  If the character doesn't exist, return
+   NULL.  If it does, save the information in `tfm_char_table', as well
+   as returning it.  */
+
+Tex_font_char_metric
+Tex_font_metric::read_char_metric (Binary_source_file* input, Char_code code)
+{
+  Tex_font_char_metric tfm_char;
+
+  /* If the character is outside the declared bounds in the file, don't
+     try to read it. */
+  if (code < info_.first_charcode || code > info_.last_charcode)
+    return tfm_char;
+  
+  //brr
+  /* Move to the appropriate place in the `char_info' array.  */
+  input->seek_ch_C (header_.char_info_pos + (code - info_.first_charcode) * 4);
+
+  /* Read the character.  */
+  tfm_char = read_char (input);
+
+  if (tfm_char.exists_b_)
+    tfm_char.code_ = code;
+
+  return tfm_char;
+}
+
+
+/* We assume we are positioned at the beginning of a `char_info' word.
+   We read that word to get the indexes into the dimension tables; then
+   we go read the tables to get the values (if the character exists).  */
+
+Tex_font_char_metric
+Tex_font_metric::read_char (Binary_source_file* input)
+{
+  /* Read the char_info word.  */
+  U8 width_index = input->get_U8 ();
+
+  U8 packed;
+  packed = input->get_U8 ();
+  U8 height_index = (packed & 0xf0) >> 4;
+  U8 depth_index = packed & 0x0f;
+
+  packed = input->get_U8 ();
+  U8 italic_correction_index = (packed & 0xfc) >> 6;
+  U8 tag = packed & 0x3;
+
+  U8 remainder = input->get_U8 ();
+
+  Tex_font_char_metric tfm_char;
+
+#define GET_CHAR_DIMEN(d) \
+   if (d##_index != 0) \
+     { \
+       input->seek_ch_C (header_.##d##_pos + d##_index*4); \
+       tfm_char.d##_fix_ = input->get_U32 (); \
+       tfm_char.d##_ = fix_to_real (tfm_char.d##_fix_) \
+                      * info_.design_size; \
+     }
+
+  GET_CHAR_DIMEN (width);
+  GET_CHAR_DIMEN (height);
+  GET_CHAR_DIMEN (depth);
+  GET_CHAR_DIMEN (italic_correction);
+
+  /* The other condition for a character existing is that it be between
+     the first and last character codes given in the header.  We've
+     already assumed that's true (or we couldn't be positioned at a
+     `char_info_word').  */
+  tfm_char.exists_b_ = width_index != 0;
+
+#ifdef PRINT
+  DOUT << format_str ("   width = %f, height = %f, ",
+                     tfm_char.width_, tfm_char.height_);
+  DOUT << format_str ("depth = %f, ic = %f.\n",
+                     tfm_char.depth, tfm_char.italic_correction); 
+#endif
+
+  if (tag == 1)
+    {
+      input->seek_ch_C (header_.lig_kern_pos + remainder * 4);
+      read_lig_kern_program (input, &tfm_char.ligature_arr_, &tfm_char.kern_arr_);
+    }
+
+  /* We don't handle the other tags.  */
+  return tfm_char;
+}
+
+/* Read a ligature/kern program at the current position, storing the
+   result into *LIGATURE and *KERN.  We don't distinguish all the kinds
+   of ligatures that Metafont can output.  */
+
+#define STOP_FLAG 128
+#define KERN_FLAG 128
+
+void
+Tex_font_metric::read_lig_kern_program (Binary_source_file* input, Array <Tfm_ligature>* ligature_arr_p, Array <Tfm_kern>* kern_arr_p)
+{
+  bool end_b;
+
+  do
+    {
+      end_b = input->get_U8 () >= STOP_FLAG;
+
+      U8 next_char = input->get_U8 ();
+      bool kern_step_b = input->get_U8 () >= KERN_FLAG;
+      U8 remainder = input->get_U8 ();
+
+#ifdef PRINT
+      DOUT << format_str ("   if next = %u (%c), ", next_char, next_char);
+#endif
+
+      if (kern_step_b)
+       {
+         Tfm_kern kern_element;
+         kern_element.character = next_char;
+
+         char const* old_pos = input->pos_ch_C ();
+         input->seek_ch_C (header_.kern_pos + remainder * 4);
+         kern_element.kern = get_U32_fix_scaled_f (input);
+         input->set_pos (old_pos);
+
+         kern_arr_p->push (kern_element);
+
+#ifdef PRINT
+         DOUT << format_str ("kern %f.\n", kern_element.kern);
+#endif
+       }
+      else
+       {
+         Tfm_ligature ligature_element;
+         ligature_element.character = next_char;
+         ligature_element.ligature = remainder;
+         ligature_arr_p->push (ligature_element);
+
+#ifdef PRINT
+         DOUT format_str ("ligature %d (hex %x).\n",
+                          ligature_element.ligature,
+                          ligature_element.ligature);
+#endif
+       }
+  } while (!end_b);
+}
+
index 6659fb42cda102d9483b7f8dc18af0edda7b4ea4..9dca4db212c72c41aee3938d3538621d6ce709d3 100644 (file)
@@ -63,7 +63,6 @@ public:
   Midi_parser_info* info_l_;
 
 protected:
-//  Byte const* inline_forward_byte_L (int n)
   Byte const* inline_forward_byte_L (char const* fun, int n)
   {
     if (info_l_->byte_L_ + n < info_l_->end_byte_L_ )
@@ -72,28 +71,23 @@ protected:
       info_l_->byte_L_ += n;
       return p;
     }
-//    exit (__FUNCTION__": unexpected EOF");
     exit (String (fun) + ": unexpected EOF");
     return 0;
   }
 
 #ifdef INLINES
-//  Byte inline_next_byte () 
   Byte inline_next_byte (char const* fun) 
     {
       if (info_l_->byte_L_ < info_l_->end_byte_L_)
         return *info_l_->byte_L_++;
-//    exit (__FUNCTION__": unexpected EOF");
       exit (String (fun) + ": unexpected EOF");
       return 0;
     }
 
-//  Byte inline_peek_byte ()
   Byte inline_peek_byte (char const* fun)
     {
       if (info_l_->byte_L_ < info_l_->end_byte_L_)
        return *info_l_->byte_L_;
-//      exit (__FUNCTION__": unexpected EOF");
       exit (String (fun) + ": unexpected EOF");
       return 0;
     }
index 92eb74833e612886af2936e8276fd89254e463a1..c20fe468e2878389c9bfcee139692a61589dfd7c 100644 (file)
@@ -23,7 +23,6 @@ Midi_score_parser::open (String filename_str, Sources* sources_l)
   if (!info_l_->source_l_)
     ::error (_f ("can't find file: `%s\'", filename_str));
   info_l_->byte_L_ = (Byte const*)info_l_->source_l_->ch_C ();
-//  info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i ();
   info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i () + 1;
 }