IPShowImpl.mesa
Last edited by:
Doug Wyatt, July 8, 1983 10:12 am
DIRECTORY
Atom USING [GetPName],
CGContext USING [Ref],
Graphics USING [Color, Context, SetColor],
IPBasic USING [Any, Identifier, Integer, Operator, Vector, VectorShape],
IPConvert USING [AnyToIdentifier, AnyToInteger, AnyToOperator, AnyToVector],
IPErrors USING [AppearanceWarning, MasterWarning],
IPExec USING [Do, FGet],
IPFont USING [FontKey, Modify, New],
IPImager USING [CachedFont, CachedFontRep, Imager, Vars],
IPImagerBasic USING [ConstantColor, Pair, Transformation],
IPImagerOps USING [ConcatT, Restore, Save, Trans],
IPState USING [State, StateRep],
IPTransform USING [Concat, DRound, InverseTransform, Transform, TransformVec],
IPVector USING [Get, Shape],
Rope USING [ActionType, Concat, ROPE, Size],
RopeReader USING [FreeRopeReader, Get, GetRopeReader, Ref, SetPosition],
Scaled USING [Float, FromReal, Value, zero],
UnifiedFonts USING [Create, DrawCharSeq, FixedUnit, FONT, GetWidthArray, Positioning, Transformation, WidthArray];
IPShowImpl: CEDAR PROGRAM
IMPORTS Atom, Graphics, IPConvert, IPErrors, IPExec, IPFont, IPImagerOps, IPTransform, IPVector, Rope, RopeReader, Scaled, UnifiedFonts
EXPORTS IPImagerOps, IPBasic
= BEGIN OPEN IPImagerBasic, IPBasic;
FONT: TYPE = UnifiedFonts.FONT;
ROPE: TYPE = Rope.ROPE;
State: TYPE = IPState.State;
StateRep: PUBLIC TYPE = IPState.StateRep; -- export to IPBasic
Imager: TYPE = IPImager.Imager;
Vars: TYPE = IPImager.Vars;
FontKey: TYPE = IPFont.FontKey;
VFont: TYPE = REF VFontRep;
VFontRep: TYPE = RECORD[vector: Vector, m: Transformation];
SetColor: PROC[imager: Imager] = INLINE {
icolor: ConstantColor = NARROW[imager.vars.color];
Graphics.SetColor[imager.context, [r: icolor.r/256, g: icolor.g/256, b: icolor.b/256]];
};
ufDeviceType: ATOM ← $Interpress;
ufPositioning: UnifiedFonts.Positioning ← rounded;
GetFont: PROC[imager: Imager] RETURNS[FONT] = INLINE { RETURN[
IF imager.font=NIL THEN (imager.font ← LookupFont[imager.vars]) ELSE imager.font] };
LookupFont: PROC[vars: Vars] RETURNS[FONT] = {
font: FONTNIL;
WITH vars.showVec SELECT FROM
key: FontKey => {
FOR f: IPImager.CachedFont ← vars.fontList, f.link UNTIL f=NIL DO
IF f.key=key THEN { font ← f.font; EXIT };
ENDLOOP;
IF font=NIL THEN {
font ← CreateFont[key, vars.T];
vars.fontList ← NEW[IPImager.CachedFontRep ← [
link: vars.fontList, key: key, font: font]];
};
};
ENDCASE;
RETURN[font];
};
CreateFont: PROC[key: FontKey, T: Transformation] RETURNS[FONT] = {
fontTransformation: UnifiedFonts.Transformation;
IF T.d=0 THEN { -- assume uniform scaling
fontTransformation ← [scale: T.a*key.m.a, rotation: 0];
}
ELSE { -- assume 90 degree rotation
fontTransformation ← [scale: ABS[T.d]*key.m.a, rotation: 90];
};
RETURN[UnifiedFonts.Create[key.name, fontTransformation, ufDeviceType]];
};
Show: PUBLIC PROC[self: State, v: Vector] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
IF vars.np.noImage=0 THEN {
font: FONT = GetFont[imager];
SetColor[imager];
IF font#NIL THEN {
widths: UnifiedFonts.WidthArray = font.GetWidthArray[];
spaceX: Scaled.Value ← Scaled.FromReal[Scaled.Float[widths[' ]]*vars.np.amplifySpace];
context: Graphics.Context = imager.context;
ref: CGContext.Ref = NARROW[context.data];
ref.cp.x ← vars.p.cpx;
ref.cp.y ← vars.p.cpy;
WITH v SELECT FROM
rope: ROPE => TRUSTED {
count: INT ← rope.Size[];
Char: TYPE = MACHINE DEPENDENT RECORD[
c(0:0..15): CHAR, width(1:0..31): Scaled.Value];
seqSize: NAT = 50;
seq: ARRAY [0..seqSize) OF Char;
reader: RopeReader.Ref = RopeReader.GetRopeReader[];
reader.SetPosition[rope, 0];
WHILE count>0 DO
p: POINTER TO Char ← @seq[0];
zero: UnifiedFonts.FixedUnit ← Scaled.zero;
n: NAT ← seqSize;
IF n>count THEN n ← count;
THROUGH [0..n) DO
p.c ← reader.Get[];
p.width ← IF p.c=' THEN spaceX ELSE widths[p.c];
p ← p+SIZE[Char];
ENDLOOP;
font.DrawCharSeq[context: context, count: n,
charPtr: @seq[0].c, charIncrement: SIZE[Char],
deltaXptr: @seq[0].width, deltaXincrement: SIZE[Char],
deltaYptr: @zero, deltaYincrement: 0,
positioning: ufPositioning];
count ← count-n;
ENDLOOP;
RopeReader.FreeRopeReader[reader];
};
ENDCASE => {
SIGNAL IPErrors.AppearanceWarning[Unimplemented];
};
vars.p.cpx ← ref.cp.x;
vars.p.cpy ← ref.cp.y;
}
ELSE {
shape: VectorShape = IPVector.Shape[v];
showVec: Vector ← vars.showVec;
m: Transformation ← NIL;
WITH showVec SELECT FROM
vfont: VFont => { showVec ← vfont.vector; m ← vfont.m };
ENDCASE;
FOR i: Integer IN[shape.l..shape.l+shape.n) DO
index: Integer; op: Operator;
IPImagerOps.Save[self, FALSE];
IPImagerOps.Trans[self];
index ← IPConvert.AnyToInteger[IPVector.Get[v, i]];
op ← IPConvert.AnyToOperator[IPVector.Get[showVec, index]];
IF m#NIL THEN IPImagerOps.ConcatT[self, m];
IPExec.Do[self, op];
IPImagerOps.Restore[self];
ENDLOOP;
};
};
};
ShowAndXRel: PUBLIC PROC[self: State, v: Vector] = {
SIGNAL IPErrors.MasterWarning[Unimplemented];
};
SetXY: PUBLIC PROC[self: State, p: Pair] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
dp: Pair = IPTransform.Transform[vars.T, p];
vars.p.cpx ← dp.x;
vars.p.cpy ← dp.y;
};
SetXYRel: PUBLIC PROC[self: State, v: Pair] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
dv: Pair = IPTransform.TransformVec[vars.T, v];
vars.p.cpx ← vars.p.cpx + dv.x;
vars.p.cpy ← vars.p.cpy + dv.y;
};
SetXRel: PUBLIC PROC[self: State, x: REAL] = {
SetXYRel[self, [x, 0]];
};
SetYRel: PUBLIC PROC[self: State, y: REAL] = {
SetXYRel[self, [0, y]];
};
GetCP: PUBLIC PROC[self: State, rounded: BOOLFALSE] RETURNS[Pair] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
dp: Pair ← [vars.p.cpx, vars.p.cpy];
IF rounded THEN dp ← IPTransform.DRound[dp];
RETURN[IPTransform.InverseTransform[vars.T, dp]];
};
HierarchicalName: PROC[v: Vector] RETURNS[ROPE] = {
shape: VectorShape = IPVector.Shape[v];
rope: ROPENIL;
FOR i: Integer IN[shape.l..shape.l+shape.n) DO
x: Any = IPVector.Get[v, i];
id: ROPE = Atom.GetPName[IPConvert.AnyToIdentifier[x]];
IF rope=NIL THEN rope ← id
ELSE rope ← rope.Concat["/"].Concat[id];
ENDLOOP;
RETURN[rope];
};
FontKeyToVector: PROC[f: FontKey] RETURNS[Vector] = INLINE { RETURN[f] };
VFontToVector: PROC[f: VFont] RETURNS[Vector] = INLINE { RETURN[f] };
FindFont: PUBLIC PROC[self: State, v: Vector] RETURNS[Vector] = {
name: ROPE = HierarchicalName[v];
RETURN[FontKeyToVector[IPFont.New[name]]];
};
ModifyFont: PUBLIC PROC[v: Vector, m: Transformation] RETURNS[Vector] = {
WITH v SELECT FROM
old: FontKey => {
RETURN[FontKeyToVector[IPFont.Modify[old, m]]];
};
old: VFont => {
new: VFont = NEW[VFontRep ← [vector: old.vector, m: IPTransform.Concat[m, old.m]]];
RETURN[VFontToVector[new]];
};
ENDCASE => {
new: VFont = NEW[VFontRep ← [vector: v, m: m]];
RETURN[VFontToVector[new]];
};
};
SetFont: PUBLIC PROC[self: State, n: Integer] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
v: Vector = IPConvert.AnyToVector[IPExec.FGet[self, n]];
vars.showVec ← v; imager.font ← NIL;
};
END.