DIRECTORY Buttons, CD, CDColors, CDIO, CDMenus, CDSequencer, CDSil, ColorMap, Commander, Containers, Convert, GraphicsBasic, GraphicsColor, Icons, Labels, Process, Real, Rope, Sliders, Terminal, TerminalIO, ViewerOps; CDSil8BitColors: CEDAR PROGRAM IMPORTS Buttons, CDColors, CDIO, CDMenus, CDSequencer, CDSil, ColorMap, Commander, Containers, Convert, Icons, Labels, Process, Real, Rope, Sliders, Terminal, TerminalIO, ViewerOps = BEGIN Init8Patterns: Buttons.ButtonProc = BEGIN standard: CARDINAL = 1; green: CARDINAL = 2; blue: CARDINAL = 4; pinktr: CARDINAL = 8; red: CARDINAL = 16; yellow: CARDINAL = 32; Checker8: PROC[col1, col2: CARDINAL] RETURNS[REF CDColors.Brick] = BEGIN RETURN[NEW[CDColors.Brick _ [col1*256+col2, col2*256+col1, col1*256+col2, col2*256+col1]]] END; DefineDimmer8: PROC[lev: CD.Layer, color: CARDINAL] = BEGIN CDColors.DefineColor[lev, Checker8[color, 0], bit8, back]; END; Full8: PROC[color: CARDINAL] RETURNS [b: REF CDColors.Brick] = BEGIN RETURN[Checker8[color, color]] END; CDColors.DefineColor[CDSil.xneutral, Full8[standard], bit8]; CDColors.DefineColor[CDSil.xgreen, Full8[green], bit8]; CDColors.DefineColor[CDSil.xcyan, Full8[blue], bit8]; CDColors.DefineColor[CDSil.xpink, Full8[pinktr], bit8]; CDColors.DefineColor[CDSil.xred, Full8[red], bit8]; CDColors.DefineColor[CDSil.xyellow, Full8[yellow], bit8]; CDColors.DefineColor[CD.backGround, NEW[CDColors.Brick _ [8, 0, 256*8, 0]], bit8]; CDColors.DefineColor[CD.highLightError, NEW[CDColors.Brick _ [255, 0, 0, 0]], bit8]; CDColors.DefineColor[CD.highLightShade, NEW[CDColors.Brick_[0, 255,0 , 255]], bit8]; DefineDimmer8[CDSil.xneutral, standard]; DefineDimmer8[CDSil.xgreen, green]; DefineDimmer8[CDSil.xcyan, blue]; DefineDimmer8[CDSil.xpink, pinktr]; DefineDimmer8[CDSil.xred, red]; DefineDimmer8[CDSil.xyellow, yellow]; END; numberOfColors: INT = 7; backgroundColor: INT = 6; Color: TYPE = RECORD[r, g, b, weight: REAL _ 0]; ColorDescRec: TYPE = ARRAY [0..numberOfColors) OF Color; ColorDesc: TYPE = REF ColorDescRec; color: ColorDesc = NEW[ColorDescRec]; indLayer: INT _ 1; previndLayer: 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 ]; ColorMode8: PROC [] RETURNS [BOOL] = INLINE BEGIN virtual: Terminal.Virtual = Terminal.Current[]; RETURN [virtual.hasColorDisplay AND ~virtual.GetColorMode[].full AND virtual.GetColorMode[].bitsPerPixelChannelA=8]; END; Check8BitMode: PROC [] RETURNS [ok: BOOL] = BEGIN ok _ ColorMode8[]; IF ~ok THEN TRUSTED{Process.Detach[FORK TerminalIO.WriteRope["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 ~ColorMode8[] THEN RETURN; color[layer].weight _ 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 ~ColorMode8[] THEN RETURN; Labels.Set[my.potarColor[layer].value, Convert.RopeFromInt[Real.Fix[value*100]]]; SELECT layer FROM 0 => color[indLayer-1].r _ value; 1 => color[indLayer-1].g _ value; 2 => color[indLayer-1].b _ value; ENDCASE=> ERROR; ComputeColors[]; END; ResetButton: Buttons.ButtonProc = BEGIN UpdateAllSliders: PROC [my: Handle] = BEGIN w: Sliders.NormalizedSliderValue; FOR layer: INT IN [0..numberOfColors) DO w _ color[layer].weight; Sliders.SetContents[my.coefLayer[layer].bar, 0]; Sliders.SetContents[my.coefLayer[layer].bar, w]; Labels.Set[my.coefLayer[layer].value, Convert.RopeFromInt[Real.Fix[color[layer].weight*100]]]; ENDLOOP; ButtonProcLayerInternal[0, my]; END; IF Check8BitMode[] THEN { SetUserColor[]; ComputeColors[]; 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, color[layer].r]; Sliders.SetContents[my.potarColor[1].bar, color[layer].g]; Sliders.SetContents[my.potarColor[2].bar, color[layer].b]; Labels.Set[my.potarColor[0].value, Convert.RopeFromInt[Real.Fix[color[layer].r*100]]]; Labels.Set[my.potarColor[1].value, Convert.RopeFromInt[Real.Fix[color[layer].g*100]]]; Labels.Set[my.potarColor[2].value, Convert.RopeFromInt[Real.Fix[color[layer].b*100]]]; END; indLayer _ layer+1; SetPotar[layer, my]; Buttons.SetDisplayStyle[my.coefLayer[previndLayer-1].select, $BlackOnWhite]; Buttons.SetDisplayStyle[my.coefLayer[indLayer-1].select, $WhiteOnBlack]; previndLayer _ indLayer; END; CreateAnInstance: PROC[] = BEGIN nameLayerButton: ARRAY [0..numberOfColors) OF Rope.ROPE _ ["blk", "grn", "blu", "pin", "red", "yel", "bck"]; nameColorSlider: ARRAY [0..3) OF Rope.ROPE _ ["R", "G", "B"]; coefX: CARDINAL = 10; coefDX: CARDINAL = 25; coefDeltaX: CARDINAL = coefDX+4; coefSelectY: CARDINAL = 5; coefSelectDY: CARDINAL = 15; coefValueY: CARDINAL = coefSelectY+coefSelectDY+3; coefValueDY: CARDINAL = 15; coefBarY: CARDINAL = coefValueY+coefValueDY; firstButtonY: CARDINAL = 10; buttonDY: CARDINAL = 15; interButtonY: CARDINAL = 3; buttonX: CARDINAL = coefX+numberOfColors*coefDeltaX+8; buttonDX: CARDINAL = 80; firstSliderY: CARDINAL = 10; sliderDY: CARDINAL = 20; interSliderY: CARDINAL = 5; labelX: CARDINAL = buttonX+buttonDX+10; -- R, G, B labelDX: CARDINAL = 14; label2X: CARDINAL = labelX+labelDX; -- number label2DX: CARDINAL = 30; sliderX: CARDINAL = label2X+label2DX; caption: Rope.ROPE = "ChiPencil 8 bit color editor"; my: Handle = NEW[AdjustColorRec]; IF ~ColorMode8[] THEN TerminalIO.WriteRope["The 8 bit color tool works only after you put the display in 8 bit mode\n"]; IF ViewerOps.FindViewer[caption]#NIL THEN { TerminalIO.WriteRope[caption]; TerminalIO.WriteRope[" 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 indLayer: INT IN [0..numberOfColors) DO wInit: REAL _ color[indLayer].weight; my.coefLayer[indLayer].select _ Buttons.Create[ info: [ name: nameLayerButton[indLayer], iconic: TRUE, wx: coefX+indLayer*coefDeltaX, wy: coefSelectY, wh: coefSelectDY, ww: coefDX, parent: my.outer, border: TRUE], proc: ButtonProcLayer, clientData: NEW[DataForSpecialProcRec _ [my: my, layer: indLayer]] ]; my.coefLayer[indLayer].value _ Labels.Create[ [ name: Convert.RopeFromInt[Real.Fix[wInit*100]], -- initial contents iconic: TRUE, wx: coefX+indLayer*coefDeltaX, wy: coefValueY, wh: coefValueDY, ww: coefDX, parent: my.outer, border: TRUE ]]; my.coefLayer[indLayer].bar _ Sliders.Create[ info: [ name: nameLayerButton[indLayer], iconic: TRUE, parent: my.outer, wx: coefX+indLayer*coefDeltaX, wy: coefBarY, wh: - 5, --guardY ww: coefDX, border: TRUE], sliderProc: UpdateWeightSlider, orientation: vertical, value: wInit, clientData: NEW[DataForSpecialProcRec _ [my: my, layer: indLayer] ]]; Containers.ChildYBound[my.outer, my.coefLayer[indLayer].bar]; ENDLOOP; [] _ Buttons.Create[ info: [name: "reset map", wx: buttonX, wy: firstButtonY, wh: buttonDY, ww: buttonDX, parent: my.outer, border: TRUE], proc: ResetButton, clientData: my, fork: TRUE ]; [] _ Buttons.Create[ info: [name: "reset pattern", wx: buttonX, wy: firstButtonY+buttonDY+interButtonY, wh: buttonDY, ww: buttonDX, parent: my.outer, border: TRUE], fork: TRUE, proc: Init8Patterns ]; FOR iColor: CARDINAL IN [0..3) DO cInit: REAL _ SELECT iColor FROM 0 => color[indLayer-1].r, 1 => color[indLayer-1].g, 2 => color[indLayer-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; ComputeColors: PROC[] = BEGIN SetMap: PROC[index: CARDINAL, color: Color] = { ColorMap.SetRGBColor[index, color.r, color.g, color.b] }; Adjust: PROC [value, x: REAL] RETURNS [REAL] = { RETURN[IF x>0 THEN value+((1-value)*x) ELSE value+(value)*x] }; ComposeColor: PROC[c1: Color, ind: CARDINAL] RETURNS [c: Color] = { c _ [ c1.r+color[ind].weight*color[ind].r, c1.g+color[ind].weight*color[ind].g, c1.b+color[ind].weight*color[ind].b, c1.weight+color[ind].weight] }; c: Color; IF ~ColorMode8[] THEN RETURN; FOR i0: CARDINAL IN [0..2) DO FOR i1: CARDINAL IN [0..2) DO FOR i2: CARDINAL IN [0..2) DO FOR i3: CARDINAL IN [0..2) DO FOR i4: CARDINAL IN [0..2) DO FOR i5: CARDINAL IN [0..2) DO c _ [0, 0, 0, 0]; IF i0=1 THEN {c _ ComposeColor[c, 0]}; IF i1=1 THEN {c _ ComposeColor[c, 1]}; IF i2=1 THEN {c _ ComposeColor[c, 2]}; IF i3=1 THEN {c _ ComposeColor[c, 3]}; IF i4=1 THEN {c _ ComposeColor[c, 4]}; IF i5=1 THEN {c _ ComposeColor[c, 5]}; c _ ComposeColor[c, backgroundColor]; IF c.weight=0 THEN c _ color[backgroundColor] ELSE c _ [c.r/c.weight, c.g/c.weight, c.b/c.weight, c.weight]; SetMap[32*i5+16*i4+8*i3+4*i2+2*i1+i0, c]; ENDLOOP; ENDLOOP; ENDLOOP; ENDLOOP; ENDLOOP; ENDLOOP; SetMap[index: 64, color: color[6]]; -- [background] SetMap[index: 128, color: [r:0, g:0, b:0]]; -- [channels] SetMap[index: 255, color: [r:1, g:1, b:1]]; -- [white] SetMap[index: 254, color: [r:1, g:0, b:0]]; -- [pure red] SetMap[index: 253, color: [r:0, g:1, b:0]]; -- [pure green] SetMap[index: 252, color: [r:0, g:0, b:1]]; -- [pure blue] SetMap[index: 251, color: [r:1, g:1, b:0]]; -- [pure yellow] [] _ Terminal.SetColorCursorPresentation[Terminal.Current[], onesAreWhite]; END; SetUserColor: PUBLIC PROC [] = BEGIN color[0].weight _ 1; color[0].r _ 0; color[0].g _ 0; color[0].b _ 0; color[1].weight _ 1; color[1].r _ 0; color[1].g _ 1; color[1].b _ 0; color[2].weight _ 1; color[2].r _ 0; color[2].g _ 0; color[2].b _ 1; color[3].weight _ 1; color[3].r _ 0.7; color[3].g _ 0.4; color[3].b _ 0.7; color[4].weight _1; color[4].r _ 1; color[4].g _ 0; color[4].b _ 0; color[5].weight _ 1; color[5].r _ 1; color[5].g _ 1; color[5].b _ 0; color[6].weight _ 0; color[6].r _ 0.4; color[6].g _ 0.5; color[6].b _ 0.5; END; CDSilColorCommand: Commander.CommandProc = BEGIN CreateAnInstance[]; END; CDSilColorComm: PROC [comm: CDSequencer.Command] = BEGIN CreateAnInstance[]; END; Init8Patterns[NIL]; SetUserColor[]; ComputeColors[]; CDSequencer.ImplementCommand[$SilColorTool, CDSilColorComm, CDSil.cdsil, dontQueue]; CDMenus.CreateEntry[$DisplayMenu, "sil 8 bit tool", $SilColorTool]; Commander.Register[ key: "CDSilColor", proc: CDSilColorCommand, doc: "cd sil 8 bit color tool" ]; END. ΪCDSil8BitColors.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Last Edited by: Monier, September 24, 1984 9:55:48 pm PDT Last Edited by: Jacobi, October 29, 1984 5:46:54 pm PST Last Edited by: Jacobi, April 11, 1985 11:22:28 am PST --**Patterns************************************** --all parameter are discarded --**end patterns************************************** -- The weights associated with every primary layer color: think of them as the transparency of each layer. The color of an intersection (i.e. standard over blue) is the weighted sum of the rgb of each color. These weights are also optionally loaded from profile and editable by the user. --Resets color map; --does not touch patterns --ResetButton -- 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 -- we need a better way, using Basics.* or similar to access the bits of the index -- compute the weighted sum of colors --makes a default color setup; reads user profile --does not set up the device Κ˜šœ™Jšœ Οmœ7™BJ™:J™8J™7—J˜šΟk ˜ Jšœ˜Jšžœ˜Jšœ ˜ Jšžœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ ˜ J˜J˜J˜Jšœ˜Jšœ˜Jšœ˜J˜J˜Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ ˜ —J˜šΟbœžœž˜Jšžœžœ—˜Ά—Jšž˜J™J™2J˜šΟn œ˜#Jšœ™Jšž˜Jšœ žœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜J˜š  œžœ žœžœžœ˜CJšžœ˜JšžœžœP˜ZJšžœ˜—J˜š  œžœžœžœ˜6Jšžœ˜Jšœ:˜:Jšžœ˜—J˜š  œžœžœžœžœ˜?Jšž˜Jšžœ˜Jšžœ˜—J˜Jšœ<˜Jšœ)˜)Jšžœ˜—Jšžœ˜—Jšžœ˜—Jšžœ˜—Jšžœ˜—Jšžœ˜—Jšœ'’˜7Jšœ.’ ˜;Jšœ.’ ˜8Jšœ.’ ˜;Jšœ.’˜=Jšœ.’˜JšœK˜KJšžœ˜—J˜š  œžœžœ˜Jšœ1™1Jšœ™Jšž˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšžœ˜J˜—šŸœ˜*Jšž˜Jšœ˜Jšžœ˜J˜—šŸœžœ˜2Jšž˜Jšœ˜Jšžœ˜J˜—Jšœžœ˜Jšœ˜Jšœ˜JšœT˜TJšœC˜CJšœh˜hJšžœ˜J˜—…—/ŒDυ