DIRECTORY CD, CDBasics, CDCells, CDCreateLabels, CDDirectory, CDOps, CDPanelFonts, CDProperties, CDRects, CDSequencer, CDSymbolicObjects, CDTexts, CStitching, Imager, ImagerBitmapContext, ImagerFont, ImagerSample, IO, Real, Rope, SF, TerminalIO; CDCreateLabelsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDDirectory, CDOps, CDPanelFonts, CDProperties, CDRects, CDSequencer, CDSymbolicObjects, CStitching, Imager, ImagerBitmapContext, ImagerFont, ImagerSample, IO, Real, Rope, SF, TerminalIO EXPORTS CDCreateLabels = BEGIN DoStop: ERROR = CODE; IntValue: PROC [ob: CD.Object, a: ATOM] RETURNS [i: INT_0] = { WITH CDProperties.GetObjectProp[ob, a] SELECT FROM ri: REF INT => i _ ri^; ENDCASE => NULL; }; PutIntValue: PROC [ob: CD.Object, a: ATOM, i: INT_0] = { CDProperties.PutObjectProp[ob, a, (IF i=0 THEN NIL ELSE NEW[INT _ i])]; }; NameForCharCache: PROC [font: Imager.Font, ch: CHAR, scale: INT, layer: CD.Layer] RETURNS [n: Rope.ROPE_NIL] = { HashT: PROC [t: Imager.Transformation] RETURNS [Rope.ROPE] = { r: Rope.ROPE _ IO.PutFR["%g,%g,%g,%g", IO.real[t.a], IO.real[t.b], IO.real[t.c], IO.real[t.d]]; RETURN [IO.PutFR["%g,%g,%g", IO.rope[r], IO.real[t.e], IO.real[t.f]]] }; h: Rope.ROPE _ HashT[font.charToClient]; n _ IO.PutFR["#%g[%g|%d|%g|%g]", IO.char[ch], IO.rope[ImagerFont.Name[font]], IO.int[scale], IO.atom[CD.LayerKey[layer]], IO.rope[h] ]; }; CStitchSampleMap: PUBLIC PROC [map: ImagerSample.SampleMap, stop: REF BOOL_NIL] RETURNS [plane: CStitching.Tesselation] = { box: ImagerSample.Box = ImagerSample.GetBox[map]; height: INTEGER _ box.max.s-box.min.s; IF stop=NIL THEN stop _ NEW[BOOL_FALSE]; plane _ CStitching.NewTesselation[stopFlag: stop]; FOR y: INTEGER IN [box.min.s..box.max.s) DO IF stop^ THEN RETURN; FOR x: INTEGER IN [box.min.f..box.max.f) DO IF ImagerSample.Get[map, [s: y, f: x]]#0 THEN CStitching.ChangeRect[ plane: plane, rect: [x1: x, x2: x+1, y1: y, y2: y+1], new: $covered ]; ENDLOOP; ENDLOOP; }; CreateCellFromCStitching: PUBLIC PROC [plane: CStitching.Tesselation, layer: CD.Layer, csOrigin: CStitching.Pos _ [0, 0], scale: INT _ 1] RETURNS [cell: CD.Object] = { stop: REF BOOL _ plane.stopFlag; IncludeRect: CStitching.TileProc = { r: CD.Rect = CStitching.Area[tile]; IF CDBasics.NonEmpty[r] THEN { IF stop^ THEN ERROR DoStop; [] _ CDCells.IncludeOb[cell: cell, ob: CDRects.CreateRect[size: [x: (r.x2-r.x1)*scale, y: (r.y2-r.y1)*scale], l: layer], trans: [[(r.x1-csOrigin.x)*scale, (r.y1-csOrigin.y)*scale], original], mode: dontResize ]; }; }; stop _ plane.stopFlag; IF stop=NIL THEN stop _ NEW[BOOL_FALSE]; cell _ CDCells.CreateEmptyCell[]; [] _ CStitching.EnumerateArea[plane: plane, rect: CDBasics.universe, eachTile: IncludeRect, data: NIL ! DoStop => CONTINUE]; IF CDCells.IsEmpty[cell] THEN [] _ CDCells.IncludeOb[cell: cell, ob: CDSymbolicObjects.CreateMark[]]; [] _ CDCells.ResizeCell[NIL, cell]; }; BuildCharCell: PROC [font: Imager.Font, char: ImagerFont.XChar, scale: INT_1, layer: CD.Layer, stop: REF BOOL_NIL] RETURNS [cell: CD.Object] = { bitmap: ImagerSample.SampleMap; context: Imager.Context; plane: CStitching.Tesselation; ext: ImagerFont.Extents _ ImagerFont.BoundingBox[font, char]; descent: INT _ Real.Ceiling[ext.descent]; ascent: INT _ Real.Ceiling[ext.ascent]; leftExtent: INT _ Real.Ceiling[ext.leftExtent]; rightExtent: INT _ Real.Ceiling[ext.rightExtent]; box: ImagerSample.Box _ [min: [0, 0], max: [ascent+descent, rightExtent+leftExtent]]; bitmap _ ImagerSample.NewSampleMap[box: box]; ImagerSample.Clear[bitmap]; context _ ImagerBitmapContext.Create[ deviceSpaceSize: SF.Size[box], scanMode: Imager.ScanMode[slow: up, fast: right], surfaceUnitsPerInch: [1, 1], --??? pixelUnits: TRUE ]; ImagerBitmapContext.SetBitmap[context, bitmap]; Imager.SetColor[context, Imager.black]; Imager.SetXY[context, [leftExtent, descent]]; Imager.SetFont[context, font]; Imager.ShowXChar[context, char]; plane _ CStitchSampleMap[bitmap, stop]; cell _ CreateCellFromCStitching[plane: plane, layer: layer, scale: scale, csOrigin: [leftExtent, descent]]; BEGIN esc: Imager.VEC _ ImagerFont.Escapement[font, char]; PutIntValue[cell, $CDxWidth, scale*Real.Round[esc.x]]; PutIntValue[cell, $CDxHeight, scale*Real.Round[esc.y]]; END; CDProperties.PutObjectProp[cell, $CreatedBy, $CreateLabel]; }; MakeCharCell: PUBLIC PROC [design: CD.Design, font: Imager.Font, char: CHAR, scale: INT, layer: CD.Layer, stop: REF BOOL_NIL] RETURNS [cell: CD.Object_NIL] = { cacheName: Rope.ROPE; IF stop=NIL THEN stop _ NEW[BOOL_FALSE]; IF scale<=0 THEN scale _ design.technology.lambda; cacheName _ NameForCharCache[font, char, scale, layer]; IF design#NIL AND cacheName#NIL THEN { cell _ CDDirectory.Fetch[design, cacheName].object; IF cell#NIL THEN IF CDProperties.GetProp[cell, $CreatedBy]#$CreateLabel THEN cell _ NIL }; IF cell=NIL THEN { cell _ BuildCharCell[font, [0, LOOPHOLE[char]], scale, layer, stop]; IF design#NIL THEN { IF cacheName=NIL THEN cacheName _ Rope.Cat["#", Rope.FromChar[char]]; [] _ CDDirectory.Include[design, cell, IF stop^ THEN "@stopped" ELSE cacheName]; }; } }; MakeRopeCell: PUBLIC PROC [design: CD.Design, text: Rope.ROPE, font: Imager.Font, scale: INT_1, layer: CD.Layer, stop: REF BOOL_NIL] RETURNS [cell: CD.Object] = { IncludeChar: PROC [c: CHAR] RETURNS [quit: BOOL _ FALSE] = { IF c=' THEN { vec: Imager.VEC _ ImagerFont.RopeEscapement[font, Rope.FromChar[' ]]; x _ x + scale*Real.Round[vec.x]; y _ y + scale*Real.Round[vec.y]; } ELSE { charCell: CD.Object _ MakeCharCell[design, font, c, scale, layer, stop]; IF charCell#NIL THEN { [] _ CDCells.IncludeOb[cell: cell, ob: charCell, trans: [[x, y]]]; x _ x + IntValue[charCell, $CDxWidth]; y _ y + IntValue[charCell, $CDxHeight]; } } }; x, y: CD.Number_0; IF scale<=0 THEN scale _ design.technology.lambda; cell _ CDCells.CreateEmptyCell[]; [] _ Rope.Map[base: text, action: IncludeChar ! DoStop => CONTINUE]; IF CDCells.IsEmpty[cell] THEN RETURN [NIL]; IF design#NIL THEN [] _ CDDirectory.Include[design, cell, Rope.Cat["Label[", text, "]"]]; }; CreateTextCellComm: PROC[comm: CDSequencer.Command] = { SelectFont: PROC [design: CD.Design] RETURNS [font: Imager.Font_NIL] = { cdFont: CDTexts.CDFont _ CDPanelFonts.CurrentFont[design]; IF cdFont#NIL THEN font _ cdFont.font }; text: Rope.ROPE; font: Imager.Font; layer: CD.Layer; scale: INT; cell: CD.Object; stop: REF BOOL _ NEW[BOOL_FALSE]; layer _ comm.l; TerminalIO.PutRopes["create a label (on layer ", CDOps.LayerRope[layer], ")\n"]; CDSequencer.UseAbortFlag[comm.design, stop]; font _ SelectFont[comm.design]; IF font=NIL THEN { TerminalIO.PutRope["font not found\n"]; RETURN }; text _ TerminalIO.RequestRope[" text -> "]; scale _ MAX[1, TerminalIO.RequestInt[" post scale factor > "]]; IF Rope.IsEmpty[text] THEN { TerminalIO.PutRope["empty text\n"]; RETURN }; cell _ MakeRopeCell[comm.design, text, font, scale, layer]; IF cell=NIL THEN TerminalIO.PutRope["not done\n"] ELSE { [] _ CDOps.IncludeObjectI[comm.design, cell, comm.pos]; TerminalIO.PutRope["done\n"]; } }; CDSequencer.ImplementCommand[$CreateTextCell, CreateTextCellComm]; END. ¬CDCreateLabelsImpl.mesa Copyright (C) 1984, 1985, 1987 by Xerox Corporation. All rights reserved. Created by: Christian Jacobi, March 1, 1985 4:52:57 pm PST Last edited by: Christian Jacobi, April 13, 1987 1:37:33 pm PDT --A NIL name should not be hashed --returns a rope for hashing transformation --prevent empty cell --paint character in bitmap --create cell from bitmap --positioning and spacing --NIL if not done Κ ˜codešœ™K™JK™šœ$œ˜3Kšœœœ ˜Kšœœ˜—Kšœ˜—K˜š Ÿ œœœ œœ˜8Kš œ#œœœœœœ˜GKšœ˜—K˜šŸœœœ œ œœ œœ˜pKšΟc!™!K˜šŸœœœœ˜>Kš +™+Kš œœœœ œ œ œ ˜_Kš œœœ œ œ ˜EKšœ˜—K˜Kšœœ˜(šœœ˜!Kš œ œœ œœœ˜cKšœ˜—Kšœ˜—K˜š Ÿœ œ%œœœœ$˜{Kšœ1˜1Kšœœ˜&Kš œœœœœœ˜(Kšœ2˜2šœœœ˜+Kšœœœ˜šœœœœ˜,šœ'˜-šœ˜Kšœ˜Kšœ'˜'Kšœ ˜ Kšœ˜——Kšœ˜—Kšœ˜—Kšœ˜—K˜š Ÿœ œ(œ2œœœ ˜§Kšœœœ˜ K˜šΠbn œ˜$Kšœœ˜#šœœ˜Kšœœœ˜šœ"˜"KšœU˜UKšœF˜FKšœ˜Kšœ˜—K˜—Kšœ˜K˜—Kšœ˜Kš œœœœœœ˜(Kšœ!˜!Kšœbœ œ˜|Kš ™šœ˜KšœG˜G—Kšœœ˜#Kšœ˜—K˜šŸ œœ4œ œœœœœœ ˜KšœW˜WKšœ=˜=Kšœ œ˜)Kšœœ˜'Kšœ œ ˜/Kšœ œ!˜1KšœV˜VKš ™KšœI˜Išœ%˜%Kšœœ ˜Kšœ1˜1Kšœ ˜"Kšœ œ˜Kšœ˜—Kšœ/˜/Kšœ(˜(Kšœ-˜-Kšœ˜Kšœ ˜ Kš ™Kšœ'˜'Kšœk˜kKš ™š˜Kšœ œ%˜4Kšœ6˜6Kšœ7˜7Kšœ˜—Kšœ;˜;šœ˜K˜——šŸ œœœ œ"œ œ œœœœœœœ˜ŸKšœœ˜Kš œœœœœœ˜(Kšœ œ"˜2Kšœ7˜7š œœœ œœ˜'Kšœ3˜3šœœœ˜Kšœ5œ˜F—K˜—šœœœ˜Kšœœ˜Dšœœœ˜Kšœ œœ0˜EKšœ'œœ œ ˜PK˜—K˜—Kšœ˜—K˜šŸ œœœ œœœ œœœœœœ ˜’Kšœ™K˜š ‘ žœœœœœœ˜<šœœ˜Kšœ œ6˜EKšœ ˜ Kšœ ˜ K˜—šœ˜Kšœ œ<˜Hšœ œœ˜KšœB˜BKšœ&˜&Kšœ'˜'K˜—K˜—Kšœ˜—K˜Kšœœ ˜Kšœ œ"˜2Kšœ!˜!Kšœ:œ˜DKšœœœœ˜+KšœœœG˜YKšœ˜—K˜šŸœœ˜7K˜š Ÿ œœ œ œœ˜HKšœ:˜:Kšœœœ˜%Kšœ˜—K˜Kšœ œ˜#Kšœœœœ˜-Kš œœœœœœ˜!Kšœ˜KšœP˜PKšœ,˜,Kšœ˜šœœœ˜Kšœ'˜.K˜—Kšœ,˜,Kšœœ5˜@šœœ˜Kšœ#˜*K˜—Kšœ;˜;Kšœœœ!˜1šœ˜Kšœ7˜7Kšœ˜K˜—šœ˜K˜——KšœB˜Bšœ˜˜˜K˜K˜————…—œ&Y