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: BOOL ← TRUE;
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:
NAT ←
NAT.
LAST, xrel:
BOOL ←
FALSE] ~ {
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: BOOL ← TRUE;
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.