<> <> <> <> <> DIRECTORY Beam USING [Drawn], Event USING [Adjust, Draw, GetScoreIndex], Graphics USING [Context, DrawBox, DrawChar, GetBounds, SetCP, SetStipple], MusicDefs, Note USING [DrawTie, InVoice], Piece USING [NearestEvent], Score USING [Draw, GetKey, Justify, LogicalToPhysical, ScalePhysical, SetStyle, ShowPitch], Selection USING [Draw, selection], Sheet USING [default, Draw, FindSection, FindStaves, Height, HiLite, MapNote, Scale, SetBegin]; ScoreImplB: CEDAR PROGRAM IMPORTS Beam, Graphics, MusicDefs, Note, Piece, Score, Selection, Sheet, Event EXPORTS Score = BEGIN OPEN MusicDefs; <<****************************************************************************>> <> <<****************************************************************************>> Draw: PUBLIC PROC[score: ScorePTR, erase: BOOLEAN] = { sheet: SheetPTR _ score.sheet; Selection.Draw[]; -- remove selection from screen IF erase THEN { SetBrush[score, white, opaque]; Graphics.DrawBox[sheet.context, Graphics.GetBounds[sheet.context]]; SetBrush[score, black, transparent]; Sheet.Draw[sheet]}; DrawInterval[score, sheet.begin, sheet.endTime]; Selection.Draw[]; }; Redraw: PUBLIC PROC[score: ScorePTR, t1, t2: Time] = { x, y: INTEGER; select: BOOLEAN; selection: SelectionPTR _ Selection.selection; SetBrush[score, black, transparent]; SELECT score.sheet.scale FROM 1 => IF t2-t1 > 700 THEN {Score.Draw[score]; RETURN}; 2 => IF t2-t1 > 2000 THEN {Score.Draw[score]; RETURN}; 4 => IF t2-t1 > 8000 THEN {Score.Draw[score]; RETURN}; ENDCASE; select _ selection.lineSelect AND selection.select2 > t1-40 AND selection.select1 < t2+50; IF select THEN Selection.Draw[]; -- remove selection from screen Sheet.HiLite[score.sheet, white, t1-20, t2+30]; DrawInterval[score, t1-30, t2+40]; IF select THEN Selection.Draw[]; IF selection.lineSelect THEN RETURN; SetBrush[score, black, invert]; FOR i: CARDINAL IN [0..selection.length) DO IF selection.note[i] = NIL THEN LOOP; IF selection[i].sync.time > t2+40 OR selection[i].sync.time < t1-30 THEN LOOP; IF ~Note.InVoice[selection[i], score.sheet.voice] THEN LOOP; [x, y] _ Sheet.MapNote[score.sheet, selection[i]]; Graphics.SetCP[score.sheet.context, x, y]; Graphics.DrawChar[score.sheet.context, 170C]; ENDLOOP; }; DrawInterval: PROC[score: ScorePTR, t1, t2: Time] = { n: NotePTR; staves: StavesPTR; j: CARDINAL _ 0; sheet: SheetPTR _ score.sheet; [] _ Beam.Drawn[score, NIL]; -- clears the beam cache SetBrush[score, black, transparent]; <> staves _ Sheet.FindStaves[sheet, t1]; FOR i: CARDINAL IN [0..staves.length) DO IF staves.staff[i].pitch # 15 AND staves.staff[i].pitch # 60 THEN LOOP; FOR j: CARDINAL DECREASING IN [0..score.length) DO IF score.event[j].time >= t1 THEN LOOP; IF score.event[j].type # staves THEN LOOP; WITH score.event[j] SELECT FROM ev: StavesPTR => { IF ev.staves NOT IN [octava1..octava2] THEN LOOP; IF ev.value # i THEN LOOP; IF ev.staves = octava2 THEN EXIT}; ENDCASE => ERROR; Event.Draw[score, score.event[j]]; EXIT; ENDLOOP; ENDLOOP; <> j _ 0; IF score.sheet.display = graphical THEN FOR i: CARDINAL IN [0..score.length) DO IF score.event[i].time < t1 THEN LOOP; IF score.event[i].time > t2 THEN EXIT; IF score.event[i].type = sync THEN { IF j = 10 THEN EXIT ELSE j _ j+1; Event.Adjust[score, NARROW[score.event[i]]]}; ENDLOOP; <> j _ 0; FOR i: CARDINAL IN [0..score.length) DO IF score.event[i].time < t1 THEN LOOP; IF score.event[i].time > t2 THEN {j _ i; EXIT}; IF score.sheet.display = graphical THEN { plus10: CARDINAL _ MIN[i+10, score.length-1]; IF score.event[plus10].type = sync THEN Event.Adjust[score, NARROW[score.event[plus10]]]}; Event.Draw[score, score.event[i]]; <> ENDLOOP; <> IF j # 0 THEN FOR i: CARDINAL IN [j..score.length) DO IF score.event[i].time > t2+200 THEN EXIT; WITH score.event[i] SELECT FROM sync: SyncPTR => { FOR j: CARDINAL IN [0..sync.length) DO IF (n _ sync.note[j]) = NIL THEN EXIT; IF n.tie = NIL THEN LOOP; IF n.tie.sync.time > t2 THEN LOOP; IF ~Note.InVoice[n, score.sheet.voice] THEN Graphics.SetStipple[score.sheet.context, light] ELSE Graphics.SetStipple[score.sheet.context, black]; Note.DrawTie[score, n]; ENDLOOP; }; ENDCASE; ENDLOOP; [] _ Beam.Drawn[score, NIL]; }; <<****************************************************************************>> <> <<****************************************************************************>> Print: PUBLIC PROC[score: ScorePTR, splines: BOOLEAN] = {}; <<****************************************************************************>> <> <<****************************************************************************>> Look: PUBLIC PROC[score: ScorePTR, look: LookCommand, switch: BOOLEAN, n: INTEGER] = { < IF score = old THEN score _ new;>> draw: BOOLEAN _ TRUE; SELECT look FROM accidental => score.sheet.accidental _ switch; hardcopy => { Sheet.Scale[score, IF switch THEN 2 ELSE 1]; score.sheet.hardcopy _ switch}; justified => { score.sheet.density _ n; Score.Justify[score, Selection.selection.select1, Selection.selection.select2]}; logical => Score.LogicalToPhysical[score, Selection.selection.select1, Selection.selection.select2]; noCarry => score.sheet.noCarry _ switch; notehead => score.sheet.notehead _ switch; overview => Overview[score, switch]; physical => Score.ScalePhysical[score, 512/n]; style => Score.SetStyle[score, n, 0, EndOfScore[score]]; sync => score.sheet.sync _ switch; voice => {score.sheet.voice _ IF ~switch THEN noVoice ELSE n}; ENDCASE; }; Overview: PROC[score: ScorePTR, switch: BOOLEAN] = { <> <> SELECT TRUE FROM score.sheet.scale < 4 AND ~switch => {score.flash _ TRUE; RETURN}; score.sheet.scale > 2 AND switch => {score.flash _ TRUE; RETURN}; switch => {Sheet.Scale[score, 4]; Sheet.SetBegin[score.sheet, 0]}; < {>> <<[x, y] _ Sheet.ScreenPoint[score.sheet];>> <