DIRECTORY Basics, CD, CDCells, CDCreateLabels, CDDirectory, CDBasics, CDMenus, CDSymbolicObjects, CDOps, CDPanelFonts, CDProperties, CDRects, CDSequencer, CDTexts, CornerStitching, Imager, ImagerBackdoor, ImagerFont, IO, Real, Rope, TerminalIO; CDCreateLabelsImpl: CEDAR PROGRAM IMPORTS Basics, CD, CDBasics, CDSymbolicObjects, CDCells, CDDirectory, CDMenus, CDOps, CDPanelFonts, CDProperties, CDSequencer, CDRects, CornerStitching, Imager, ImagerBackdoor, ImagerFont, IO, Real, Rope, TerminalIO EXPORTS CDCreateLabels = BEGIN IntValue: PROC [ob: CD.Object, a: ATOM] RETURNS [i: INT_0] = BEGIN WITH CDProperties.GetPropFromObject[ob, a] SELECT FROM ri: REF INT => i _ ri^; ENDCASE => NULL; END; PutIntValue: PROC [ob: CD.Object, a: ATOM, i: INT_0] = BEGIN CDProperties.PutPropOnObject[ob, a, (IF i=0 THEN NIL ELSE NEW[INT _ i])]; END; HashT: PROC [t: Imager.Transformation] RETURNS [Rope.ROPE] = BEGIN 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]]] END; MakeName: PROC [font: Imager.Font, ch: CHAR, scale: INT, lev: CD.Layer] RETURNS [n: Rope.ROPE_NIL] = BEGIN h: Rope.ROPE _ HashT[font.charToClient]; n _ IO.PutFR["#%g[%g|%d|%g|%g]", IO.char[ch], IO.rope[font.name], IO.int[scale], IO.atom[CD.LayerKey[lev]], IO.rope[h] ]; END; BitmapToCornerstitching: PROC [bitmap: ImagerBackdoor.Bitmap] RETURNS [plane: REF CornerStitching.Tesselation] = BEGIN plane _ CornerStitching.NewTesselation[]; FOR y: CARDINAL IN [0..bitmap.height) DO FOR x: CARDINAL IN [0..bitmap.width) DO TRUSTED { bitsRef: LONG POINTER TO CARDINAL _ LOOPHOLE[bitmap.base, LONG POINTER TO CARDINAL] + LONG[y]*bitmap.wordsPerLine + LONG[x/Basics.bitsPerWord]; IF Basics.BITAND[8000h, Basics.BITSHIFT[bitsRef^, x MOD Basics.bitsPerWord]]#0 THEN CornerStitching.ChangeRect[ plane: plane, rect: [x1: x, x2: x+1, y1: bitmap.height-y-1, y2: bitmap.height-y], newValue: $covered ]; } ENDLOOP; ENDLOOP; END; CornerstitchingToCell: PROC [plane: REF CornerStitching.Tesselation, layer: CD.Layer, csOrigin: CornerStitching.Pos _ [0, 0], scale: INT _ 1] RETURNS [cell: CD.Object] = BEGIN offset: CD.Position _ [-csOrigin.x*scale, -csOrigin.y*scale]; IncludeRectangle: CornerStitching.PerTileProc = BEGIN r: CD.Rect ~ CornerStitching.Area[tile]; IF CDBasics.NonEmpty[r] THEN [] _ CDCells.IncludeOb[cell: cell, ob: CDRects.CreateRect[size: [x: (r.x2-r.x1)*scale, y: (r.y2-r.y1)*scale], l: layer], position: CDBasics.AddPoints[[x: r.x1*scale, y: r.y1*scale], offset], cellCSystem: cdCoords, obCSystem: cdCoords, mode: dontPropagate ]; END; cell _ CDCells.CreateEmptyCell[]; [] _ CornerStitching.EnumerateArea[plane: plane, rect: CDBasics.universe, perTile: IncludeRectangle, data: NIL]; IF NARROW[cell.specificRef, CD.CellPtr].contents=NIL THEN [] _ CDCells.IncludeOb[cell: cell, ob: CDSymbolicObjects.CreateMark[], mode: dontPropagate]; [] _ CDCells.RepositionCell[cell, NIL]; END; Up: PROC [r: REAL] RETURNS [i: INT] = { i _ Real.Fix[r]; IF Real.Float[i]#r THEN i _ i+1; }; MakeChar: PROC [font: Imager.Font, char: CHAR, scale: INT_1, lev: CD.Layer] RETURNS [cell: CD.Object] = BEGIN vec: Imager.VEC; bitmap: ImagerBackdoor.Bitmap; context: Imager.Context; plane: REF CornerStitching.Tesselation; ext: ImagerFont.Extents _ ImagerFont.FontBoundingBox[font]; p1: CD.Position _ [Up[ext.leftExtent], Up[ext.descent]]; p2: CD.Position _ [Up[ext.rightExtent], Up[ext.ascent]]; bitmap _ ImagerBackdoor.NewBitmap[width: p1.x+p2.x, height: p1.y+p2.y]; context _ ImagerBackdoor.BitmapContext[bitmap]; Imager.SetColor[context, Imager.white]; Imager.MaskRectangleI[context, 0, 0, bitmap.width, bitmap.height]; Imager.SetColor[context, Imager.black]; Imager.SetXY[context, [x: p1.x, y: p1.y]]; Imager.SetFont[context, font]; Imager.ShowChar[context, char]; plane _ BitmapToCornerstitching[bitmap]; cell _ CornerstitchingToCell[plane, lev, p1, scale]; vec _ ImagerFont.RopeWidth[font, Rope.FromChar[char]]; PutIntValue[cell, $CDxWidth, scale*Real.RoundI[vec.x]]; PutIntValue[cell, $CDxHeight, scale*Real.RoundI[vec.y]]; END; FindOrCreateCharCell: PUBLIC PROC [design: CD.Design, font: Imager.Font, char: CHAR, scale: INT, lev: CD.Layer] RETURNS [cell: CD.Object_NIL] = BEGIN hashName: Rope.ROPE; IF scale<=0 THEN scale _ design.technology.lambda; hashName _ MakeName[font, char, scale, lev]; IF design#NIL AND hashName#NIL THEN cell _ CDDirectory.Fetch[design, hashName].object; IF cell=NIL THEN { cell _ MakeChar[font, char, scale, lev]; IF design#NIL THEN { IF hashName=NIL THEN hashName _ Rope.Cat["#", Rope.FromChar[char]]; [] _ CDDirectory.Include[design, cell, hashName]; }; } END; CreateTextCell: PUBLIC PROC [design: CD.Design, text: Rope.ROPE, font: Imager.Font, scale: INT_1, lev: CD.Layer] RETURNS [cell: CD.Object] = BEGIN IncludeChar: PROC [c: CHAR] RETURNS [quit: BOOL _ FALSE] = BEGIN IF c=' THEN { vec: Imager.VEC _ ImagerFont.RopeWidth[font, Rope.FromChar[' ]]; x _ x + scale*Real.RoundI[vec.x]; y _ y + scale*Real.RoundI[vec.y]; } ELSE { charCell: CD.Object _ FindOrCreateCharCell[design, font, c, scale, lev]; IF charCell#NIL THEN { [] _ CDCells.IncludeOb[cell: cell, ob: charCell, position: [x, y], cellCSystem: originCoords, obCSystem: originCoords ]; x _ x + IntValue[charCell, $CDxWidth]; y _ y + IntValue[charCell, $CDxHeight]; } } END; x: CD.Number_0; y: CD.Number_0; IF scale<=0 THEN scale _ design.technology.lambda; cell _ CDCells.CreateEmptyCell[]; [] _ Rope.Map[base: text, action: IncludeChar]; IF NARROW[cell.specificRef, CD.CellPtr].contents=NIL THEN RETURN [NIL]; IF design#NIL THEN [] _ CDDirectory.Include[design, cell, Rope.Cat["Label[", text, "]"]]; END; GetFont: PROC [design: CD.Design] RETURNS [font: Imager.Font_NIL] = BEGIN IF TerminalIO.Confirm["use font from panel"] THEN { cdFont: CDTexts.CDFont _ CDPanelFonts.CurrentFont[design]; IF cdFont#NIL THEN font _ cdFont.font } ELSE { fontName: Rope.ROPE _ TerminalIO.RequestRope["font name -> "]; font _ ImagerFont.Find[fontName ! Imager.Error => { TerminalIO.WriteRope[Rope.Cat["font not loaded: ", error.explanation]]; GOTO oops }; ]; } EXITS oops => NULL END; PostScaling: PROC [lambda: INT] RETURNS [scale: INT_1] = BEGIN IF TerminalIO.Confirm["use a post scale factor on cell?"] THEN { text: Rope.ROPE _ IO.PutFR1["post scale [lambda/%g] >", IO.int[lambda]]; scale _ MAX[1, TerminalIO.RequestInt[text]]; } END; PreScaling: PROC [font: Imager.Font] RETURNS [Imager.Font] = BEGIN IF TerminalIO.Confirm["use a pre scale factor on font (but prevents caching)"] THEN { scale: INT _ MAX[1, TerminalIO.RequestInt["pre scale -> "]]; font _ ImagerFont.Scale[font, scale]; }; RETURN [font] END; CreateTextCellComm: PROC[comm: CDSequencer.Command] = BEGIN text: Rope.ROPE; font: Imager.Font; layer: CD.Layer; scale: INT; cell: CD.Object; layer _ comm.l; TerminalIO.WriteRope[Rope.Cat["create a label (using ", CDOps.LayerName[layer], ")\n"]]; font _ GetFont[comm.design]; IF font=NIL THEN { TerminalIO.WriteRope["font not found\n"]; RETURN }; scale _ PostScaling[comm.design.technology.lambda]; font _ PreScaling[font]; text _ TerminalIO.RequestRope["text -> "]; IF Rope.IsEmpty[text] THEN { TerminalIO.WriteRope["empty text\n"]; RETURN }; cell _ CreateTextCell[comm.design, text, font, scale, layer]; IF cell=NIL THEN TerminalIO.WriteRope["not done\n"] ELSE { CDOps.AddAnObject[comm.design, cell, comm.pos]; TerminalIO.WriteRope["done\n"]; } END; CDSequencer.ImplementCommand[$CreateTextCell, CreateTextCellComm]; CDMenus.CreateEntry[menu: $RectProgramMenu, entry: "Enter text", key: $CreateTextCell]; END. RCDCreateLabelsImpl.mesa Copyright (C) 1984, 1985 by Xerox Corporation. All rights reserved. Created by: Jacobi, March 1, 1985 4:52:57 pm PST Last Edited by: Jacobi, January 8, 1986 3:45:23 pm PST --A NIL name should not be hashed --does not yet include cell into a design --csOrigin: in CornerStitching coords; will be origin of cell --scale: applied after offset for csOrigin --prevent empty cell -- returns integer i: i >= r; there exists no integer j such that j < i and j >= r --paint character in bitmap --create cell from bitmap --positioning and spacing --NIL if not done Κ ˜codešœ™K™DK™2Kšœ8™8—K˜šΟk ˜ K˜Kšœ˜K˜Kšœ˜Kšœ ˜ K˜ Kšœ˜Kšœ˜K˜K˜ K˜ K˜K˜ K˜K˜K˜Kšœ˜Kšœ ˜ Kšœ˜K˜K˜Kšœ ˜ K˜—šΟbœœ˜!Kšœ œͺœ˜ΩKšœ˜—Kš˜K˜š Οnœœœ œœœ˜™>Kšœ*™*Kš˜Kšœœ3˜=K˜šžœ ˜0Kš˜Kšœœ#˜(šœœ˜šœ"˜"KšœU˜UKšœE˜EKšœ˜Kšœ˜Kšœ˜Kšœ˜——Kšœ˜K˜—Kšœ!˜!Kšœkœ˜pKšœ™š œœœœœ˜;Kšœ\˜\—Kšœ"œ˜'Kšœ˜—K˜š Ÿœœœœœ˜'K™TKšœ˜Kšœœ ˜ K˜K˜—š Ÿœœœ œœœ ˜gKš˜Kšœ œ˜Kšœ˜Kšœ˜Kšœœ˜'Kšœ;˜;Kšœ9˜9Kšœ8˜8Kšœ™KšœG˜GKšœ/˜/Kšœ'˜'KšœB˜BKšœ'˜'Kšœ*˜*Kšœ˜K˜Kšœ™Kšœ(˜(Kšœ4˜4Kšœ™Kšœ6˜6Kšœ7˜7Kšœ8˜8šœ˜K˜——šŸœœœ œ"œ œœœœœ˜Kš˜Kšœ˜Kšœ œ"˜2Kšœ,˜,š œœœ œœ˜$Kšœ2˜2—šœœœ˜Kšœ(˜(šœœœ˜Kšœ œœ/˜CKšœ1˜1K˜—K˜—Kšœ˜—K˜šŸœœœ œœœ œœœ ˜ŒKšœ™Kš˜K˜š Πbn žœœœœœœ˜:Kš˜šœœ˜Kšœ œ1˜@Kšœ!˜!Kšœ!˜!K˜—šœ˜Kšœ œ<˜Hšœ œœ˜šœ0˜0Kšœ˜Kšœ˜Kšœ˜K˜—Kšœ&˜&Kšœ'˜'K˜—K˜—Kšœ˜—K˜Kšœœ ˜Kšœœ ˜Kšœ œ"˜2Kšœ!˜!Kšœ/˜/Kšœœœœœœœ˜GKšœœœG˜YKšœ˜—K˜š Ÿœœ œ œœ˜CKš˜šœ+œ˜3Kšœ:˜:Kšœœœ˜%Kšœ˜—šœ˜Kšœœ+˜>šœ"˜"šœ˜KšœG˜GKšœ˜ Kšœ˜—Kšœ˜—K˜—Kšœ ˜Kšœ˜—K˜š Ÿ œœ œœ œ˜8Kš˜šœ8œ˜@Kšœ œœ$œ˜HKšœœ!˜,Kšœ˜—Kšœ˜—K˜šŸ œœœ˜