TextInVoiceImpl.mesa:
it's all getting so recursive !!!! - routines which draw the artwork around voice viewers; that artwork is actually a textual display
Ades, April 30, 1986 10:09:49 am PDT
although the extents and positions of text in artworks are given in terms of constants from VoiceMarkers, note that the line spacing is set up independently by VoiceProfile.Style
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.