<> <> <> <<>> 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: BOOL _ FALSE; <> 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: INT _ IF 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: BOOL _ FALSE; 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 WORD _ NEW[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: BOOL _ FALSE] ~ { 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: BOOL _ FALSE; 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: REAL _ IF 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: BOOL _ FALSE] ~ { 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. <> <> <> <<_ &c _ ImagerViewer.Create[[name: "Random Imager"], pixels]>> <<_ RandomImagerImpl.Setup[]>> <<_ RandomImagerImpl.Run[&c]>>