DIRECTORY Basics USING [BITAND, BITSHIFT], Buttons USING [Button, ButtonProc, Create, SetDisplayStyle], CD USING [backgroundLayer, FetchTechnology, errorLayer, shadeLayer, Layer, Technology], CDColors USING [Brick, DefineColor, DefineIColor], CDCommandOps USING [RegisterWithMenu], CDIO USING [GetWorkingDirectory], CDSequencer USING [Command, CommandProc, FetchCommand, ImplementCommand], CDSil USING [cdsil, xaqua, xblue, xbrown, xcyan, xgreen, xlime, xmagenta, xneutral, xorange, xpink, xred, xsmoke, xturquise, xultraviolet, xviolet, xwhite, xyellow], Commander USING [CommandProc, Handle, Register], Containers USING [ChildXBound, ChildYBound, Container, Create], Convert USING [RopeFromInt], Imager USING [Context], ImagerColor USING [ColorFromRGB], ImagerColorMap USING [LoadEntries, MapEntry], ImagerDitherContext USING [MapEntries, SetDitherMap], ImagerTerminal USING [BWContext, ColorContext], InterminalBackdoor USING [terminal], Icons USING [NewIconFromFile], Labels USING [Create, Label, Set], MessageWindow USING [Append], Process USING [Detach], Real USING [Fix, Float, Round], Rope USING [Cat, Concat, Equal, ROPE], Sliders USING [Create, NormalizedSliderValue, SetContents, Slider, SliderProc], Terminal USING [GetColorMode, LegalColorMode, SetColorCursorPresentation, Virtual], TerminalIO USING [RequestSelection, PutRope], UserProfile USING [Boolean, Number, Token], ViewerClasses USING [Viewer], ViewerOps USING [FindViewer, OpenIcon, PaintViewer, SetOpenHeight], ViewerPrivate USING [ContextCreatorProc, SetCreator], WindowManager USING [ScreenPos, StartColorViewers]; CDSil8BitColors: CEDAR PROGRAM IMPORTS Basics, Buttons, CD, CDColors, CDCommandOps, CDIO, CDSequencer, CDSil, Commander, Containers, Convert, Icons, ImagerColor, ImagerColorMap, ImagerDitherContext, ImagerTerminal, InterminalBackdoor, Labels, MessageWindow, Process, Real, Rope, Sliders, Terminal, TerminalIO, UserProfile, ViewerOps, ViewerPrivate, WindowManager = BEGIN terminal: Terminal.Virtual _ InterminalBackdoor.terminal; useMapEntries: ImagerDitherContext.MapEntries _ NIL; ContextCreator: ViewerPrivate.ContextCreatorProc = BEGIN context: Imager.Context; SELECT screen FROM bw => context _ ImagerTerminal.BWContext[vt: terminal, pixelUnits: TRUE]; color => { context _ ImagerTerminal.ColorContext[vt: terminal, pixelUnits: TRUE]; IF useMapEntries#NIL THEN ImagerDitherContext.SetDitherMap[context, useMapEntries]; [] _ Terminal.SetColorCursorPresentation[terminal, onesAreWhite]; } ENDCASE => ERROR; RETURN [context] END; ForceColors: PROC [mapEntries: ImagerDitherContext.MapEntries] = BEGIN useMapEntries _ mapEntries; ImagerColorMap.LoadEntries[vt: terminal, mapEntries: mapEntries, gamma: 1, shared: FALSE]; [] _ Terminal.SetColorCursorPresentation[terminal, onesAreWhite]; [] _ ViewerPrivate.SetCreator[ContextCreator]; END; CallMenu: Buttons.ButtonProc = BEGIN p: CDSequencer.CommandProc _ CDSequencer.FetchCommand[$ColorDisplayMenuC, technology].proc; IF p#NIL THEN p[NIL]; END; ColorRec: TYPE = RECORD [r, g, b, w: REAL _ 0, name: Rope.ROPE _ NIL]; ColorDescRep: TYPE = ARRAY [0..numberOfColors) OF ColorRec; Exception: TYPE = RECORD [x: CARDINAL, c: ColorRec, replace: BOOL _ TRUE]; technology: CD.Technology _ CDSil.cdsil; technologyName: Rope.ROPE _ technology.name; numberOfColors: INT = 8; -- background and "primary" colors numberOfNormalColors: INT = 7; -- without background numberOfTotalColors: INT = 18; mapRange: TYPE = [0 .. numberOfTotalColors); myMap: ARRAY mapRange OF RECORD [l: CD.Layer, c: ColorRec] = [ [CD.backgroundLayer, [r: 0.49, g: 0.62, b: 0.62, w: 0.05, name: "Sub"]], [CDSil.xred, [r: 1, g: 0, b: 0, w: 0.75, name: "Red"]], [CDSil.xgreen, [r: 0, g: 1, b: 0, w: 0.75, name: "Green"]], [CDSil.xblue, [r: 0, g: 0, b: 1, w: 0.75, name: "Blue"]], [CDSil.xcyan, [r: 0, g: 1, b: 1, w: 0.75, name: "Cyan"]], [CDSil.xmagenta, [r: 1, g: 0, b: 1, w: 0.75, name: "Magenta"]], [CDSil.xyellow, [r: 1, g: 1, b: 0, w: 0.75, name: "Yellow"]], [CDSil.xwhite, [r: 1, g: 1, b: 1, w: 1, name: "White"]], [CDSil.xaqua, [r: 0.42, g: 0.92, b: 0.55, w: 0.75, name: "Aqua"]], [CDSil.xturquise, [r: 0.42, g: 0.70, b: 0.92, w: 0.75, name: "Turquoise"]], [CDSil.xbrown, [r: 0.25, g: 0.12, b: 0.08, w: 0.75, name: "DarkBrown"]], [CDSil.xviolet, [r: 0.45, g: 0.25, b: 0.75, w: 0.75, name: "Violet"]], [CDSil.xultraviolet, [r: 0.13, g: 0.0, b: 0.33, w: 0.75, name: "Ultraviolet"]], [CDSil.xorange, [r: 0.64, g: 0.2752, b: 0.16, w: 0.75, name: "Orange"]], -- we prefer our orange [CDSil.xsmoke, [r: 0.50, g: 0.50, b: 0.50, w: 0.75, name: "Smoke"]], -- grey [CDSil.xlime, [r: 0.39, g: 0.75, b: 0.25, w: 0.75, name: "Lime"]], [CDSil.xpink, [r: 0.90 , g: 0.45, b: 0.55, w: 0.75, name: "Pink"]], -- we need a bit more red and less green in it [CDSil.xneutral, [r: 0, g: 0, b: 0, w: 0.75, name: "Neutral"]]]; -- Black -- Order is important !!! cDefaults: REF ColorDescRep _ NEW [ColorDescRep _ [ myMap[0].c, myMap[1].c, myMap[2].c, myMap[3].c, myMap[4].c, myMap[5].c, myMap[6].c, myMap[7].c ]]; neutral: ColorRec = myMap[17].c; -- Black violet: ColorRec = myMap[11].c; darkBrown: ColorRec = myMap[10].c; lime: ColorRec = myMap[15].c; turquoise: ColorRec = myMap[9].c; aqua: ColorRec = myMap[8].c; ultraviolet: ColorRec = myMap[12].c; pink: ColorRec = myMap[16].c; smoke: ColorRec = myMap[14].c; -- Grey red: CARDINAL = 1; green: CARDINAL = 2; blue: CARDINAL = 4; cyan: CARDINAL = 8; magenta: CARDINAL = 16; yellow: CARDINAL = 32; white: CARDINAL = 64; fakeAqua: CARDINAL = green+cyan; -- 10 fakeTurquoise: CARDINAL = blue + cyan; -- 12 fakeBrown: CARDINAL = green+magenta; -- 18 fakeViolet: CARDINAL = cyan+magenta; -- 24 fakeUltraviolet: CARDINAL = blue + cyan + magenta; -- 28 orange: CARDINAL = red+yellow; -- 33 this orange is better than the one used by Sil fakeSmoke: CARDINAL = blue+yellow; -- 36 fakeLime: CARDINAL = cyan+yellow; -- 40 fakePink: CARDINAL = magenta + white; -- 80 fakeBlack: CARDINAL = white-1; Init8Patterns: Buttons.ButtonProc = BEGIN pixel1: CARDINAL = 1; pixel3: CARDINAL = 256; Mixture: PROC [col: CARDINAL] RETURNS [REF CDColors.Brick] ~ BEGIN RETURN [Dither1to1 [col, col]] END; -- Dither1to0 Dither1to1: PROC [col1, col2: CARDINAL _ white] RETURNS [REF CDColors.Brick] ~ BEGIN RETURN [NEW [CDColors.Brick _ [col1*pixel1+col2*pixel3, col2*pixel1+col1*pixel3, col1*pixel1+col2*pixel3, col2*pixel1+col1*pixel3]]] END; -- Dither1to1 Lighten: PROC[l: CD.Layer, color: CARDINAL] = BEGIN CDColors.DefineColor [l, Dither1to1[color], bit8, pushedOut]; END; CDColors.DefineColor[CDSil.xneutral, Mixture[fakeBlack], bit8]; CDColors.DefineColor[CDSil.xred, Mixture[red], bit8]; CDColors.DefineColor[CDSil.xyellow, Mixture[yellow], bit8]; CDColors.DefineColor[CDSil.xgreen, Mixture[green], bit8]; CDColors.DefineColor[CDSil.xcyan, Mixture[cyan], bit8]; CDColors.DefineColor[CDSil.xviolet, Mixture[fakeViolet], bit8]; CDColors.DefineColor[CDSil.xmagenta, Mixture[magenta], bit8]; CDColors.DefineColor[CDSil.xwhite, Mixture[white], bit8]; CDColors.DefineColor[CDSil.xbrown, Mixture[fakeBrown], bit8]; CDColors.DefineColor[CDSil.xorange, Mixture[orange], bit8]; CDColors.DefineColor[CDSil.xlime, Mixture[fakeLime], bit8]; CDColors.DefineColor[CDSil.xturquise, Mixture[fakeTurquoise], bit8]; CDColors.DefineColor[CDSil.xaqua, Mixture[fakeAqua], bit8]; CDColors.DefineColor[CDSil.xultraviolet, Mixture[fakeUltraviolet], bit8]; CDColors.DefineColor[CDSil.xpink, Mixture[fakePink], bit8]; CDColors.DefineColor[CDSil.xsmoke, Mixture[fakeSmoke], bit8]; CDColors.DefineColor[CDSil.xblue, Mixture[blue], bit8]; CDColors.DefineColor[CD.backgroundLayer, NEW[CDColors.Brick _ [8, 0, 256*8, 0]], bit8]; CDColors.DefineColor[CD.errorLayer, NEW[CDColors.Brick _ [255, 0, 0, 0]], bit8]; CDColors.DefineColor[CD.shadeLayer, NEW[CDColors.Brick_[0, 255,0 , 255]], bit8]; Lighten[CDSil.xneutral, fakeBlack]; Lighten[CDSil.xred, red]; Lighten[CDSil.xyellow, yellow]; Lighten[CDSil.xgreen, green]; Lighten[CDSil.xcyan, cyan]; Lighten[CDSil.xviolet, fakeViolet]; Lighten[CDSil.xmagenta, magenta]; Lighten[CDSil.xwhite, white]; Lighten[CDSil.xbrown, fakeBrown]; Lighten[CDSil.xorange, orange]; Lighten[CDSil.xlime, fakeLime]; Lighten[CDSil.xturquise, fakeTurquoise]; Lighten[CDSil.xaqua, fakeAqua]; Lighten[CDSil.xultraviolet, fakeUltraviolet]; Lighten[CDSil.xpink, fakePink]; Lighten[CDSil.xsmoke, fakeBlack]; Lighten[CDSil.xblue, blue]; HackContextColors[]; END; SetupSpecials: PROC [] = BEGIN specials2 _ LIST [ [x: fakeAqua + 1, c: aqua], [x: fakeTurquoise + 1, c: turquoise], [x: fakeBrown + 1, c: darkBrown], [x: fakeViolet + 1, c: violet], [x: fakeUltraviolet + 1, c: ultraviolet], [x: fakeSmoke + 1, c: smoke], [x: fakeLime + 1, c: lime], [x: fakePink, c: pink], [x: fakeBlack, c: neutral]]; specials3 _ LIST[ [x: 245, c: [0, 0, 1, 1]], --get all nice colors back for other users [x: 247, c: [0, 1, 0, 1]], [x: 249, c: [0, 1, 1, 1]], [x: 250, c: [1, 0, 1, 1]], [x: 251, c: [1, 1, 0, 1]], [x: 252, c: [1, 1, 1, 1]], --white as opposite to 1+2 [x: 253, c: [0, 0, 0, 1]], [x: 254, c: [1, 0, 0, 1]], IF whiteOutLine THEN Exception[x: 255, c: [1, 1, 1, 1]] ELSE Exception[x: 255, c: [0, 0, 0, 1]] --all bits set ] END; HackContextColors: PROC [] = BEGIN FOR i: mapRange IN mapRange DO CDColors.DefineIColor[ layer: myMap[i].l, col: ImagerColor.ColorFromRGB[rgb: [R: myMap[i].c.r, G: myMap[i].c.g, B: myMap[i].c.b]], display: bit8 ] ENDLOOP; END; whiteOutLine: BOOL; currentColor: REF ColorDescRep = NEW[ColorDescRep]; curLayer: INT _ 1; prevLayer: INT _ 1; -- to deselect the previous layer button CoefSlider: TYPE = RECORD [ value: Labels.Label _ NIL, select: Buttons.Button _ NIL, bar: Sliders.Slider _ NIL ]; ColorSlider: TYPE = RECORD [ value: Labels.Label _ NIL, bar: Sliders.Slider _ NIL ]; Handle: TYPE = REF AdjustColorRec; AdjustColorRec: TYPE = RECORD [ outer: Containers.Container _ NIL, coefLayer: ARRAY [0..numberOfColors) OF CoefSlider, potarColor: ARRAY [0..3) OF ColorSlider, height: CARDINAL _ 0 -- height measured from the top of the container ]; DataForSpecialProc: TYPE = REF DataForSpecialProcRec; DataForSpecialProcRec: TYPE = RECORD [ my: Handle, layer: CARDINAL ]; caption: Rope.ROPE = Rope.Concat[technologyName, " 8 bit color editor"]; ColorModeIs8: PROC [] RETURNS [BOOL] = INLINE BEGIN RETURN [terminal.hasColorDisplay AND ~terminal.GetColorMode[].full AND terminal.GetColorMode[].bitsPerPixelChannelA=8]; END; Check8BitMode: PROC [] RETURNS [ok: BOOL] = BEGIN ok _ ColorModeIs8[]; IF ~ok THEN TRUSTED{Process.Detach[FORK TerminalIO.PutRope["Put the display in 8 bit per pixel mode first\n"]]}; END; UpdateWeightSlider: Sliders.SliderProc = BEGIN datac: DataForSpecialProc _ NARROW[clientData]; my: Handle _ datac.my; layer: CARDINAL _ datac.layer; IF ~ColorModeIs8[] THEN RETURN; currentColor[layer].w _ value; ComputeColors[]; Labels.Set[my.coefLayer[layer].value, Convert.RopeFromInt[Real.Fix[value*100]]]; END; UpdateColorSlider: Sliders.SliderProc = BEGIN data: DataForSpecialProc _ NARROW[clientData]; my: Handle _ data.my; layer: CARDINAL _ data.layer; IF ~ColorModeIs8[] THEN RETURN; Labels.Set[my.potarColor[layer].value, Convert.RopeFromInt[Real.Fix[value*100]]]; SELECT layer FROM 0 => currentColor[curLayer-1].r _ value; 1 => currentColor[curLayer-1].g _ value; 2 => currentColor[curLayer-1].b _ value; ENDCASE => ERROR; ComputeColors[]; END; ResetButton: Buttons.ButtonProc = BEGIN Init8Patterns[parent: parent, clientData: clientData]; ResetMapButton[parent: parent, clientData: clientData]; END; XSelection: Buttons.ButtonProc = BEGIN whiteOutLine _ ~whiteOutLine; ComputeColors[]; END; ResetAndCreateButton: Buttons.ButtonProc = BEGIN viewer: ViewerClasses.Viewer _ ViewerOps.FindViewer[caption]; IF viewer=NIL THEN { IF mouseButton=yellow THEN CallMenu[NIL] ELSE { IF Terminal.LegalColorMode[terminal, [FALSE, 8, 0]] AND ~ColorModeIs8[] THEN { pos: WindowManager.ScreenPos _ left; IF Rope.Equal["right", UserProfile.Token[key: "ColorDisplay.Side"], FALSE] THEN pos _ right; WindowManager.StartColorViewers[screenPos: pos, bitsPerPixel: 8]; }; ResetButton[parent: parent]; IF mouseButton=blue THEN CreateAnInstance[]; } } ELSE { IF viewer.iconic THEN ViewerOps.OpenIcon[viewer] ELSE MessageWindow.Append["use the color editor tool", TRUE]; }; END; ResetMapButton: Buttons.ButtonProc = BEGIN UpdateAllSliders: PROC [my: Handle] = BEGIN w: Sliders.NormalizedSliderValue; IF my=NIL OR my.outer=NIL OR my.outer.destroyed THEN RETURN; FOR layer: INT IN [0..numberOfColors) DO w _ currentColor[layer].w; Sliders.SetContents[my.coefLayer[layer].bar, 0]; Sliders.SetContents[my.coefLayer[layer].bar, w]; Labels.Set[my.coefLayer[layer].value, Convert.RopeFromInt[Real.Fix[currentColor[layer].w*100]]]; ENDLOOP; ButtonProcLayerInternal[0, my]; END; IF Check8BitMode[] THEN { ReadProfileColors[]; ComputeColors[]; IF clientData#NIL THEN UpdateAllSliders[NARROW[clientData, Handle]]; }; END; ButtonProcLayer: Buttons.ButtonProc = BEGIN data: DataForSpecialProc _ NARROW[clientData]; IF Check8BitMode[] THEN { ButtonProcLayerInternal[data.layer, data.my]; } END; ButtonProcLayerInternal: PROC[layer: CARDINAL, my: Handle] = BEGIN SetPotar: PROC[layer: CARDINAL, my: Handle] = BEGIN Sliders.SetContents[my.potarColor[0].bar, currentColor[layer].r]; Sliders.SetContents[my.potarColor[1].bar, currentColor[layer].g]; Sliders.SetContents[my.potarColor[2].bar, currentColor[layer].b]; Labels.Set[my.potarColor[0].value, Convert.RopeFromInt[Real.Fix[currentColor[layer].r*100]]]; Labels.Set[my.potarColor[1].value, Convert.RopeFromInt[Real.Fix[currentColor[layer].g*100]]]; Labels.Set[my.potarColor[2].value, Convert.RopeFromInt[Real.Fix[currentColor[layer].b*100]]]; END; curLayer _ layer+1; SetPotar[layer, my]; Buttons.SetDisplayStyle[my.coefLayer[prevLayer-1].select, $BlackOnWhite]; Buttons.SetDisplayStyle[my.coefLayer[curLayer-1].select, $WhiteOnBlack]; prevLayer _ curLayer; END; CreateAnInstance: PROC[] = BEGIN nameColorSlider: ARRAY [0..3) OF Rope.ROPE _ ["R", "G", "B"]; coefX: CARDINAL = 10; coefDX: CARDINAL = 25; coefDeltaX: CARDINAL = coefDX+4; coefSelectY: CARDINAL = 3; coefSelectDY: CARDINAL = 15; coefValueY: CARDINAL = coefSelectY+coefSelectDY+3; coefValueDY: CARDINAL = 15; coefBarY: CARDINAL = coefValueY+coefValueDY; firstButtonY: CARDINAL = 3; buttonX: CARDINAL = coefX+numberOfColors*coefDeltaX+8; buttonDX: CARDINAL = 80; firstSliderY: CARDINAL = 6; sliderDY: CARDINAL = 22; interSliderY: CARDINAL = 6; labelX: CARDINAL = buttonX+buttonDX+10; -- R, G, B labelDX: CARDINAL = 14; label2X: CARDINAL = labelX+labelDX; -- number label2DX: CARDINAL = 30; sliderX: CARDINAL = label2X+label2DX; my: Handle = NEW[AdjustColorRec]; buttonWy: CARDINAL _ firstButtonY; NextButton: PROC [name: Rope.ROPE, proc: Buttons.ButtonProc] = BEGIN buttonDY: CARDINAL = 15; interButtonY: CARDINAL = 2; [] _ Buttons.Create[ info: [name: name, wx: buttonX, wy: buttonWy, wh: buttonDY, ww: buttonDX, parent: my.outer, border: TRUE], proc: proc, clientData: my, fork: TRUE ]; buttonWy _ buttonWy+buttonDY+interButtonY; END; IF ~ColorModeIs8[] THEN TerminalIO.PutRope["The 8 bit color tool works only after setting the display in 8 bit mode\n"]; IF ViewerOps.FindViewer[caption]#NIL THEN { TerminalIO.PutRope[caption]; TerminalIO.PutRope[" viewer already exits\n"]; RETURN }; my.outer _ Containers.Create[[ name: caption, iconic: TRUE, icon: Icons.NewIconFromFile[CDIO.GetWorkingDirectory[NIL].Cat["Chipndale.icons"], 2], column: left, scrollable: FALSE ]]; my.height _ firstSliderY+3*(sliderDY+interSliderY); FOR curLayer: INT IN [0..numberOfColors) DO wInit: REAL _ currentColor[curLayer].w; my.coefLayer[curLayer].select _ Buttons.Create[ info: [ name: cDefaults[curLayer].name, iconic: TRUE, wx: coefX+curLayer*coefDeltaX, wy: coefSelectY, wh: coefSelectDY, ww: coefDX, parent: my.outer, border: TRUE], proc: ButtonProcLayer, clientData: NEW[DataForSpecialProcRec _ [my: my, layer: curLayer]] ]; my.coefLayer[curLayer].value _ Labels.Create[ [ name: Convert.RopeFromInt[Real.Fix[wInit*100]], -- initial contents iconic: TRUE, wx: coefX+curLayer*coefDeltaX, wy: coefValueY, wh: coefValueDY, ww: coefDX, parent: my.outer, border: TRUE ]]; my.coefLayer[curLayer].bar _ Sliders.Create[ info: [ name: cDefaults[curLayer].name, iconic: TRUE, parent: my.outer, wx: coefX+curLayer*coefDeltaX, wy: coefBarY, wh: -5, --guardY ww: coefDX, border: TRUE], sliderProc: UpdateWeightSlider, orientation: vertical, value: wInit, clientData: NEW[DataForSpecialProcRec _ [my: my, layer: curLayer] ]]; Containers.ChildYBound[my.outer, my.coefLayer[curLayer].bar]; ENDLOOP; NextButton["reset all", ResetButton]; NextButton["reset map", ResetMapButton]; NextButton["reset pattern", Init8Patterns]; NextButton["X Selection", XSelection]; NextButton["Menu", CallMenu]; FOR iColor: CARDINAL IN [0..3) DO cInit: REAL _ SELECT iColor FROM 0 => currentColor[curLayer-1].r, 1 => currentColor[curLayer-1].g, 2 => currentColor[curLayer-1].b, ENDCASE => ERROR; [] _ Labels.Create[ info: [name: nameColorSlider[iColor], parent: my.outer, wx: labelX, wy: firstSliderY+iColor*(sliderDY+interSliderY), ww: labelDX, wh: sliderDY, border: TRUE ]]; my.potarColor[iColor].bar _ Sliders.Create[ info: [parent: my.outer, wx: sliderX, wy: firstSliderY+iColor*(sliderDY+interSliderY), ww: 10, wh: sliderDY], sliderProc: UpdateColorSlider, orientation: horizontal, value: cInit, clientData: NEW[DataForSpecialProcRec _ [my: my, layer: iColor]] ]; Containers.ChildXBound[my.outer, my.potarColor[iColor].bar]; my.potarColor[iColor].value _ Labels.Create[[ name: Convert.RopeFromInt[Real.Fix[cInit*100]], -- initial contents wx: label2X, wy: firstSliderY+iColor*(sliderDY+interSliderY), ww: label2DX, wh: sliderDY, parent: my.outer, border: TRUE ]]; ENDLOOP; ViewerOps.SetOpenHeight[my.outer, my.height]; -- hint our desired height ViewerOps.PaintViewer[my.outer, all]; -- reflect above change Buttons.SetDisplayStyle[my.coefLayer[0].select, $WhiteOnBlack]; END; SaturationComm: CDSequencer.CommandProc = BEGIN sat: CARDINAL _ 1; IF Check8BitMode[] THEN { list: LIST OF Rope.ROPE _ LIST["from profile"]; FOR i: INT DECREASING IN [0..numberOfColors) DO list _ CONS[cDefaults[i].name, list] ENDLOOP; curLayer _ TerminalIO.RequestSelection[header: "Layers", choice: list]; IF curLayer=0 THEN RETURN[]; IF curLayer<=numberOfColors THEN { sat _ TerminalIO.RequestSelection[ header: "Values", choice: LIST["Invisible", "1", "2", "3", "4", "5", "6", "7", "8", "9", "Saturated"] ]; IF sat = 0 THEN RETURN[]; currentColor[curLayer-1].w _ Real.Float[sat-1]/10; } ELSE ReadProfileColors[]; ComputeColors[]; }; END; specials1: LIST OF Exception _ NIL; --specials in the range of stipples [use for any comb] specials2: LIST OF Exception _ NIL; --specials in the range of stipples [use for exact comb] specials3: LIST OF Exception _ NIL; --specials to be considered later ComputeColors: PROC[] = BEGIN ComposeColor: PROC[c1, wc2: ColorRec] RETURNS [c: ColorRec] = INLINE BEGIN w: REAL _ wc2.w; c _ [c1.r+w*wc2.r, c1.g+w*wc2.g, c1.b+w*wc2.b, c1.w+w] END; SetMap: PROC[index: CARDINAL, color: ColorRec] = BEGIN RtoC: PROC [r: REAL] RETURNS [c: [0..256)] = INLINE { c _ MAX[MIN[Real.Round[r*255], 255], 0] }; mapEntrie: ImagerColorMap.MapEntry _ [index, RtoC[color.r], RtoC[color.g], RtoC[color.b]]; mapEntries _ CONS[mapEntrie, mapEntries]; END; mapEntries: LIST OF ImagerColorMap.MapEntry _ NIL; c: ColorRec; bits: CARDINAL _ numberOfNormalColors; power: CARDINAL _ Basics.BITSHIFT[1, bits]; IF ~ColorModeIs8[] THEN RETURN; SetupSpecials[]; FOR i: CARDINAL IN [0..power) DO c _ [0, 0, 0, 0]; FOR bit: CARDINAL IN [0..bits) DO IF Basics.BITAND[i, Basics.BITSHIFT[1, bit]]#0 THEN { c _ ComposeColor[c, currentColor[bit+1]]; }; ENDLOOP; FOR list: LIST OF Exception _ specials1, list.rest WHILE list#NIL DO IF Basics.BITAND[i, list.first.x]=list.first.x THEN { IF list.first.replace THEN c _ list.first.c ELSE c _ ComposeColor[c, list.first.c]; }; ENDLOOP; FOR list: LIST OF Exception _ specials2, list.rest WHILE list#NIL DO IF i=list.first.x THEN { IF list.first.replace THEN c _ list.first.c ELSE c _ ComposeColor[c, list.first.c]; }; ENDLOOP; IF c.w<0.2 THEN c _ ComposeColor[c, currentColor[0]]; IF c.w=0 THEN c _ currentColor[0] ELSE c _ [c.r/c.w, c.g/c.w, c.b/c.w, 0]; SetMap[i, c]; ENDLOOP; FOR list: LIST OF Exception _ specials3, list.rest WHILE list#NIL DO IF list.first.x>=power THEN SetMap[list.first.x, list.first.c]; ENDLOOP; ForceColors[mapEntries: mapEntries]; END; ReadProfileColors: PUBLIC PROC [] = BEGIN DefaultColor: PROC [def: ColorRec] RETURNS [c: ColorRec] = BEGIN r: Rope.ROPE _ Rope.Cat["ChipNDale.", technologyName, ".", def.name]; c.w _ Real.Float[UserProfile.Number[key: r.Concat[".w"], default: Real.Round[def.w*100]]]/100; c.r _ Real.Float[UserProfile.Number[key: r.Concat[".r"], default: Real.Round[def.r*100]]]/100; c.g _ Real.Float[UserProfile.Number[key: r.Concat[".g"], default: Real.Round[def.g*100]]]/100; c.b _ Real.Float[UserProfile.Number[key: r.Concat[".b"], default: Real.Round[def.b*100]]]/100; END; FOR i: INT IN [0..numberOfColors) DO currentColor[i] _ DefaultColor[cDefaults[i]]; ENDLOOP; whiteOutLine _ UserProfile.Boolean[ key: Rope.Cat["ChipNDale." , technologyName, ".WhiteOutline"], default: TRUE ]; END; ColorCommand: Commander.CommandProc = BEGIN CreateAnInstance[]; END; ColorComm: PROC [comm: CDSequencer.Command] = BEGIN CreateAnInstance[]; END; Init8Patterns[NIL]; ReadProfileColors[]; IF UserProfile.Boolean[ key: Rope.Cat["ChipNDale.", technologyName, ".StartColorMap8"], default: CD.FetchTechnology[$cmos]=NIL AND CD.FetchTechnology[$cmosB]=NIL AND CD.FetchTechnology[$nmos]=NIL ] THEN ComputeColors[]; CDSequencer.ImplementCommand[$SaturationComm, SaturationComm, technology, doQueue]; CDSequencer.ImplementCommand[$ColorTool, ColorComm, technology, dontQueue]; CDCommandOps.RegisterWithMenu[menu: $DisplayMenu, entry: Rope.Concat[technologyName, " 8 bit tool"], key: $ColorTooltech, tech: technology, queue: dontQueue]; [] _ Buttons.Create[ info: [name: Rope.Concat[technologyName, " colors"]], proc: ResetAndCreateButton ]; Commander.Register[ key: Rope.Cat["CD", technologyName, "ColorRec"], proc: ColorCommand, doc: Rope.Concat[technologyName, " 8 bit color tool"] ]; END. 4CDSil8BitColors.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Last Edited by: Jacobi, March 19, 1986 5:17:35 pm PST Last Edited by: Christian Jacobi, January 29, 1987 3:26:27 pm PST gbb, November 5, 1986 6:56:12 pm PST --**color device************************************** --experimenting showed that the following line was necessary.... FOR list: ImagerDitherContext.MapEntries _ mapEntries, list.rest WHILE list#NIL DO Terminal.SetColor[terminal, list.first.mapIndex, 0, list.first.red, list.first.green, list.first.blue]; ENDLOOP; --**end color device************************************** --w is a weight; The color of an intersection (i.e. green1 over blue) is the --weighted sum of the rgb of each color. --index 0 is supposed to be background --XXXXXXXXXXXXXXXX TECHNOLOGY XXXXXXXXXXXXXXXX Set colour map: each of the eight elements sets the RGB colour to corresponding to a given bit in the pattern. "Auxiliary" colours orange myMap[13].c; we prefer our orange pink: ColorRec = myMap[16].c; we need a bit more red and less green in it Colour mixtures --all parameter are discarded Pixels in a dither: 1 2 3 4 5 6 7 8 Each pixel has 8 bits, one for every element in the table cDefaults. Dithers Full colour Dither 1 to 1 Dither1to3: PROC [col1, col2: CARDINAL] RETURNS [REF CDColors.Brick] ~ BEGIN Dither 1 to 3 RETURN [NEW [CDColors.Brick _ [col1*pixel1+col2*pixel3, col2*pixel1+col2*pixel3, col1*pixel1+col2*pixel3, col2*pixel1+col2*pixel3]]] END; -- Dither1to3 Dither2to1to1to4: PROC [col1, col2, col3, col4: CARDINAL] RETURNS [REF CDColors.Brick] ~ BEGIN Dither 4 to 2 to 1 to 1 RETURN [NEW [CDColors.Brick _ [col1*pixel1+col4*pixel3, col4*pixel1+col2*pixel3, col1*pixel1+col4*pixel3, col4*pixel1+col3*pixel3]]] END; -- Dither2to1to1to4 --XXXXX end technology XXXXXXXXXXXXXXXXXXXXX --we do only open the viewer, --because resetting can not reset already painted sliders... --Resets color map; --does not touch patterns --ResetMapButton -- ButtonProcLayerInternal --create an icon of the tool; --does not change any color setup at initialization of the tool -- create sliders for weights -- create command buttons -- create sliders for rgb colors --takes a color setting (weights and rgb values) and sets up the device --c1 not weighted; wc2 weighted --colors in the range of layers --bit loop --check exception loops --assign color --include further colors from exception loop gbb August 26, 1986 3:27:17 pm PDT Replaced discontinued module CDMenus by the replacement CDCommandOps. changes to: DIRECTORY, CDSil8BitColors, BEGIN, terminal, CDCommandOps Κη˜codešœ™Kšœ Οmœ7™BK™6K™AK™$—K˜šΟk ˜ Kšœžœžœžœ˜ Kšœžœ/˜žœžœž™RKšœg™gKšžœ™——KšœA˜AKšœ.˜.Kšžœ˜—K˜š œ˜Kšž˜Kšœ[˜[Kšžœžœžœžœ˜Kšžœ˜—K™:K˜š œ žœžœ žœžœžœ˜FKšœM™MKšœ(™(—K˜šœžœžœžœ ˜;Kšœ&™&—K˜Kš œ žœžœžœžœžœ˜JK˜K˜Kšœ.™.K˜Kšœ žœ˜(Kšœžœ˜,KšœžœΟc"˜;Kšœžœ’˜4Kšœžœ˜Kšœ žœ˜,Kš6œžœ žœžœžœžœ> œ5 œ9 œ: œ9 œ< œ> œ9 œC œF œH œI œJ œN œ ’œ; œ ’œ: œC œ’.œ5 œ ’"˜ή K˜K™nšœ žœžœ˜3Kšœ^˜^Kšœ˜—K™Kšœ$’˜)Kšœ˜Kšœ"˜"Kšœ(™(Kšœ˜Kšœ!˜!Kšœ˜Kšœ$˜$KšœJ™JKšœ˜Kšœ’˜&K™Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœ žœ˜Kšœžœ˜Kšœžœ˜Kšœ žœ’˜&Kšœžœ’˜,Kšœ žœ’˜*Kšœ žœ’˜*Kšœžœ’˜8Kšœžœ’4˜SKšœ žœ’˜(Kšœ žœ’˜'Kšœ žœ’˜+Kšœ žœ ˜K˜š‘ œ˜#Kšœ™Kšž˜™K™K™K™K™—Kšœ:Οe ™DKšœžœ˜Kšœžœ˜K˜K™š ‘œžœžœžœžœž˜BK™ Kšžœ˜Kšžœ’ ˜—š ‘ œžœžœ žœžœž˜TK™ Kšžœžœx˜„Kšžœ’ ˜—š ‘ œžœžœžœžœž™LK™ Kšžœžœx™„Kšžœ’ ™—š ‘œžœžœžœžœž™^K™Kšžœžœx™„Kšžœ’™—š‘œžœžœžœ˜.Kšžœ˜Kšœ=˜=Kšžœ˜—K˜Kšœ?˜?Kšœ5˜5Kšœ;˜;Kšœ:˜:Kšœ7˜7Kšœ?˜?Kšœ=˜=Kšœ9˜9Kšœ=˜=Kšœ;˜;Kšœ;˜;KšœE˜EKšœ;˜;KšœI˜IKšœ;˜;Kšœ=˜=Kšœ7˜7K˜Kšœžœžœ+˜WKšœžœ žœ)˜PKšœžœ žœ)˜PK˜Kšœ#˜#Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ#˜#Kšœ!˜!Kšœ˜Kšœ!˜!Kšœ˜Kšœ˜Kšœ(˜(Kšœ˜Kšœ-˜-Kšœ˜Kšœ!˜!Kšœ˜Kšœ˜Kšžœ˜—š‘ œžœ˜Kšž˜Kšœ žœŸ˜―šœ žœ˜Kšœ’*˜EKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ’˜5Kšœ˜Kšœ˜Kšžœžœ#˜8Kšžœ#’˜6Kšœ˜—Kšžœ˜—K™š‘œžœ˜Kšž˜šžœ žœ ž˜šœ˜Kšœ˜KšœX˜XKšœ ˜ K˜—Kšžœ˜—Kšžœ˜—K™Kšœ,™,K˜K˜Kšœžœ˜Kšœžœžœ£˜4K˜Kšœ žœ˜Kšœ žœ’(˜Kšž˜Kšœ žœ˜Kšœžœ˜šœ˜šœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœžœ˜—Kšœ ˜ Kšœ˜Kšœž˜ Kšœ˜—Kšœ*˜*Kšžœ˜—K˜šžœžœ˜Kšœ`˜`—šžœžœžœ˜,Kšœ˜Kšœ.˜.Kšž˜K˜—šœ˜Kšœ˜Kšœžœ˜ Kšœžœžœ˜UKšœ ˜ Kšœ žœ˜Kšœ˜—Kšœ3˜3Kšœ™šžœ žœžœž˜+Kšœžœ˜'šœ/˜/šœ˜Kšœ˜Kšœžœ˜ Kšœ˜Kšœ˜Kšœ˜K˜ Kšœ˜Kšœžœ˜—Kšœ˜Kšœ žœ3˜BKšœ˜—šœ/˜/Kšœ0’˜CKšœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœž˜ Kšœ˜—šœ,˜,šœ˜Kšœ˜Kšœžœ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ’˜Kšœ ˜ Kšœžœ˜—Kšœ˜Kšœ˜Kšœ ˜ Kšœ žœ2˜AKšœ˜—Kšœ=˜=Kšžœ˜—K™Kšœ™Kšœ%˜%Kšœ(˜(Kšœ+˜+Kšœ&˜&Kšœ˜K™Kšœ ™ šžœ žœžœž˜!šœžœžœž˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšžœžœ˜—šœ˜šœ%˜%Kšœ˜Kšœ ˜ Kšœ0˜0Kšœ ˜ Kšœ ˜ Kšœž˜ —Kšœ˜—šœ+˜+šœ˜Kšœ ˜ Kšœ0˜0Kšœ˜Kšœ˜—Kšœ˜Kšœ˜Kšœ ˜ Kšœ žœ1˜@Kšœ˜—Kšœ<˜<šœ-˜-Kšœ0’˜CKšœ ˜ Kšœ0˜0Kšœ ˜ Kšœ ˜ Kšœ˜Kšœž˜ Kšœ˜—Kšžœ˜—K˜Kšœ.’˜HKšœ)’˜@Kšœ?˜?Kšžœ˜—K˜š œ˜)Kšžœ’˜Kšœžœ˜šžœžœ˜Kš œžœžœžœžœ˜/š žœžœž œžœž˜/Kšœžœ˜$Kšžœ˜—KšœG˜GKšžœ žœžœ˜šžœž˜"šœ#˜#Kšœ˜KšœžœH˜TK˜—Kšžœ žœžœ˜Kšœ2˜2Kšž˜—Kšžœ˜Kšœ˜K˜—Kšžœ˜—K˜K˜Kšœ žœžœ žœ’7˜[Kšœ žœžœ žœ’8˜\Kšœ žœžœ žœ’!˜EK˜K˜š‘ œžœ˜KšœG™GKšž˜K˜š‘ œžœžœ˜>Kšœ™Kšž ˜ Kšœžœ ˜Kšœ6˜6Kšžœ˜—K˜š‘œžœžœ˜1Kšž˜š ‘œžœžœžœžœ˜5Kšœžœžœ˜'Kšœ˜—KšœZ˜ZKšœ žœ˜)Kšžœ˜—K˜Kšœ žœžœžœ˜2Kšœ ˜ Kšœžœ˜&Kšœžœ žœ ˜+K˜Kšžœžœžœ˜K˜Kšœ™šžœžœžœ ž˜ Kšœ˜Kšœ ™ šžœžœžœ ž˜!šžœžœ žœ žœ˜5Kšœ)˜)K˜—Kšž˜—Kšœ™š žœžœžœ"žœžœž˜Dšžœžœžœ˜5Kšžœžœ˜,Kšžœ#˜'Kšœ˜—Kšžœ˜—š žœžœžœ"žœžœž˜Dšžœžœ˜Kšžœžœ˜,Kšžœ#˜'Kšœ˜—Kšžœ˜—K™Kšžœ žœ&˜5Kšžœžœ˜!Kšžœ$˜(Kšœ ˜ Kšžœ˜—Kšœ,™,š žœžœžœ"žœžœž˜DKšžœžœ$˜?Kšžœ˜—Kšœ$˜$Kšžœ˜—K˜š‘œžœžœ˜#Kšž˜š‘ œžœžœ˜:Kšž˜Kšœžœ9˜EKšœ^˜^Kšœ^˜^Kšœ^˜^Kšœ^˜^Kšžœ˜—šžœžœžœž˜$Kšœ-˜-Kšžœ˜—šœ#˜#Kšœ?˜?Kšœ ž˜ Kšœ˜—Kšžœ˜K˜—š  œ˜%Kšž˜Kšœ˜Kšžœ˜K˜—š  œžœ˜-Kšž˜Kšœ˜Kšžœ˜K˜—Kšœžœ˜Kšœ˜šžœ˜Kšœ@˜@Kš œ žœžœžœžœžœž˜oKšœžœ˜—KšœS˜SKšœK˜KKšœž˜žšœ˜Kšœ6˜6Kšœ˜Kšœ˜—šœ˜Kšœ1˜1Kšœ˜Kšœ5˜5Kšœ˜—Kšžœ˜™"Kšœ£œ£ œ™EKšœ Οr9™E—K™—…—VΎzΩ