💾 Archived View for runjimmyrunrunyoufuckerrun.com › src › foreign › pmw › src › sethairpin.c captured on 2021-12-17 at 13:26:06.
View Raw
More Information
-=-=-=-=-=-=-
/*************************************************
- The PMW Music Typesetter - 3rd incarnation *
- ************************************************/
/* Copyright (c) Philip Hazel, 1991 - 2008 */
/* Written by Philip Hazel, starting November 1991 */
/* This file last modified: December 2019 */
/* This file contains code for outputting hairpins */
#include "pmwhdr.h"
#include "outhdr.h"
#include "pagehdr.h"
/*************************************************
- Deal with start of hairpin *
- ************************************************/
/* This remembers the hairpin parameters for later use.
Arguments:
h the hairpin data for the start of the hairpin
x the x coordinate of the start of the hairpin
Returns: nothing
void
out_setstarthairpin(b_hairpinstr *h, int x)
{
hairpinstr *hh = store_Xget(sizeof(hairpinstr));
hh->hairpin = h;
hh->x = x;
hh->maxy = -BIGNUMBER;
hh->miny = BIGNUMBER;
bar_cont->hairpin = hh;
if ((h->flags & hp_bar) != 0)
hh->x = out_startlinebar?
(out_sysblock->timexposition + out_sysblock->xjustify) : out_lastbarlinex;
/* The /bar option overrides /h */
else if ((h->flags & hp_halfway) != 0) out_hairpinhalf = TRUE;
/* And /h overrides /lc and /rc. Adjust the x coordinate by looking for the
relevant musical offset. If x == 0 it means we are setting up for a
continuation hairpin while paginating, so don't do anything. */
else if (h->offset != 0 && x != 0)
{
int offset = mac_muldiv(len_crotchet, h->offset, 1000);
hh->x = out_barx + out_findAoffset(out_moff + offset);
}
}
/*************************************************
- Draw a hairpin *
- ************************************************/
/* This actually draws the hairpin.
Arguments:
h1 the data for the end of the hairpin
x1 the x coordinate of the end of the hairpin
Returns: nothing
void
out_drawhairpin(b_hairpinstr *h1, int x1)
{
hairpinstr *hh = bar_cont->hairpin;
b_hairpinstr *h0 = hh->hairpin;
BOOL skip = FALSE;
int flags = h0->flags;
int abs = (flags & hp_abs) != 0;
int cwidth = h0->width/2;
int dwidth = cwidth;
int thickness = curmovt->hairpinlinewidth;
int x0 = hh->x;
int offset, y0, y1, y0hole, y1hole;
/* Compute basic offset from stave base */
if ((flags & hp_below) == 0)
{
offset = abs? 16000 : (((hh->maxy > 16000)? hh->maxy + 6000 : 22000) +
(h0->width - 7000)/2);
}
else
{
offset = abs? 0 : (((hh->miny < 0)? hh->miny - 6000 : -6000) -
(h0->width - 7000)/2);
if ((flags & hp_middle) != 0 && out_stave < out_laststave)
{
int gap = out_sysblock->stavespacing[out_stave]/2;
int st = out_stave + 1;
while (gap == 0 && st < out_laststave)
if (mac_teststave(out_sysblock->notsuspend, st))
gap = out_sysblock->stavespacing[st++]/2;
gap -= 8 * main_stavemagn;
if (-gap < offset) offset = -gap;
}
}
/* At start of line, start just before first note; also set small gap at start
of hairpin. If continued decrescendo, start at smaller width. */
if (x0 == 0)
{
x0 = out_sysblock->firstnoteposition - 4*main_stavemagn;
y0 = h0->y + ((h1 == NULL)? 0 : h1->su);
y0hole = main_stavemagn;
dwidth = (80*dwidth)/100;
}
else /* not start of line */
{
x0 += h0->x;
y0 = h0->y;
y0hole = 0;
}
/* Add manual right-hand adjustment; at end of line we use the left-hand value.
Set small gap in decrescendo at end of line. */
if (h1 != NULL)
{
if ((h1->flags & hp_bar) != 0) /* /bar overrides /h */
{
x1 = out_barlinex;
}
else if ((h1->flags & hp_halfway) != 0)
{
x1 += mac_muldiv(out_barx + out_findXoffset(out_moff) - x1 -
6*main_stavemagn, h1->h, 1000);
}
else if (h1->offset != 0)
{
int xoffset = mac_muldiv(len_crotchet, h1->offset, 1000);
x1 = out_barx + out_findAoffset(out_moff + xoffset);
}
x1 += h1->x;
y1 = h0->y + h1->y;
y1hole = 0;
}
else /* end of line; reduce crescendo width a bit */
{
y1 = h0->y + h0->su;
y1hole = main_stavemagn;
cwidth = (cwidth*80)/100;
}
/* Final y values */
y0 = ((y0 + offset)*main_stavemagn)/1000;
y1 = ((y1 + offset)*main_stavemagn)/1000;
/* Draw the hairpin, enforcing a minimum length of 10 points, except at the end
of line where we can suppress a decrescendo. We can't suppress a crescendo -
the user will have to fix. */
if (x1 - x0 < 10*main_stavemagn)
{
if (h1 != NULL || h0->opt == '<') x1 = x0 + 10*main_stavemagn;
else skip = TRUE;
}
if (!skip)
{
if (h0->opt == '>')
{
ps_line(x0, y0 + dwidth, x1, y1 + y1hole, thickness, 0);
ps_line(x0, y0 - dwidth, x1, y1 - y1hole, thickness, 0);
}
else
{
ps_line(x0, y0 + y0hole, x1, y1 + cwidth, thickness, 0);
ps_line(x0, y0 - y0hole, x1, y1 - cwidth, thickness, 0);
}
}
/* Free the dynamic store and clear its pointer. */
store_free(hh);
bar_cont->hairpin = NULL;
}
/* End of sethairpin.c */