smallpond

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/smallpond
Log | Files | Refs

commit ff4ce86c7afb809fa4ca0c30a37290e4e29f57e9
parent 0618938569c298ba126f6ec82dc4e7fd76089037
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Wed, 28 Sep 2022 14:44:03 -0500

new staff scheme in rest of stages

Diffstat:
Msmallpond.lua | 399++++++++++++++++++++++++++++++++++++++++++-------------------------------------
1 file changed, 212 insertions(+), 187 deletions(-)

diff --git a/smallpond.lua b/smallpond.lua @@ -161,6 +161,7 @@ function parse(text) end f = assert(io.open("score.sp")) +parse(f:read("*a")) local time = 0 -- time in increments of denom local octave = 0 @@ -206,52 +207,55 @@ abstract_dispatch = { end } -parse(f:read("*a")) - for _, voice in ipairs(voices) do for _, item in ipairs(voice) do assert(abstract_dispatch[item.command])(item) end end +first_order = nil + -- second-order placement -local staff = {} +local staff2 = {} local tobeam = {} -for i, el in ipairs(first_order) do - if el.kind == 'note' and el.beamed then - tobeam[#tobeam + 1] = el - else - if #tobeam > 1 then - -- check which way the stem should point on all the notes in the beam - local ysum = 0 - for _, note in ipairs(tobeam) do - ysum = ysum + note.sy - end +for staff, _ in pairs(staff1) do + staff2[staff] = {} + for i, el in ipairs(staff1[staff]) do + if el.kind == 'note' and el.beamed then + tobeam[#tobeam + 1] = el + else + if #tobeam > 1 then + -- check which way the stem should point on all the notes in the beam + local ysum = 0 + for _, note in ipairs(tobeam) do + ysum = ysum + note.sy + end - local stemdir - if ysum >= 0 then - stemdir = -1 - else - stemdir = 1 - end + local stemdir + if ysum >= 0 then + stemdir = -1 + else + stemdir = 1 + end - -- update the stem direction - for _, note in ipairs(tobeam) do - note.stemdir = stemdir - table.insert(staff, note) + -- update the stem direction + for _, note in ipairs(tobeam) do + note.stemdir = stemdir + table.insert(staff2[staff], note) + end + table.insert(staff2[staff], {kind='beam', first=tobeam[1], last=tobeam[#tobeam]}) + elseif #tobeam == 1 then + tobeam[1].beamed = false + table.insert(staff2[staff], tobeam[1]) end - table.insert(staff, {kind='beam', first=tobeam[1], last=tobeam[#tobeam]}) - elseif #tobeam == 1 then - tobeam[1].beamed = false - table.insert(staff, tobeam[1]) + tobeam = {} + table.insert(staff2[staff], el) end - tobeam = {} - table.insert(staff, el) end end -drawables = {} +local staff3 = {} -- starting yoffset at 20 is a hack local yoffset = 20 @@ -259,196 +263,217 @@ local xoffset = 20 local x = 10 local lasttime = 0 -for i, el in ipairs(staff) do - if el.kind == "note" then - local rx = xoffset + x - local ry = yoffset + (em*el.sy) / 2 + 2*em - if el.acc == "s" then - table.insert(drawables, {kind="glyph", glyph=Glyph["accidentalSharp"], x=rx, y=ry}) - elseif el.acc == "f" then - table.insert(drawables, {kind="glyph", glyph=Glyph["accidentalFlat"], x=rx, y=ry}) - elseif el.acc == "n" then - table.insert(drawables, {kind="glyph", glyph=Glyph["accidentalNatural"], x=rx, y=ry}) - end +for staff, _ in pairs(staff2) do + staff3[staff] = {} + for i, el in ipairs(staff2[staff]) do + if el.kind == "note" then + local rx = xoffset + x + local ry = yoffset + (em*el.sy) / 2 + 2*em + if el.acc == "s" then + table.insert(staff3[staff], {kind="glyph", glyph=Glyph["accidentalSharp"], x=rx, y=ry}) + elseif el.acc == "f" then + table.insert(staff3[staff], {kind="glyph", glyph=Glyph["accidentalFlat"], x=rx, y=ry}) + elseif el.acc == "n" then + table.insert(staff3[staff], {kind="glyph", glyph=Glyph["accidentalNatural"], x=rx, y=ry}) + end - rx = rx + 10 - - local glyph - if el.length == 1 then - glyph = Glyph["noteheadWhole"] - elseif el.length == 2 then - glyph = Glyph["noteheadHalf"] - elseif el.length == 4 then - glyph = Glyph["noteheadBlack"] - elseif el.length == 8 then - glyph = Glyph["noteheadBlack"] - end + rx = rx + 10 + + local glyph + if el.length == 1 then + glyph = Glyph["noteheadWhole"] + elseif el.length == 2 then + glyph = Glyph["noteheadHalf"] + elseif el.length == 4 then + glyph = Glyph["noteheadBlack"] + elseif el.length == 8 then + glyph = Glyph["noteheadBlack"] + end - local w, h = glyph_extents(glyph) - -- leger lines - if el.sy <= -6 then - for j = -6, el.sy, -2 do - table.insert(drawables, {kind="line", t=1.2, x1=rx - .2*em, y1=yoffset + (em * (j + 4)) / 2, x2=rx + w + .2*em, y2=yoffset + (em * (j + 4)) / 2}) + local w, h = glyph_extents(glyph) + -- leger lines + if el.sy <= -6 then + for j = -6, el.sy, -2 do + table.insert(staff3[staff], {kind="line", t=1.2, x1=rx - .2*em, y1=yoffset + (em * (j + 4)) / 2, x2=rx + w + .2*em, y2=yoffset + (em * (j + 4)) / 2}) + end end - end - if el.sy >= 6 then - for j = 6, el.sy, 2 do - table.insert(drawables, {kind="line", t=1.2, x1=rx - .2*em, y1=yoffset + (em * (j + 4)) / 2, x2=rx + w + .2*em, y2=yoffset + (em * (j + 4)) / 2}) + if el.sy >= 6 then + for j = 6, el.sy, 2 do + table.insert(staff3[staff], {kind="line", t=1.2, x1=rx - .2*em, y1=yoffset + (em * (j + 4)) / 2, x2=rx + w + .2*em, y2=yoffset + (em * (j + 4)) / 2}) + end end - end - table.insert(drawables, {kind="glyph", glyph=glyph, x=rx, y=ry}) + table.insert(staff3[staff], {kind="glyph", glyph=glyph, x=rx, y=ry}) - if not el.stemdir and el.length > 1 then - if el.sy <= 0 then - el.stemdir = -1 - else - el.stemdir = 1 + if not el.stemdir and el.length > 1 then + if el.sy <= 0 then + el.stemdir = -1 + else + el.stemdir = 1 + end end - end - -- stem - if el.stemdir then - if el.stemdir == -1 then - -- stem up - -- advance width for bravura is 1.18 - .1 for stem width - el.stemx = w + rx - 1.08 - el.stemy = ry -.168*em - el.stemlen*em - table.insert(drawables, {kind="line", t=1, x1=el.stemx, y1=ry - .168*em, x2=el.stemx, y2=ry -.168*em - el.stemlen*em}) - else - el.stemx = rx + .5 - el.stemy = ry + el.stemlen*em - table.insert(drawables, {kind="line", t=1, x1=el.stemx, y1=ry + .168*em, x2=el.stemx, y2=ry + el.stemlen*em}) + -- stem + if el.stemdir then + if el.stemdir == -1 then + -- stem up + -- advance width for bravura is 1.18 - .1 for stem width + el.stemx = w + rx - 1.08 + el.stemy = ry -.168*em - el.stemlen*em + table.insert(staff3[staff], {kind="line", t=1, x1=el.stemx, y1=ry - .168*em, x2=el.stemx, y2=ry -.168*em - el.stemlen*em}) + else + el.stemx = rx + .5 + el.stemy = ry + el.stemlen*em + table.insert(staff3[staff], {kind="line", t=1, x1=el.stemx, y1=ry + .168*em, x2=el.stemx, y2=ry + el.stemlen*em}) + end end - end - if el.length == 8 and not el.beamed then - if el.stemdir == 1 then - table.insert(drawables, {kind="glyph", glyph=Glyph["flag8thDown"], x=rx, y=ry + 3.5*em}) - else - -- TODO: move glyph extents to a precalculated table or something - local fx, fy = glyph_extents(Glyph["flag8thUp"]) - table.insert(drawables, {kind="glyph", glyph=Glyph["flag8thUp"], x=el.stemx - .48, y=ry -.168*em - 3.5*em}) - x = x + fx + if el.length == 8 and not el.beamed then + if el.stemdir == 1 then + table.insert(staff3[staff], {kind="glyph", glyph=Glyph["flag8thDown"], x=rx, y=ry + 3.5*em}) + else + -- TODO: move glyph extents to a precalculated table or something + local fx, fy = glyph_extents(Glyph["flag8thUp"]) + table.insert(staff3[staff], {kind="glyph", glyph=Glyph["flag8thUp"], x=el.stemx - .48, y=ry -.168*em - 3.5*em}) + x = x + fx + end end + x = x + 100 / el.length + 10 + lasttime = el.time + elseif el.kind == "beam" then + table.insert(staff3[staff], {kind="quad", x1=el.first.stemx - 0.5, y1=el.first.stemy, x2=el.last.stemx, y2=el.last.stemy, x4=el.first.stemx - 0.5, y4=el.first.stemy + 5, x3=el.last.stemx, y3=el.last.stemy + 5}) + elseif el.kind == "barline" then + x = x + 20 + table.insert(staff3[staff], {kind="line", t=1, x1=x + xoffset, y1=yoffset, x2=x + xoffset, y2 = yoffset + 4*em}) + x = x + 20 + elseif el.kind == "clef" then + table.insert(staff3[staff], {kind="glyph", glyph=el.class.glyph, x=xoffset + x, y=yoffset + el.class.yoff}) + x = x + 30 + elseif el.kind == "time" then + -- TODO: draw multidigit time signatures properly + table.insert(staff3[staff], {kind="glyph", glyph=numerals[el.num], x=xoffset + x, y=yoffset + em}) + table.insert(staff3[staff], {kind="glyph", glyph=numerals[el.denom], x=xoffset + x, y=yoffset + 3*em}) + x = x + 30 end - x = x + 100 / el.length + 10 - lasttime = el.time - elseif el.kind == "beam" then - table.insert(drawables, {kind="quad", x1=el.first.stemx - 0.5, y1=el.first.stemy, x2=el.last.stemx, y2=el.last.stemy, x4=el.first.stemx - 0.5, y4=el.first.stemy + 5, x3=el.last.stemx, y3=el.last.stemy + 5}) - elseif el.kind == "barline" then - x = x + 20 - table.insert(drawables, {kind="line", t=1, x1=x + xoffset, y1=yoffset, x2=x + xoffset, y2 = yoffset + 4*em}) - x = x + 20 - elseif el.kind == "clef" then - table.insert(drawables, {kind="glyph", glyph=el.class.glyph, x=xoffset + x, y=yoffset + el.class.yoff}) - x = x + 30 - elseif el.kind == "time" then - -- TODO: draw multidigit time signatures properly - table.insert(drawables, {kind="glyph", glyph=numerals[el.num], x=xoffset + x, y=yoffset + em}) - table.insert(drawables, {kind="glyph", glyph=numerals[el.denom], x=xoffset + x, y=yoffset + 3*em}) - x = x + 30 end end -- calculate extents -local xmin = 0 -local ymin = 0 -local xmax = 0 -local ymax = 0 -for i, d in ipairs(drawables) do - if d.kind == "glyph" then - -- TODO - local w, h = glyph_extents(glyph) - elseif d.kind == "line" then - if d.x1 < xmin then - xmin = d.x1 - elseif d.x1 > xmax then - xmax = d.x1 - end +local extents = {} + +for staff, items in pairs(staff3) do + extents[staff] = {xmin=0, ymin=0, xmax=0, ymax=0} + for i, d in ipairs(items) do + if d.kind == "glyph" then + -- TODO + local w, h = glyph_extents(glyph) + elseif d.kind == "line" then + if d.x1 < extents[staff].xmin then + extents[staff].xmin = d.x1 + elseif d.x1 > extents[staff].xmax then + extents[staff].xmax = d.x1 + end - if d.x2 < xmin then - xmin = d.x2 - elseif d.x2 > xmax then - xmax = d.x2 - end + if d.x2 < extents[staff].xmin then + extents[staff].xmin = d.x2 + elseif d.x2 > extents[staff].xmax then + extents[staff].xmax = d.x2 + end - if d.y1 < ymin then - ymin = d.y1 - elseif d.y1 > ymax then - ymax = d.y1 - end + if d.y1 < extents[staff].ymin then + extents[staff].ymin = d.y1 + elseif d.y1 > extents[staff].ymax then + extents[staff].ymax = d.y1 + end - if d.y2 < ymin then - ymin = d.y2 - elseif d.y2 > ymax then - ymax = d.y2 - end - elseif d.kind == "quad" then - if d.x1 < xmin then - xmin = d.x1 - elseif d.x1 > xmax then - xmax = d.x1 - end + if d.y2 < extents[staff].ymin then + extents[staff].ymin = d.y2 + elseif d.y2 > extents[staff].ymax then + extents[staff].ymax = d.y2 + end + elseif d.kind == "quad" then + if d.x1 < extents[staff].xmin then + extents[staff].xmin = d.x1 + elseif d.x1 > extents[staff].xmax then + extents[staff].xmax = d.x1 + end - if d.x2 < xmin then - xmin = d.x2 - elseif d.x2 > xmax then - xmax = d.x2 - end + if d.x2 < extents[staff].xmin then + extents[staff].xmin = d.x2 + elseif d.x2 > extents[staff].xmax then + extents[staff].xmax = d.x2 + end - if d.y1 < ymin then - ymin = d.y1 - elseif d.y1 > ymax then - ymax = d.y1 - end + if d.y1 < extents[staff].ymin then + extents[staff].ymin = d.y1 + elseif d.y1 > extents[staff].ymax then + extents[staff].ymax = d.y1 + end - if d.y2 < ymin then - ymin = d.y2 - elseif d.y2 > ymax then - ymax = d.y2 - end + if d.y2 < extents[staff].ymin then + extents[staff].ymin = d.y2 + elseif d.y2 > extents[staff].ymax then + extents[staff].ymax = d.y2 + end - if d.x3 < xmin then - xmin = d.x3 - elseif d.x3 > xmax then - xmax = d.x3 - end + if d.x3 < extents[staff].xmin then + extents[staff].xmin = d.x3 + elseif d.x3 > extents[staff].xmax then + extents[staff].xmax = d.x3 + end - if d.x4 < xmin then - xmin = d.x4 - elseif d.x4 > xmax then - xmax = d.x4 - end + if d.x4 < extents[staff].xmin then + extents[staff].xmin = d.x4 + elseif d.x4 > extents[staff].xmax then + extents[staff].xmax = d.x4 + end - if d.y3 < ymin then - ymin = d.y3 - elseif d.y3 > ymax then - ymax = d.y3 - end + if d.y3 < extents[staff].ymin then + extents[staff].ymin = d.y3 + elseif d.y3 > extents[staff].ymax then + extents[staff].ymax = d.y3 + end - if d.y4 < ymin then - ymin = d.y4 - elseif d.y4 > ymax then - ymax = d.y4 + if d.y4 < extents[staff].ymin then + extents[staff].ymin = d.y4 + elseif d.y4 > extents[staff].ymax then + extents[staff].ymax = d.y4 + end end end end -create_surface(xmax - xmin, ymax - ymin) +local xmax = 0 +local yoff = 0 +local xmin = 0 +for staff, extent in pairs(extents) do + if xmin > extent.xmin then + xmin = extent.xmin + end -for i, d in ipairs(drawables) do - if d.kind == "glyph" then - draw_glyph(d.glyph, d.x - xmin, d.y - ymin) - elseif d.kind == "line" then - draw_line(d.t, d.x1 - xmin, d.y1 - ymin, d.x2 - xmin, d.y2 - ymin) - elseif d.kind == "quad" then - draw_quad(d.t, d.x1 - xmin, d.y1 - ymin, d.x2 - xmin, d.y2 - ymin, d.x3 - xmin, d.y3 - ymin, d.x4 - xmin, d.y4 - ymin) + if xmax < extent.xmax then + xmax = extent.xmax end + + extent.yoff = yoff + yoff = yoff + extent.ymax - extent.ymin end +create_surface(xmax - xmin, yoff) + +for staff, extent in pairs(extents) do + for i, d in ipairs(staff3[staff]) do + if d.kind == "glyph" then + draw_glyph(d.glyph, d.x - extent.xmin, d.y - extent.ymin + extent.yoff) + elseif d.kind == "line" then + draw_line(d.t, d.x1 - extent.xmin, d.y1 - extent.ymin + extent.yoff, d.x2 - extent.xmin, d.y2 - extent.ymin + extent.yoff) + elseif d.kind == "quad" then + draw_quad(d.t, d.x1 - extent.xmin, d.y1 - extent.ymin + extent.yoff, d.x2 - extent.xmin, d.y2 - extent.ymin + extent.yoff, d.x3 - extent.xmin, d.y3 - extent.ymin + extent.yoff, d.x4 - extent.xmin, d.y4 - extent.ymin + extent.yoff) + end + end --- draw staff -for y=0,em*4,em do - draw_line(1, xoffset - xmin, y + yoffset - ymin, x + xoffset - xmin, y + yoffset - ymin) + -- draw staff + for y=0,em*4,em do + draw_line(1, xoffset - extent.xmin, y + extent.yoff - extent.ymin + yoffset, x + xoffset - extent.xmin, y + extent.yoff - extent.ymin + yoffset) + end end