DIRECTORY Beam USING [Draw, Grace, InVoice], Chord USING [Draw, Width], Graphics USING [DrawArea, EnterPoint, MoveTo, SetTexture, StartAreaPath], MusicDefs, Note USING [Draw, Width], Real USING [FixI], Sheet USING [FindLine, Height, MapHeight, NextLine], StringDefs USING [AppendDecimal], Utility USING [DrawLine, DrawString, SetFont]; BeamImplB: CEDAR PROGRAM IMPORTS Beam, Chord, Graphics, MusicDefs, Note, Real, Sheet, StringDefs, Utility EXPORTS Beam = BEGIN OPEN Graphics, MusicDefs, Utility; Draw: PUBLIC PROC[b: BeamPTR] RETURNS[INTEGER, INTEGER] = { start: Time; a: BeamArray; slope: REAL _ 5; i, end: CARDINAL; inVoice: BOOL; nonGrace: BOOL _ FALSE; thickness, lineHeight: INTEGER; level, space, s, k, up, d: CARDINAL _ 0; x0, y0, xn, yn, xi, yi, overX: REAL _ 1; j, value, beamValue: NoteValue _ unknown; dotted, oldDotted, stemUp, none: BOOL _ FALSE; IF NOT show.notehead THEN {DrawPhysicalBeam[b]; RETURN[0, 0]}; IF NOT b.beamed THEN { DrawNTuple[b]; RETURN[0, 0]; }; start _ b.sync1.time; [x0, y0] _ Sheet.MapHeight[b.sync1.time, b.height+Sheet.Height[b.sync1.time,, b.staff]]; overX _ sheet[Sheet.FindLine[b.sync2.time]].x; inVoice _ ~(voice AND NOT Beam.InVoice[b, selectedVoice]); IF b.tilt > -x0/slope AND b.tilt < x0/slope THEN space _ 5 ELSE space _ 7; IF Beam.Grace[b] THEN {space _ space-2; thickness _ 1} ELSE thickness _ 2; FOR i IN [0..beamLength) DO IF b.chord[i] = endOfBeam THEN { a[i].dotted _ FALSE; end _ i; EXIT; }; WITH n: b.chord[i] SELECT FROM note => { IF show.display#graphical THEN n.n.delta _ 0; IF i=0 THEN start _ start + n.n.delta + (IF n.n.stemUp THEN Note.Width[n.n] ELSE 0); IF i=0 THEN x0 _ x0 + n.n.delta + (IF n.n.stemUp THEN Note.Width[n.n] ELSE 0); a[i].x _ n.n.sync.time - start + n.n.delta; IF n.n.stemUp THEN a[i].x _ a[i].x + Note.Width[n.n]; a[i].y _ y0 + b.tilt*a[i].x; a[i].value _ n.n.value; a[i].stemUp _ n.n.stemUp; a[i].dotted _ n.n.dotted; }; chord=> { IF show.display#graphical THEN n.c.delta _ 0; IF i=0 THEN start _ start + n.c.delta + (IF n.c.stemUp THEN Chord.Width[n.c] ELSE 0); IF i=0 THEN x0 _ x0 + n.c.delta + (IF n.c.stemUp THEN Chord.Width[n.c] ELSE 0); a[i].x _ n.c.note[0].sync.time - start + n.c.delta; IF n.c.stemUp THEN a[i].x _ a[i].x + Chord.Width[n.c]; a[i].y _ y0 + b.tilt*a[i].x; a[i].value _ n.c.note[0].value; a[i].stemUp _ n.c.stemUp; a[i].dotted _ n.c.note[0].dotted; }; beam => { x: Time _ 0; WITH ev: n.b.chord[0] SELECT FROM note => IF (a[i].stemUp _ ev.n.stemUp) THEN x _ Note.Width[ev.n]; chord => IF (a[i].stemUp _ ev.c.stemUp) THEN x _ Chord.Width[ev.c]; ENDCASE; IF i=0 THEN start _ start +x; IF i=0 THEN x0 _ x0 + x; a[i].x _ n.b.sync1.time - start+x; a[i].y _ y0 + b.tilt*a[i].x; a[i].value _ eighth; a[i].dotted _ FALSE; n.b.tilt _ b.tilt; n.b.staff _ b.staff; n.b.height _ Real.FixI[b.height+a[i].y-y0]; IF i#beamLength-1 AND b.chord[i+1]#endOfBeam THEN LOOP; FOR j: CARDINAL IN [0..beamLength) DO IF n.b.chord[j]=endOfBeam THEN EXIT; WITH ev: n.b.chord[j] SELECT FROM note => IF ev.n.stemUp THEN x _ 8 ELSE x _ 0; chord => IF ev.c.stemUp THEN x _ 8 ELSE x _ 0; ENDCASE; ENDLOOP; a[i].stemUp _ (x#0); a[i].x _ n.b.sync2.time- start+ x; a[i].y _ y0 + b.tilt*a[i].x; }; ENDCASE; ENDLOOP; i _ Sheet.FindLine[b.sync1.time]; lineHeight _ sheet[i].y-sheet[Sheet.NextLine[i]].y; FOR j IN [eighth..unknown) DO none _ TRUE; FOR i IN [0..end) DO IF none THEN IF a[i].value>=j THEN { none _ FALSE; s _ i; } ELSE LOOP; IF (i=j) THEN LOOP; up _ d _ 0; FOR k IN [s..i] DO IF a[k].stemUp THEN up _ up+1 ELSE d _ d+1; ENDLOOP; stemUp _ (up>d); xn _ a[i].x + x0; yn _ a[i].y; xi _ a[s].x + x0; none _ TRUE; IF xi=xn THEN SELECT TRUE FROM -- half beam i=0 => {xn _ xn+10; yn _ yn+b.tilt*10}; i=end-1 => xi _ xi-10; a[i-1].value {xn _ xn+10; yn _ yn+b.tilt*10}; a[i-1].value>a[i+1].value => xi _ xi-10; a[i+1].dotted => {xn _ xn+10; yn _ yn+b.tilt*10}; ENDCASE => xi _ xi-10; IF stemUp THEN yn _ yn - space*level ELSE yn _ yn + space*level; yi _ yn + b.tilt*(xi-xn); Graphics.SetTexture[context, IF inVoice THEN black ELSE light]; DrawClippedRect[xi, yi, xn-1, yn, overX, b.tilt, thickness, lineHeight]; FOR k IN [s..i] DO IF a[k].value#j THEN LOOP; IF a[k].stemUp=TRUE AND stemUp=FALSE THEN a[k].y _ a[k].y + space*level; IF a[k].stemUp=FALSE AND stemUp=TRUE THEN a[k].y _ a[k].y - space*level; yi _ a[k].y; IF a[k].stemUp AND a[k].x+x0>=staffLength+8 OR NOT a[k].stemUp AND a[k].x+x0>=staffLength THEN yi _ a[k].y - lineHeight; IF ~print AND AnyBug[] THEN RETURN[0, 0]; -- impatient user WITH ev: b.chord[k] SELECT FROM note => Note.Draw[ev.n, Real.FixI[yi]]; chord=> Chord.Draw[ev.c, Real.FixI[yi]]; beam=> [] _ Beam.Draw[ev.b]; ENDCASE; ENDLOOP; ENDLOOP; level _ level+1; ENDLOOP; IF b.ntuple#0 AND ~(print AND b.invisible) THEN { string: STRING _ [10]; IF xnstaffLength THEN { xi _ xi-staffLength; y0 _ y0-lineHeight; }; MoveTo[context,[xi, y0]]; StringDefs.AppendDecimal[string, b.ntuple]; SELECT TRUE FROM b.invisible => Graphics.SetTexture[context, grey]; inVoice => Graphics.SetTexture[context, black]; ENDCASE => Graphics.SetTexture[context, light]; SetFont[context, text, 12]; DrawString[context, string]; SetFont[context, music, 8]; }; RETURN[i, i]; }; BeamArray: TYPE = ARRAY [0..beamLength) OF BeamRecord; BeamRecord: TYPE = RECORD[value: NoteValue, stemUp, dotted: BOOL, x, y: REAL]; DrawNTuple: PROC[b: BeamPTR] = { inVoice: BOOL; x, y, x1, y1: INTEGER; height1, height2, i, j: INTEGER _ beamLength; up0, upN: BOOL; string: STRING _ [10]; IF print AND b.invisible THEN RETURN; inVoice _ ~(voice AND NOT Beam.InVoice[b, selectedVoice]); height1 _ b.height+Sheet.Height[0,, b.staff]; [x, y] _ Sheet.MapHeight[b.sync1.time, height1]; [x1,] _ Sheet.MapHeight[b.sync2.time, height1]; y1 _ Real.FixI[y+ b.tilt*(x1+12-x)]; height2 _ Real.FixI[height1+y1-y]; SELECT TRUE FROM b.invisible => Graphics.SetTexture[context, grey]; inVoice => Graphics.SetTexture[context, black]; ENDCASE => Graphics.SetTexture[context, light]; DrawLine[x-2, y, x1+10, y1]; WITH n: b.chord[0] SELECT FROM note => up0 _ (Sheet.Height[n.n.sync.time, n.n.pitch, n.n.staff]>height1); chord=> up0 _ (Sheet.Height[n.c.note[0].sync.time, n.c.note[0].pitch, n.c.note[0].staff]>height1); beam => up0 _ (n.b.height+Sheet.Height[n.b.sync1.time,, n.b.staff]>height1); ENDCASE; FOR i IN [0..beamLength) DO IF b.chord[i]=endOfBeam THEN { j _ i; EXIT; }; ENDLOOP; IF j#0 THEN j _ j-1; WITH n: b.chord[j] SELECT FROM note => upN _ (Sheet.Height[n.n.sync.time, n.n.pitch, n.n.staff]>height2); chord=> upN _ (Sheet.Height[n.c.note[0].sync.time, n.c.note[0].pitch, n.c.note[0].staff]>height2); beam => upN _ (n.b.height+Sheet.Height[n.b.sync1.time,, n.b.staff]>height2); ENDCASE; IF up0 THEN DrawLine[x-2, y, x-2, y+4] ELSE DrawLine[x-2, y, x-2, y-4]; IF upN THEN DrawLine[x1+10, y1, x1+10, y1+4] ELSE DrawLine[x1+10, y1, x1+10, y1-4]; FOR i IN [0..beamLength) DO IF b.chord[i]=endOfBeam THEN EXIT; WITH n: b.chord[i] SELECT FROM note => Note.Draw[n.n]; chord=> Chord.Draw[n.c]; beam => [] _ Beam.Draw[n.b]; ENDCASE; ENDLOOP; MoveTo[context,[(x+x1)/2, y+b.tilt*(x1-x)/2+(IF up0 THEN -15 ELSE 5)]]; SELECT TRUE FROM b.invisible => Graphics.SetTexture[context, grey]; inVoice => Graphics.SetTexture[context, black]; ENDCASE => Graphics.SetTexture[context, light]; StringDefs.AppendDecimal[string, b.ntuple]; SetFont[context, text, 12]; DrawString[context, string]; SetFont[context, music, 8]; }; DrawPhysicalBeam: PROC[b: BeamPTR] = { i: CARDINAL; FOR i IN [0..beamLength) DO IF b.chord[i] = endOfBeam THEN EXIT; WITH ev: b.chord[i] SELECT FROM note => Note.Draw[ev.n]; chord=> Chord.Draw[ev.c]; beam => DrawPhysicalBeam[ev.b]; ENDCASE; ENDLOOP; }; DrawClippedRect: PROC[x0, y0, xn, yn, delta: REAL, tilt: REAL, thickness, lineHeight: INTEGER] = { xi: REAL _ xn; yi: REAL _ yn; clip: BOOL; clip _ x0staffLength; IF clip THEN { xi _ staffLength; yi _ y0 + tilt*(xi-x0); }; IF x0> staffLength THEN { y0 _ y0 - lineHeight; yi _ yi - lineHeight; x0 _ x0 - staffLength+ delta; xi _ xi - staffLength+ delta; }; StartAreaPath[context]; EnterPoint[context,[x0, y0-thickness]]; EnterPoint[context,[x0, y0+thickness]]; EnterPoint[context,[xi+1, yi+thickness]]; EnterPoint[context,[xi+1, yi-thickness]]; DrawArea[context]; IF NOT clip THEN RETURN; xi _ delta; xn _ xn - staffLength+ delta; yn _ yn - lineHeight; yi _ yn - tilt*(xn-xi); StartAreaPath[context]; EnterPoint[context,[xi, yi+thickness]]; EnterPoint[context,[xi, yi-thickness]]; EnterPoint[context,[xn+1, yn-thickness]]; EnterPoint[context,[xn+1, yn+thickness]]; DrawArea[context]; }; Drawn: PUBLIC PROC[b: BeamPTR] RETURNS[BOOL] = { i: CARDINAL; IF b=NIL THEN FOR i IN [0..3) DO beamQueue[i] _ NIL; ENDLOOP; IF b=NIL THEN RETURN[FALSE]; FOR i IN [0..3) DO IF beamQueue[i]=b THEN RETURN[TRUE]; ENDLOOP; beamIndex _ beamIndex+1; IF beamIndex = 3 THEN beamIndex _ 0; beamQueue[beamIndex] _ b; RETURN[FALSE]; }; beamQueue: ARRAY [0..3) OF BeamPTR; beamIndex: CARDINAL _ 0; END. ÎBeamImplB.mesa Copyright (C) 1981, 1984 Xerox Corporation. All rights reserved. Author: John Maxwell last modified: December 11, 1981 9: 03 AM Edited by Doug Wyatt, June 14, 1984 3:34:20 pm PDT **************************************************************************** displaying beams **************************************************************************** first we figure out where everything is going to be then we draw the beams and components Ê µ˜šœ™Jšœ@™@Jšœ™Jšœ*™*J™2J˜—šÏk ˜ Jšœœ˜"Jšœœ˜Jšœ œ;˜IJ˜ Jšœœ˜Jšœœ˜Jšœœ)˜4Jšœ œ˜!Jšœœ!˜.J˜—Jšœ œ˜JšœJ˜QJšœ˜ Jšœœœ˜*J˜JšœL™LJšœ™JšœL™LJ˜š Ïnœœœ œœœ˜;J˜ J˜ Jšœœ˜Jšœœ˜Jšœ œ˜Jšœ œœ˜Jšœœ˜Jšœœ˜(Jšœœ˜(J˜)Jšœ!œœ˜.Jšœœœœ˜>Jšœœ œœ ˜6J˜J˜XJ˜.Jšœœœ"˜;Jšœœœ œ ˜JJšœœ"œ˜JJšœ3™3šœœ˜šœœ˜Jšœœ œ˜(—šœœ˜šœ ˜ Jšœœ˜-Jš œœœ œœ˜TJš œœœ œœ˜NJ˜+Jšœ œ#˜5J˜J˜J˜J˜Jšœ˜—šœ ˜ Jšœœ˜-Jš œœœ œœ˜UJš œœœ œœ˜OJ˜3Jšœ œ$˜6J˜J˜!J˜J˜!Jšœ˜—šœ˜šœœ˜!Jšœœœ˜BJšœ œœ˜CJšœ˜—Jšœœ˜Jšœœ ˜J˜"J˜J˜Jšœœ˜J˜J˜J˜-Jšœœœœ˜7šœœœ˜%Jšœœœ˜$šœœ˜!Jšœœ œœ˜-Jšœ œ œœ˜.Jšœ˜—Jšœ˜—J˜J˜"J˜Jšœ˜——šœ˜Jšœ˜——Jšœ%™%J˜!J˜4šœœ˜Jšœœ˜ Jšœœ ˜šœœœ˜Jšœ œ ˜Jšœœ˜ —Jš œ œ œ œœœ˜EJ˜ Jšœœœœ œ œ œ˜GJ˜J˜1Jšœœ˜ š œœœœœÏc ˜+J˜'J˜J˜=J˜(J˜1Jšœ˜—Jšœœœ˜@J˜Jšœœ œœ˜?J˜Hšœœ˜Jšœœœ˜š œ œœœ˜)J˜—š œ œœœ˜)J˜—J˜ šœ œ˜.Jšœ œ˜*Jšœ˜—Jš œœ œœŸ˜<šœœ˜J˜'J˜(J˜Jšœ˜—Jšœ˜—Jšœ˜J˜—Jšœ˜šœ œ œ˜/Jšœ˜Jšœœ˜Jšœœ˜"J˜Jšœ"œœœ˜>Jšœœ.˜DJ˜J˜+šœœ˜J˜2J˜/Jšœ(˜/—J˜J˜J˜Jšœ˜—Jšœ˜ Jšœ˜—J˜Jšœ œœœ ˜6Jš œ œœ#œœ˜NJ˜šž œœ˜ Jšœ œ˜Jšœœ˜Jšœœ˜-Jšœ œ˜Jšœœ˜Jšœœ œœ˜%Jšœœœ!˜:J˜-J˜0J˜/J˜$J˜"šœœ˜J˜2J˜/Jšœ(˜/—J˜šœœ˜J˜JJ˜bJ˜LJšœ˜—šœœ˜Jšœœœ œ˜1Jšœ˜—Jšœœ ˜šœœ˜J˜JJ˜bJ˜LJšœ˜—šœœ˜&Jšœ˜ —šœœ!˜,Jšœ"˜&—šœœ˜Jšœœœ˜"šœœ˜J˜J˜J˜Jšœ˜—Jšœ˜—Jšœ-œœœ˜Gšœœ˜J˜2J˜/Jšœ(˜/—J˜+J˜J˜J˜Jšœ˜—J˜šžœœ˜&Jšœœ˜ šœœ˜Jšœœœ˜$šœœ˜J˜J˜J˜Jšœ˜—Jšœ˜—Jšœ˜—J˜šžœœœ˜2Jšœœœ˜/Jšœœ˜Jšœœ˜Jšœœ˜ Jšœœ˜)Jšœœ/˜;šœ˜šœ.˜.J˜J˜Jšœ˜——J˜J˜'J˜'J˜)J˜)J˜Jšœœœœ˜J˜ J˜J˜J˜J˜J˜'J˜'J˜)J˜)J˜Jšœ˜—J˜š žœœœ œœ˜0Jšœœ˜ Jšœœœœœœœœ˜=Jš œœœœœ˜šœœœ˜Jš œœœœœ˜-—J˜Jšœœ˜$J˜Jšœœ˜Jšœ˜—J˜Jšœ œœ ˜#Jšœ œ˜J˜Jšœ˜—…—#ž0!