App-Music-ChordPro

 view release on metacpan or  search on metacpan

lib/ChordPro/res/abc/abc2svg/abc2svg-1.js  view on Meta::CPAN

	out_sxsy(x1, ' ', y1);
	output += 'c' +
		((xx1 - x1) / stv_g.scale).toFixed(1) + ' ' +
		((y1 - yy1) / scale_y).toFixed(1) + ' ' +
		((xx2 - x1) / stv_g.scale).toFixed(1) + ' ' +
		((y1 - yy2) / scale_y).toFixed(1) + ' ' +
		((x2 - x1) / stv_g.scale).toFixed(1) + ' ' +
		((y1 - y2) / scale_y).toFixed(1)

	if (!dotted)
		output += '\n\tv' +
			(-dz).toFixed(1) + 'c' +
			((xx2 - dx - x2) / stv_g.scale).toFixed(1) + ' ' +
			((y2 + dz - yy2 - dy) / scale_y).toFixed(1) + ' ' +
			((xx1 + dx - x2) / stv_g.scale).toFixed(1) + ' ' +
			((y2 + dz - yy1 - dy) / scale_y).toFixed(1) + ' ' +
			((x1 - x2) / stv_g.scale).toFixed(1) + ' ' +
			((y2 - y1) / scale_y).toFixed(1)
	output += '"/>\n'
}

// draw a slur between two chords / notes
/* (the staves are not yet defined) */
/* (delayed output) */
/* (not a pretty routine, this) */
function draw_slur(path,	// list of symbols under the slur
		   sl,		// slur variables: type, end symbol, note
		   recurr) {	// recurrent call when slur on two staves
    var	i,
	k, g, x1, y1, x2, y2, height, addy, s_st2,
	a, y, z, h, dx, dy,
	ty = sl.ty,
	dir = (ty & 0x07) == C.SL_ABOVE ? 1 : -1,
	n = path.length,
	i1 = 0,
	i2 = n - 1,
	not1 = sl.nts,		// if the slur starts on a note
	k1 = path[0],
	k2 = path[i2],
	nn = 1

	set_dscale(k1.st)

	for (i = 1; i < n; i++) {
		k = path[i]
		if (k.type == C.NOTE || k.type == C.REST) {
			nn++
			if (k.st != k1.st
			 && !s_st2)
				s_st2 = k
		}
	}

	// if slur on 2 staves, define it, but don't output it now
	// this will be done in draw_sl2()
	if (s_st2 && !recurr) {			// if not 2nd call to draw_slur()
		if (!gene.a_sl)
			gene.a_sl = []

		// replace the symbols of the other staff
		// by symbols in the current staff but with updated y offsets
		h = 24 + k1.fmt.sysstaffsep		// delta y
		if (s_st2.st > k1.st)
			h = -h
		for (i = 0; i < n; i++) {
			k = path[i]
			if (k.st == k1.st) {
				if (k.dur)
					a = k		// (used for types // and \\)
				continue
			}
			k = clone(k)
			if (path[i] == s_st2)
				s_st2 = k
			path[i] = k
			if (k.dur) {
				k.notes = clone(k.notes)
				k.notes[0] = clone(k.notes[0])
				if (sl.ty & C.SL_CENTER) {
					if (k.st != a.st) {
						sl.ty = (sl.ty & ~0x07)
							 | (a.st < k.st
								? C.SL_BELOW
								: C.SL_ABOVE)
						z = k1.ymn
						h = k2.ymx
						if (k.st < a.st) {
							for (i1 = 1; i1 < i; i1++) {
								a = path[i1]
								if (a.ymn < z)
									z = a.ymn
							}
							for (i1 = i; i1 < i2; i1++) {
								a = path[i1]
								if (a.ymx > h)
									h = a.ymx
							}
						} else {
							for (i1 = 1; i1 < i; i1++) {
								a = path[i1]
								if (a.ymx > h)
									h = a.ymx
							}
							for (i1 = i; i1 < i2; i1++) {
								a = path[i1]
								if (a.ymn < z)
									z = a.ymn
							}
						}
						h += z
						a = k
					}
					k.y = h - k.y
					k.notes[0].pit = (k.y / 3 | 0) + 18
					k.ys = h - k.ys
					y = k.ymx
					k.ymx = h - k.ymn
					k.ymn = h - y
					k.stem = -k.stem
				} else {
					k.notes[0].pit += h / 3 | 0

lib/ChordPro/res/abc/abc2svg/abc2svg-1.js  view on Meta::CPAN

			 && s2.st == st
			 && s2.type == C.NOTE
			 && s2.notes[0].pit <= 13)	/* G, */
				continue
			s2 = s.ts_next
			if (s2
			 && s2.st == st
			 && s2.time == time
			 && s2.type == C.NOTE
			 && s2.notes[0].pit <= 13)	/* G, */
				continue
		}

		/* if first change, change the starting clef */
		if (!s_last_chg) {
			clef_type = clef_type_start =
					clef_type == 't' ? 'b' : 't';
			s_last_chg = s
			continue
		}

		/* go backwards and search where to insert a clef change */
		s3 = s
		for (s2 = s.ts_prev; s2 != s_last_chg; s2 = s2.ts_prev) {
			if (s2.st != st)
				continue
			if (s2.type == C.BAR) {
				s3 = s2.bar_type[0] != ':' ? s2 : s2.next
				break
			}
			if (s2.type != C.NOTE)
				continue

			/* have a 2nd choice on beam start */
			if (s2.beam_st
			 && !s2.p_v.second)
				s3 = s2
		}

		/* no change possible if no insert point */
		if (s3.time == s_last_chg.time) {
			s_last_chg = s
			continue
		}
		s_last_chg = s;

		/* insert a clef change */
		clef_type = clef_type == 't' ? 'b' : 't';
		s2 = insert_clef(s3, clef_type, clef_type == "t" ? 2 : 4);
		s2.clef_auto = true
//		s3.prev.st = st
	}
	return clef_type_start
}

/* set the clefs */
/* this function is called once at start of tune generation */
/*
 * global variables:
 *	- staff_tb[st].clef = clefs at start of line (here, start of tune)
 *				(created here, updated on clef draw)
 *	- voice_tb[v].clef = clefs at end of generation
 *				(created on voice creation, updated here)
 */
function set_clefs() {
    var	s, s2, st, v, p_voice, g, new_type, new_line, p_staff, pit,
	staff_clef = new Array(nstaff + 1),	// st -> { clef, autoclef }
	sy = cur_sy,
	mid = []

	// create the staff table
	staff_tb = new Array(nstaff + 1)
	for (st = 0; st <= nstaff; st++) {
		staff_clef[st] = {
			autoclef: true
		}
		staff_tb[st] = {
			output: "",
			sc_out: ""
		}
	}

	for (st = 0; st <= sy.nstaff; st++)
		mid[st] = (sy.staves[st].stafflines.length - 1) * 3

	for (s = tsfirst; s; s = s.ts_next) {
		if (s.repeat_n)
			set_repeat(s)

		switch (s.type) {
		case C.STAVES:
			sy = s.sy			// new system
			for (st = 0; st <= nstaff; st++)
				staff_clef[st].autoclef = true
			for (v = 0; v < voice_tb.length; v++) {
				if (!sy.voices[v])
					continue
				p_voice = voice_tb[v];
				st = sy.voices[v].st
				if (!sy.voices[v].second) {
					sy.staves[st].staffnonote = p_voice.staffnonote
					if (p_voice.staffscale)
						sy.staves[st].staffscale = p_voice.staffscale
					if (sy.voices[v].sep)
						sy.staves[st].sep = sy.voices[v].sep
					if (sy.voices[v].maxsep)
						sy.staves[st].maxsep = sy.voices[v].maxsep
				}
				s2 = p_voice.clef
				if (!s2.clef_auto)
					staff_clef[st].autoclef = false
			}
			for (st = 0; st <= sy.nstaff; st++)
				mid[st] = (sy.staves[st].stafflines.length - 1) * 3
			for (v = 0; v < voice_tb.length; v++) {
				if (!sy.voices[v]
				 || sy.voices[v].second)	// main voices
					continue
				p_voice = voice_tb[v];
				st = sy.voices[v].st;
				s2 = p_voice.clef
				if (s2.clef_auto) {
//fixme: the staff may have other voices with explicit clefs...

lib/ChordPro/res/abc/abc2svg/abc2svg-1.js  view on Meta::CPAN

			staff_tb[stv_g.st].output += output
		} else {
			staff_tb[stv_g.st].sc_out += output
		}
		output = ""
	}
	if (st < 0)
		stv_g.scale = 1
	else
		stv_g.scale = no_scale ? 1 : staff_tb[st].staffscale;
	stv_g.st = st;
	stv_g.dy = 0
}

// update the y offsets of delayed output
function delayed_update() {
	var st, new_out, text

	for (st = 0; st <= nstaff; st++) {
		if (staff_tb[st].sc_out) {
			output += '<g ' + staff_tb[st].scale_str + '>\n' +
				staff_tb[st].sc_out + '</g>\n';
			staff_tb[st].sc_out = ""
		}
		if (!staff_tb[st].output)
			continue
		output += '<g transform="translate(0,' +
				(-staff_tb[st].y).toFixed(1) +
				')">\n' +
			staff_tb[st].output +
			'</g>\n';
		staff_tb[st].output = ""
	}
}

// output the annotations
function anno_out(s, t, f) {
	if (s.istart == undefined)
		return
	var	type = s.type,
		h = s.ymx - s.ymn + 4,
		wl = s.wl || 2,
		wr = s.wr || 2

	if (s.grace)
		type = C.GRACE

	f(t || abc2svg.sym_name[type], s.istart, s.iend,
		s.x - wl - 2, staff_tb[s.st].y + s.ymn + h - 2,
		wl + wr + 4, h, s);
}

function a_start(s, t) {
	anno_out(s, t, user.anno_start)
}
function a_stop(s, t) {
	anno_out(s, t, user.anno_stop)
}
function empty_function() {
}
	// the values are updated on generate()
    var	anno_start = empty_function,
	anno_stop = empty_function

// output the stop user annotations
function anno_put() {
    var	s
	while (1) {
		s = anno_a.shift()
		if (!s)
			break
		switch (s.type) {
		case C.CLEF:
		case C.METER:
		case C.KEY:
		case C.REST:
			if (s.type != C.REST || s.rep_nb) {
				set_sscale(s.st)
				break
			}
			// fall thru
		case C.GRACE:
		case C.NOTE:
		case C.MREST:
			set_scale(s)
			break
//		default:
//			continue
		}
		anno_stop(s)
	}
} // anno_put()

// output a string with x, y, a and b
// In the string,
//	X and Y are replaced by scaled x and y
//	A and B are replaced by a and b as string
//	F and G are replaced by a and b as float
function out_XYAB(str, x, y, a, b) {
	x = sx(x);
	y = sy(y);
	output += str.replace(/X|Y|A|B|F|G/g, function(c) {
		switch (c) {
		case 'X': return x.toFixed(1)
		case 'Y': return y.toFixed(1)
		case 'A': return a
		case 'B': return b
		case 'F': return a.toFixed(1)
//		case 'G':
		default: return b.toFixed(1)
		}
		})
}

// open / close containers
function g_open(x, y, rot, sx, sy) {
	glout()
	out_XYAB('<g transform="translate(X,Y', x, y);
	if (rot)
		output += ') rotate(' + rot.toFixed(2)
	if (sx) {



( run in 1.621 second using v1.01-cache-2.11-cpan-d7f47b0818f )