/************************************************* * The PMW Music Typesetter - 3rd incarnation * *************************************************/ /* Copyright (c) Philip Hazel, 1991 - 2021 */ /* Written by Philip Hazel, starting November 1991 */ /* This file last modified: January 2021 */ /* This is the main header file, imported by all other sources. */ /* ANSI C includes */ #include #include #include #include #include #include #include #include /* Unix includes */ #include #include #include /* Optionsl B2PF include */ #ifdef SUPPORT_B2PF #include #endif /* Debugging */ #define DEBUG(x) if (debugging) debug_printf x /************************************************* * Program parameters * *************************************************/ #define B2PF_STACKBSIZE 2000 /* On-stack buffer size */ #define DEF_MAX_BARS 500 /* Default max bars per movement */ #define DEF_MAX_MOVEMENTS 50 /* Default max movements */ #define DRAW_BLOCKSIZE 256 /* Chunk size for draw routines */ #define DRAW_STACKSIZE 100 /* Size of draw stack */ #define LAYOUT_MAXSIZE 200 /* Max items in layout list */ #define MAX_BEAMSIZE 100 /* Should be large enough for anything */ #define MAX_CHORDSIZE 16 /* 16-note chords should be enough */ #define MAX_DRAW_VARIABLE 19 /* Max number of a draw variable */ #define MAX_FONTS 50 /* Maximum number of different fonts */ #define MAX_INCLUDE 10 /* Max depth of included files */ #define MAX_MACROARGS 20 /* Max number of macro arguments */ #define MAX_MACRODEFAULT 256 /* Max length of macro default argument */ #define MAX_POSTABLESIZE 400 /* Max number of entries */ #define MAX_UTRANSLATE 1000 /* Max Unicode translations for a font */ #define MAX_XKEYS 10 /* Max number of custom keys (must be <= 21)*/ #define MIDI_MAXCHANNEL 16 /* Maximum MIDI channel number */ #define READ_BUFFERSIZE 2000 /* Input buffer size */ #define TEXT_QUEUE_SIZE 50 /* Max texts before a note */ #define WORD_BUFFERSIZE 256 /* Buffer for reading words */ /* Maximum stave is defined in terms of the length of the bit vector that maps stave presence, suspension, etc. If STAVE_BITVEC_SIZE is increased, some tables in tables.c must also be extended. Also, the mac_initstave, mac_anystave and mac_samestave macros below must be suitably modified. */ #define STAVE_BITVEC_SIZE 2 /* Number of ints in the bit vector */ #define MAX_STAVE (STAVE_BITVEC_SIZE * 32 - 1) /* Typesetting parameters */ #define PAGE_LEFTBARSPACE 8000 /* Space at left of bar */ /************************************************* * Macros etc for types and character handling * *************************************************/ /* Some operating systems (naughtily, imo) include a definition for "uchar" in the standard header files, so we use "uschar". Solaris has u_char in sys/types.h. This is just a typing convenience, of course. */ typedef unsigned char uschar; typedef unsigned int usint; /* These macros save typing for the casting that is needed to cope with the mess that is "char" in ISO/ANSI C. */ #define CS (char *) #define CSS (char **) #define US (unsigned char *) #define USS (unsigned char **) /* The C library string functions expect "char *" arguments. Use macros to avoid having to write a cast each time. We do this for string and file functions; for other calls to external libraries (which are on the whole special-purpose) we just use casts. */ #define Uatoi(s) atoi(CS(s)) #define Ufgets(b,n,f) fgets(CS(b),n,f) #define Ufopen(s,t) fopen(CS(s),CS(t)) #define Ufputs(b,f) fputs(CS(b),f) #define Ustrcat(s,t) strcat(CS(s),CS(t)) #define Ustrchr(s,n) US strchr(CS(s),n) #define Ustrcmp(s,t) strcmp(CS(s),CS(t)) #define Ustrcpy(s,t) strcpy(CS(s),CS(t)) #define Ustrlen(s) (int)strlen(CS(s)) #define Ustrncat(s,t,n) strncat(CS(s),CS(t),n) #define Ustrncmp(s,t,n) strncmp(CS(s),CS(t),n) #define Ustrncpy(s,t,n) strncpy(CS(s),CS(t),n) #define Ustrstr(s, t) US strstr(CS(s),CS(t)) #define Ustrtol(s,t,b) strtol(CS(s),CSS(t),b) #define Ustrtoul(s,t,b) strtoul(CS(s),CSS(t),b) /* Define boolean types here so they can be used in included headers */ #define BOOL int #define CBOOL char /* The following value (LOWCHARLIMIT) must not be less than 256. Characters whose Unicode values are less than this limit are treated specially in two ways: (1) Each font has a table of widths of this size, so that the widths of the most common characters can be found quickly. Characters whose code points are greater than this limit have their widths stored in a tree structure instead. (2) Cloned PostScript fonts are created, with different encodings, so that characters up to this value can be directly printed without much translation. NOTE: At present, we assume that the value is less than 512, because only two fonts are used. It seems unlikely that we will ever need to extend this, but you never know. */ #define LOWCHARLIMIT 384 /* These define the characters that are substituted for unavailable characters, in standardly encoded and non-standardly encoded fonts, respectively. The first should be one that is always available in the base font, with code less that 256, because it is used unmodified in the PostScript output. */ #define UNKNOWN_CHAR_S 0x00a4 /* Currency symbol */ #define UNKNOWN_CHAR_N 0x00b4 /* Triangle in Music, multiply in Symbol */ /* Other specific Unicode characters that are needed */ #define QUOTE_LEFT 0x2018 #define QUOTE_RIGHT 0x2019 #define CHAR_FI 0xfb01 /* fi ligature */ /* Macros for loading UTF-8 characters */ /* Get the next UTF-8 character, not advancing the pointer. */ #define GETCHAR(c, ptr) \ c = *ptr; \ if ((c & 0xc0) == 0xc0) \ { \ int gcii; \ int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & utf8_table3[gcaa]) << gcss; \ for (gcii = 1; gcii <= gcaa; gcii++) \ { \ gcss -= 6; \ c |= (ptr[gcii] & 0x3f) << gcss; \ } \ } /* Get the next UTF-8 character, advancing the pointer. */ #define GETCHARINC(c, ptr) \ c = *ptr++; \ if ((c & 0xc0) == 0xc0) \ { \ int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & utf8_table3[gcaa]) << gcss; \ while (gcaa-- > 0) \ { \ gcss -= 6; \ c |= (*ptr++ & 0x3f) << gcss; \ } \ } /************************************************* * Structures used in barhdr.h * *************************************************/ /* We need to define certain structures before including barhdr.h. Other structures are defined later, below. */ /* Structure for describing a text item used in drawing functions */ typedef struct { int ident; int rotate; int xdelta; int ydelta; uschar *text; short int flags; short int size; } drawtextstr; /* Structure for items in encoded draw function vectors, variables, and stack. A union is needed for the value because some are integers and some are addresses. They used to be punned, stuffing pointers into ints, but this doesn't work in 64-bit environments. */ typedef struct { usint dtype; /* data type, eg dd_number */ union { void *ptr; int val; } d; } drawitem; /* Types of value in draw programs, stacks, and variables; used in the dtype field in the structure above for items on the stack and for variables. */ #define dd_any 1 /* Used in the checklist for any type allowed */ #define dd_number 2 #define dd_text 3 #define dd_code 4 #define dd_varname 5 /* Structure for each node in a tree */ typedef struct tree_node { struct tree_node *left; /* pointer to left child */ struct tree_node *right; /* pointer to right child */ uschar *name; /* node name */ uschar *data; /* for string values */ int val[3]; /* for numeric values */ uschar balance; /* balancing factor */ } tree_node; /* One heading/footing/footnote. There are three different cases: a text string, a drawing, or a PostScript string. They use different subsets of the fields in this structure. */ typedef struct headstr { struct headstr *next; int size; /* Font size: 0 => PostScript; < 0 => drawing */ int space; /* Space to follow; must be 0 except for text */ uschar *text; /* String for text or PostScript */ /* --- Text string --- */ int *matrix; /* points to transformation or NULL */ int font; /* initial font */ int stretch; /* amount to stretch spaces by */ int spaceabove; /* space above the line of text */ /* --- Drawing --- */ tree_node *drawing; /* pointer to the drawing */ drawitem *drawargs; /* drawing arguments */ } headstr; /* Text associated with a line or slur gap */ typedef struct { uschar *text; short int flags; short int size; int x; int y; } gaptextstr; /* Bar structures are held separately for convenience */ #include "barhdr.h" /************************************************* * Global Macros * *************************************************/ #define FALSE 0 #define TRUE 1 #define BIGNUMBER 0x7FFFFFFF #define rc_noerror 0 /* Return codes */ #define rc_warning 1 #define rc_serious 2 #define rc_failed 3 #define time_common 255 #define time_cut 254 /* If MaxExtraFont is increased, check that font_IdStrings in tables.c contains sufficient identifying strings, and that ps_IdStrings in ps.c is of the right size too. If MaxFontSizes is changed, the initializing table init_fontsizes in tables.c must be made to be the correct size. */ #define MaxFontSizes 20 /* for different text sizes */ #define MaxExtraFont 12 /* for different faces */ /* It is helpful to have names for the vertical offsets of the various lines and spaces on the stave. The bottom line is numbered one. These pitches are the appropriate vertical offsets from the bottom line to print a note or an accidental on the relevant line or space. */ #define L_0L -6000 #define L_0S -4000 #define L_1L -2000 #define L_1S 0 #define L_2L 2000 #define L_2S 4000 #define L_3L 6000 #define L_3S 8000 #define L_4L 10000 #define L_4S 12000 #define L_5L 14000 #define L_5S 16000 #define L_6L 18000 /* Similarly, it is helpful to have names for the equivalent stave pitches. */ #define P_0L 124 #define P_0S 126 #define P_1L 128 #define P_1S 130 #define P_2L 132 #define P_2S 134 #define P_3L 136 #define P_3S 138 #define P_4L 140 #define P_4S 142 #define P_5L 144 #define P_5S 146 #define P_6L 148 /* Flags for diffent kinds of text - 16-bit field */ #define text_ul 0x0001 #define text_fb 0x0002 #define text_above 0x0004 #define text_box 0x0008 #define text_endalign 0x0010 #define text_middle 0x0020 #define text_ps 0x0040 #define text_rehearse 0x0080 #define text_ring 0x0100 #define text_baralign 0x0200 #define text_atulevel 0x0400 #define text_absolute 0x0800 #define text_centre 0x1000 #define text_timealign 0x2000 #define text_followon 0x4000 /* Flags for stave name texts */ #define snf_vcentre 0x01 #define snf_hcentre 0x02 #define snf_rightjust 0x04 #define snf_vertical 0x08 /* Clef style flags */ #define clef_oldbass 0x01 #define clef_oldalto 0x02 /* A maximum is set for transposition - 5 octaves should be ample - and a conventional value for "no transposition". */ #define max_transpose 60 #define no_transpose 1000 /* Names for C major and the special key 'N', which behaves like C major (no key signature) but does not transpose. There are 42 normal keys (7 letters times 2 modes times 3 accidentals) whose values are 0-41. There are also up to MAX_XKEYS custom-defined keys, starting at 43. Note that the 64-bit is used in some contexts to indicate "reset with naturals". */ #define C_key 2 #define N_key 42 /* The answer to life, the universe, and everything. */ #define X_key 43 /* The first custom key */ /************************************************* * Global procedure macros * *************************************************/ #define ROUND(x) ((((x) + sizeof(void *) - 1)/sizeof(void *)) * sizeof(void *)) #define mac_fdiv(f,d) ((int)(((double)(f) * 1000.0)/((double) (d)))) #define mac_muldiv(a,b,c) \ ((int)((((double)((int)(a)))*((double)((int)(b))))/((double)((int)(c))))) #define mac_setstavesize(i) \ main_stavemagn = (curmovt->stavesizes)[i] #define mac_advancechord(ww) \ if ((ww = (b_notestr *)((uschar *)ww + length_table[b_note]))->type == b_Jump) \ ww = (b_notestr *) \ ((uschar *)(((b_Jumpstr *)ww)->next) + length_table[b_Jump]) #define mac_couplepitch(p, f) \ if ((f & (nf_coupleU | nf_coupleD)) != 0) \ p += (((f & nf_coupleU) != 0)? (out_upgap - 24):(24 - out_downgap)) #define mac_clearstave(a, z) \ a[z >> 5] &= ~main_bit[z & 0x1f] /* Needs manual adjustment when STAVE_BITVEC_SIZE changes */ #define mac_initstave(a, b) \ a[0] = a[1] = (usint)b #define mac_setstave(a, z) \ a[z >> 5] |= main_bit[z & 0x1f] /* Test for the presence of a stave a bitmap */ #define mac_teststave(a, z) \ ((a[z >> 5] & main_bit[z & 0x1f]) != 0) /* Test for the absence of a stave a bitmap */ #define mac_testNstave(a, z) \ ((a[z >> 5] & main_bit[z & 0x1f]) == 0) /* Test for the presence of a stave in both of two bitmaps */ #define mac_teststave2(a, b, z) \ ((a[z >> 5] & b[z >> 5] & main_bit[z & 0x1f]) != 0) /* Test for the absence of a stave in at least one of two bitmaps */ #define mac_testNstave2(a, b, z) \ ((a[z >> 5] & b[z >> 5] & main_bit[z & 0x1f]) == 0) /* Needs manual adjustment when STAVE_BITVEC_SIZE changes */ #define mac_anystave(a) \ ((a[0] | a[1]) != 0) /* Needs manual adjustment when STAVE_BITVEC_SIZE changes */ #define mac_diffstave(a, b) \ (a[0] != b[0] || a[1] != b[1]) /* Needs manual adjustment when STAVE_BITVEC_SIZE changes */ #define mac_samestave(a, b) \ (a[0] == b[0] && a[1] == b[1]) /************************************************* * Global enumerations * *************************************************/ /* Stem swap options */ enum { stemswap_default, stemswap_up, stemswap_down, stemswap_left, stemswap_right }; /* Justification values */ enum { just_top = 1, just_bottom = 2, just_left = 4, just_right = 8, just_all = just_top+just_bottom+just_left+just_right }; /* Clefs - real ones come first, and clef_count is the number of different ones. */ enum { clef_treble, clef_soprano, clef_mezzo, clef_alto, clef_tenor, clef_cbaritone, clef_baritone, clef_bass, clef_deepbass, clef_h, clef_none, clef_trebledescant, clef_trebletenor, clef_trebletenorB, clef_soprabass, clef_contrabass, clef_count}; /* Movement options */ enum { movt_default, movt_newpage, movt_thispage, movt_thisline, movt_nopageheading = 0x0100, movt_uselastfooting = 0x0200 }; /* Skip options for errors */ enum { skip_OFF, skip_EOL, skip_KET, skip_BACKSLASH, skip_BAR }; /* Notehead type options. If these are changed, the tables in shownote.c must also be changed. No stems are printed for values greater than or equal to nh_only. */ enum { nh_normal, /* conventional noteheads, with stems and beams */ nh_cross, /* X noteheads, with stems and beams */ nh_harmonic, /* diamond-shaped, with stems and beams */ nh_none, /* no noteheads, just stems and beams */ nh_only, /* conventional noteheads, no stems or beams */ nh_direct /* fancy 'w', no stems or beams */ }; /* System or heading block identification */ enum { sh_system, sh_heading }; /* Types for data in a layout vector */ enum { lv_barcount, lv_repeatcount, lv_repeatptr, lv_newpage }; /* Specific sheet sizes */ enum { sheet_unknown, sheet_A5, sheet_A4, sheet_A3, sheet_B5, sheet_letter }; /* Identifiers for each type of font. Any changes in this table must be kept in step with the list of 2-letter font ids which is kept in FontIdStrings. The running PostScript copy in ps_IdStrings must also be kept at the same size. */ enum { font_rm, font_it, font_bf, font_bi, font_sy, font_mu, font_mf, font_xx, font_tablen = font_xx + MaxExtraFont }; /* Small caps are identified by a pseudo-font in some places. */ #define font_sc 256 /* Give names to error numbers so they can be more easily tracked. */ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90, ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99, ERR100,ERR101,ERR102,ERR103,ERR104,ERR105,ERR106,ERR107,ERR108,ERR109, ERR110,ERR111,ERR112,ERR113,ERR114,ERR115,ERR116,ERR117,ERR118,ERR119, ERR120,ERR121,ERR122,ERR123,ERR124,ERR125,ERR126,ERR127,ERR128,ERR129, ERR130,ERR131,ERR132,ERR133,ERR134,ERR135,ERR136,ERR137,ERR138,ERR139, ERR140,ERR141,ERR142,ERR143,ERR144,ERR145,ERR146,ERR147,ERR148,ERR149, ERR150,ERR151,ERR152,ERR153,ERR154,ERR155,ERR156 }; /************************************************* * Structure Definitions * *************************************************/ /* See further up for the structures "tree_node", "headstr", and "gaptextstr", which are used in barhdr and so have to be defined before it is included. */ /* Structure for handling macros. We can't unfortunately have a variable length vector at the end, as C doesn't support such things. */ typedef struct { int argcount; /* number of default arguments */ uschar *text; /* replacement text */ uschar *args[1]; /* vector of pointers */ } macrostr; /* Items in a kerning table, pointed to from a fontstr */ typedef struct kerntablestr { usint pair; int kwidth; } kerntablestr; /* Items in Unicode translation table, pointed to from a fontstr */ typedef struct utrtablestr { int unicode; int pscode; } utrtablestr; /* Font data */ typedef struct { uschar *psname; /* PostScript font name */ int *widths; /* Pointer to basic width table */ int *r2ladjusts; /* Pointer to right-to-left adjusts */ int *heights; /* Pointer to height table, if any */ int kerncount; /* Size of kern table */ int utrcount; /* Size of utr table */ utrtablestr *utr; /* Unicode translation for nonstd font */ tree_node *high_tree; /* Tree for data for high val stdenc chars */ kerntablestr *kerns; /* Pointer to kerning table */ BOOL stdencoding; /* True if std encoding */ BOOL fixedpitch; /* True if fixed pitch */ BOOL hasfi; /* True if has "fi" */ BOOL include; /* True if to include in output */ } fontstr; /* Offsets for special text font sizes and matrices, which follow in the same vector as sizes specified by the user. */ #define ff_offset_ts (MaxFontSizes) #define ff_offset_ulay (ff_offset_ts+1) #define ff_offset_olay (ff_offset_ulay+1) #define ff_offset_fbass (ff_offset_olay+1) #define ff_offset_init (ff_offset_fbass+1) #define SIZES_SIZE (ff_offset_init+1) /* Structure for overall font sizes at standard magnification, and pointers to matrices for font stretching and shearing, where defined. */ typedef struct { int fontsize_music; int fontsize_grace; int fontsize_cue; int fontsize_cuegrace; int fontsize_clefs; int fontsize_barno; int fontsize_footnote; int fontsize_rehearse; int fontsize_triplet; int fontsize_repno; /* repeat bar number */ int fontsize_restct; /* long rest count */ int fontsize_trill; int fontsize_vertacc; /* vertical accidentals */ int fontsize_text[SIZES_SIZE]; /* vector of sizes */ /* These must be in the same order as the font sizes, and music must be first. */ int *fontmatrix_music; int *fontmatrix_grace; int *fontmatrix_cue; int *fontmatrix_cuegrace; int *fontmatrix_clefs; int *fontmatrix_barno; int *fontmatrix_footnote; int *fontmatrix_rehearse; int *fontmatrix_triplet; int *fontmatrix_repno; int *fontmatrix_restct; int *fontmatrix_trill; int *fontmatrix_vertacc; int *fontmatrix_text[SIZES_SIZE]; } fontsizestr; /* Data for spacing at the start of a line */ typedef struct { int clefspace; int keyspace; int timespace; int notespace; } startlinestr; /* One item in a chain of stave selections */ typedef struct stave_list { struct stave_list *next; int first; int last; } stave_list; /* One stave name text */ typedef struct snamestr { struct snamestr *next; struct snamestr *extra; /* additional string(s); maybe different options */ uschar *text; tree_node *drawing; drawitem *args; /* for drawing */ uschar flags; uschar offset; uschar linecount; } snamestr; /* One printtime item */ typedef struct ptimestr { struct ptimestr *next; int movt_number; /* movement in which defined */ int time; uschar *top; uschar *bot; uschar offsettop; uschar offsetbot; } ptimestr; /* One printkey item */ typedef struct pkeystr { struct pkeystr *next; int movt_number; /* movement in which defined */ int key; int clef; uschar *string; uschar *cstring; } pkeystr; /* One transposed key masquerade item */ typedef struct trkeystr { struct trkeystr *next; int oldkey; int newkey; } trkeystr; /* One KeyTranspose item */ typedef struct keytransposestr { struct keytransposestr *next; int oldkey; int newkeys[12]; int letterchanges[12]; } keytransposestr; /* Data pertaining to one stave */ typedef struct { bstr **barindex; snamestr *stave_name; int lastbar; int toppitch; int botpitch; int totalpitch; short int notecount; CBOOL omitempty; uschar stavelines; uschar barlinestyle; } stavestr; /* Layout of the items in the final position table for a bar */ typedef struct { int moff; /* musical offset of the position */ int xoff; /* horizontal offset */ } posstr; /* Layout of one item in a bar's positioning table while it is being worked on. The stemup & stemdown flags are used as stated only at the beginning of processing, when non-grace notes are the only things considered. For auxiliary items, the stemup field is re-used to track which staves have the auxiliary item. We should really use a union, but the notation is too messy! In the pos routines which use this we cheat by defining a macro "posstaves" instead. */ typedef struct { int moff; int xoff; int space; /* additional space required */ usint stemup[STAVE_BITVEC_SIZE]; /* bitmap of staves where there is an */ /* actual stem up, aka "posstaves" */ usint stemdown[STAVE_BITVEC_SIZE]; /* ditto for stem down */ int auxid; /* identification of auxiliary items */ /* (may be -ve) */ } workposstr; /* Layout of the entries in the vector kept for a movement's bars */ typedef struct { posstr *vector; /* points to positioning vector */ int barnoX; /* X offset for bar number */ int barnoY; /* Y offset for bar number */ short int count; /* number of entries in the vector */ short int multi; /* multi-bar rest count */ uschar posxRL; /* offset for left repeat */ uschar barnoforce; /* force/unforce flag */ } barposstr; /* Layout of structure for remembering things while measuring a line. Three versions of this are kept: previous points to the version that was current after accepting the previous bar; accepted points to the current structure after accepting a bar; next points to the values that have changed as a result of measuring the bar being checked. */ typedef struct { int xposition; /* total width of bars */ int startxposition; /* position of lhs, after stave names */ int endbar; /* end bar number */ int count; /* count of bars */ int notespacing[8]; /* notespacing values */ usint notsuspend[STAVE_BITVEC_SIZE]; /* not suspended staves */ snamestr **stavenames; /* stave name vector */ CBOOL endkey; /* line ends with key signature */ CBOOL endtime; /* line ends with time signature */ } pagedatastr; /* Structure for keeping data about a copy of stave 0 for another stave */ struct contstr; /* Defined further down */ typedef struct zcopystr { struct zcopystr *next; struct contstr *cont; /* Holds cont ptr for this copy */ int adjust; /* Overall adjustment for this stave */ int baradjust; /* Adjustment for this bar */ int level; /* Used to hold actual level for printing */ int stavenumber; /* Stave to overprint */ } zcopystr; /* Data pertaining to a movement */ typedef struct { stavestr **stavetable; fontsizestr *fontsizes; barposstr *posvector; startlinestr *startline; zcopystr *zcopy; stave_list *bracelist; stave_list *bracketlist; stave_list *joinlist; stave_list *joindottedlist; stave_list *thinbracketlist; headstr *footing; headstr *heading; headstr *lastfooting; headstr *pagefooting; headstr *pageheading; b_playchangestr *play_changes; uschar *barnovector; uschar *hyphenstring; uschar *trillstring; uschar *play_volume; uschar *midi_channel; uschar *midi_note; uschar *midi_voice; uschar *midi_volume; int *accadjusts; int *accspacing; int *notespacing; int *layout; int *midi_start; int *play_tempo_changes; int *stavesizes; int *stave_ensure; int *stave_spacing; int *stemswaplevel; int barcount; int barlinesize; int barlinespace; int barlinestyle; int barno_interval; int barno_level; int barno_textflags; int baroffset; int beamdepth; int beamflaglength; int botmargin; int bracestyle; int breveledgerextra; int caesurastyle; int clefsize; int clefstyle; int dotspacefactor; int endlinesluradjust; int endlineslurstyle; int endlinetieadjust; int endlinetiestyle; int extenderlevel; int font_barnumber; int font_longrest; int font_rehearse; int font_repeat; int font_time; int font_triplet; int footnotesep; int gracespacing[2]; int gracestyle; int hflatstyle; int hsharpstyle; int hairpinlinewidth; int hairpinwidth; int hyphenthreshold; int justify; int key; int keyspacing; int laststave; int ledger; int leftmargin; int linelength; int maxbarcount; int maxbeamslope1; int maxbeamslope2; int movt_opt; int number; int overlaydepth; int play_tempo; int rehearsalstyle; int repeatstyle; int shorten; int smallcapsize; int startbracketbar; int stemswaptype; int systemgap; int time; int timespacing; int topmargin; int totalnocount; int transpose; int tripletlinewidth; int truelinelength; int underlaydepth; int underlaystyle; usint breakbarlines[STAVE_BITVEC_SIZE]; usint staves[STAVE_BITVEC_SIZE]; usint suspend[STAVE_BITVEC_SIZE]; int clefwidths[clef_count]; int tailadjusts[8]; CBOOL beamendrests; CBOOL breverests; CBOOL check; CBOOL checkdoublebars; CBOOL codemultirests; CBOOL fullbarend; CBOOL startjoin; CBOOL keydoublebar; CBOOL keywarn; CBOOL rehearsallsleft; CBOOL showtime; CBOOL showtimebase; CBOOL tiesoverwarnings; CBOOL timewarn; CBOOL startnotime; CBOOL spreadunderlay; CBOOL underlayextenders; CBOOL unfinished; signed char playtranspose[MAX_STAVE+1]; } movtstr; /* Layout of the data for an active line gap */ typedef struct gapstr { struct gapstr *next; int x; b_linegapstr *gap; } gapstr; /* Layout of the data for an active slur */ typedef struct slurstr { struct slurstr *next; b_slurstr *slur; gapstr *gaps; int moff; int x; int y; int maxy; int miny; int lastx; int lasty; int slopeleft; int sloperight; short int count; short int section; } slurstr; /* Layout of the data for an active hairpin */ typedef struct { b_hairpinstr *hairpin; int x; int maxy; int miny; } hairpinstr; /* Layout of data for an active nth time bar. There can be a chain of these when, e.g. 1 & 2 are given for the same bar. It is wasteful of store, but this is so rare it isn't worth bothering. */ typedef struct nbarstr { struct nbarstr *next; b_nbarstr *nbar; int x; int maxy; int miny; } nbarstr; /* Layout of data for a pending underlay hyphen string or extension. Also used for overlay, with levels going from olay_offset. */ typedef struct ulaystr { struct ulaystr *next; int x; /* start position */ int y; /* vertical level */ uschar type; /* '=' or '-' */ uschar level; /* underlay level */ uschar htype; /* hyphen type index */ } ulaystr; /* Layout of data for custom built "hyphen type" */ typedef struct htypestr { struct htypestr *next; uschar *string1; /* main repeat string */ uschar *string2; /* line start string */ uschar *string3; /* final case string */ int font; /* initial font */ int adjust; /* vertical adjust */ uschar size1; /* size for first string */ uschar size2; /* size for second string */ } htypestr; /* Layout of data saved when a beam extends over a bar line. Longestnote is used when the split is over a line end. */ typedef struct { int firstX; int firstY; int slope; int count; int Xcorrection; int longestnote; BOOL splitOK; BOOL upflag; }obeamstr; /* Layout of one stave's continuation data held in a vector for use at the start of each system, and while setting the stave. */ typedef struct { slurstr *slurs; /* chain of pending slurs */ hairpinstr *hairpin; /* pending hairpin */ nbarstr *nbar; /* chain of pending nth time bars */ b_tiestr *tie; /* pending tie */ ulaystr *ulay; /* pending {und,ov}erlay hyphens or extension */ obeamstr *overbeam; /* data for beam over bar line */ int tiex; /* start position for tie */ int time; /* time signature */ uschar noteheadstyle; /* sic */ uschar flags; /* see below */ uschar clef; /* current clef */ uschar key; /* current key signature */ } contstr; #define cf_bowingabove 1 #define cf_notes 2 /* on/off switch */ #define cf_triplets 4 /* on/off switch */ #define cf_noteheads 8 /* on/off switch for noteheads only */ #define cf_rdrepeat 16 /* last bar ended with double repeat */ #define cf_default (cf_bowingabove|cf_notes|cf_triplets) /* Layout of data in a system block structure. Up to and including the movement pointer it must have the same layout as a headblock, because they are held in the same chain. */ typedef struct sysblock { uschar type; /* indicates sysblock or headblock */ uschar flags; /* see below */ uschar overrun; /* overrun (whole points) */ uschar dummy2; struct sysblock *next; /* next system or headblock */ movtstr *movt; /* -> relevant movement */ /********** The following are specific to sysblock **********/ snamestr **stavenames; /* -> pointers to name structures */ contstr *cont; /* -> vector of contstrs */ int *stavespacing; /* -> vector of stave spacings */ int *ulevel; /* -> vector of underlay levels */ int *olevel; /* -> vector of overlay levels */ int systemgap; /* system gap value */ int systemdepth; /* total of stavespacings */ int xjustify; /* justify amount for whole system */ int barlinewidth; /* stretched for this system */ int startxposition; /* position after staff name text */ int joinxposition; /* position for joining signs */ int keyxposition; /* position for key signature */ int timexposition; /* position for time signature */ int firstnoteposition; /* sic */ usint notsuspend[STAVE_BITVEC_SIZE]; /* staves not suspended in this system */ usint showtimes[STAVE_BITVEC_SIZE]; /* staves which have starting time signatures */ short int barstart; /* starting bar number */ short int barend; /* ending bar number */ } sysblock; /* Flag bits */ #define sysblock_warnkey 1 /* print additional key signature warning bar */ #define sysblock_warntime 2 /* ditto, time signature */ #define sysblock_warn 3 /* mask for either one of the above */ #define sysblock_stretch 4 /* flag set when stretched */ #define sysblock_noadvance 8 /* don't advance vertically */ /* Layout of data in a head block structure. Up to and including the movement pointer, it must have the same layout as a sysblock, because they are held in the same chain. We avoid using a union because the notation is so long and clumsy. */ typedef struct { uschar type; /* indicates sysblock or headblock */ CBOOL pageheading; /* indicates this is a page heading */ uschar dummy2; uschar dummy3; sysblock *next; movtstr *movt; /********** The following are specific to headblock **********/ headstr *headings; } headblock; /* Layout of a head of page block */ typedef struct pagestr { struct pagestr *next; sysblock *sysblocks; /* -> chain of head+sysblocks */ headblock *footing; /* -> footing blocks */ int number; /* page number */ int topspace; /* space to insert at top of page */ int spaceleft; /* space left (used for justifying) */ int overrun; /* space required to fit another system on */ } pagestr; /* Layout of entry in music font printing structure */ typedef struct mfstr { struct mfstr *next; int x; int y; usint ch; /* Holds up to 4 chars */ } mfstr; /* Layout of data structure used for saving drawing operations until the end of a stave - to ensure they are over everything else. Use a union to handle the two different types. */ struct overdrawstr_graphic { int linewidth; int gray; int ystave; int count; int data[1]; }; struct overdrawstr_text { uschar *text; int fontsize; int boxring; int xx; int yy; int matrix[4]; }; typedef struct overdrawstr { struct overdrawstr *next; BOOL texttype; union { struct overdrawstr_graphic g; struct overdrawstr_text t; } d; } overdrawstr; /************************************************* * Global variables * *************************************************/ extern movtstr *format_movt; /* Pointer to movement for formatting */ extern movtstr **movement; /* Pointer to vector of pointers */ extern movtstr *curmovt; /* Current movement */ extern pagestr *curpage; /* Current page */ extern int curstave; /* Current stave number */ extern uschar *arg_from_name; /* Name on command line */ extern uschar *arg_to_name; /* Name on command line */ extern BOOL bar_use_draw; /* Use direct drawing for bar lines */ extern uschar *copyright; extern FILE *debug_file; extern BOOL debugging; extern int draw_gap; /* +/- 1, for /a or /b gaps */ extern int draw_lgx; /* Line gap x0 value for draw */ extern int draw_lgy; /* Line gap y0 value for draw */ extern int draw_nextvariable; /* Next variable number */ extern int draw_ox; /* Draw origin coordinates */ extern int draw_oy; extern tree_node *draw_tree; /* Tree of draw routines */ extern tree_node *draw_variable_tree; /* Tree of draw variables */ extern int draw_thickness; /* Line thickness */ extern int error_count; /* Count of errors in one file */ extern int error_maximum; /* Limit (raiseable for testing) */ extern int error_ptr_correction; /* For pointing within strings */ extern int error_skip; /* Skip option */ #ifdef SUPPORT_B2PF extern b2pf_context **font_b2pf_contexts; /* Table of B2PF context pointers */ extern uint32_t *font_b2pf_options; /* Table of B2PF options */ #endif extern int font_count; /* Count of defined fonts */ extern int font_basecount; /* Ditto, as read from file */ extern uschar *font_IdStrings[]; /* 2-uschar ID strings */ extern fontstr *font_List; /* In-store list of fonts */ extern uschar *font_data_default; /* Default font data directory */ extern uschar *font_data_extra; /* Additional font data directory */ extern uschar *font_music_default; /* Default music font directory */ extern uschar *font_music_extra; /* Additional music font directory */ extern int font_sinr; /* Sin of rotation angle */ extern int font_cosr; /* Cos of rotation angle */ extern int font_stringheight; /* 2nd value from width function */ extern int *font_table; /* Table of font identities */ extern int font_transform[]; /* For esoteric fonts - normally unit */ extern int font_xstretch; /* Amount to stretch each space by */ extern uschar init_midi_voice[]; /* Default midi voice structure */ extern movtstr init_movtstr; /* Initializing movement structure */ extern int init_notespacing[]; /* Initial notespacing value */ extern int init_stavesizes[]; /* Initial stave sizes table */ extern zcopystr init_zcopy; /* Default stave zero copy structure */ extern FILE *input_file; /* The current input file */ extern uschar length_table[]; /* Table of item lengths */ extern int longrest_barwidths[]; /* Fixed widths for longrest bars */ extern int longrest_widths[]; /* Widths of longrest symbols */ extern usint main_bit[]; /* Table of bits in a word */ extern uschar *main_caesurastrings[]; /* For printing caesuras */ extern int main_clefoffset[]; /* Offsets in tables for clefs */ extern int main_cleftypes[]; /* Types of shape indicators for next */ extern uschar *main_filename; /* Name of current file */ extern int main_firstpage; /* Number of first page */ extern int main_flatorder[]; /* Key sig table */ extern uschar *main_format; /* User-selected format */ extern BOOL main_format_tested; /* Format has been tested */ extern htypestr *main_htypes; /* Chain of hyphen types */ extern BOOL main_initialized; /* True when initialized */ extern BOOL main_kerning; /* Kerning flag */ extern int main_keysigtable[]; /* Table of sharps and flats */ extern keytransposestr *main_keytranspose; /* List of explicit transpositions */ extern int main_lastmovement; /* Number of last movement */ extern int main_lastpage; /* Number of last page */ extern int main_magnification; /* Overall magnification */ extern int main_max_bars; /* Max bars per staff */ extern int main_max_movements; /* Maximum number of movements */ extern int main_maxvertjustify; /* Max vertical justification */ extern uschar *main_musicchoice; /* Music file named in Choices */ extern int main_notenum; /* Multiplies length */ extern int main_noteden; /* Divides length */ extern int main_notespacing[]; /* Start of movement values */ extern pagestr *main_pageanchor; /* Anchor of page structure */ extern int main_pageinc; /* Page increments */ extern int main_pagelength; /* Virtual page length */ extern pkeystr *main_printkey; /* Chain of printkey structs */ extern ptimestr *main_printtime; /* Chain of printtime structs */ extern headstr *main_pssetup; /* PostScript set-up "headings" */ extern int main_rc; /* The final return code */ extern BOOL main_righttoleft; /* As it says */ extern int main_sharporder[]; /* Key sig order table */ extern int main_sheetheight; /* Height of paper */ extern int main_sheetwidth; /* Width of paper */ extern BOOL main_shownlogo; /* FALSE if need to show logo on error */ extern int main_stavemagn; /* Magnification for current stave */ extern usint main_staves[STAVE_BITVEC_SIZE]; /* External stave selection */ extern int main_storetotal; /* Total store used */ extern int main_storestaves; /* Store used for staves */ extern int main_stretchrespacethresh; /* Threshold for re-spacing */ extern int main_stretchthreshnum; /* Stretching threshold */ extern int main_stretchthreshden; extern int main_totalbars; /* Total number of bars */ extern int main_tracepos; /* Debugging option */ extern int main_transpose; /* External transpose value */ extern BOOL main_transposedaccforce; /* TRUE => retain accs when transposed */ extern trkeystr *main_transposedkeys; /* Transposed keys masquerades */ extern int main_truepagelength; /* Actual page length */ extern uschar main_xkeys[MAX_XKEYS][10]; /* Custom key signatures */ extern uschar main_xkeyorder[MAX_XKEYS][10]; /* Acc order for custom keys */ extern uschar *midi_filename; /* name of MIDI file */ extern BOOL midi_for_notes_off; /* If TRUE, do MIDI even if [notes off] */ extern uschar *midi_perc; /* File name with midi perc */ extern uschar *midi_percnames; /* Percussion name => "pitch" */ extern uschar *midi_voices; /* File name with midi voices */ extern uschar *midi_voicenames; /* Voice name => voice number */ extern int music_xmovement[]; /* Table of x movement-chars */ extern int music_ymovement[]; /* Ditto y */ extern BOOL opt_landscape; /* User-settable options */ extern BOOL opt_oldbeambreak; extern BOOL opt_oldrestlevel; extern BOOL opt_oldstemlength; extern BOOL opt_print_postscript; extern int opt_sheetsize; extern int opt_stretchrule; extern int play_endbar; extern int play_movt_number; extern BOOL play_repeats; extern int play_startbar; extern stave_list *print_curlist; /* Printing selection list */ extern int print_curnumber; /* Printing page number */ extern int print_gutter; /* Gutter adjustment */ extern int print_imposition; /* Imposition option */ extern int print_lastpage; /* Logical last page number */ extern int print_image_xadjust; /* Image adjustment values */ extern int print_image_yadjust; extern int print_image_sxadjust; /* ... for sideways paper */ extern int print_image_syadjust; extern int print_magnification; /* Scaling value */ extern int print_pagefeed; /* Page feed type */ extern int print_pageorigin; /* Page origin type */ extern BOOL print_pamphlet; /* Printing options */ extern BOOL print_reverse; extern BOOL print_side1; extern BOOL print_side2; extern uschar *ps_header; /* Name of PostScript header file */ extern BOOL reading_input; /* TRUE while reading */ extern stavestr *stavehead; /* Points to current stave structure */ extern stavestr **stavetable; /* Points to pointers to stave struct */ extern int stave_bottoms[]; /* Levels of top/bottom lines of staves */ extern int stave_tops[]; extern int stave_use_draw; /* Use direct drawing for staves */ extern BOOL stave_use_widechars; /* Use 100-pt chars for staves */ extern const int utf8_table1[]; /* Various tables for UTF-8 processing */ extern const int utf8_table2[]; extern const int utf8_table3[]; extern const uschar utf8_table4[]; extern int string_font; /* Final font after measuring a string */ extern BOOL verify; /* The -v option */ extern int version_fixed; /* Identity number in binary */ extern uschar version_string[]; /* Identity of program version */ /************************************************* * Global procedures * *************************************************/ extern void debug_printf(const char *, ...); extern void debug_showbar(int, int, int); #ifdef Debug extern void debug_showbarpos(int, int); extern void debug_showglobals(void); extern void debug_showmovement(int); extern void debug_showpage(int); extern void debug_showstave(int, int); #endif extern uschar *define_find(uschar *); extern void error_moan(int, ...); extern FILE *font_finddata(uschar *, const char *, uschar *, uschar *, uschar *, BOOL); extern int font_fontword(BOOL); extern void font_init(void); extern void font_loadtables(int); extern void font_reset(void); extern void font_rotate(int); extern int font_search(uschar *); extern int font_stringwidth(uschar *, int, int); extern int font_utranslate(int, fontstr *); extern int format_sprintf(uschar *, const char *, ...); /* 2nd is format */ extern int format_vsprintf(uschar *, const char *, va_list); /* ditto */ extern void info_printf(const char *, ...); extern int init_command(int, char **, char **, const char *); extern void main_tidyup(void); extern void midi_write(void); extern void misc_commoncont(bstr *); extern contstr *misc_copycontstr(contstr *, int, BOOL); extern void misc_drawslur(slurstr *, int, int, BOOL); extern void misc_freecontstr(contstr *, int); extern slurstr *misc_getendslur(bstr *); extern int misc_keywidth(int, int); extern b_notestr *misc_nextnote(b_notestr *, int *); extern int misc_ord2utf8(int, uschar *); extern slurstr *misc_setstartslur(bstr *); extern int misc_timewidth(int); extern int misc_ybound(int, b_tiestr *, BOOL, BOOL); extern void paginate_go(void); extern BOOL print_nextpage(pagestr **, pagestr **); extern void print_setup_pagelist(BOOL); extern void ps_go(void); extern void read_start(void); extern void read_go(void); extern void read_midi_translation(uschar **, uschar *); extern void *store_copy(void *); extern uschar *store_copystring(uschar *); extern void store_debug_print(void); extern void store_debug_print(void); extern void store_free(void *); extern void *store_get(usint); extern void *store_getitem(int); extern void *store_nextitem(void); extern void *store_Xget(int); extern uschar *string_check(uschar *); extern uschar *string_escape(uschar *, uschar *, int *, int *); extern uschar *string_read(void); extern void string_stavestring(BOOL); extern int string_width(uschar *, int, int); extern void sys_relativize(uschar *, int); extern int transpose_key(int, int); extern int transpose_note(int, int *, int *, int, BOOL, BOOL, BOOL, int); extern BOOL Tree_InsertNode(tree_node **, tree_node *); extern tree_node *Tree_Search(tree_node *, uschar *); extern void version_init(void); /* End of pmwhdr.h */