DIRECTORY Imager, ImagerBasic USING [PixelArray, PathMapType], ImagerTransform USING [InverseTransform, Contents, Transform], ImagerPD USING[PDFileDescription, PDFileDescriptionRep, Hornet], PDFileFormat, Real USING [Fix], SampledColors USING[bitmap, DrawImage], Font USING [CreateScaled, FONT, Box, FormattingBox], Rope USING [ROPE, Cat, Substr], Convert USING [RopeFromInt], FS USING [ExpandName, ComponentPositions, StreamOpen], IO USING [time, rope, real, int, PutFR, Close, PutRope, STREAM], ImagerPrivate, BasicTime, PrintFonts, SDtoSF USING[PathToStream], PrintFontsPrivate; PrintFontsImpl: CEDAR PROGRAM IMPORTS Imager, SampledColors, Rope, ImagerTransform, Real, Font, Convert, ImagerPD, FS, IO, BasicTime, PrintFontsPrivate, SDtoSF EXPORTS PrintFonts = BEGIN OPEN PrintFonts; ROPE: TYPE = Rope.ROPE; PrivateFont: TYPE = PrintFontsPrivate.PrivateFont; doChars: BOOLEAN _ TRUE; currentWD: ROPE _ "///PD/"; PrintSFFile: PUBLIC PROC[name: ROPE, device: DeviceType, pointSize, scale: REAL] RETURNS [pd: ROPE] = { sfFont: PrivateFont; base, wdir, label, pdFile: ROPE; devicePts: REAL; ctx: Imager.Context; [base, wdir] _ GetName[name]; [ctx, pdFile] _ OpenPD[base, device]; IF pointSize=0 THEN devicePts _ 1 --special for fonts generated "at size`' ELSE [[devicePts, ]] _ ImagerTransform.Transform[[pointSize, 1],ctx.state.T]; sfFont _ PrintFontsPrivate.LoadSF[Rope.Cat[wdir,base,".sf"], devicePts]; label _ IO.PutFR["%g.sf, scale=%g, time= %g", IO.rope[base], IO.real[scale], IO.time[]]; PrintPages[label, sfFont, device, ctx, scale]; RETURN[pdFile] }; PrintSDFile: PUBLIC PROC[name: ROPE, device: DeviceType, pointSize, scale: REAL] RETURNS [pd: ROPE] = { sdFont: PrivateFont; base, wdir, label, pdFile: ROPE; devicePts: REAL; ctx: Imager.Context; [base, wdir] _ GetName[name]; [ctx, pdFile] _ OpenPD[base, device]; IF pointSize=0 THEN devicePts _ 1 --special for fonts generated "at size`' ELSE [[devicePts, ]] _ ImagerTransform.Transform[[pointSize, 1],ctx.state.T]; sdFont _ PrintFontsPrivate.LoadSD[Rope.Cat[wdir,base,".sd"], devicePts]; label _ IO.PutFR["%g.sd, scale=%g, time= %g", IO.rope[base], IO.real[scale], IO.time[]]; PrintPages[label, sdFont, device, ctx, scale]; RETURN[pdFile] }; PrintACFile: PUBLIC PROC[name: ROPE, device: DeviceType, scale: REAL] RETURNS [ROPE] = { acFont: PrivateFont; base, wdir, label, pdFile: ROPE; ctx: Imager.Context; [base, wdir] _ GetName[name]; acFont _ PrintFontsPrivate.LoadAC[Rope.Cat[wdir,base,".ac"]]; [ctx, pdFile] _ OpenPD[base, device]; label _ IO.PutFR["%g.ac, scale=%g, time= %g", IO.rope[base], IO.real[scale], IO.time[]]; PrintPages[label, acFont, device, ctx, scale]; RETURN[pdFile] }; ScaleSF: PUBLIC PROC [input, output: ROPE, scale: REAL] = { font: PrintFontsPrivate.PrivateFont; base, wdir: ROPE; sfFont: IO.STREAM; [base, wdir] _ GetName[input]; font _ PrintFontsPrivate.LoadSF[Rope.Cat[wdir,base,".sf"], scale]; [base, wdir] _ GetName[output]; sfFont _ FS.StreamOpen[fileName: Rope.Cat[wdir,base,".sf"], accessOptions: $create, keep: 2]; FOR char: CHAR IN [font.bc..font.ec) DO PrintFontsPrivate.ScalePathData[font.charRep[char].outline.pathData, scale, scale]; SDtoSF.PathToStream[ dest: sfFont, pathMap: font.charRep[char].outline.pathMap, pathData: font.charRep[char].outline.pathData, family: font.family, face: "M R R", charCode: VAL[char], widthx: font.charRep[char].width, widthy: 0]; ENDLOOP; IO.PutRope[sfFont, "STOP\n"]; IO.Close[sfFont]; }; PrintPages: PROC[label: ROPE, font: PrivateFont, device: DeviceType, ctx: Imager.Context, scale: REAL] = { maxH, maxW, gl, gt: REAL _ 0; areaW, areaH, boxW, boxH: REAL; nw, nh: INT; bc, nchars: NAT; maxW _ font.maxW*scale; --max size a function of scale maxH _ (font.ascent+font.descent)*scale; areaW _ pageW-right-left-5*captions.nwidth; --in points areaH _ pageH-top-bottom-4*captions.height; [[boxW, boxH]] _ ImagerTransform.InverseTransform[[maxW, maxH], ctx.state.T]; --in points boxW _ boxW+8; boxH _ boxH+8; --add the gridline space plus some white space nw _ Real.Fix[areaW/boxW]; --determine the count nh _ Real.Fix[areaH/boxH]; bc _ VAL[font.bc]; nchars _ ORD[font.ec-VAL[bc]]; IF nw*nh=0 THEN ERROR; IF nchars > nw*nh THEN { -- print multiple pages page: INT _ 1; UNTIL nw*nh >= nchars DO [gl, gt] _ GridAndTitle[ctx, bc, nw, nh, boxW, boxH, IO.PutFR["%g page = %g", IO.rope[label], IO.int[page]]]; PrintChars[ctx, font, VAL[bc], gl, gt, nw, nh, boxW, boxH, scale]; [] _ Imager.SpecialOp[ctx, $NewPage, NIL]; --resets the context ctx.ScaleT[0.0254/72]; --meters to points bc _ bc+nw*nh; nchars _ ORD[font.ec-VAL[bc]]; page _ page+1; ENDLOOP; label _ IO.PutFR["%g page = %g", IO.rope[label], IO.int[page]]; --for last page }; IF nw*nh > nchars THEN {nh _ nchars/nw; IF nh*nw"]; wdir _ Rope.Cat[wdir, Rope.Substr[full, cp.subDirs.start, cp.subDirs.length], ">"]; }; PrintChars: PROC [ctx: Imager.Context, font: PrivateFont, bc: CHAR, gl, gt: REAL, nw, nh: INT, boxW,boxH, scale: REAL] = { bitsW, bitsH, sx, sy: REAL; char: CHAR _ bc; class: ImagerPrivate.Class _ NARROW[ctx.class]; DoRow: PROC _ IF font.type=raster THEN DoRasterRow ELSE DoOutlineRow; DoRasterRow: PROC = { FOR i: INT IN [0..nw) DO IF font.charRep[char].pixels#NIL THEN { dx: REAL _ (bitsW-font.charRep[char].width)/2.0; --center it Imager.TranslateT[ctx, dx, 0]; SampledColors.DrawImage[ctx,font.charRep[char].pixels,SampledColors.bitmap]; Imager.TranslateT[ctx,bitsW-dx,0]; } ELSE Imager.TranslateT[ctx, bitsW, 0]; char _ char+1; IF char > font.ec THEN EXIT; ENDLOOP; }; DoOutlineRow: PROC = { DoChar: PROC = { Imager.ScaleT[ctx,font.pointSize]; class.MaskFill[ctx, font.charRep[char].outline.pathMap, font.charRep[char].outline.pathData]; }; FOR i: INT IN [0..nw) DO IF font.charRep[char].outline#NIL THEN { dx: REAL _ (bitsW-font.charRep[char].width)/2.0; --center it Imager.TranslateT[ctx, dx, 0]; Imager.DoSaveAll[ctx, DoChar]; Imager.TranslateT[ctx,bitsW-dx,0]; } ELSE Imager.TranslateT[ctx, bitsW, 0]; char _ char+1; IF char > font.ec THEN EXIT; ENDLOOP; }; Imager.TranslateT[ctx, gl+1, gt-2-3]; [[sx, , , ,sy, ]] _ ImagerTransform.Contents[ctx.state.T]; bitsW _ sx*boxW/scale; bitsH _ sy*boxH/scale; Imager.Scale2T[ctx, scale/sx, scale/sy]; --Convert to scaled bits Imager.TranslateT[ctx, 0, -font.ascent]; --drop down by the maximum ascent FOR i: INT IN [0..nh) DO Imager.DoSaveAll[ctx, DoRow]; IF char > font.ec THEN EXIT; Imager.TranslateT[ctx, 0, -bitsH]; ENDLOOP; }; OpenPD: PROC[base: ROPE, device: DeviceType] RETURNS [ctx: Imager.Context, name: ROPE] = { pdDescr: ImagerPD.PDFileDescription; name _ SELECT device FROM hornet => Rope.Cat[currentWD, base, "-ht.pd"], platemaker => Rope.Cat[currentWD, base, "-pm.pd"], versatec => Rope.Cat[currentWD, base, "-vtec.pd"], ENDCASE => ERROR; pdDescr _ SELECT device FROM hornet => ImagerPD.Hornet[name], platemaker => PlatemakerPD[name], versatec => VersatecPD[name], ENDCASE => ERROR; ctx _ Imager.Create[$PD, pdDescr]; ctx.ScaleT[0.0254/72]; --meters to points }; GridAndTitle: PROC [ctx: Imager.Context, first: NAT, nw, nh: INT, boxW,boxH: REAL, label: ROPE] RETURNS [gridLeft, gridTop: REAL]= { gw,gh: REAL; val: NAT; showVal: PROC = { Imager.ShowCharacters[ctx,Convert.RopeFromInt[from: val, base: 10, showRadix: FALSE]]}; Imager.SetFont[ctx, captions.font]; Imager.SetXY[ctx,[left, bottom]]; Imager.ShowCharacters[ctx,label]; --font name label gridLeft _ left+5*captions.nwidth; gridTop _ pageH-top-2*captions.height; gw _ nw*boxW+2; gh _ nh*boxH; FOR i: INT IN [0..nh] DO Imager.MaskRectangle[ctx,gridLeft, gridTop-i*boxH, gw, 2]; ENDLOOP; FOR i: INT IN [0..nw] DO Imager.MaskRectangle[ctx,gridLeft+i*boxW, gridTop-gh, 2, gh]; ENDLOOP; Imager.SetXY[ctx,[gridLeft+boxW/2-captions.nwidth, gridTop+captions.height]]; val _ 0; FOR i: INT IN [0..nw) DO --top line Imager.DoSaveAll[ctx,showVal]; Imager.SetXYRel[ctx,[boxW, 0]]; val _ val+1; ENDLOOP; Imager.SetXY[ctx,[left, gridTop-boxH/2-captions.height/2]]; val _ first; FOR i: INT IN [0..nh) DO Imager.DoSaveAll[ctx,showVal]; Imager.SetXYRel[ctx,[0, -boxH]]; val _ val+nw; ENDLOOP; RETURN[gridLeft, gridTop] }; PlatemakerPD: PROC[name: ROPE] RETURNS [ImagerPD.PDFileDescription] = { param: ImagerPD.PDFileDescription _ NEW[ImagerPD.PDFileDescriptionRep _ PlatemakerTemplate]; param.fileName _ name; RETURN[param]; }; VersatecPD: PROC[name: ROPE] RETURNS [ImagerPD.PDFileDescription] = { param: ImagerPD.PDFileDescription _ NEW[ImagerPD.PDFileDescriptionRep _ VersatecTemplate]; param.fileName _ name; RETURN[param]; }; PlatemakerTemplate: ImagerPD.PDFileDescriptionRep _ [ fileName: NIL, deviceCode: mig, sResolution: 1200, fResolution: 1200, imageSSize: 13200, imageFSize: 10200, nColors: 1, bandSSize: 16, maxLoadWords: 60000, leftovers: TRUE, copies: 1 ]; VersatecTemplate: ImagerPD.PDFileDescriptionRep _ [ fileName: NIL, deviceCode: mig, sResolution: 200, fResolution: 200, imageSSize: 20000, imageFSize: 8000, nColors: 1, bandSSize: 64, maxLoadWords: 60000, leftovers: FALSE, copies: 1 ]; captions: RECORD [ font: Imager.FONT, nwidth: REAL, height: REAL ]; left: REAL _ .5*72; top: REAL _ .75*72; right: REAL _ .5*72; bottom: REAL _ .75*72; pageH: REAL _ 11*72; pageW: REAL _ 8.5*72; Init: PROC = { box: Font.Box; captions.font _ Font.CreateScaled["Xerox/PressFonts/Helvetica/MRR", 8]; box _ Font.FormattingBox[captions.font,'0]; captions.nwidth _ box.xmax-box.xmin; captions.height _ box.ymax-box.ymin; }; Init[]; END. ΰPrintFontsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last Changed: Maureen Stone March 18, 1985 3:58:23 pm PST Written by: Maureen Stone May 7, 1985 5:22:04 pm PDT for debugging Prints all the characters in the file. SD and SF fonts do not inherently contain a pointSize so the pointSize parameter is necessary. Size is in output coordinates as above. Prints all the characters in the file divide the page into characters and captions. Compute how many bits are in the character area and divide it into equal squares big enough for the maximum character size now print last page. May be partial page print nw*nh chars, begining at bc in points, translate to the upper right of the grid, include the gridwidth and some whitespace We need to think in scaled bits for the pixel arrays. Convert the transformation system to scaled bits, the stepping quantities to unscaled bits Write the captions and gridlines. Ctx coordinate system is in points. grid Κ L˜šœ™Icodešœ Οmœ1™Jšœ žœ2˜@J˜ Jšœžœ˜Jšœžœ˜'Jšœžœžœžœ˜4Jšœžœžœ˜Jšœžœ˜Jšžœžœ.˜6Jšžœžœ0žœ˜@J˜J˜ Jšœ ˜ Jšœžœ˜Jšœ˜—J˜šœž ˜Jšžœz˜Jšžœžœžœ ˜+Jšžœžœžœ˜Jšœ žœ!˜2J™ Jšœ žœžœ˜Jšœ žœ ˜J™J™±J˜š Οn œž œžœ(žœžœžœ˜gJšœ˜Jšœžœ˜ Jšœ žœ˜J˜Jšœ˜Jšœ%˜%Jšžœ žœΟc)˜KJšžœFžœ˜MJšœH˜HJš œžœ$žœ žœžœ ˜XJ˜.Jšžœ˜J˜—š Ÿ œž œžœ(žœžœžœ˜gJšœ˜Jšœžœ˜ Jšœ žœ˜J˜Jšœ˜Jšœ%˜%Jšžœ žœ )˜KJšžœFžœ˜MJšœH˜HJš œžœ$žœ žœžœ ˜XJ˜.Jšžœ˜J˜—J˜š Ÿ œž œžœžœžœžœ˜XJ™%Jšœ˜Jšœžœ˜ J˜Jšœ˜Jšœ=˜=Jšœ%˜%Jš œžœ$žœ žœžœ ˜XJ˜.Jšžœ˜J˜—J˜šŸœž œžœ žœ˜;Jšœ$˜$Jšœ žœ˜Jšœžœžœ˜Jšœ˜JšœB˜BJšœ˜Jšœ]˜]šžœžœžœž˜'JšœS˜Sšœ˜Jšœ:˜:Jšœ/˜/Jšœ.žœ˜9Jšœ-˜-—Jšžœ˜—Jšžœ˜Jšžœ˜šžœ˜J˜——šŸ œžœžœEžœ˜jJšœžœ˜Jšœžœ˜Jšœžœ˜ Jšœ žœ˜Jšœ ˜6Jšœ(˜(J™©Jšœ,  ˜7J˜+JšœJžœ  ˜YJšœ .˜MJšœ ˜0Jšœ˜Jšœžœ ˜Jšœ žœ žœ˜Jšžœ žœžœ˜šžœžœ ˜0Jšœžœ˜šžœž˜Jšœ5žœžœžœ ˜nJšœžœ)˜BJšœ%žœ ˜?Jšœ ˜)J˜Jšœ žœ žœ˜J˜Jšžœ˜—Jšœžœžœžœ  ˜PJ˜—J™)Jšžœžœžœžœ ˜HJšœ<˜Jšœžœ˜ Jšœžœ˜Jšœžœ˜#J˜8˜OJ˜5—JšœS˜SJ˜—š Ÿ œžœ.žœ žœ žœžœ˜zJšœ!™!Jšœžœ˜Jšœžœ˜Jšœžœ ˜/Jš Ÿœžœžœžœ žœ˜EšŸ œžœ˜šžœžœžœ ž˜šžœžœžœ˜'Jšœžœ)  ˜žœ˜F—JšœM˜MJ˜š žœžœžœ žœ  ˜#Jšœ˜Jšœ˜J˜ Jšžœ˜—Jšœ;˜;J˜ šžœžœžœ ž˜Jšœ˜J˜ J˜ Jšžœ˜Jšžœ˜—J˜—J˜šŸ œžœžœžœ ˜GJšœ$žœ5˜\Jšœ˜Jšžœ˜J˜J˜—šŸ œžœžœžœ ˜EJšœ$žœ3˜ZJšœ˜Jšžœ˜J˜J˜J˜—šœ5˜5Jšœ žœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ žœ˜Jšœ ˜ Jšœ˜J˜—šœ3˜3Jšœ žœ˜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šœ>žœ˜GJ˜+J˜$J˜$J˜—J˜J˜J˜Jšžœ˜J˜—J˜—…—&€5Π