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: BOOLFALSE] ~ {
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: INTINT.LAST, xrel: BOOLFALSE] ~ {
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: NATNAT.LAST, xrel: BOOLFALSE] ~ {
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: BOOLFALSE] ~ {
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: BOOLFALSE] ~ {
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: BOOLFALSE] ~ {
class: Class ~ context.class;
class.MaskFill[context: context, path: path, parity: parity];
};
MaskFillTrajectory: PUBLIC PROC[context: Context, trajectory: Trajectory, parity: BOOLFALSE] ~ {
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: BOOLFALSE] ~ {
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: BOOLFALSE] ~ {
class: Class ~ context.class;
class.MaskStroke[context: context, path: path, closed: closed];
};
MaskStrokeTrajectory: PUBLIC PROC[context: Context, trajectory: Trajectory,
closed: BOOLFALSE] ~ {
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: BOOLFALSE] ~ {
class: Class ~ context.class;
class.Clip[context: context, path: path, parity: parity, exclude: exclude];
};
ClipOutline: PUBLIC PROC[context: Context, outline: Outline, parity, exclude: BOOLFALSE] ~ {
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: BOOLFALSE] ~ {
class: Class ~ context.class;
class.ClipRectangle[context: context, r: r, exclude: exclude];
};
ClipRectangleI: PUBLIC PROC[context: Context, x, y, w, h: INTEGER, exclude: BOOLFALSE] ~ {
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: BOOLFALSE] 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: WORDWORD.LAST, xor: BOOLFALSE]
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.