DIRECTORY Imager, ImagerBasic USING [PixelArray], ImagerTransform USING [InverseTransform, Contents], ImagerPD USING[PDFileDescription, PDFileDescriptionRep, Hornet], PDFileFormat, Real USING [Fix], SampledColors USING[bitmap, DrawImage], UFFileManager USING[KeyOf], UFPressFontReader USING[Size, Range, Family, Face, Resolution, GetCharInfo, GetCharRaster, CharInfo, NumberOfFontsInFile], Font USING [Key, CreateScaled, FONT, Box, FormattingBox], Rope USING [ROPE, Cat, Substr], Convert USING [RopeFromInt], FS USING [ExpandName, ComponentPositions], IO USING [time, rope, real, int, PutFR], BasicTime, PrintAC; PrintACImpl: CEDAR PROGRAM IMPORTS Imager, SampledColors, Rope, ImagerTransform, Real, UFFileManager, UFPressFontReader, Font, Convert, ImagerPD, FS, IO, BasicTime EXPORTS = BEGIN OPEN PrintAC; ROPE: TYPE = Rope.ROPE; doChars: BOOLEAN _ TRUE; doPages: BOOLEAN _ FALSE; PrintACChars: PUBLIC PROC[name: ROPE, device: DeviceType, scale: REAL, chars: ROPE] RETURNS [pd: ROPE]; PrintACCodes: PUBLIC PROC[name: ROPE, device: DeviceType, scale: REAL, codes0, codes1, codes2, codes3, codes4: Subrange _ [0,0]] RETURNS [pd: ROPE]; PrintACFile: PUBLIC PROC[name: ROPE, device: DeviceType, scale: REAL] RETURNS [ROPE] = { acFont: InternalFont; base, wdir, label: ROPE; maxH, maxW, gl, gt: REAL _ 0; areaW, areaH, boxW, boxH: REAL; nw, nh: INT; bc, nchars: NAT; ctx: Imager.Context; [base, wdir] _ GetName[name]; acFont _ LoadAC[Rope.Cat[wdir,base,".ac"]]; ctx _ OpenPD[Rope.Cat[wdir,base,".pd"], device]; maxW _ acFont.maxW*scale; --max size a function of scale maxH _ (acFont.ascent+acFont.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]; label _ IO.PutFR["%g.ac, scale=%g, time= %g", IO.rope[base], IO.real[scale], IO.time[]]; bc _ VAL[acFont.bc]; nchars _ ORD[acFont.ec-VAL[bc]]; 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, acFont, 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[acFont.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, acFont: InternalFont, bc: CHAR, gl, gt: REAL, nw, nh: INT, boxW,boxH, scale: REAL] = { bitsW, bitsH, sx, sy: REAL; char: CHAR _ bc; DoRow: PROC = { FOR i: INT IN [0..nw) DO IF acFont.charRep[char].pixels#NIL THEN { dx: REAL _ (bitsW-acFont.charRep[char].width)/2.0; --center it Imager.TranslateT[ctx, dx, 0]; SampledColors.DrawImage[ctx,acFont.charRep[char].pixels,SampledColors.bitmap]; Imager.TranslateT[ctx,bitsW-dx,0]; } ELSE Imager.TranslateT[ctx, bitsW, 0]; char _ char+1; IF char > acFont.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, -acFont.ascent]; --drop down by the maximum ascent FOR i: INT IN [0..nh) DO Imager.DoSaveAll[ctx, DoRow]; IF char > acFont.ec THEN EXIT; Imager.TranslateT[ctx, 0, -bitsH]; ENDLOOP; }; OpenPD: PROC[name: ROPE, device: DeviceType] RETURNS [ctx: Imager.Context] = { pdDescr: ImagerPD.PDFileDescription _ 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: 8, showRadix: TRUE]]}; 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] }; FontNotFound: SIGNAL = CODE; InternalFont: TYPE ~ REF InternalFontRep; InternalFontRep: TYPE ~ RECORD [ family: Rope.ROPE _ NIL, face: [0..255] _ 0, descent, ascent, maxW: REAL _ 0, bc, ec: CHAR, charRep: ARRAY CHAR OF InternalCharRep ]; InternalCharRep: TYPE ~ RECORD [ width: REAL, pixels: ImagerBasic.PixelArray ]; LoadAC: PROC [fileName: Rope.ROPE] RETURNS [font: InternalFont] ~ TRUSTED { fileKey: Font.Key _ UFFileManager.KeyOf[fileName]; sizeInMeters, bitsPerEmQuad: REAL; IF UFPressFontReader.NumberOfFontsInFile[fileKey] = 0 THEN SIGNAL FontNotFound; sizeInMeters _ UFPressFontReader.Size[[fileKey, 0]]; font _ NEW [InternalFontRep]; [font.bc, font.ec] _ UFPressFontReader.Range[[fileKey, 0]]; font.family _ UFPressFontReader.Family[[fileKey, 0]]; font.face _ UFPressFontReader.Face[[fileKey, 0]]; bitsPerEmQuad _ sizeInMeters*UFPressFontReader.Resolution[[fileKey, 0]].xRes/0.0254; FOR char: CHAR IN [font.bc..font.ec] DO info: UFPressFontReader.CharInfo _ UFPressFontReader.GetCharInfo[[fileKey, 0], char]; pixelArray: ImagerBasic.PixelArray _ UFPressFontReader.GetCharRaster[[fileKey, 0], char]; font.charRep[char] _ [ width: (info.maxX-info.minX)*bitsPerEmQuad, pixels: pixelArray ]; IF font.charRep[char].width > font.maxW THEN font.maxW _ font.charRep[char].width; IF info.maxY > font.ascent THEN font.ascent _ info.maxY; IF ABS[info.minY] > font.descent THEN font.descent _ ABS[info.minY]; ENDLOOP; font.ascent _ font.ascent*bitsPerEmQuad; font.descent _ font.descent*bitsPerEmQuad; }; 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", 10]; box _ Font.FormattingBox[captions.font,'0]; captions.nwidth _ box.xmax-box.xmin; captions.height _ box.ymax-box.ymin; }; END. ΊPrintACImpl.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 March 26, 1985 1:24:14 pm PST for debugging Prints only the chars in the rope Prints only the chars in the subranges 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 Copied out of RasterFontWriterImpl. Changed PixelMap to PixelArray Κ Υ˜šœ™Icodešœ Οmœ1™Jšœžœ˜ Jšœžœ˜Jšœžœ˜#J˜8˜OJ˜5—JšœS˜SJ˜—š Ÿ œžœ1žœ žœ žœžœ˜}Jšœ!™!Jšœžœ˜Jšœžœ˜šŸœžœ˜šžœžœžœ ž˜šžœžœžœ˜)Jšœžœ+  ˜>Jšœ˜JšœN˜NJšœ"˜"J˜—Jšžœ"˜&J˜Jšžœžœžœ˜Jšžœ˜—J˜—Jš ^™^Jšœ%˜%J™‘Jšœ7žœ˜:Jšœ ˜J˜Jšœ) ˜AJšœ+ !˜Lšžœžœžœ ž˜J˜Jšžœžœžœ˜J˜"Jšžœ˜—J˜—šŸœžœžœžœ˜Nšœ&žœž˜8Jšœ ˜ Jšœ!˜!Jšœ˜Jšžœžœ˜—Jšœ"˜"Jšœ ˜)J˜J˜—šŸ œžœžœ žœ žœ žœžœžœ˜…J™FJšœžœ˜ Jšœžœ˜ šœ žœ˜JšœMžœ˜U—Jšœ#˜#J˜!Jšœ" ˜3J™Jšœ"˜"Jšœ&˜&J˜J˜ šžœžœžœ ž˜Jšœ;žœ˜C—šžœžœžœ ž˜Jšœ>žœ˜F—JšœM˜MJ˜š žœžœžœ žœ  ˜#Jšœ˜Jšœ˜J˜ Jšžœ˜—Jšœ;˜;J˜ šžœžœžœ ž˜Jšœ˜J˜ J˜ Jšžœ˜Jšžœ˜—J˜—J˜Jšœžœžœ˜J™CJšœžœžœ˜)šœžœžœ˜ Jšœ žœžœ˜J˜Jšœžœ˜ Jšœžœ˜ Jšœ žœžœžœ˜&Jšœ˜—šœžœžœ˜ Jšœžœ˜ J˜Jšœ˜—š Ÿœžœžœžœžœ˜KJšœ2˜2Jšœžœ˜"Jšžœ4žœžœ˜OJšœ4˜4Jšœžœ˜Jšœ;˜;Jšœ5˜5Jšœ1˜1JšœT˜Tšžœžœžœž˜'JšœU˜UJšœY˜Yšœ˜Jšœ+˜+Jšœ˜J˜—Jšžœ&žœ&˜RJšžœžœ˜8Jšžœžœžœžœ ˜DJšžœ˜—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šœ>žœ˜HJ˜+J˜$J˜$J˜—J˜Jšžœ˜J˜—J˜—…—!r/