---- ../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
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.
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;
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;
}
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);
}
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 ();
}
#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
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
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;
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_;
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)
name_str_ = name_str;
istream_p_ = 0;
storage_p_ = new String_storage (data_str);
+ pos_ch_C_ = ch_C ();
}
istream*
{
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;
+}
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 ;
--- /dev/null
+/*
+ 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
--- /dev/null
+/*
+ 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 */
+
}
}
+#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 ;
--- /dev/null
+/*
+ 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);
+}
+
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_ )
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;
}
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;
}