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™<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šœ˜K˜�—šÏbœœ˜!Kšœœ¡œœ˜ÚKšœ˜—Kš˜K˜�KšÏnœœœ˜K˜�šŸœœœœœœ˜>šœ$œ˜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��