IIPrivateImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Michael Plass, December 10, 1986 12:03:55 pm PST
DIRECTORY
FunctionCache,
II USING [ClipRectangle, ClipRectangleI, Color, ColorOperator, ConcatT, Context, DoSave, DoSaveAll, DrawSampledColor, Error, MaskBitmap, MaskPixel, MaskRectangleI, Move, Object, PathProc, PixelArray, PixelMap, Rectangle, ROPE, SampleMap, ScanMode, SetColor, SetGray, SetXY, Trans, Transformation, VEC, XChar, XStringProc],
IIBackdoor,
IIMaskCapture,
IIBox USING [Box, BoxFromRectangle, IntersectBox],
IIFont USING [MapText],
IIPixel USING [MakePixelMap],
IIPixelArray USING [FromPixelMap],
IIPrivate USING [Class, ClassRep],
IISample,
IIStroke USING [Dashes],
IITransformation,
Process USING [CheckForAbort],
Real,
SF USING [Box, SizeF, SizeS, Vec],
Vector2;
IIPrivateImpl: CEDAR PROGRAM
IMPORTS FunctionCache, II, IIBackdoor, IIBox, IIFont, IIMaskCapture, IIPixel, IIPixelArray, IISample, IIStroke, IITransformation, Process, Real, SF, Vector2
EXPORTS IIPrivate, II
~ BEGIN OPEN II;
Class: TYPE ~ IIPrivate.Class;
ClassRep: PUBLIC TYPE ~ IIPrivate.ClassRep; -- export to II.ClassRep
CoordSys: TYPE ~ IIBackdoor.CoordSys;
Visibility: TYPE ~ IIBackdoor.Visibility;
noViewOps: ROPE ~ "View operations not implemented for this context";
DefaultShowAndFixedXRel: PUBLIC PROC [context: Context, string: XStringProc, x: REAL] ~ {
class: Class ~ context.class;
first: BOOLTRUE;
eachChar: PROC [char: XChar] ~ {
thisChar: XStringProc ~ { charAction[char] };
IF first THEN first ← FALSE ELSE class.SetXYRel[context, [x, 0]];
class.Show[context: context, string: thisChar, xrel: FALSE];
};
string[eachChar];
};
DefaultShowText: PUBLIC PROC [context: Context, text: REF READONLY TEXT,
start: NAT ← 0, len: NATNAT.LAST, xrel: BOOLFALSE] ~ {
class: Class ~ context.class;
string: XStringProc ~ { IIFont.MapText[text, start, len, charAction] };
Process.CheckForAbort[];
class.Show[context, string, xrel];
};
DefaultMaskRectangleI: PUBLIC PROC [context: Context, x, y, w, h: INTEGER] ~ {
class: Class ~ context.class;
class.MaskRectangle[context, [x: x, y: y, w: w, h: h]];
};
DefaultMaskVector: PUBLIC PROC [context: Context, p1, p2: VEC] ~ {
class: Class ~ context.class;
vectorPath: PathProc ~ { moveTo[p1]; lineTo[p2] };
class.MaskStroke[context: context, path: vectorPath, closed: FALSE];
};
DefaultMaskDashedStroke: PUBLIC PROC [context: Context, path: PathProc,
patternLen: NAT, pattern: PROC [NAT] RETURNS [REAL], offset, length: REAL] ~ {
class: Class ~ context.class;
dashedPath: PathProc ~ { IIStroke.Dashes[path: path, patternLen: patternLen, pattern: pattern, offset: offset, length: length, moveTo: moveTo, lineTo: lineTo, conicTo: conicTo, curveTo: curveTo] };
class.MaskStroke[context: context, path: dashedPath, closed: FALSE];
};
DefaultMaskBitmap: PUBLIC PROC [context: Context, bitmap: SampleMap, referencePoint: SF.Vec,
scanMode: ScanMode, position: VEC] ~ {
box: SF.Box ~ IISample.GetBox[bitmap];
pa: PixelArray ~ IIPixelArray.FromPixelMap[pixelMap: IIPixel.MakePixelMap[bitmap], box: box, scanMode: [slow: right, fast: up], immutable: FALSE];
IITransformation.ApplyPreTranslate[pa.m, position];
IITransformation.ApplySFToXY[pa.m, scanMode, 0, 0];
IITransformation.ApplyPreTranslate[pa.m, [box.min.s-referencePoint.s, box.min.f-referencePoint.f]];
MaskPixel[context, pa];
};
DefaultDrawBitmap: PUBLIC PROC [context: Context, bitmap: SampleMap, referencePoint: SF.Vec,
scanMode: ScanMode, position: VEC] ~ {
proc: PROC ~ {
box: SF.Box ~ IISample.GetBox[bitmap];
m: Transformation ← IITransformation.Translate[position];
IITransformation.ApplySFToXY[m, scanMode, 0, 0];
IITransformation.ApplyPreTranslate[m, [-referencePoint.s, -referencePoint.f]];
ConcatT[context, m];
SetGray[context, 0];
MaskRectangleI[context: context, x: box.min.s, y: box.min.f, w: SF.SizeS[box], h: SF.SizeF[box]];
SetGray[context, 1];
MaskBitmap[context: context, bitmap: bitmap, referencePoint: [0, 0], scanMode: [slow: right, fast: up], position: [0, 0]];
};
DoSave[context, proc];
};
DefaultDrawPixels: PUBLIC PROC [context: Context, pixelMap: PixelMap, colorOperator: ColorOperator, referencePoint: SF.Vec, scanMode: ScanMode, position: VEC] ~ {
pa: PixelArray ~ IIPixelArray.FromPixelMap[pixelMap: pixelMap, box: pixelMap.box, scanMode: [slow: right, fast: up], immutable: FALSE];
IITransformation.ApplySFToXY[pa.m, scanMode, 0, 0];
IITransformation.ApplyPreTranslate[pa.m, [pixelMap.box.min.s-referencePoint.s, pixelMap.box.min.f-referencePoint.f]];
DrawSampledColor[context: context, pa: pa, colorOperator: colorOperator, m: NIL, position: position];
};
DefaultViewReset: PUBLIC PROC [context: Context] ~ {
Error[[$unimplemented, noViewOps]];
};
DefaultViewTranslateI: PUBLIC PROC [context: Context, x, y: INTEGER] ~ {
Error[[$unimplemented, noViewOps]];
};
DefaultViewClip: PUBLIC PROC [context: Context, path: PathProc, oddWrap: BOOL, exclude: BOOL] ~ {
Error[[$unimplemented, noViewOps]];
};
DefaultViewClipRectangleI: PUBLIC PROC [context: Context, x, y, w, h: INTEGER, exclude: BOOL] ~ {
Error[[$unimplemented, noViewOps]];
};
DefaultGetTransformation: PUBLIC PROC [context: Context, from, to: CoordSys] RETURNS [Transformation] ~ {
Error[[$unimplemented, noViewOps]];
};
DefaultTransform: PUBLIC PROC [context: Context, v: VEC, from, to: CoordSys, vec: BOOL] RETURNS [VEC] ~ {
M: Transformation ~ IIBackdoor.GetTransformation[context: context, from: from, to: to];
vM: VEC ~ (IF vec THEN IITransformation.TransformVec ELSE IITransformation.Transform)[M, v];
IITransformation.Destroy[M];
RETURN [vM];
};
DefaultMoveViewRectangle: PUBLIC PROC [context: Context, width, height, fromX, fromY, toX, toY: INTEGER] ~ {
Error[[$unimplemented, noViewOps]];
};
DefaultTestViewRectangle: PUBLIC PROC [context: Context, x, y, w, h: INTEGER]
RETURNS
[Visibility] ~ { RETURN [part] };
DefaultGetBounds: PUBLIC PROC [context: Context] RETURNS [Rectangle] ~ {
Error[[$unimplemented, "GetBounds not implemented for this context"]];
};
DefaultDoIfVisible: PUBLIC PROC [context: Context, r: Rectangle, action: PROC] ~ {
class: Class ~ context.class;
br: Rectangle ← r;
IF class.GetBounds # DefaultGetBounds THEN {
br ← class.GetBounds[context ! Error => CONTINUE];
};
{ bb: IIBox.Box ~ IIBox.BoxFromRectangle[br];
cb: IIBox.Box ~ IIBox.BoxFromRectangle[r];
ib: IIBox.Box ~ IIBox.IntersectBox[bb, cb];
IF ib.xmin < ib.xmax AND ib.ymin < ib.ymax THEN action[];
};
};
DefaultDoWithBuffer: PUBLIC PROC [context: Context, action: PROC, x, y, w, h: INTEGER, backgroundColor: Color ← NIL] ~ {
paintBack: PROC ~ {
SetColor[context, backgroundColor];
MaskRectangleI[context, x, y, w, h];
};
clippedAction: PROC ~ {
ClipRectangleI[context, x, y, w, h];
IF backgroundColor # NIL THEN DoSave[context, paintBack];
action[];
};
DoSave[context, clippedAction];
};
DefaultDrawObject: PUBLIC PROC [context: Context, object: Object, position: VEC, interactive: BOOL] ~ {
proc: PROC ~ {
SetXY[context, position];
IF interactive THEN Trans[context] ELSE Move[context];
ClipRectangle[context, object.clip];
object.draw[object, context]
};
DoSaveAll[context, proc];
};
objectCache: FunctionCache.Cache ← FunctionCache.Create[maxEntries: 30, maxTotalSize: 250000];
ObjectCacheData: TYPE ~ REF ObjectCacheDataRep;
ObjectCacheDataRep: TYPE ~ RECORD [
object: Object,
clientToDevice: Transformation,
v: SELECT tag: * FROM
notCached => [],
bitmap => [bitmap: SampleMap],
boxes => [boxes: ManhattanPolygon],
ENDCASE
];
maxBitsForCachedObject: REAL ← 2000000;
RasterDrawObject: PUBLIC PROC [context: Context, object: Object, position: VEC, interactive: BOOL] ~ {
contextBox: IIBox.Box ~ IIBox.BoxFromRectangle[IIBackdoor.GetBounds[context]];
objectRect: Rectangle ~ [x: position.x+object.clip.x, y: position.y+object.clip.y, w: object.clip.w, h: object.clip.h];
intersection: IIBox.Box ~ IIBox.IntersectBox[contextBox, IIBox.BoxFromRectangle[objectRect]];
IF intersection.xmax=intersection.xmin THEN RETURN; -- not visible
IF interactive THEN {
clientToDevice: Transformation ~ IIBackdoor.GetTransformation[context: context, from: client, to: device];
Compare: PROC [argument: REF] RETURNS [BOOL] ~ {
key: ObjectCacheData ~ NARROW[argument];
IF object # key.object THEN RETURN [FALSE];
RETURN [IITransformation.CloseToTranslation[key.clientToDevice, clientToDevice]];
};
bounds: II.Rectangle ~ IITransformation.TransformRectangle[clientToDevice, objectRect];
IF ABS[bounds.w*bounds.h] <= maxBitsForCachedObject THEN {
objectCacheData: ObjectCacheData ← NARROW [FunctionCache.Lookup[x: objectCache, compare: Compare, clientID: NIL].value];
IF objectCacheData = NIL THEN {
bitmap: II.SampleMap ← NIL;
size: INT ← 0;
ok: BOOLTRUE;
Op: PROC [c: Context] ~ { ClipRectangle[c, object.clip]; object.draw[object, c] };
bitmap ← IIMaskCapture.CaptureBitmap[Op, clientToDevice, TRUE !
IIMaskCapture.Cant => {ok ← FALSE; CONTINUE}];
IF ok
THEN {
o: REF ObjectCacheDataRep.bitmap ← NEW[ObjectCacheDataRep.bitmap];
objectCacheData ← o;
o.bitmap ← bitmap;
size ← IISample.WordsForMap[IISample.GetSize[bitmap]] + 10;
}
ELSE {
objectCacheData ← NEW[ObjectCacheDataRep.notCached];
size ← SIZE[ObjectCacheDataRep.notCached];
};
objectCacheData.object ← object;
objectCacheData.clientToDevice ← IITransformation.Copy[clientToDevice];
FunctionCache.Insert[x: objectCache, argument: objectCacheData, value: objectCacheData, size: size, clientID: NIL];
};
WITH objectCacheData SELECT FROM
ocd: REF ObjectCacheDataRep.bitmap => {
t1: VEC ~ IITransformation.TransformVec[clientToDevice, position];
t2: VEC ~ IITransformation.TransformVec[clientToDevice, [0, 0]];
t3: VEC ~ IITransformation.TransformVec[ocd.clientToDevice, [0, 0]];
t: VEC ← Vector2.Add[t1, Vector2.Sub[t2, t3]];
save: PROC ~ {
m: Transformation ~ IIBackdoor.GetTransformation[context: context, from: device, to: view];
IIBackdoor.SetT[context, m];
MaskBitmap[context: context, bitmap: ocd.bitmap, scanMode: [slow: right, fast: up], position: t];
IITransformation.Destroy[m];
};
IF ABS[t.x]+ABS[t.x] < 100000 THEN {t.x ← Real.Round[t.x]; t.y ← Real.Round[t.y]}; -- try to make an integer transformation
II.DoSave[context, save];
IITransformation.Destroy[clientToDevice];
RETURN;
};
ENDCASE => NULL;
};
IITransformation.Destroy[clientToDevice];
};
DefaultDrawObject[context, object, position, interactive];
};
END.