RandomImagerImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Michael Plass, July 20, 1985 11:31:04 am PDT
DIRECTORY Random, Imager, ImagerColor, ImagerFont, Process, ImagerBackdoor, ImagerPixelArrayDefs, ImagerPixelArray, ImagerPixelArrayPrivate, ImagerTransformation, ImagerSample, ImagerColorOperator, ImagerInterpress, ImagerDitheredDevice, Rope;
RandomImagerImpl: CEDAR PROGRAM
IMPORTS Random, Imager, ImagerColor, ImagerFont, Process, ImagerBackdoor, ImagerPixelArray, ImagerTransformation, ImagerSample, ImagerColorOperator, ImagerInterpress, ImagerDitheredDevice, Rope
EXPORTS ImagerPixelArrayDefs
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
VEC: TYPE ~ Imager.VEC;
Context: TYPE ~ Imager.Context;
PixelArray: TYPE ~ ImagerPixelArrayDefs.PixelArray;
random: Random.RandomStream ← Random.Create[];
Rand: PROC RETURNS [REAL] ~ {
RETURN [RandI[0, INT.LAST]/REAL[INT.LAST]];
};
RandI: PROC [min,max: INT] RETURNS [INT] ~ {
RETURN [random.ChooseInt[min,max]];
};
imagePA: Imager.PixelArray ← ImagerPixelArray.FromAIS["Mandrill.ais"];
imageColorOperator: Imager.ColorOperator ← ImagerColorOperator.GrayLinearColorModel[255, 0, 255, NIL];
SetGrayImage: PROC [rootName: ROPE] ~ {
imagePA ← ImagerPixelArray.FromAIS[rootName.Concat[".ais"]];
};
rgbImagePA: Imager.PixelArray ← ImagerPixelArray.Join3AIS["Umbrella-red.ais", "Umbrella-grn.ais", "Umbrella-blu.ais"];
rgbImageColorOperator: Imager.ColorOperator ← ImagerColorOperator.RGBLinearColorModel[255];
SetColorImage: PROC [rootName: ROPE] ~ {
rgbImagePA ← ImagerPixelArray.Join3AIS[rootName.Concat["-red.ais"], rootName.Concat["-grn.ais"], rootName.Concat["-blu.ais"]];
};
RandomColor: PROC [context: Context] ~ {
selectR: PROC [NAT] RETURNS [NAT] ~ {RETURN [RandI[0, pixelMasks.samplesPerPixel-1]]};
SELECT Rand[] FROM
IN [0.0..0.15] => Imager.SetColor[context, Imager.black];
IN [0.15..0.2] => Imager.SetColor[context, ImagerDitheredDevice.ColorFromSpecialPixel[[55H, xor]]];
IN [0.2..0.3] => Imager.SetGray[context, Rand[]];
IN [0.3..0.6] => Imager.SetColor[context, ImagerColor.ColorFromRGB[[Rand[], Rand[], Rand[]]]];
IN [0.6..0.7] => Imager.SetSampledColor[context, rgbImagePA, ImagerTransformation.Scale[Rand[]+0.1], rgbImageColorOperator];
IN [0.7..0.75] => Imager.SetSampledBlack[context, ImagerPixelArray.Extract[old: pixelMasks, samplesPerPixel: 1, select: selectR], ImagerTransformation.Scale[RandI[1, 8]/2.0], 0=RandI[0,1]];
IN [0.75..0.8] => Imager.SetSampledColor[context, imagePA, ImagerTransformation.Scale[Rand[]+0.1], imageColorOperator];
IN [0.9..1.0] => Imager.SetColor[context, Imager.white];
ENDCASE => NULL;
};
goodForText: BOOLFALSE;
Anything is OK for text, but we try not to get too many different transformations to keep it quick.
RandomScaleRotate: PROC [context: Context] ~ {
SELECT Rand[] FROM
IN [0.0..0.5] => {Imager.ScaleT[context, 0.5*(1+ABS[RandI[1, 6]+RandI[-5, 5]])]; goodForText ← TRUE};
IN [0.5..0.7] => Imager.ScaleT[context, Rand[]*Rand[]*10+0.01];
IN [0.7..0.8] => Imager.Scale2T[context, [2*Rand[]+0.01, 2*Rand[]+0.01]];
IN [0.9..0.95] => {Imager.Scale2T[context, [0.5*RandI[1, 3], 0.5*RandI[1, 3]]]; goodForText ← TRUE};
ENDCASE => goodForText ← TRUE;
SELECT Rand[] FROM
IN [0.0..0.7] => Imager.RotateT[context, 90*RandI[-20, 19]];
IN [0.7..0.9] => {Imager.RotateT[context, 360*4*Rand[]-360*2]; goodForText ← FALSE};
IN [0.9..0.95] => {Imager.RotateT[context, 23.0*RandI[-1, 1]]};
ENDCASE => NULL;
};
RandomTranslate: PROC [context: Context] ~ {
RandBI: PROC RETURNS [INT] ~ {RETURN [RandI[-50, 50]+RandI[-50, 50]+RandI[-50, 50+RandI[-50, 50]]]};
SELECT Rand[] FROM
IN [0.0..0.7] => Imager.TranslateT[context, [RandBI[], RandBI[]]];
IN [0.7..1.0] => Imager.TranslateT[context, [RandBI[]*Rand[], RandBI[]*Rand[]]];
ENDCASE => NULL;
};
CoordSys: PROC [context: Context] ~ {
it: PROC ~ {
Imager.MaskVector[context, [0,0], [0,5]];
Imager.MaskVector[context, [0,0], [4.8,0]];
Imager.MaskVector[context, [1,-0.2], [1,0.2]];
Imager.MaskVector[context, [-0.2,1], [0.2,1]];
Imager.MaskVector[context, [5,0], [4.8, 0.1]];
Imager.MaskVector[context, [4.8, 0.1], [4.8, -0.1]];
Imager.MaskVector[context, [4.8, -0.1], [5,0]];
Imager.MaskVector[context, [0,5], [0.1,4.8]];
Imager.MaskVector[context, [0,5], [-0.1,4.8]];
};
inner: PROC ~ {
Imager.SetStrokeWidth[context, 0.2];
Imager.SetStrokeEnd[context, round];
Imager.SetColor[context, Imager.white];
Imager.SetStrokeWidth[context, 0.3];
Imager.MaskVector[context, [0,0], [0,0]];
it[];
Imager.SetStrokeWidth[context, 0];
Imager.SetColor[context, Imager.black];
it[];
Imager.SetStrokeWidth[context, 0.15];
it[];
};
Imager.DoSaveAll[context, inner];
};
Interp: PROC [a, b: VEC, r: REAL] RETURNS [VEC] ~ {
s: REAL ~ 1.0-r;
RETURN [[a.x*s+b.x*r, a.y*s+b.y*r]]
};
RandomSplinePath: PROC [n: [3..10), close: BOOL, moveTo: PROC [VEC], curveTo: PROC [VEC, VEC, VEC]] ~ {
k: ARRAY [0..11) OF VEC;
nn: INTIF close THEN INT[n]+1 ELSE n;
Mod: PROC [i: INT] RETURNS [INT] ~ {
WHILE i<0 DO i ← i + nn ENDLOOP;
WHILE i>=nn DO i ← i - nn ENDLOOP;
RETURN [i];
};
FOR i: INT IN [0..nn) DO
k[i] ← [Rand[]*scale.x, Rand[]*scale.y];
ENDLOOP;
FOR i: INT IN [0..n) DO
a: VEC ← Interp[k[Mod[i-2]], k[Mod[i-1]], 2/3.0];
c: VEC ← Interp[k[Mod[i-1]], k[Mod[i]], 1/3.0];
b: VEC ← Interp[a, c, 0.5];
d: VEC ← Interp[k[Mod[i-1]], k[Mod[i]], 2/3.0];
f: VEC ← Interp[k[Mod[i]], k[Mod[i+1]], 1/3.0];
e: VEC ← Interp[d, f, 0.5];
IF i=0 THEN moveTo[b];
curveTo[c, d, e];
ENDLOOP;
};
RandomArc: PROC [start: VEC, arcTo: PROC [VEC, VEC]] RETURNS [lp: VEC] ~ {
lp ← [Rand[]*scale.x, Rand[]*scale.y];
arcTo[[Rand[]*scale.x, Rand[]*scale.y], lp];
};
RandomLine: PROC [start: VEC, lineTo: PROC [VEC]] RETURNS [lp: VEC] ~ {
lp ← [Rand[]*scale.x, Rand[]*scale.y];
lineTo[lp];
};
RandVec: PROC RETURNS [lp: VEC] ~ {
lp ← [Rand[]*scale.x, Rand[]*scale.y];
};
strokeScale: REAL ← 10.0;
RandomStrokeStyle: PROC [context: Context] ~ {
Imager.SetStrokeWidth[context, strokeScale*Rand[]];
Imager.SetStrokeEnd[context, VAL[NAT[RandI[0,2]]]];
Imager.SetStrokeJoint[context, VAL[NAT[RandI[0,1]]]];
};
scale: VEC ← [1.0, 1.0];
closed: BOOLFALSE;
RandomPath: Imager.PathProc ~ {
lp: VEC ← RandVec[];
SELECT Rand[] FROM
IN [0.0..0.3] => {
FOR i: INT IN [0..RandI[0,3]*RandI[0,1]) DO
RandomSplinePath[RandI[3,9], closed, moveTo, curveTo];
ENDLOOP;
};
IN [0.3..0.4] => {
RandomSplinePath[RandI[3,9], FALSE, moveTo, curveTo];
};
IN [0.4..0.6] => {
n: INT ← RandI[1,4];
moveTo[lp];
FOR i: INT IN [0..n) DO
lp ← RandomArc[lp, arcTo];
ENDLOOP;
};
IN [0.6..1.0] => {
n: INT ← RandI[0,20];
moveTo[lp];
FOR i: INT IN [0..n) DO
lp ← RandomLine[lp, lineTo];
ENDLOOP;
};
ENDCASE => NULL;
};
PixelArrayImpl: TYPE ~ ImagerPixelArrayPrivate.PixelArrayImpl;
PixelArrayImplRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayImplRep;
PixelArrayClass: TYPE ~ ImagerPixelArrayPrivate.PixelArrayClass;
PixelArrayClassRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayClassRep;
RandomStippleColor: PROC RETURNS [Imager.Color] ~ {
IF 0=RandI[0,4] THEN {
bits: REF ARRAY [0..16) OF WORDNEW[ARRAY [0..16) OF WORD];
height: NAT ~ RandI[1,16];
width: NAT ~ RandI[1,16];
pa: PixelArray ~ NEW[ImagerPixelArrayDefs.PixelArrayRep ← [
samplesPerPixel: 1, sSize: height, fSize: width,
m: ImagerTransformation.Scale[1], class: bitsClass, data: bits]];
t: CARDINAL ← 1;
FOR i: NAT DECREASING IN [0..16) DO
bits^[i] ← t;
t ← 2*t;
ENDLOOP;
RETURN [ImagerColor.MakeSampledBlack[pa, ImagerTransformation.Scale[1], 0=RandI[0,1]]]
};
RETURN [ImagerBackdoor.MakeStipple[RandI[0, LAST[WORD]]]]
};
bitsClass: PixelArrayClass ~ NEW[PixelArrayClassRep ← [
type: $Bits,
MaxSampleValue: BitsMaxSampleValue,
UnsafeGetSamples: BitsUnsafeGetSamples
]];
BitsMaxSampleValue: PROC [pa: PixelArray, i: NAT] RETURNS [ImagerPixelArray.Sample] ~ {
RETURN [1];
};
BitsUnsafeGetSamples: UNSAFE PROC [pa: PixelArray, i: NAT, s, f: INT,
samples: ImagerSample.UnsafeSamples, count: NAT] ~ UNCHECKED {
data: REF ARRAY [0..16) OF WORD ~ NARROW[pa.data];
ImagerSample.UnsafeGetF[samples: samples, count: count, base: LOOPHOLE[data, LONG POINTER], wordsPerLine: 1, bitsPerSample: 1, s: s, f: f]
};
RandomClip: PROC [context: Context] ~ {
path: Imager.PathProc ~ {
RandomSplinePath[5, TRUE, moveTo, curveTo];
};
Imager.Clip[context, path, FALSE, RandI[0,4]=0];
Imager.SetColor[context, RandomStippleColor[]];
Imager.MaskBox[context, [-99999, -99999, 99999, 99999]];
};
RandomFill: PROC [context: Context] ~ {
closed ← TRUE;
Imager.MaskFill[context, RandomPath, RandI[0,1]=0];
};
RandomStroke: PROC [context: Context] ~ {
closed ← RandI[0,1]=0;
RandomStrokeStyle[context];
Imager.MaskStroke[context, RandomPath, closed];
};
RandomVector: PROC [context: Context] ~ {
RandomStrokeStyle[context];
Imager.MaskVector[context, RandVec[], RandVec[]];
};
RandomRectangle: PROC [context: Context] ~ {
p0: VEC ← RandVec[];
p1: VEC ← RandVec[];
Imager.MaskRectangle[context, [p0.x, p0.y, p1.x-p0.x, p1.y-p0.y]];
};
pa1: PixelArray ← ImagerPixelArray.FromAIS["Mask1.ais"];
pa2: PixelArray ← ImagerPixelArray.FromAIS["Mask2.ais"];
pa3: PixelArray ← ImagerPixelArray.FromAIS["Mask3.ais"];
pixelMasks: PixelArray ← ImagerPixelArray.Join3[pa1, pa2, pa3];
RandomPixels: PROC [context: Context] ~ {
selectR: PROC [NAT] RETURNS [NAT] ~ {RETURN [RandI[0, pixelMasks.samplesPerPixel-1]]};
pa: PixelArray ~ ImagerPixelArray.Extract[old: pixelMasks, samplesPerPixel: 1, select: selectR];
Imager.MaskPixel[context, pa];
};
RandomMask: PROC [context: Context, textBounds: BOOLFALSE] ~ {
SELECT Rand[] FROM
IN [0.0..0.2] => RandomFill[context];
IN [0.2..0.3] => RandomStroke[context];
IN [0.3..0.58] => {IF goodForText THEN RandomShow[context, textBounds] ELSE RandomFill[context]};
IN [0.58..0.6] => RandomShow[context, textBounds];
IN [0.6..0.65] => RandomRectangle[context];
IN [0.65..0.85] => {IF goodForText THEN RandomPixels[context] ELSE RandomRectangle[context]};
IN [0.85..0.9] => RandomPixels[context];
ENDCASE => RandomVector[context];
};
nfonts: NAT ← 9;
xerox: BOOLFALSE;
logo: ROPE ~ "xerox/pressfonts/logo-mrr";
fontName: ARRAY [0..35) OF ROPE ← ["xerox/pressfonts/helvetica-bir", "xerox/pressfonts/modern-bir", "xerox/pressfonts/timesroman-brr", "xerox/pressfonts/modernpione-brr", logo, "xerox/pressfonts/classic-brr", "xerox/pressfonts/classic-mir", "xerox/pressfonts/timesroman-mrr", "xerox/pressfonts/oldenglish-mrr", "xerox/pressfonts/classic-mrr", "xerox/pressfonts/classicpione-brr", "xerox/pressfonts/classicpione-mir", "xerox/pressfonts/classicpione-mrr", "xerox/pressfonts/gacha-mrr", "xerox/pressfonts/gates-mrr", "xerox/pressfonts/helvetica-brr", "xerox/pressfonts/helvetica-mir", "xerox/pressfonts/helvetica-mrr", "xerox/pressfonts/hippo-mrr", "xerox/pressfonts/keyhole-brr", "xerox/pressfonts/laurel-mrr", "xerox/pressfonts/math-mrr", "xerox/pressfonts/mockingbird-mrr", "xerox/pressfonts/modern-brr", "xerox/pressfonts/modern-mir", "xerox/pressfonts/modern-mrr", "xerox/pressfonts/modernpione-bir", "xerox/pressfonts/modernpione-mir", "xerox/pressfonts/modernpione-mrr", "xerox/pressfonts/template-mrr", "xerox/pressfonts/timesroman-bir", "xerox/pressfonts/timesroman-mrr", "xerox/pressfonts/timesroman-mir", "xerox/pressfonts/xeroxbook-mrr", "xerox/pressfonts/arrows-mrr"];
RandomFont: PROC [context: Context] ~ {
name: ROPE ~ fontName[RandI[0,MIN[nfonts, 35]-1]];
font: Imager.Font ~ ImagerFont.Find[name];
Imager.SetFont[context, ImagerFont.Scale[font, 8]];
xerox ← (name = logo);
};
text: ARRAY [0..11) OF ROPE ~ ["Now is the time for all good ", "people to party", "The Quick Brown ", "Fox Jumps Over Lazy Dogs ", "Flash ", "Dazzle ", "Imager ", "Cedar ", "Dorado ", "Color Is Fun ", "XEROX "];
RandomShow: PROC [context: Context, checkBounds: BOOL] ~ {
amp: REALIF RandI[0,3] = 0 THEN 0.5+1.5*Rand[] ELSE 1.0;
RandomFont[context];
Imager.SetAmplifySpace[context, amp];
IF checkBounds THEN {
bounds: Imager.Rectangle ~ ImagerBackdoor.GetBounds[context];
cp: VEC ~ ImagerBackdoor.GetCP[context];
IF cp.x IN [bounds.x..bounds.x+bounds.w) AND cp.y IN [bounds.y..bounds.y+bounds.h) THEN NULL
ELSE Imager.SetXY[context, [bounds.x+0.5*bounds.w*Rand[], bounds.y+0.5*bounds.h*Rand[]]];
};
Imager.ShowRope[context, IF xerox THEN "XEROX " ELSE text[RandI[0, 11-1]]];
};
limit: INT ← 0;
Setup: PROC [n: INT ← -1, newRand: BOOLFALSE] ~ {
IF newRand THEN random ← Random.Create[];
limit ← n;
};
Run: PROC [context: Context] ~ {
Do20: PROC ~ {
bounds: Imager.Rectangle ← ImagerBackdoor.GetBounds[context];
scale ← [bounds.w, bounds.h];
RandomTranslate[context];
Imager.TranslateT[context, [bounds.w/2, bounds.h/2]];
RandomScaleRotate[context];
Imager.TranslateT[context, [-bounds.w/2, -bounds.h/2]];
CoordSys[context];
Imager.SetXY[context, [0, 0]];
IF 0 = RandI[0,5] THEN RandomClip[context];
FOR i: INT IN [0..20) UNTIL limit = 0 DO
IF 0 = RandI[0,99] THEN RandomClip[context];
RandomColor[context];
RandomMask[context, TRUE];
limit ← limit - 1;
Process.CheckForAbort[];
ENDLOOP;
};
UNTIL limit = 0 DO
Imager.DoSaveAll[context, Do20];
ENDLOOP;
};
WriteInterpress: PROC [nOpsPerPage, nPages: INT ← 1] ~ {
page: PROC [context: Context] ~ {
n: INT ← nOpsPerPage;
bounds: Imager.Rectangle ~ [0, 0, 8.5*72, 11*72];
Do20: PROC ~ {
Imager.TranslateT[context, [bounds.w/2, bounds.h/2]];
RandomScaleRotate[context];
Imager.TranslateT[context, [-bounds.w/2, -bounds.h/2]];
CoordSys[context];
Imager.SetXY[context, [0, 0]];
IF 0 = RandI[0,5] THEN RandomClip[context];
FOR i: INT IN [0..20) UNTIL n = 0 DO
IF 0 = RandI[0, 99] THEN RandomClip[context];
RandomColor[context];
RandomMask[context];
n ← n - 1;
Process.CheckForAbort[];
ENDLOOP;
};
Imager.ScaleT[context, 0.0254/72];
scale ← [bounds.w, bounds.h];
UNTIL n <= 0 DO
Imager.DoSaveAll[context, Do20];
ENDLOOP;
};
interpress: ImagerInterpress.Ref ~ ImagerInterpress.Create["Random.interpress"];
FOR i: NAT IN [0..5) DO
ImagerInterpress.DeclareFont[interpress, ImagerFont.Find[fontName[i]]];
ENDLOOP;
ImagerInterpress.DeclarePixelArray[interpress, imagePA];
ImagerInterpress.DeclarePixelArray[interpress, rgbImagePA];
ImagerInterpress.DeclarePixelArray[interpress, pa1];
ImagerInterpress.DeclarePixelArray[interpress, pa2];
ImagerInterpress.DeclarePixelArray[interpress, pa3];
ImagerInterpress.DeclareColorOperator[interpress, imageColorOperator];
THROUGH [0..nPages) DO ImagerInterpress.DoPage[interpress, page] ENDLOOP;
ImagerInterpress.Close[interpress];
};
END.
Run InterpressPackage
Run RandomImagerImpl
Run ImagerViewerImpl
← &c ← ImagerViewer.Create[[name: "Random Imager"], pixels]
← RandomImagerImpl.Setup[]
← RandomImagerImpl.Run[&c]