DIRECTORY ColorFns, ColorTypes, ImagerBackdoor USING [invert], ImagerColor, NamedColors, RealFns USING [AlmostZero, Log, Power], Rope USING [ROPE], JaMIPrivate, JaM USING [Any, Error, Pop, PopReal, Register, PopBool, PushReal, State, Push, PopRope], WindowManager USING[ ScreenPos]; JaMIColorImpl: CEDAR MONITOR IMPORTS ColorFns, JaM, ImagerBackdoor, ImagerColor, NamedColors, RealFns EXPORTS JaMIPrivate = { OPEN J: JaM, P: JaMIPrivate; ROPE: TYPE = Rope.ROPE; screenpos: WindowManager.ScreenPos ฌ left; OnLeft: PROC [state: JaM.State] = { onLeft: BOOLEAN ฌ J.PopBool[state]; IF onLeft THEN screenpos ฌ left ELSE screenpos ฌ right; }; ColorFromName: PROC [r: Rope.ROPE] RETURNS [c: ImagerColor.ConstantColor] ~ { RETURN [ImagerColor.ColorFromRGB[ ColorFns.RGBFromHSL[NamedColors.RopeToHSL[r]] ]]; }; PopColor: PROC [self: JaM.State] RETURNS [ImagerColor.OpConstantColor] ~ TRUSTED { x: JaM.Any ~ JaM.Pop[self]; WITH x SELECT FROM x: ImagerColor.Color => RETURN[LOOPHOLE[x]]; x: ImagerColor.ConstantColor => RETURN[LOOPHOLE[x]]; x: ImagerColor.OpConstantColor => RETURN[x]; ENDCASE => ERROR JaM.Error[WrongType]; }; Red: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Red"]]}; Green: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Green"]]}; Blue: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Blue"]]}; Magenta: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Magenta"]]}; Cyan: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Cyan"]]}; Yellow: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Yellow"]]}; Black: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Black"]]}; White: PROC [state: JaM.State] = {PushColor[state, ColorFromName["White"]]}; InvertedColor: PROC [state: JaM.State] = { PushColor[state, ImagerBackdoor.invert] }; Gray: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromGray[.5]]}; PushColor: PROC [self: J.State, x: ImagerColor.ConstantColor] ~ { IF x#NIL THEN J.Push[self, x] ELSE ERROR J.Error[WrongType]; }; IColor: PROC [state: JaM.State] = { gray: REAL ฌ J.PopReal[state]; gray ฌ MIN[MAX[0,gray],1]; JaM.Push[state, ImagerColor.ColorFromGray[gray]]; }; RGBColor: PROC [state: JaM.State] = { b: REAL ฌ MAX[MIN[1,J.PopReal[state]],0]; g: REAL ฌ MAX[MIN[1,J.PopReal[state]],0]; r: REAL ฌ MAX[MIN[1,J.PopReal[state]],0]; JaM.Push[state, ImagerColor.ColorFromRGB[rgb: [r,g,b]]]; }; CMYKColor: PROC [state: JaM.State] = { k: REAL = MAX[MIN[1,J.PopReal[state]],0]; y: REAL = MAX[MIN[1,J.PopReal[state]],0]; m: REAL = MAX[MIN[1,J.PopReal[state]],0]; c: REAL = MAX[MIN[1,J.PopReal[state]],0]; JaM.Push[state, ImagerColor.ColorFromCMYK[[c,m,y,k]]]; }; CMYColor: PROC [state: JaM.State] = { y: REAL = MAX[MIN[1,J.PopReal[state]],0]; m: REAL = MAX[MIN[1,J.PopReal[state]],0]; c: REAL = MAX[MIN[1,J.PopReal[state]],0]; JaM.Push[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromCMY[[c,m,y]] ]]; }; HSVColor: PROC [state: JaM.State] = { v: REAL = MAX[MIN[1,J.PopReal[state]],0]; s: REAL = MAX[MIN[1,J.PopReal[state]],0]; h: REAL = MAX[MIN[1,J.PopReal[state]],0]; rgb: ImagerColor.RGB = ColorFns.RGBFromHSV[[h, s, v]]; JaM.Push[state, ImagerColor.ColorFromRGB[rgb]]; }; HSLColor: PROC [state: JaM.State] = { l: REAL = MAX[MIN[1,J.PopReal[state]],0]; s: REAL = MAX[MIN[1,J.PopReal[state]],0]; h: REAL = MAX[MIN[1,J.PopReal[state]],0]; rgb: ImagerColor.RGB = ColorFns.RGBFromHSL[[h, s, l]]; JaM.Push[state, ImagerColor.ColorFromRGB[rgb]]; }; HSLFromColor: PROC [state: JaM.State] = { color: ImagerColor.OpConstantColor = PopColor[state]; rgb: ImagerColor.RGB ฌ ImagerColor.RGBFromColor[color]; hsl: ColorTypes.HSL ฌ ColorFns.HSLFromRGB[rgb]; JaM.PushReal[state,hsl.H]; JaM.PushReal[state,hsl.S]; JaM.PushReal[state,hsl.L]; }; HSVFromColor: PROC [state: JaM.State] = { color: ImagerColor.OpConstantColor = PopColor[state]; rgb: ImagerColor.RGB ฌ ImagerColor.RGBFromColor[color]; hsv: ColorFns.HSV ฌ ColorFns.HSVFromRGB[rgb]; J.PushReal[state,hsv.H]; J.PushReal[state,hsv.S]; J.PushReal[state,hsv.V]; }; RGBFromColor: PROC [state: JaM.State] = { color: ImagerColor.OpConstantColor = PopColor[state]; rgb: ImagerColor.RGB ฌ ImagerColor.RGBFromColor[color]; JaM.PushReal[state,rgb.R]; JaM.PushReal[state,rgb.G]; JaM.PushReal[state,rgb.B]; }; GetColorFromName: PROC [state: JaM.State] = { name: ROPE ฌ JaM.PopRope[state]; PushColor[state, ColorFromName[name]]; }; FindColor: PROC [state: JaM.State] = { name: ROPE ฌ JaM.PopRope[state]; PushColor[state, ImagerColor.Find[name]]; }; Vec3: TYPE = RECORD[v0, v1, v2: REAL]; GetVec3: PROC[state: JaM.State] RETURNS[v: Vec3] = { v.v2 ฌ JaM.PopReal[state]; v.v1 ฌ JaM.PopReal[state]; v.v0 ฌ JaM.PopReal[state]; }; Mix3: PROC[state: JaM.State] RETURNS[v: Vec3] = { pb: REAL ฌ JaM.PopReal[state]; pa: REAL ฌ JaM.PopReal[state]; b: Vec3 ฌ GetVec3[state]; a: Vec3 ฌ GetVec3[state]; v.v0 ฌ MIN[MAX[a.v0*pa+b.v0*pb, 0],1]; v.v1 ฌ MIN[MAX[a.v1*pa+b.v1*pb, 0],1]; v.v2 ฌ MIN[MAX[a.v2*pa+b.v2*pb, 0],1]; }; Interp3: PROC[state: JaM.State] RETURNS[v: Vec3] = { d: REAL ฌ JaM.PopReal[state]; b: Vec3 ฌ GetVec3[state]; a: Vec3 ฌ GetVec3[state]; v.v0 ฌ (1-d)*a.v0+d*b.v0; v.v1 ฌ (1-d)*a.v1+d*b.v1; v.v2 ฌ (1-d)*a.v2+d*b.v2; }; MixRGB: PROC[state: JaM.State] = { rgb: ImagerColor.RGB; [[rgb.R, rgb.G, rgb.B]] ฌ Mix3[state]; PushColor[state, ImagerColor.ColorFromRGB[rgb]]; }; MixHSL: PROC[state: JaM.State] = { hsl: ColorFns.HSL; [[hsl.H, hsl.S, hsl.L]] ฌ Mix3[state]; PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromHSL[hsl]]]; }; MixHSV: PROC[state: JaM.State] = { hsv: ColorFns.HSV; [[hsv.H, hsv.S, hsv.V]] ฌ Mix3[state]; PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromHSV[hsv]]]; }; MixCMY: PROC[state: JaM.State] = { cmy: ColorFns.CMY; [[cmy.C, cmy.M, cmy.Y]] ฌ Mix3[state]; PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromCMY[cmy]]]; }; InterpRGB: PROC[state: JaM.State] = { rgb: ImagerColor.RGB; [[rgb.R, rgb.G, rgb.B]] ฌ Interp3[state]; PushColor[state, ImagerColor.ColorFromRGB[rgb]]; }; InterpHSL: PROC[state: JaM.State] = { hsl: ColorFns.HSL; [[hsl.H, hsl.S, hsl.L]] ฌ Interp3[state]; PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromHSL[hsl]]]; }; InterpHSV: PROC[state: JaM.State] = { hsv: ColorFns.HSV; [[hsv.H, hsv.S, hsv.V]] ฌ Interp3[state]; PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromHSV[hsv]]]; }; InterpCMY: PROC[state: JaM.State] = { cmy: ColorFns.CMY; [[cmy.C, cmy.M, cmy.Y]] ฌ Interp3[state]; PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromCMY[cmy]]]; }; drMax: REAL ฌ 1.385; dgMax: REAL ฌ 1.032; dbMax: REAL ฌ 1.13; rMin: REAL ฌ 0.041; gMin: REAL ฌ 0.09; bMin: REAL ฌ 0.074; RGBForVtec: PROC [state: JaM.State] = { b: REAL ฌ JaM.PopReal[state]; g: REAL ฌ JaM.PopReal[state]; r: REAL ฌ JaM.PopReal[state]; dr: REAL ฌ IF r < rMin THEN drMax ELSE RealFns.Log[arg: 1.0/r,base: 10]; dg: REAL ฌ IF g < gMin THEN dgMax ELSE RealFns.Log[arg: 1.0/g,base: 10]; db: REAL ฌ IF b < bMin THEN dbMax ELSE RealFns.Log[arg: 1.0/b,base: 10]; newDr, newDg, newDb: REAL; newDr ฌ dr*0.8038-dg*0.1154-db*0.0999; newDg ฌ dr*(-0.5522)+dg*1.1776-db*0.119; newDb ฌ dr*0.1035-dg*0.7085+db*0.9906; JaM.PushReal[state, ClipRange[RealFns.Power[base: 10, exponent: -1*newDr]]]; JaM.PushReal[state, ClipRange[RealFns.Power[base: 10, exponent: -1*newDg]]]; JaM.PushReal[state, ClipRange[RealFns.Power[base: 10, exponent: -1*newDb]]]; }; ClipRange: PROC [v: REAL] RETURNS[REAL] = { RETURN[MIN[MAX[0,v],1]]; }; Defuzz: PROC [v: REAL] RETURNS[REAL] = { IF RealFns.AlmostZero[v,-10] THEN v ฌ 0; IF RealFns.AlmostZero[v-1.0,-10] THEN v ฌ 1; RETURN[v]; }; RegisterColor: PUBLIC PROC[state: JaM.State] = { J.Register[state,".onleft",OnLeft]; J.Register[state,".red", Red]; J.Register[state,".green", Green]; J.Register[state,".blue", Blue]; J.Register[state,".magenta", Magenta]; J.Register[state,".cyan", Cyan]; J.Register[state,".yellow", Yellow]; J.Register[state,".black", Black]; J.Register[state,".white", White]; J.Register[state,".gray", Gray]; J.Register[state,".invertedcolor", InvertedColor]; J.Register[state,".icolor", IColor]; J.Register[state,".rgbcolor", RGBColor]; J.Register[state,".hsvcolor", HSVColor]; J.Register[state,".cmykcolor", CMYKColor]; J.Register[state,".cmycolor", CMYColor]; J.Register[state,".hslcolor", HSLColor]; J.Register[state,".hsvfromcolor", HSVFromColor]; J.Register[state,".rgbfromcolor", RGBFromColor]; J.Register[state,".hslfromcolor", HSLFromColor]; J.Register[state,".rgbforvtec", RGBForVtec]; J.Register[state,".colorfromname", GetColorFromName]; J.Register[state,".findcolor", FindColor]; J.Register[state,".mixRGB", MixRGB]; J.Register[state,".mixHSL", MixHSL]; J.Register[state,".mixHSV", MixHSV]; J.Register[state,".mixCMY", MixCMY]; J.Register[state,".interpRGB", InterpRGB]; J.Register[state,".interpHSL", InterpHSL]; J.Register[state,".interpHSV", InterpHSV]; J.Register[state,".interpCMY", InterpCMY]; }; }. ฦ JaMIColorImpl.mesa Copyright ำ 1984, 1985, 1987, 1992 by Xerox Corporation. All rights reserved. last edited by Maureen Stone August 14, 1984 6:25:02 pm PDT Tim Diebert: August 1, 1985 1:55:30 pm PDT Last edited by: Mik Lamming - June 20, 1986 11:24:24 am PDT Alfred Permuy July 1, 1986 2:38:54 pm PDT Maureen Stone, July 12, 1987 6:08:08 pm PDT Bier, September 15, 1992 5:40 pm PDT Terminal USING [Current, GetColorMode, SetColorCursorPresentation, ColorMode], maxIndex: INTEGER _ MaxIndex[]; TurnOnColor: PROC[state: JaM.State] = { nbits: INTEGER _ J.PopInt[state]; SELECT nbits FROM 0 => WindowManager.StopColorViewers[]; 1 => WindowManager.StartColorViewers[screenpos,1]; 2 => WindowManager.StartColorViewers[screenpos,2]; 4 => WindowManager.StartColorViewers[screenpos,4]; 8 => WindowManager.StartColorViewers[screenpos,8]; 24 => WindowManager.StartColorViewers[screenpos,24]; ENDCASE; maxIndex _ MaxIndex[]; }; MaxIndex: PROC RETURNS[max: CARDINAL] = { mode: Terminal.ColorMode _ Terminal.GetColorMode[Terminal.Current[]]; max _ IF NOT mode.full THEN SELECT mode.bitsPerPixelChannelA FROM 1 => 1, 2 => 3, 4 => 15, 8 => 255, ENDCASE => 0 ELSE 0; }; TurnOffColor: PROC [state: JaM.State] = {WindowManager.StopColorViewers[]}; GrayMap: PROCEDURE [state: JaM.State] = {ColorMap.GrayMap[]}; StandardMap: PROCEDURE [state: JaM.State] = {ColorMap.StandardMap[]}; SetGamma: PROC [state: JaM.State] = {ColorMap.SetGamma[J.PopReal[state]]}; GetGamma: PROC [state: JaM.State] = {J.PushReal[state, ColorMap.GetGamma[]]}; SetRGBColorMap: PROC [state: JaM.State] = { b: REAL _ MAX[MIN[1,J.PopReal[state]],0]; g: REAL _ MAX[MIN[1,J.PopReal[state]],0]; r: REAL _ MAX[MIN[1,J.PopReal[state]],0]; index: INTEGER _ J.PopInt[state]; index _ MAX[MIN[maxIndex,index],0]; [] _ ColorMap.SetRGBColor[index,r,g,b]; }; SetHSVColorMap: PROC [state: JaM.State] = { v: REAL _ MAX[MIN[1,J.PopReal[state]],0]; s: REAL _ MAX[MIN[1,J.PopReal[state]],0]; h: REAL _ MAX[MIN[1,J.PopReal[state]],0]; index: INTEGER _ J.PopInt[state]; index _ MAX[MIN[maxIndex,index],0]; [] _ ColorMap.SetHSVColor[index,h,s,v]; }; GetMapValue: PROC [state: JaM.State] = { index: INTEGER _ J.PopInt[state]; r,g,b: REAL; [r,g,b] _ ColorMap.GetColor[MAX[MIN[maxIndex,index],0]]; J.PushReal[state,r/255.0]; J.PushReal[state,g/255.0]; J.PushReal[state,b/255.0]; }; BlackCursor: PROC [state: JaM.State] = { [] _ Terminal.SetColorCursorPresentation[Terminal.Current[], onesAreBlack]}; WhiteCursor: PROC [state: JaM.State] = { [] _ Terminal.SetColorCursorPresentation[Terminal.Current[], onesAreWhite]}; a value of 0 is an infinite density. need infinity and zero values to keep values in bounds Initialization starts here J.Register[state, ".displayatom", SetDisplayAtom]; J.Register[state,".turnoncolor",TurnOnColor]; J.Register[state,".turnoffcolor",TurnOffColor]; J.Register[state,".graymap",GrayMap]; J.Register[state,".standardmap",StandardMap]; J.Register[state,".setgamma",SetGamma]; J.Register[state,".getgamma",GetGamma]; J.Register[state,".setrgbmap",SetRGBColorMap]; J.Register[state,".sethsvmap", SetHSVColorMap]; J.Register[state,".getmapvalue", GetMapValue]; J.Register[state,".blackcursor", BlackCursor]; J.Register[state,".whitecursor", WhiteCursor]; J.Register[state,".getcolor", GetColor]; ส –"cedarcode" style•NewlineDelimiter ™codešœ™Kšœ ฯeœC™NKšœ;™;K™*K™;K™)K™+K™$—K˜šฯk ˜ K˜ K˜ Kšœžœ ˜Kšœ ˜ K˜ Kšœžœ˜'Kšœžœžœ˜K˜ KšœžœO˜XKšœ žœ@™NKšœžœ ˜ K˜—šะln œž ˜KšžœA˜HKšžœ˜Kšžœžœžœ˜K˜Kšžœžœžœ˜Kšœ žœ™šฯn œžœ™(Kšœžœžœ™!šžœž™K™&K™2K™2K™2K™2K™4Kšžœ™—™K™K™——š œžœžœžœ™)KšœE™Ešœ™š žœžœ žœžœžœ™Kš  œž œ/™FKš œžœ)žœ™JKš œžœžœ'™MK™š œžœ™+Kš œžœžœžœžœ™)Kš œžœžœžœžœ™)Kš œžœžœžœžœ™)Kšœžœžœ™!Kšœžœžœ™#K™'K™K™—š œžœ™+Kš œžœžœžœžœ™)Kš œžœžœžœžœ™)Kš œžœžœžœžœ™)Kšœžœžœ™!Kšœžœžœ™#K™'K™K™—š  œžœ™(Kšœžœžœ™!Kšœžœ™ Kšœžœžœ™8Kšžœ™Kšžœ™Kšžœ™K™K˜—š  œžœ žœžœ#˜MKšžœM˜SK˜K˜—š œžœžœ!žœ˜RK˜šžœžœž˜Kšœžœžœ˜,Kšœ žœžœ˜4Kšœ"žœ˜,Kšžœžœ˜&—K˜K˜—Kš œžœE˜NKš œžœG˜RKš œžœF˜PKš œžœI˜VKš œžœF˜PKš œžœH˜TKš œžœA˜LKš œžœA˜Lš  œžœ˜*Kšœ'˜'Kšœ˜—Kš œžœH˜RK˜š  œžœžœ)˜AKšžœžœžœžœ˜Kšžœžœžœ˜K˜—K˜š œžœ˜#Kšœžœžœ˜Kšœžœžœ ˜Kšœ1˜1K˜K˜—š œžœ˜%Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)Kšœ8˜8K˜K˜—š  œžœ˜&Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)K˜6K˜K˜—š œžœ˜%Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)K˜IK˜K˜—š œžœ˜%Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)Kšœžœ"˜6Kšœ/˜/K˜K˜—š œžœ˜%Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)Kš œžœžœžœžœ˜)Kšœžœ"˜6Kšœ/˜/K˜K˜—š  œžœ˜)K˜5Kšœžœ#˜7Kšœžœ˜/K˜K˜K˜K˜—š  œžœ˜)K˜5Kšœžœ#˜7Kšœžœ˜-Kšœ˜Kšœ˜Kšœ˜K˜K˜—š  œžœ˜)K˜5Kšœžœ#˜7K˜K˜K˜K˜—K˜šฯbœžœ˜-Kšœžœ˜ Kšœ&˜&K˜K˜—šก œžœ˜&Kšœžœ˜ Kšœ)˜)K˜—K˜Kšœžœžœ žœ˜&š œžœžœ ˜4K˜K˜K˜K˜—š œžœžœ ˜1Kšœžœ˜Kšœžœ˜K˜K˜Kšœžœžœ˜&Kšœžœžœ˜&Kšœžœžœ˜&K˜—š œžœžœ ˜4Kšœžœ˜K˜K˜K˜K˜K˜K˜—š œžœ˜"K˜K˜&Kšœ0˜0K˜—š œžœ˜"K˜K˜&K˜EK˜—š œžœ˜"K˜K˜&K˜EK˜—š œžœ˜"Kšœžœ˜K˜&K˜EK˜—K˜š  œžœ˜%K˜K˜)Kšœ0˜0K˜—š  œžœ˜%K˜K˜)K˜EK˜—š  œžœ˜%K˜K˜)K˜EK˜—š  œžœ˜%Kšœžœ˜K˜)K˜EK˜—K˜š  œžœ™(KšœL™L—š  œžœ™(KšœL™L—K˜Kšœžœ ˜Kšœžœ ˜Kšœžœ˜Kšœžœ ˜Kšœžœ˜Kšœžœ ˜K˜K˜š  œžœ˜'Kšœžœ˜Kšœžœ˜Kšœžœ˜K™\Kš œžœžœ žœžœ"˜HKš œžœžœ žœžœ"˜HKš œžœžœ žœžœ"˜HKšœžœ˜K˜&K˜(K˜&KšœL˜LKšœL˜LKšœL˜LK˜—K˜š   œžœžœžœžœ˜+Kšžœžœžœ ˜K˜K˜—š  œžœžœžœžœ˜(Kšžœžœ˜(Kšžœžœ˜,Kšžœ˜ K˜K˜—K˜Kšœ™K˜šœž œ˜0Kšžœ1™2Kšžœ,™-Kšžœ.™/Kšžœ"˜#Kšžœ$™%Kšžœ,™-Kšžœ&™'Kšžœ&™'Kšžœ-™.Kšžœ.™/Kšžœ-™.Kšžœ˜Kšžœ!˜"Kšžœ˜ Kšžœ%˜&Kšžœ˜ Kšžœ#˜$Kšžœ!˜"Kšžœ!˜"Kšžœ˜ Kšžœ1˜2Kšžœ#˜$Kšžœ'˜(Kšžœ'˜(Kšžœ)˜*Kšžœ'˜(Kšžœ'˜(Kšžœ/˜0Kšžœ/˜0Kšžœ/˜0Kšžœ+˜,Kšžœ-™.Kšžœ-™.Kšžœ4˜5Kšžœ)˜*Kšœ$˜$Kšœ$˜$Kšœ$˜$Kšœ$˜$Kšœ*˜*Kšœ*˜*Kšœ*˜*Kšœ*˜*Kšžœ'™(K˜K˜K˜—K˜—K˜Kšกœ˜—…—"า<ฉ