App-Music-ChordPro
view release on metacpan or search on metacpan
lib/ChordPro/res/abc/abc2svg/jianpu-1.js view on Meta::CPAN
// jianpu.js - module to output jiÄnpÅ (ç®è°±) music sheets
//
// Copyright (C) 2020-2025 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%jianpu" appears in a ABC source.
//
// Parameters (none)
// %%jianpu 1
if (typeof abc2svg == "undefined")
var abc2svg = {}
abc2svg.jianpu = {
k_tb: [ "Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F",
"C",
"G", "D", "A", "E", "B", "F#", "C#" ],
cde2fcg: new Int8Array([0, 2, 4, -1, 1, 3, 5]),
cgd2cde: new Int8Array([0, -4, -1, -5, -2, -6, -3,
0, -4, -1, -5, -2, -6, -3, 0]),
acc2: new Int8Array([-2, -1, 3, 1, 2]),
acc_tb: ["\ue264", "\ue260", , "\ue262", "\ue263", "\ue261"],
// don't calculate the beams
calc_beam: function(of, bm, s1) {
if (!s1.p_v.jianpu)
return of(bm, s1)
// return 0
}, // calc_beam()
// adjust some symbols before the generation
output_music: function(of) {
var p_v, v,
C = abc2svg.C,
abc = this,
cur_sy = abc.get_cur_sy(),
voice_tb = abc.get_voice_tb()
// handle the overlay voices
function ov_def(v) {
var s1, tim,
s = p_v.sym
while (s) {
s1 = s.ts_prev
if (!s.invis
&& s.dur
&& s1.v != v
&& s1.st == s.st // overlay start
&& s1.time == s.time) {
while (1) { // go back to the previous bar
if (!s1.prev
|| s1.prev.bar_type)
break
s1 = s1.prev
}
//add deco '{' on s1
while (!s1.bar_type) {
s1.dy = 14
s1.notes[0].pit = 30
if (s1.type == C.REST)
s1.combine = -1
s1 = s1.next
}
// add deco '}' on s1
while (1) {
s.dy = -14
s.notes[0].pit = 20
if (!s.next
|| s.next.bar_type
|| s.next.time >= s1.time)
break
s = s.next
}
}
s = s.next
}
} // ov_def()
// output the key and time signatures
function set_head() {
var v, p_v, mt, s2, sk, s,
tsfirst = abc.get_tsfirst()
// search a jianpu voice
for (v = 0; v < voice_tb.length; v++) {
p_v = voice_tb[v]
if (p_v.jianpu)
break
}
if (v >= voice_tb.length)
return
mt = p_v.meter.a_meter[0]
sk = p_v.key
s2 = p_v.sym
s = {
type: C.BLOCK,
subtype: "text",
time: s2.time,
dur: 0,
v: 0,
p_v: p_v,
st: 0,
fmt: s2.fmt,
seqst: true,
text: (sk.k_mode + 1) + "=" +
(abc2svg.jianpu.k_tb[sk.k_sf + 7 +
lib/ChordPro/res/abc/abc2svg/jianpu-1.js view on Meta::CPAN
out_svg('<path class="stroke" \
d="m' + (l / 2 - 3).toFixed(1)+' '+y.toFixed(1))
if (s.gr_shift) {
out_svg('m0 0c0 10 0 10 -10 10')
} else {
out_svg('m0 0c0 10 0 10 10 10')
}
out_svg('"/>\n')
}
out_svg('</g>\n')
abc.stv_g().g--
} // draw_dgr()
function out_mus(x, y, p) {
out_svg('<text x="')
out_sxsy(x, '" y="', y)
out_svg('">' + p + '</text>\n')
} // out_mus()
function out_txt(x, y, p) {
out_svg('<text class="fj" x="')
out_sxsy(x, '" y="', y)
out_svg('">' + p + '</text>\n')
} // out_txt()
function draw_hd(s, x, y) {
var m, note, ym
for (m = 0; m <= s.nhd; m++) {
note = s.notes[m]
out_txt(x - 3.5, y + 8, "01234567-"[note.jn])
if (note.acc)
out_mus(x - 12, y + 12,
abc2svg.jianpu.acc_tb[note.acc + 2])
if (note.jo > 2) {
out_mus(x - 1, y + 22, dot)
if (note.jo > 3) {
y += 3
out_mus(x - 1, y + 22, dot)
}
} else if (note.jo < 2) {
ym = y + 4
if (m == 0 && s.nflags > 0)
ym -= 2.5 * s.nflags
out_mus(x - 1, ym, dot)
if (note.jo < 1) {
ym -= 3
out_mus(x - 1, ym, dot)
}
}
y += 20
}
} // draw_hd()
function draw_note(s) {
var sc = 1,
x = s.x,
y = staff_tb[s.st].y
if (s.dy)
y += s.dy // voice overlay
if (s.grace) {
out_svg('<g transform="translate(')
out_sxsy(x, ',', y + 15) // (font height)
out_svg(') scale(.5)">\n')
abc.stv_g().g++ // in container
x = 0
y = 0
sc = .5
}
draw_hd(s, x, y)
if (s.nflags >= 0 && s.dots)
out_mus(x + 8 * sc, y + 13 * sc, dot)
if (s.grace) {
out_svg('</g>\n')
abc.stv_g().g--
}
anno_a.push(s)
} // draw_note()
// -- draw_symbols --
for (s = p_voice.sym; s; s = s.next) {
if (s.invis)
continue
switch (s.type) {
case C.METER:
abc.draw_meter(s)
break
case C.NOTE:
case C.REST:
draw_note(s)
break
case C.GRACE:
for (g = s.extra; g; g = g.next)
draw_note(g)
break
}
}
// draw the (pseudo) beams
for (s = p_voice.sym; s; s = s.next) {
if (s.invis)
continue
switch (s.type) {
case C.NOTE:
case C.REST:
nl = s.nflags
if (nl <= 0)
continue
y = staff_tb[s.st].y
s2 = s
while (1) {
if (s.nflags > nl)
nl = s.nflags
if (s.beam_end)
break
if (s.type == C.GRACE)
draw_dgr(s)
( run in 1.999 second using v1.01-cache-2.11-cpan-aadc1410aed )