<> <> << Ades, April 30, 1986 10:09:49 am PDT>> <<>> <> <<>> DIRECTORY Rope USING [ROPE], Basics USING [BYTE], Imager USING [Context, Move, ShowChar, SetStrokeWidth, SetStrokeJoint, MaskStroke, SetXY, ShowRope, SetFont, black, SetColor], ImagerFont USING [Extents, Width, Font], ImagerPath USING [PathProc], TextNode USING [Location], NodeStyle USING [Ref], NodeStyleOps USING [OfStyle], TEditFormatExtras USING [CharacterArtwork, CharacterArtworkRep, CharacterArtworkClass, CharacterArtworkClassRep, RegisterCharacterArtwork, GetFont], TextEdit USING [FetchChar, CharSet, GetCharProp], Vector2 USING [VEC], VoiceMarkers USING [voiceMarkerFont, voiceCharSet, voiceCharHeight, voiceCharDescent]; TextInVoiceImpl: CEDAR PROGRAM IMPORTS Imager, ImagerFont, TEditFormatExtras, TextEdit, VoiceMarkers = BEGIN VoiceMarkerDataRep: TYPE ~ RECORD [ letter: CHAR, label: Rope.ROPE, charHeight: REAL, charWidth: REAL ]; VoiceMarkerPaint: PROC [self: TEditFormatExtras.CharacterArtwork, context: Imager.Context] ~ { data: REF VoiceMarkerDataRep ~ NARROW[self.data]; DrawArrow: ImagerPath.PathProc = { moveTo[[0.0, 2.0*data.charHeight]]; lineTo[[0.0, data.charHeight]]; lineTo[[3.0, 4.0*data.charHeight/3.0]]; lineTo[[-2.0, 4.0*data.charHeight/3.0]]; lineTo[[0.0, data.charHeight]] }; Imager.Move[context]; Imager.ShowChar[context, data.letter]; Imager.SetColor[context, Imager.black]; Imager.SetStrokeWidth[context, 1.0]; Imager.SetStrokeJoint[context, round]; Imager.MaskStroke[context, DrawArrow, TRUE]; Imager.SetXY[context, [2.0, 3.0*data.charHeight/2.0]]; Imager.SetFont[context, VoiceMarkers.voiceMarkerFont]; Imager.ShowRope[context, data.label]; }; VoiceMarkerFormat: PROC [class: TEditFormatExtras.CharacterArtworkClass, loc: TextNode.Location, style: NodeStyle.Ref, kind: NodeStyleOps.OfStyle] RETURNS [TEditFormatExtras.CharacterArtwork] ~ { voiceCharSet: TextEdit.CharSet _ TextEdit.FetchChar[loc.node, loc.where].charSet; letter: CHAR _ TextEdit.FetchChar[loc.node, loc.where].char; label: Rope.ROPE _ NARROW[TextEdit.GetCharProp[loc.node, loc.where, $VoiceMark], Rope.ROPE]; escapement: Vector2.VEC _ ImagerFont.Width[TEditFormatExtras.GetFont[style], [set: VoiceMarkers.voiceCharSet, code: letter-'\000]]; charWidth: REAL _ escapement.x; data: REF VoiceMarkerDataRep ~ NEW[VoiceMarkerDataRep _ [ letter: letter, label: label, charHeight: VoiceMarkers.voiceCharHeight, charWidth: charWidth ]]; extents: ImagerFont.Extents _ [leftExtent: 0.0, rightExtent: 20.0, ascent: 5.0*data.charHeight/2.0, descent: VoiceMarkers.voiceCharDescent]; RETURN [NEW[TEditFormatExtras.CharacterArtworkRep _ [paint: VoiceMarkerPaint, extents: extents, escapement: escapement, data: data]]] }; talksBubbleClass: TEditFormatExtras.CharacterArtworkClass ~ NEW[TEditFormatExtras.CharacterArtworkClassRep _ [ name: $VoiceMarker, format: VoiceMarkerFormat, data: NIL ]]; TEditFormatExtras.RegisterCharacterArtwork[talksBubbleClass]; END.