From: Jan Nieuwenhuizen Date: Sun, 24 Jan 1999 20:33:31 +0000 (+0100) Subject: patch::: 1.1.23.jcn8: tfm reader X-Git-Tag: release/1.1.24~4 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=7944f2ee15f69b8c39ed032bc39c9f2c58c4a471;p=lilypond.git patch::: 1.1.23.jcn8: tfm reader 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 --- diff --git a/NEWS b/NEWS index 6209ed181a..be7d1bee97 100644 --- 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 95eb4dc541..808e832952 100644 --- 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. diff --git a/flower/include/fproto.hh b/flower/include/fproto.hh index d149d5f022..9983eef245 100644 --- a/flower/include/fproto.hh +++ b/flower/include/fproto.hh @@ -10,13 +10,6 @@ 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 struct Link_array; template struct Array; template 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; diff --git a/lib/binary-source-file.cc b/lib/binary-source-file.cc index 9bcf0e5f70..17a712fa81 100644 --- a/lib/binary-source-file.cc +++ b/lib/binary-source-file.cc @@ -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 (); + char const* end_ch_C = pos_ch_C + 7 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; +} diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index b44dab4223..fb8f26e12f 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -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 index 0000000000..b44dab4223 --- /dev/null +++ b/lily/include/lily-proto.hh.orig @@ -0,0 +1,266 @@ +/* + lily-proto.hh -- declare class names. + + source file of the GNU LilyPond music typesetter + + (c) 1997--1998 Han-Wen Nienhuys +*/ + +#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 index 0000000000..685c921201 --- /dev/null +++ b/lily/include/tfm.hh @@ -0,0 +1,168 @@ +/* + tfm.hh -- declare Tex_font_metric + + source file of the GNU LilyPond music typesetter + + (c) 1999 Jan Nieuwenhuizen + + */ + +#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 kern_arr_; + Array 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 char_metrics_; + Array 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 * ligature_arr_p, Array * kern_arr_p); +}; + + +#endif /* TFM_HH */ + diff --git a/lily/main.cc b/lily/main.cc index b5ca928061..4e41395e42 100644 --- a/lily/main.cc +++ b/lily/main.cc @@ -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 index 0000000000..14a83e2776 --- /dev/null +++ b/lily/tfm.cc @@ -0,0 +1,393 @@ +/* + tfm.cc -- implement Tex_font_metric + + source file of the GNU LilyPond music typesetter + + (c) 1999 Jan Nieuwenhuizen + + + 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 * ligature_arr_p, Array * 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); +} + diff --git a/mi2mu/include/midi-parser.hh b/mi2mu/include/midi-parser.hh index 6659fb42cd..9dca4db212 100644 --- a/mi2mu/include/midi-parser.hh +++ b/mi2mu/include/midi-parser.hh @@ -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; } diff --git a/mi2mu/midi-score-parser.cc b/mi2mu/midi-score-parser.cc index 92eb74833e..c20fe468e2 100644 --- a/mi2mu/midi-score-parser.cc +++ b/mi2mu/midi-score-parser.cc @@ -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; }