<> <> <> DIRECTORY UnifiedFonts, ViewerClasses, ViewerOps, Graphics, Rope, RopeIO, RopeReader, Process, ShowTime, Scaled; UFTextTest: CEDAR MONITOR IMPORTS UnifiedFonts, ViewerOps, Graphics, RopeIO, RopeReader, Process, ShowTime, Scaled = BEGIN leading: NAT _ 2; indent: NAT _ 6; text: Rope.ROPE _ "Quick brown fox, jump over the lazy dogs."; deviceType: ATOM _ $Ideal; fontName: Rope.ROPE _ "Tioga"; size: REAL _ 10.0; rotation: REAL _ 0; viewer: ViewerClasses.Viewer; positioning: UnifiedFonts.Positioning _ rounded; spaceChar: CHAR _ ' ; Load: PROC [fileName: Rope.ROPE] = TRUSTED {text _ RopeIO.FromFile[fileName]; Paint[]}; Paint: PROC = TRUSTED {ViewerOps.PaintViewer[viewer, client]}; CharSeq: TYPE = REF CharSeqRec; CharSeqRec: TYPE = RECORD [ length: NAT _ 0, charWidthPairs: SEQUENCE maxLength: NAT OF CharWidthPair ]; CharWidthPair: TYPE = RECORD [ char: CHAR, width: Scaled.Value ]; buf1: CharSeq _ NEW[CharSeqRec[1030]]; bufAvail: CONDITION; GetBuf: ENTRY PROC RETURNS [b: CharSeq] = {IF buf1 = NIL THEN WAIT bufAvail; b _ buf1; buf1 _ NIL; IF b = NIL THEN b _ NEW[CharSeqRec[1030]]}; FreeBuf: ENTRY PROC [b: CharSeq] = {buf1 _ b; NOTIFY bufAvail}; t, timeForPaint: ShowTime.Microseconds _ 0; painting: BOOLEAN _ TRUE; -- make false to determine formatting time. clippedBottomLine: BOOLEAN _ TRUE; -- make false to eliminate clipped line at bottom TextTestPaint: ViewerClasses.PaintProc = TRUSTED { font: UnifiedFonts.FONT _ UnifiedFonts.Create[fontName, [size, rotation], deviceType]; ropeReader: RopeReader.Ref _ RopeReader.GetRopeReader[]; done: BOOLEAN _ FALSE; charWidths: UnifiedFonts.WidthArray _ font.GetWidthArray[UnifiedFonts.FixedPoint, UnifiedFonts.FixedPoint]; lineWidth: Scaled.Value _ Scaled.FromInt[MAX[self.cw - 2*indent, 5]]; buf: CharSeq _ GetBuf[]; startTime: ShowTime.Microseconds _ ShowTime.GetMark[]; ylimit: REAL _ IF clippedBottomLine THEN (-font.fontBoundingBox.ymax) ELSE (1-font.fontBoundingBox.ymin); ropeReader.SetPosition[text]; ropeReader.SetCharForEndOfRope['\377]; IF NOT clear THEN { Graphics.SetColor[context, Graphics.white]; Graphics.DrawBox[context, [-100000, -100000, 100000, 100000]]; }; Graphics.SetColor[context, Graphics.black]; Graphics.Translate[context, indent, 0]; FOR y: REAL _ self.ch - size, y - size - leading UNTIL y {spaceLoc[numberOfSpaces] _ i; numberOfSpaces _ numberOfSpaces + 1; buf[i] _ [spaceChar, Scaled.zero]; i _ i+1; lastLine _ TRUE; EXIT}; '\n => {spaceLoc[numberOfSpaces] _ i; numberOfSpaces _ numberOfSpaces + 1; buf[i] _ [spaceChar, Scaled.zero]; i _ i+1; EXIT}; ' , '\t => {spaceLoc[numberOfSpaces] _ i; numberOfSpaces _ numberOfSpaces + 1; w _ charWidths[char]; char _ spaceChar}; ENDCASE => w _ charWidths[char]; buf[i] _ [char, w]; totWidth _ totWidth.PLUS[w]; i _ i+1; ENDLOOP; WHILE i>1 AND totWidth.GREATER[lineLength] DO i _ i-1; totWidth _ totWidth.MINUS[buf[i].width]; ENDLOOP; WHILE numberOfSpaces>0 AND spaceLoc[numberOfSpaces-1] > i DO numberOfSpaces _ numberOfSpaces-1 ENDLOOP; IF numberOfSpaces>0 THEN i _ spaceLoc[numberOfSpaces-1]; ropeReader.SetIndex[startIndex + i]; buf.length _ i; }; Create: PROCEDURE RETURNS [viewer: ViewerClasses.Viewer] = TRUSTED { viewer _ ViewerOps.CreateViewer[flavor: $UFTextTest, info: [name: "Text Tester"], paint: TRUE]; }; textTestClass: ViewerClasses.ViewerClass _ NEW[ViewerClasses.ViewerClassRec _ [ paint: TextTestPaint, tipTable: NIL ]]; TRUSTED {ViewerOps.RegisterViewerClass[$UFTextTest, textTestClass]}; TRUSTED {Process.InitializeCondition[@bufAvail, Process.MsecToTicks[500]]}; viewer _ Create[]; END.