ImagerImpl.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Michael Plass, July 17, 1985 4:10:24 pm PDT
Doug Wyatt, May 30, 1985 11:30:32 pm PDT
DIRECTORY
Atom USING [PropList],
CountedVM USING [Handle, SimpleAllocate],
Imager USING [Box, Color, ColorOperator, ConstantColor, Context, ErrorDesc, Font, Outline, PathProc, PixelArray, Rectangle, ROPE, StrokeEnd, StrokeJoint, Trajectory, Transformation, VEC, XChar, XStringProc],
ImagerBackdoor USING [Bitmap, BitmapRep, Clipper, IntKey, RealKey],
ImagerBox USING [BoxFromRect, IntersectBox],
ImagerColor USING [ColorFromGray],
ImagerColorPrivate USING [ColorFromStipple],
ImagerFont USING [MapRope],
ImagerPath USING [MapOutline, MapTrajectory],
ImagerPixelMap USING [PixelMap, PixelMapRep],
ImagerPrivate USING [Class, ClassRep, StrokeDashes],
ImagerRaster USING [Create, NewBitmapDevice],
ImmutablePropList USING [Get, Put];
ImagerImpl: CEDAR PROGRAM
IMPORTS CountedVM, ImagerBox, ImagerColor, ImagerColorPrivate, ImagerFont, ImagerPath, ImagerRaster, ImmutablePropList
EXPORTS Imager, ImagerBackdoor, ImagerPrivate
~ BEGIN OPEN Imager, ImagerBackdoor, ImagerPrivate;
Class: TYPE ~ ImagerPrivate.Class;
ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; -- export to Imager.ClassRep
Error: PUBLIC ERROR[error: ErrorDesc] ~ CODE;
GetClass:
PUBLIC
PROC[context: Context]
RETURNS[
ATOM] ~ {
class: Class ~ context.class;
RETURN[class.type];
};
GetProp:
PUBLIC
PROC[context: Context, key:
REF]
RETURNS[val:
REF] ~ {
RETURN[ImmutablePropList.Get[context.propList, key]];
};
PutProp:
PUBLIC
PROC[context: Context, key:
REF, val:
REF] ~ {
context.propList ← ImmutablePropList.Put[context.propList, key, val];
};
DoSave:
PUBLIC
PROC[context: Context, action:
PROC] ~ {
class: Class ~ context.class;
propList: Atom.PropList ~ context.propList;
class.DoSave[context: context, action: action, all: FALSE !
UNWIND => context.propList ← propList];
context.propList ← propList;
};
DoSaveAll:
PUBLIC
PROC[context: Context, action:
PROC] ~ {
class: Class ~ context.class;
propList: Atom.PropList ~ context.propList;
class.DoSave[context: context, action: action, all: TRUE !
UNWIND => context.propList ← propList];
context.propList ← propList;
};
ConcatT:
PUBLIC
PROC[context: Context, m: Transformation] ~ {
class: Class ~ context.class;
class.ConcatT[context: context, m: m];
};
ScaleT:
PUBLIC
PROC[context: Context, s:
REAL] ~ {
class: Class ~ context.class;
class.Scale2T[context: context, s: [s, s]];
};
Scale2T:
PUBLIC
PROC[context: Context, s:
VEC] ~ {
class: Class ~ context.class;
class.Scale2T[context: context, s: s];
};
RotateT:
PUBLIC
PROC[context: Context, a:
REAL] ~ {
class: Class ~ context.class;
class.RotateT[context: context, a: a];
};
TranslateT:
PUBLIC
PROC[context: Context, t:
VEC] ~ {
class: Class ~ context.class;
class.TranslateT[context: context, t: t];
};
Move:
PUBLIC
PROC[context: Context] ~ {
class: Class ~ context.class;
class.Move[context: context, rounded: FALSE];
};
Trans:
PUBLIC
PROC[context: Context] ~ {
class: Class ~ context.class;
class.Move[context: context, rounded: TRUE];
};
SetXY:
PUBLIC
PROC[context: Context, p:
VEC] ~ {
class: Class ~ context.class;
class.SetXY[context: context, p: p];
};
SetXYI:
PUBLIC
PROC[context: Context, x, y:
INTEGER] ~ {
class: Class ~ context.class;
class.SetXY[context: context, p: [x, y]];
};
SetXYRel:
PUBLIC
PROC[context: Context, v:
VEC] ~ {
class: Class ~ context.class;
class.SetXYRel[context: context, v: v];
};
SetXYRelI:
PUBLIC
PROC[context: Context, x, y:
INTEGER] ~ {
class: Class ~ context.class;
class.SetXYRel[context: context, v: [x, y]];
};
SetXRel:
PUBLIC
PROC[context: Context, x:
REAL] ~ {
class: Class ~ context.class;
class.SetXYRel[context: context, v: [x, 0]];
};
SetXRelI:
PUBLIC
PROC[context: Context, x:
INTEGER] ~ {
class: Class ~ context.class;
class.SetXYRel[context: context, v: [x, 0]];
};
SetYRel:
PUBLIC
PROC[context: Context, y:
REAL] ~ {
class: Class ~ context.class;
class.SetXYRel[context: context, v: [0, y]];
};
SetYRelI:
PUBLIC
PROC[context: Context, y:
INTEGER] ~ {
class: Class ~ context.class;
class.SetXYRel[context: context, v: [0, y]];
};
SetFont:
PUBLIC
PROC[context: Context, font: Font] ~ {
class: Class ~ context.class;
class.SetFont[context: context, font: font];
};
SetAmplifySpace:
PUBLIC
PROC[context: Context, amplifySpace:
REAL] ~ {
class: Class ~ context.class;
class.SetReal[context: context, key: $amplifySpace, val: amplifySpace];
};
Show:
PUBLIC
PROC[context: Context, string: XStringProc, xrel:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
class.Show[context: context, string: string, xrel: xrel];
};
ShowChar:
PUBLIC
PROC[context: Context, char:
CHAR] ~ {
string: XStringProc ~ { charAction[[set: 0, code: ORD[char]]] };
class: Class ~ context.class;
class.Show[context: context, string: string, xrel: FALSE];
};
ShowXChar:
PUBLIC
PROC[context: Context, char: XChar] ~ {
string: XStringProc ~ { charAction[char] };
class: Class ~ context.class;
class.Show[context: context, string: string, xrel: FALSE];
};
ShowRope:
PUBLIC
PROC[context: Context, rope:
ROPE,
start:
INT ← 0, len:
INT ←
INT.
LAST, xrel:
BOOL ←
FALSE] ~ {
string: XStringProc ~ { ImagerFont.MapRope[
rope: rope, start: start, len: len, charAction: charAction] };
class: Class ~ context.class;
class.Show[context: context, string: string, xrel: xrel];
};
ShowText:
PUBLIC
PROC[context: Context, text:
REF
READONLY
TEXT,
start:
NAT ← 0, len:
NAT ←
NAT.
LAST, xrel:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
class.ShowText[context: context, text: text, start: start, len: len, xrel: xrel];
};
StartUnderline:
PUBLIC
PROC[context: Context] ~ {
class: Class ~ context.class;
class.StartUnderline[context: context];
};
MaskUnderline:
PUBLIC
PROC[context: Context, dy, h:
REAL] ~ {
class: Class ~ context.class;
class.MaskUnderline[context: context, dy: dy, h: h];
};
MaskUnderlineI:
PUBLIC
PROC[context: Context, dy, h:
INTEGER] ~ {
class: Class ~ context.class;
class.MaskUnderline[context: context, dy: dy, h: h];
};
CorrectMask:
PUBLIC
PROC[context: Context] ~ {
class: Class ~ context.class;
class.CorrectMask[context: context];
};
CorrectSpace:
PUBLIC
PROC[context: Context, v:
VEC] ~ {
class: Class ~ context.class;
class.CorrectSpace[context: context, v: v];
};
Space:
PUBLIC
PROC[context: Context, x:
REAL] ~ {
class: Class ~ context.class;
class.Space[context: context, x: x];
};
SpaceI:
PUBLIC
PROC[context: Context, x:
INTEGER] ~ {
class: Class ~ context.class;
class.Space[context: context, x: x];
};
SetCorrectMeasure:
PUBLIC
PROC[context: Context, v:
VEC] ~ {
class: Class ~ context.class;
class.SetCorrectMeasure[context: context, v: v];
};
SetCorrectTolerance:
PUBLIC
PROC[context: Context, v:
VEC] ~ {
class: Class ~ context.class;
class.SetCorrectTolerance[context: context, v: v];
};
SetCorrectShrink:
PUBLIC
PROC[context: Context, correctShrink:
REAL] ~ {
class: Class ~ context.class;
class.SetReal[context: context, key: $correctShrink, val: correctShrink];
};
Correct:
PUBLIC
PROC[context: Context, action:
PROC] ~ {
class: Class ~ context.class;
class.Correct[context: context, action: action];
};
DontCorrect:
PUBLIC
PROC[context: Context, action:
PROC, saveCP:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
class.DontCorrect[context: context, action: action, saveCP: saveCP];
};
SetColor:
PUBLIC
PROC[context: Context, color: Color] ~ {
class: Class ~ context.class;
class.SetColor[context: context, color: color];
};
black: PUBLIC ConstantColor ← ImagerColor.ColorFromGray[1];
white:
PUBLIC ConstantColor ← ImagerColor.ColorFromGray[0];
MakeGray:
PUBLIC
PROC[f:
REAL]
RETURNS[ConstantColor] ~ {
IF f>=1.0 THEN RETURN[black];
IF f<=0.0 THEN RETURN[white];
RETURN[ImagerColor.ColorFromGray[f]];
};
SetGray:
PUBLIC
PROC[context: Context, f:
REAL] ~ {
class: Class ~ context.class;
class.SetGray[context: context, f: f];
};
SetSampledColor:
PUBLIC
PROC[context: Context, pa: PixelArray,
m: Transformation, colorOperator: ColorOperator] ~ {
class: Class ~ context.class;
class.SetSampledColor[context: context, pa: pa, m: m, colorOperator: colorOperator];
};
SetSampledBlack:
PUBLIC
PROC[context: Context, pa: PixelArray,
m: Transformation, clear:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
class.SetSampledBlack[context: context, pa: pa, m: m, clear: clear];
};
DrawSampledColor:
PUBLIC
PROC [context: Context, pa: PixelArray,
m: Transformation, colorOperator: ColorOperator, p:
VEC] ~ {
drawSampledColorAction:
PROC ~ {
TranslateT[context, p];
SetSampledColor[context, pa, m, colorOperator];
ConcatT[context, m];
ConcatT[context, pa.m];
MaskRectangle[context, [0, 0, pa.sSize, pa.fSize]];
};
DoSave[context, drawSampledColorAction];
};
SetPriorityImportant:
PUBLIC
PROC[context: Context, priorityImportant:
BOOL] ~ {
class: Class ~ context.class;
class.SetInt[context: context, key: $priorityImportant, val: IF priorityImportant THEN 1 ELSE 0];
};
SetNoImage:
PUBLIC
PROC[context: Context, noImage:
BOOL] ~ {
class: Class ~ context.class;
class.SetInt[context: context, key: $noImage, val: IF noImage THEN 1 ELSE 0];
};
MaskFill:
PUBLIC
PROC[context: Context, path: PathProc, parity:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
class.MaskFill[context: context, path: path, parity: parity];
};
MaskFillTrajectory:
PUBLIC
PROC[context: Context, trajectory: Trajectory, parity:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
path: PathProc ~ { ImagerPath.MapTrajectory[trajectory: trajectory,
moveTo: moveTo, lineTo: lineTo, curveTo: curveTo, conicTo: conicTo, arcTo: arcTo] };
class.MaskFill[context: context, path: path, parity: parity];
};
MaskFillOutline:
PUBLIC
PROC[context: Context, outline: Outline, parity:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
path: PathProc ~ { ImagerPath.MapOutline[outline: outline,
moveTo: moveTo, lineTo: lineTo, curveTo: curveTo, conicTo: conicTo, arcTo: arcTo] };
class.MaskFill[context: context, path: path, parity: parity];
};
MaskRectangle:
PUBLIC
PROC[context: Context, r: Rectangle] ~ {
class: Class ~ context.class;
class.MaskRectangle[context: context, r: r];
};
MaskRectangleI:
PUBLIC
PROC[context: Context, x, y, w, h:
INTEGER] ~ {
class: Class ~ context.class;
class.MaskRectangleI[context: context, x: x, y: y, w: w, h: h];
};
MaskBox:
PUBLIC
PROC[context: Context, box: Box] ~ {
class: Class ~ context.class;
class.MaskRectangle[context: context,
r: [x: box.xmin, y: box.ymin, w: box.xmax-box.xmin, h: box.ymax-box.ymin]];
};
SetStrokeWidth:
PUBLIC
PROC[context: Context, strokeWidth:
REAL] ~ {
class: Class ~ context.class;
class.SetReal[context: context, key: $strokeWidth, val: strokeWidth];
};
SetStrokeEnd:
PUBLIC
PROC[context: Context, strokeEnd: StrokeEnd] ~ {
class: Class ~ context.class;
class.SetInt[context: context, key: $strokeEnd, val: ORD[strokeEnd]];
};
SetStrokeJoint:
PUBLIC
PROC[context: Context, strokeJoint: StrokeJoint] ~ {
class: Class ~ context.class;
class.SetInt[context: context, key: $strokeJoint, val: ORD[strokeJoint]];
};
SetStrokeDashes:
PUBLIC
PROC[context: Context, strokeDashes: StrokeDashes] ~ {
class: Class ~ context.class;
class.SetStrokeDashes[context: context, strokeDashes: strokeDashes];
};
MaskStroke:
PUBLIC
PROC[context: Context, path: PathProc,
closed:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
class.MaskStroke[context: context, path: path, closed: closed];
};
MaskStrokeTrajectory:
PUBLIC
PROC[context: Context, trajectory: Trajectory,
closed:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
path: PathProc ~ { ImagerPath.MapTrajectory[trajectory: trajectory,
moveTo: moveTo, lineTo: lineTo, curveTo: curveTo, conicTo: conicTo, arcTo: arcTo] };
class.MaskStroke[context: context, path: path, closed: closed];
};
MaskVector:
PUBLIC
PROC[context: Context, p1, p2:
VEC] ~ {
class: Class ~ context.class;
class.MaskVector[context: context, p1: p1, p2: p2];
};
MaskVectorI:
PUBLIC
PROC[context: Context, x1, y1, x2, y2:
INTEGER] ~ {
class: Class ~ context.class;
class.MaskVector[context: context, p1: [x1, y1], p2: [x2, y2]];
};
MaskPixel:
PUBLIC
PROC[context: Context, pa: PixelArray] ~ {
class: Class ~ context.class;
class.MaskPixel[context: context, pa: pa];
};
MaskBits:
PUBLIC
PROC[context: Context, base:
LONG
POINTER, wordsPerLine:
NAT,
sMin, fMin, sSize, fSize:
NAT, tx, ty:
INTEGER] ~ {
class: Class ~ context.class;
class.MaskBits[context: context, base: base, wordsPerLine: wordsPerLine,
sMin: sMin, fMin: fMin, sSize: sSize, fSize: fSize, tx: tx, ty: ty];
};
DrawBits:
PUBLIC
PROC[context: Context, base:
LONG
POINTER, wordsPerLine:
NAT,
sMin, fMin, sSize, fSize:
NAT, tx, ty:
INTEGER] ~ {
class: Class ~ context.class;
drawBitsAction:
PROC ~ {
class.SetColor[context: context, color: white];
class.MaskRectangleI[context: context, x: tx, y: ty, w: fSize, h: -sSize];
class.SetColor[context: context, color: black];
class.MaskBits[context: context, base: base, wordsPerLine: wordsPerLine,
sMin: sMin, fMin: fMin, sSize: sSize, fSize: fSize, tx: tx, ty: ty];
};
IF class.DrawBits # NIL THEN class.DrawBits[context: context, base: base, wordsPerLine: wordsPerLine, sMin: sMin, fMin: fMin, sSize: sSize, fSize: fSize, tx: tx, ty: ty]
ELSE DoSave[context, drawBitsAction];
};
Clip:
PUBLIC
PROC[context: Context, path: PathProc, parity, exclude:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
class.Clip[context: context, path: path, parity: parity, exclude: exclude];
};
ClipOutline:
PUBLIC
PROC[context: Context, outline: Outline, parity, exclude:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
path: PathProc ~ { ImagerPath.MapOutline[outline: outline,
moveTo: moveTo, lineTo: lineTo, curveTo: curveTo, conicTo: conicTo, arcTo: arcTo] };
class.Clip[context: context, path: path, parity: parity, exclude: exclude];
};
ClipRectangle:
PUBLIC
PROC[context: Context, r: Rectangle, exclude:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
class.ClipRectangle[context: context, r: r, exclude: exclude];
};
ClipRectangleI:
PUBLIC
PROC[context: Context, x, y, w, h:
INTEGER, exclude:
BOOL ←
FALSE] ~ {
class: Class ~ context.class;
class.ClipRectangleI[context: context, x: x, y: y, w: w, h: h, exclude: exclude];
};
SetInt:
PUBLIC
PROC[context: Context, key: IntKey, val:
INT] ~ {
class: Class ~ context.class;
class.SetInt[context, key, val];
};
SetReal:
PUBLIC
PROC[context: Context, key: RealKey, val:
REAL] ~ {
class: Class ~ context.class;
class.SetReal[context, key, val];
};
SetT:
PUBLIC
PROC[context: Context, m: Transformation] ~ {
class: Class ~ context.class;
class.SetT[context, m];
};
SetClipper:
PUBLIC
PROC[context: Context, clipper: Clipper] ~ {
class: Class ~ context.class;
class.SetClipper[context, clipper];
};
GetInt:
PUBLIC
PROC[context: Context, key: IntKey]
RETURNS[
INT] ~ {
class: Class ~ context.class;
RETURN[class.GetInt[context, key]];
};
GetReal:
PUBLIC
PROC[context: Context, key: RealKey]
RETURNS[
REAL] ~ {
class: Class ~ context.class;
RETURN[class.GetReal[context, key]];
};
GetT:
PUBLIC
PROC[context: Context]
RETURNS[Transformation] ~ {
class: Class ~ context.class;
RETURN[class.GetT[context]];
};
GetFont:
PUBLIC
PROC[context: Context]
RETURNS[Font] ~ {
class: Class ~ context.class;
RETURN[class.GetFont[context]];
};
GetColor:
PUBLIC
PROC[context: Context]
RETURNS[Color] ~ {
class: Class ~ context.class;
RETURN[class.GetColor[context]];
};
GetClipper:
PUBLIC
PROC[context: Context]
RETURNS[Clipper] ~ {
class: Class ~ context.class;
RETURN[class.GetClipper[context]];
};
GetStrokeDashes:
PUBLIC
PROC[context: Context]
RETURNS[StrokeDashes] ~ {
class: Class ~ context.class;
RETURN[class.GetStrokeDashes[context]];
};
GetCP:
PUBLIC
PROC[context: Context, rounded:
BOOL ←
FALSE]
RETURNS[
VEC] ~ {
class: Class ~ context.class;
RETURN[class.GetCP[context: context, rounded: rounded]];
};
GetBounds:
PUBLIC
PROC[context: Context]
RETURNS[Rectangle] ~ {
class: Class ~ context.class;
RETURN[class.GetBoundingRectangle[context: context]];
};
DoIfVisible:
PUBLIC
PROC [context: Context, r: Rectangle, action:
PROC] ~ {
class: Class ~ context.class;
IF class.GetBoundingRectangle = NIL THEN action[]
ELSE {
bb: Box ~ ImagerBox.BoxFromRect[class.GetBoundingRectangle[context: context]];
cb: Box ~ ImagerBox.BoxFromRect[r];
ib: Box ~ ImagerBox.IntersectBox[bb, cb];
IF ib.xmin < ib.xmax AND ib.ymin < ib.ymax THEN action[];
};
};
invert: PUBLIC ConstantColor ← ImagerColorPrivate.ColorFromStipple[
word: WORD.LAST, function: invert];
MakeStipple:
PUBLIC
PROC[stipple:
WORD ←
WORD.
LAST, xor:
BOOL ←
FALSE]
RETURNS[ConstantColor] ~ {
IF xor AND stipple=WORD.LAST THEN RETURN[invert];
RETURN[ImagerColorPrivate.ColorFromStipple[
word: stipple, function: (IF xor THEN invert ELSE replace)]];
};
Bitmap: TYPE ~ ImagerBackdoor.Bitmap;
NewBitmap:
PUBLIC
PROC [width, height:
NAT]
RETURNS [Bitmap] ~ {
wordsPerLine: NAT ~ (width+15)/16;
words: INT ~ LONG[wordsPerLine]*height;
vm: CountedVM.Handle ~ CountedVM.SimpleAllocate[words];
RETURN[NEW[ImagerBackdoor.BitmapRep ← [ref: vm, base: vm.pointer,
wordsPerLine: wordsPerLine, width: width, height: height]]];
};
BitmapContext:
PUBLIC
PROC [bitmap: Bitmap]
RETURNS [Context] ~ {
refRep:
REF ImagerPixelMap.PixelMapRep ~
NEW[ImagerPixelMap.PixelMapRep ← [
ref: bitmap.ref, pointer: bitmap.base, words: LONG[bitmap.wordsPerLine]*bitmap.height,
lgBitsPerPixel: 0, rast: bitmap.wordsPerLine, lines: bitmap.height
]];
frame: ImagerPixelMap.PixelMap ~ [
sOrigin: 0, fOrigin: 0, sMin: 0, fMin: 0,
sSize: bitmap.height, fSize: bitmap.width, refRep: refRep
];
RETURN[ImagerRaster.Create[ImagerRaster.NewBitmapDevice[frame], TRUE]];
};
MakePixelArrayFromBits: PUBLIC PROC[
bitPointer: LONG POINTER TO PACKED ARRAY [0..0) OF [0..1],
bitsPerLine, samplesPerLine, numberOfLines: NAT]
RETURNS [pixelArray: PixelArray] ~ TRUSTED {
pixelMap: ImagerPixelMap.PixelMap ← ImagerPixelMap.Create[0, [0, 0, numberOfLines, samplesPerLine]];
bbTableSpace: PrincOps.BBTableSpace;
bb: PrincOps.BBptr ~ PrincOpsUtils.AlignedBBTable[@bbTableSpace];
bb^ ← [
dst: [word: pixelMap.refRep.pointer, bit: 0],
dstBpl: pixelMap.refRep.rast*Basics.bitsPerWord,
src: [word: bitPointer, bit: 0],
srcDesc: [srcBpl[bitsPerLine]],
height: numberOfLines,
width: samplesPerLine,
flags: [direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: FALSE, srcFunc: null, dstFunc: null]
];
PrincOpsUtils.BITBLT[bb];
pixelArray ← ImagerMask.PixelArrayFromPixelMap[pixelMap];
pixelArray.m.PostRotate[-90];
pixelArray.m.PostTranslate[0, numberOfLines];
};
END.