UFSample:
CEDAR PROGRAM
IMPORTS UnifiedFonts, ViewerOps, Graphics, GraphicsColor, Rope, Real
= BEGIN
ComplexNumber: TYPE = RECORD [x,y: REAL];
ComplexMul: PROCEDURE [a, b: ComplexNumber] RETURNS [ComplexNumber] = {RETURN[[(a.x*b.x - a.y*b.y), (a.x*b.y + a.y*b.x)]]};
Create:
PROCEDURE
RETURNS [viewer: ViewerClasses.Viewer] =
TRUSTED {
viewer ← ViewerOps.CreateViewer[flavor: $UFSampler, info: [name: "Font Sampler"], paint: TRUE];
};
baseline: NAT ← 40;
scale: REAL ← 1.0;
indent: NAT ← 6;
text: Rope.ROPE ← "Quick brown fox, jump over the lazy dogs.";
defaultFontName: Rope.ROPE ← "Xerox/NS/Times/italic/body";
defaultSize: REAL ← 10.0;
defaultRotation: REAL ← 0;
drawingBoundingBoxes, drawingDesignBoxes, drawingWidths: BOOLEAN ← FALSE;
boundingBoxColor: Graphics.Color ← GraphicsColor.HSVToColor[.1, .7, .85];
designBoxColor: Graphics.Color ← GraphicsColor.HSVToColor[.8, .6, .4];
widthVectorColor: Graphics.Color ← GraphicsColor.HSVToColor[.6, .6, .1];
font: UnifiedFonts.FONT;
viewer: ViewerClasses.Viewer;
path: Graphics.Path ← Graphics.NewPath[5];
deviceType: ATOM ← $Ideal;
Font:
PROC [fontName: Rope.
ROPE, size:
REAL ← -1.0, rotation:
REAL ← -360.0] = {
IF fontName.Length[]=0 THEN fontName ← defaultFontName;
defaultFontName ← fontName;
IF size=-1.0 THEN size ← defaultSize;
defaultSize ← size;
IF rotation=-360.0 THEN rotation ← defaultRotation;
defaultRotation ← rotation;
font ← UnifiedFonts.Create[fontName, [size, rotation], deviceType];
TRUSTED {ViewerOps.PaintViewer[viewer, client]};
};
SamplePaint: ViewerClasses.PaintProc = {
paintChar:
PROC [c:
CHAR]
RETURNS [quit:
BOOL ←
FALSE] = {
IF drawingBoundingBoxes
THEN {
mark: Graphics.Mark ← Graphics.Save[context];
Graphics.SetColor[context, boundingBoxColor];
Graphics.Translate[context, Graphics.GetCP[context].x, Graphics.GetCP[context].y];
Graphics.DrawBox[context, font.BoundingBox[c]];
Graphics.Restore[context, mark];
};
IF drawingDesignBoxes
THEN {
box: Graphics.Box ← font.FormattingBox[c];
mark: Graphics.Mark ← Graphics.Save[context];
Graphics.SetColor[context, designBoxColor];
Graphics.Translate[context, Graphics.GetCP[context].x, Graphics.GetCP[context].y];
Graphics.Rotate[context, defaultRotation];
BEGIN
OPEN box;
Graphics.SetCP[context, xmin, 0];
Graphics.DrawTo[context, xmin+.55, 0];
Graphics.SetCP[context, xmin, 0];
Graphics.DrawTo[context, xmin, ymin];
Graphics.DrawTo[context, xmax, ymin];
Graphics.DrawTo[context, xmax, 0];
Graphics.DrawTo[context, xmax-0.55, 0];
Graphics.SetCP[context, xmax, 0];
Graphics.DrawTo[context, xmax, ymax];
Graphics.DrawTo[context, xmin, ymax];
Graphics.DrawTo[context, xmin, 0];
Graphics.Restore[context, mark];
END;
};
Graphics.SetColor[context, Graphics.black];
font.DrawChar[c, context];
IF drawingWidths
THEN {
w,d,e: ComplexNumber;
wx, wy, s: REAL;
mark: Graphics.Mark ← Graphics.Save[context];
[[wx, wy]] ← font.WidthVector[c];
s ← Real.SqRt[wx*wx+wy*wy]/2;
Graphics.Translate[context, Graphics.GetCP[context].x, Graphics.GetCP[context].y];
Graphics.FlushPath[path];
Graphics.MoveTo[path, -wx, -wy];
Graphics.DrawStroke[context, path, IF scale>5 THEN 10/scale ELSE 2, FALSE, round];
Graphics.LineTo[path, 0, 0];
Graphics.DrawStroke[context, path, 0, FALSE, round];
Graphics.FlushPath[path];
w ← [-wx/s, -wy/s]; d ← ComplexMul[w,[1,1]]; e ← ComplexMul[w,[1,-1]];
Graphics.MoveTo[path, d.x, d.y];
Graphics.LineTo[path, 0, 0];
Graphics.LineTo[path, e.x, e.y];
Graphics.DrawStroke[context, path, 0, FALSE, round];
Graphics.Restore[context, mark];
};
};
IF
NOT clear
THEN {
Graphics.SetColor[context, Graphics.white];
Graphics.DrawBox[context, [-100000, -100000, 100000, 100000]];
};
Graphics.Translate[context, indent, self.ch];
Graphics.Scale[context, scale, scale];
Graphics.Translate[context, 0, -baseline];
Graphics.SetCP[context, 0, 0];
IF font # NIL THEN [] ← Rope.Map[base: text, action: paintChar];
};
samplerClass: ViewerClasses.ViewerClass ←
NEW[ViewerClasses.ViewerClassRec ← [
paint: SamplePaint,
tipTable: NIL
]];
TRUSTED {ViewerOps.RegisterViewerClass[$UFSampler, samplerClass]};
viewer ← Create[];
END.