<> <> <> <> <<>> DIRECTORY ColorizeViewPoint, ColorizeViewPointBackdoor, ColorizeViewPointGraphicsCommon, PBasics, Ieee, IO, IPScan, Profiles, Real, Rope, Scaled, SymTab, Vector2; ColorizeViewPointGraphicsImpl: CEDAR PROGRAM IMPORTS ColorizeViewPoint, ColorizeViewPointBackdoor, ColorizeViewPointGraphicsCommon, IO, IPScan, PBasics, Profiles, Real, Rope, Scaled, SymTab EXPORTS ColorizeViewPointBackdoor ~ BEGIN OPEN ColorizeViewPointGraphicsCommon; Colorization: TYPE ~ ColorizeViewPointBackdoor.Colorization; Profile: TYPE ~ Profiles.Profile; MapData: TYPE ~ ColorizeViewPointBackdoor.MapData; ROPE: TYPE ~ Rope.ROPE; SampledColorIPFragments: TYPE ~ ColorizeViewPointBackdoor.SampledColorIPFragments; VEC: TYPE ~ Vector2.VEC; ASSERTION: TYPE ~ BOOL [TRUE..TRUE]; <> ColorizeColorVP: PUBLIC Colorization ~ { <<[ip: ROPE, palette: Profiles.Profile, checkSystemSetting: ColorizeViewPoint.CheckSystemSettingProc, mapData: MapData] RETURNS [newIP: ROPE]>> GetColor: GetColorProc ~ {--looking for Bitmapper colors currently specified as n1 n2 n3 3 MAKEVEC 47 FGET (frame 47 is where the YESColorModelOperator is stored in the prefix) <> newMin _ min; newMax _ max; SELECT TRUE FROM Rope.Run[s1: ip, pos1: min-4, s2: "\017\243\241\033\017\317\224\240\347" --3 MAKEVEC 47 FGET DO (a ColorViewPoint YEScolor)--]=9 => { newMin _ min-10; newMax _ max+2; --markers now point to full color def, not just 47 FGET color _ ip.Substr[start: newMin, len: newMax-newMin]; addendum _ IF Rope.Run[s1: ip, pos1: newMax, s2: "\017\255\223" --13 ISET --]=3 THEN "\017\255\223" ELSE NIL; --sometimes the YES colors are not immediately followed by a 13 ISET, eg if followed by Xerox Map color oper. newMax _ newMax+addendum.Length; }; ENDCASE => RETURN; --eg, an fget which is not a YES color }; IF checkSystemSetting[key: "AmbushAllYESColors", default: FALSE] THEN ColorizeViewPointBackdoor.SetProfileBoolean[profile: palette, key: "AmbushAllYESColors", val: TRUE]; --this can get reset during ColorizeGraphics newIP _ ColorizeGraphics[ip: ip, subs: BitmapperPaletteFromProfile[profile: palette, mapData: mapData], opList: LIST[fget], getColor: GetColor, customOnly: ~Profiles.Boolean[profile: palette, key: "AmbushAllYESColors", default: FALSE]]; --fget will be used to capture Bitmapper colors IF Profiles.Boolean[profile: palette, key: "AmbushAllYESColors", default: FALSE] THEN newIP _ RemoveYESColorOp[newIP]; --Printers which don't support YES color operator don't want to see the reference to YES in the preamble. IF Profiles.Boolean[profile: palette, key: "IP2", default: FALSE] THEN newIP _ RemoveIP3Ops[newIP, palette]; --To produce an IP 2.0 doc, remove all known IP3 constructs. If not possible, change the palette back to read "IP2: FALSE". }; BitmapperPaletteFromProfile: PROC [profile: Profiles.Profile, mapData: MapData] RETURNS [bitmapperColorSubstitution: SubsInfo] ~ { EachIPFrag: Profiles.EnumProc = { <<[key: ROPE] RETURNS [quit: BOOL _ FALSE]>> IF ~SymTab.Insert[x: ipFragsToColors, key: Profiles.Token[profile: profile, key: key], val: NEW [ColorRep _ [value: key.Substr[9--after "IPFragFor"--], type: $CVPColorName]]] THEN ERROR; -- SysErr }; prefixes: LIST OF ROPE _ Profiles.ListOfTokens[profile: profile, key: "ColorVPPalette", default: NIL]; ipFragsToColors: SymTab.Ref _ SymTab.Create[]; prefixes _ ColorizeViewPointBackdoor.SubpaletteSearchList[prefixes, profile]; --adds document-wide prefixes in correct order Profiles.EnumerateKeys[profile: profile, pattern: "IPFragFor*", proc: EachIPFrag]; --the profile should contain all named colors as keys with their IPFrags as values bitmapperColorSubstitution _ NEW [SubsInfoRep _ [palette: profile, mapData: mapData, subpaletteList: prefixes, subs: ipFragsToColors]]; }; RemoveYESColorOp: PROC [ip: ROPE] RETURNS [newIP: ROPE] ~ { --check for the remaining reference to the YES color model operator (in the preamble of the document). This is highly specific to current Bitmapper implementation ! YESRemove: IPScan.ScanProc ~ { <<[min: INT, max: INT, op: IPMaster.Op _ nil, seq: IPScan.Seq _ nil, num: INTEGER _ 0, punt: BOOL _ FALSE]>> IF min<22 THEN RETURN; SELECT TRUE FROM Rope.Run[s1: ip, pos1: min-22, s2: "\017\240\017\240\017\240\017\243\241\0336\260\017\240\017\2406\260\017\244\241\033\305\005Xerox\305\tYESLinear\017\242\241\033\241\246\240\347\017\317\225\017\317\224\240\347" --10000 0 0 10000 4 MAKEVEC Xerox YESLinear 2 MAKEVEC FINDCOLORMODELOPERATOR DO 47 FSET 47 FGET DO--]=56 => --this is how the YES operator is set up in the preamble of current Bitmapper interpress masters newIP _ newIP.Replace[start: min-22, len: 56, with: "\017\241\241\251"--1 MAKEGRAY--]; --Replace doesn't mess up Scan because only happens once ENDCASE => NULL; }; newIP _ ip; IPScan.ScanRope[ip: newIP, ops: LIST[findcolormodeloperator], action: YESRemove]; }; RemoveIP3Ops: PROC [ip: ROPE, palette: Profiles.Profile] RETURNS [newIP: ROPE _ NIL] ~ {--make a final scan to pick up any leftover colormodeloperator calls and makesampledcolor calls (which can't occur in IP 2.0), and replace them with "makegray" and "makesampledblack". Raven printers also don't support MAKESIMPLECO, it turns out. This is highly specific to current Bitmapper implementation ! PerOp: IPScan.ScanProc ~ { <<[min: INT, max: INT, op: IPMaster.Op _ nil, seq: IPScan.Seq _ nil, num: INTEGER _ 0, punt: BOOL _ FALSE]>> IF min<6 THEN RETURN; SELECT TRUE FROM Rope.Run[s1: ip, pos1: min-6, s2: "\241\251\017\242\241\033\305\005Xerox\305\003Map\017\242\241\033\241\246\240\347\017\320\225" --MAKEGRAY 2 MAKEVEC Xerox Map 2 MAKEVEC FINDCOLORMODELOPERATOR DO 48 FSET--]=29 => {--this is how Bitmapper makes colored patterns (followed by a defining pixel array) => erase & use MakeSampledBlack on the pixel array instead of MakeSampledColor newIP _ newIP.Concat[ip.Substr[start: flushFrom, len: (min-12)-flushFrom]]; --gets rid of preceeding two MAKEGRAYS as well flushFrom _ max+5; --after DO 48 FSET }; Rope.Run[s1: ip, pos1: max-5, s2: "\017\320\224\241\253" --48 FGET MAKESAMPLEDCOLOR --]=5 => {--the corresponding call to the Xerox Map color operator call above; change to 0 MAKESAMPLEDBLACK (opaque MSB) newIP _ newIP.Cat[ip.Substr[start: flushFrom, len: (max-5)-flushFrom], "\017\240\241\252" --0 MAKESAMPLEDBLACK--]; flushFrom _ max; }; < { --assume the correct pixel array and transform is on the stack; change to 0 MAKESAMPLEDBLACK (opaque MSB)>> <> <> <<};>> Rope.Run[s1: ip, pos1: min, s2: "\240r\240j" --MAKESIMPLECO { --]=4 => { --MAKESIMPLECO used by Bitmapper to do highlight behind text; simply remove the whole section and don't do a highlight (better for B&W anyway) maxLen: INT _ ip.Length-4; endBody: INT; FOR endBody IN [max..maxLen] DO --search forward for matching } IF ip.Substr[start: endBody, len: 6].Equal["\241\236\240k\240\351"] -- MASKUNDERLINE } DOSAVEALL-- THEN EXIT; ENDLOOP; IF endBody=maxLen THEN GOTO NotFound; newIP _ newIP.Cat[ip.Substr[start: flushFrom, len: min-flushFrom]]; flushFrom _ endBody+6; EXITS NotFound => ColorizeViewPointBackdoor.SetProfileBoolean[profile: palette, key: "IP2", val: FALSE]; --since MAKESIMPLECO not removed }; ENDCASE => ColorizeViewPointBackdoor.SetProfileBoolean[profile: palette, key: "IP2", val: FALSE]; --if any color calls slip thru unprocessed }; flushFrom: INT _ 0; IPScan.ScanRope[ip: ip, ops: LIST[findcolormodeloperator, makesampledcolor, makesimpleco], action: PerOp]; newIP _ newIP.Concat[ip.Substr[start: flushFrom]]; }; <> msbFirstPart: ROPE ~ "\017\260\017\260\017\241\017\241\017\241\304\004\000\001\000\020\240\244\017F\240\243\240\245\017\240\017\241\240\242\240\245\311D\000\001\000\020"; -- 16 16 1 1 1 n SCALE -90 ROTATE CONCAT 0 1 TRANSLATE CONCAT sequencePackedPixelVector, 68 bytes long, 1 bit/sample, 16 samples/scan line msbThirdPart: ROPE ~ "\241\302\304\004\360 \000\036\304\004\017\340\000\036\240\246\017\244\222\240\245"; --MAKEPIXELARRAY n n SCALE2 4 IGET CONCAT whitePixels: ROPE ~ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"; --creates a white makeSampledBlack blackPixels: ROPE ~ "\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000"; --creates a black makeSampledBlack transparentWhite: ROPE ~ msbFirstPart.Cat[whitePixels, msbThirdPart, "\017\241\241\252" --1 MAKESAMPLEDBLACK--]; opaqueWhite: ROPE ~ msbFirstPart.Cat[whitePixels, msbThirdPart, "\017\240\241\252" --0 MAKESAMPLEDBLACK--]; opaqueBlack: ROPE ~ msbFirstPart.Cat[blackPixels, msbThirdPart, "\017\240\241\252" --0 MAKESAMPLEDBLACK--]; BGProGetColor: GetColorProc ~ {-- Looking for MAKESAMPLEDBLACK segments 127 bytes long (32 fixed bytes, a 70-byte string representing a sequencePackedPixelVector, and another 25 fixed bytes), and SETGRAY segments <> newMin _ min; newMax _ max; addendum _ "\017\255\223"; --13 (color) ISET; should follow all SETGRAY substitutions SELECT TRUE FROM Rope.Run[s1: ip, pos1: max, s2: "\240\265\017\255\223\017\321\225" --DUP 13 ISET 49 FSET--]=8 => { --probably a ViewPoint2.0 MAKESAMPLEDBLACK color _ ip.Substr[start: min, len: max-min]; IF color.Run[10, "\304\002"]=2--a 2 byte IPX seqRational for MAKES.B. -- THEN color _ color.Replace[start: 11, len: 3, with: "\004\000\001\000\020"];--restructured to ViewPoint 4 byte form addendum _ "\240\265\017\255\223\017\321\225"; --DUP 13 ISET 49 FSET newMax _ newMax+addendum.Length; }; Rope.Run[s1: ip, pos1: max-5, s2: "\001\000\000\241\250"-- 65536 SETGRAY--]=5 => { color _ ip.Substr[start: min, len: max-min]; IF color.Run[0, "\304\006"]=2--a 6 byte IPX seqRational for SETGRAY -- THEN color _ Rope.Cat["\304\b\000"--8 bytes--, color.Substr[2, 3], "\000\001\000\000\241\250"]--IPX form restructured to 8 byte ViewPoint form }; Rope.Run[s1: ip, pos1: min, s2: "\017\240\241\250"-- 0 SETGRAY--]=4 => { color _ "\304\b\000\000\000\000\000\001\000\000\241\250"; --0/65536 SETGRAY }; Rope.Run[s1: ip, pos1: min, s2: "\017\241\241\250"-- 1 SETGRAY--]=4 => { color _ "\304\b\000\001\000\000\000\001\000\000\241\250"; --65536/65536 SETGRAY }; ENDCASE => RETURN; --eg, an fget which is not a YES color }; <> ColorizeBasicGraphics: PUBLIC Colorization ~ { <<[ip: ROPE, palette: Profiles.Profile, checkSystemSetting: ColorizeViewPoint.CheckSystemSettingProc, mapData: MapData] RETURNS [newIP: ROPE]>> RETURN [ColorizeGraphics[ip: ip, subs: BasicGraphicsPaletteFromProfile[profile: palette, mapData: mapData], opList: LIST[makesampledblack, setgray], getColor: BGProGetColor]]; }; BasicGraphicsPaletteFromProfile: PROC [profile: Profiles.Profile, mapData: MapData] RETURNS [bgColorSubstitution: SubsInfo] ~ { BGTextureProc: GfxTextureProc ~ { <<[texture: GfxTexture] RETURNS [Pattern]>> IF texture IN BGTexture THEN RETURN [bgTexture[texture]] ELSE ERROR InvalidGfxKey; }; BGGrayProc: GfxGrayProc ~ { <<[gray: REAL] RETURNS [Pattern]>> SELECT gray FROM 0 => RETURN [bgGray[0]]; 0.25 => RETURN [bgGray[1]]; 0.5 => RETURN [bgGray[2]]; 0.75 => RETURN [bgGray[3]]; ENDCASE => ERROR InvalidGfxKey; }; BGSeqAction: SeqAction ~ { <<[key, makeSampledBlack: ROPE, real: REAL, textured, transparent: BOOL]>> to: Color; IF (transparent AND makeSampledBlack.Equal[transparentWhite]) THEN key _ "0%T"; --for xpnt white, user must specify "0%T" explicitly, unlike other xpnt colors to _ NEW [ColorRep _ [value: key, type: $BGPattern]]; IF ~SymTab.Insert[x: bgSubs, key: makeSampledBlack, val: to] AND --the exceptions-- ~(key.Equal["0%"] OR key.Equal[s2: "0%T", case: FALSE]) THEN { already: ROPE _ NARROW[bgSubs.Fetch[makeSampledBlack].val, Color].value; --Fetch what's already there. SIGNAL ColorizeViewPoint.Warning[$MalformedPaletteEntry, IO.PutFR[format: "BG sampledBlack from \"%g\" collides with that from \"%g\"", v1: [rope[key]], v2: [rope[already]]]]; }; }; prefixes: LIST OF ROPE _ Profiles.ListOfTokens[profile: profile, key: "BGPalette", default: NIL]; bgSubs: SymTab.Ref _ SymTab.Create[]; prefixes _ ColorizeViewPointBackdoor.SubpaletteSearchList[prefixes, profile]; --adds document-wide prefixes in correct order GfxPaletteFromProfile[profile: profile, seqAction: BGSeqAction, gfxTexture: BGTextureProc, gfxGray: BGGrayProc, opaque: FALSE]; bgColorSubstitution _ NEW [SubsInfoRep _ [palette: profile, mapData: mapData, subpaletteList: prefixes, subs: bgSubs]]; }; BGTexture: TYPE ~ GfxTexture [0..5); bgTexture: ARRAY BGTexture OF Pattern _ [ [17B, 17B, 17B, 17B, 17B, 17B, 17B, 17B, 17B, 17B, 17B, 17B, 17B, 17B, 17B, 17B], [0B, 0B, 0B, 0B, 177777B, 177777B, 177777B, 177777B, 0B, 0B, 0B, 0B, 0B, 0B, 0B, 0B], [160001B, 170000B, 74000B, 36000B, 17000B, 7400B, 3600B, 1700B, 740B, 360B, 170B, 74B, 36B, 17B, 100007B, 140003B], [74B, 170B, 360B, 740B, 1700B, 3600B, 7400B, 17000B, 36000B, 74000B, 170000B, 160001B, 140003B, 100007B, 17B, 36B], [0B, 0B, 0B, 0B, 0B, 0B, 0B, 0B, 377B, 377B, 377B, 377B, 377B, 377B, 377B, 377B] ]; bgGray: ARRAY [0..4) OF Pattern _ [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1002B, 3407B, 3407B, 1002B, 20040B, 70160B, 70160B, 20040B, 1002B, 3407B, 3407B, 1002B, 20040B, 70160B, 70160B, 20040B], [7417B, 7417B, 7417B, 7417B, 170360B, 170360B, 170360B, 170360B, 7417B, 7417B, 7417B, 7417B, 170360B, 170360B, 170360B, 170360B], [157737B, 107617B, 107617B, 157737B, 176775B, 174370B, 174370B, 176775B, 157737B, 107617B, 107617B, 157737B, 176775B, 174370B, 174370B, 176775B] ]; <> ColorizeProIllustrator: PUBLIC Colorization ~ { <<[ip: ROPE, palette: Profiles.Profile, checkSystemSetting: ColorizeViewPoint.CheckSystemSettingProc, mapData: MapData] RETURNS [newIP: ROPE]>> RETURN [ColorizeGraphics[ip: ip, subs: ProPaletteFromProfile[profile: palette, mapData: mapData], opList: LIST[makesampledblack, setgray], getColor: BGProGetColor]]; }; ProTexture: TYPE ~ GfxTexture; ProGray: TYPE ~ [0..33); realFudge: RECORD [lo, hi: INT] _ [-1,1]; ProPaletteFromProfile: PROC [profile: Profiles.Profile, mapData: MapData] RETURNS [proColorSubstitution: SubsInfo] ~ { ProTextureProc: GfxTextureProc ~ {RETURN [proTexture[texture]]}; <<[texture: GfxTexture] RETURNS [Pattern]>> ProGrayProc: GfxGrayProc ~ { <<[gray: REAL] RETURNS [Pattern]>> brickIndex: ProGray _ ColorizeViewPointBackdoor.AltRound[gray * ProGray.LAST]; RETURN [proGray[brickIndex]]; }; ProSeqAction: SeqAction ~ { <<[key, makeSampledBlack: ROPE, real: REAL, textured, transparent: BOOL]>> InstallMapping: PROC [from: ROPE, to: Color] ~ { IF ~SymTab.Insert[x: proSubs, key: from, val: to] AND (textured OR ~transparent) --a sticky wicket. This means people REALLY using transparent grays in their document won't be warned when they collide (eg, 15% and 17% both map to proGray[5]). However, most use the default opaque gray values and this check avoids false error msgs in those more common cases -- THEN { already: ROPE _ NARROW[proSubs.Fetch[from].val, Color].value; --Fetch what's already there. SIGNAL ColorizeViewPoint.Warning[$MalformedPaletteEntry, IO.PutFR[format: "Pro sampledBlack from \"%g\" collides with that from \"%g\"", v1: [rope[key]], v2: [rope[already]]]]; }; }; IF (transparent AND makeSampledBlack.Equal[transparentWhite]) THEN key _ "0%T"; --for xpnt white, user must specify "0%T" explicitly, unlike other xpnt colors IF textured OR transparent THEN { to: Color ~ NEW [ColorRep _ [value: key, type: IF (~textured AND transparent) THEN $TransGray--transp grays are rendered as transp. makeSampledBlacks-- ELSE $ProPattern]]; --opaque grays are rendered as SetGrays (below), except sometimes opaque black is rendered for unknown reasons as an opaque msb InstallMapping[from: makeSampledBlack, to: to]; } ELSE { --construct SetGray stuff for opaque, non-textured grays to: Color ~ NEW [ColorRep _ [value: key, type: $OpaqGray]]; FOR fudge: INT IN [realFudge.lo .. realFudge.hi] DO InstallMapping[from: ProIllustratorSetGrayFromReal[real, fudge], to: to]; ENDLOOP; }; }; prefixes: LIST OF ROPE _ Profiles.ListOfTokens[profile: profile, key: "ProPalette", default: NIL]; proSubs: SymTab.Ref _ SymTab.Create[]; prefixes _ ColorizeViewPointBackdoor.SubpaletteSearchList[prefixes, profile]; --adds document-wide prefixes in correct order GfxPaletteFromProfile[profile: profile, seqAction: ProSeqAction, gfxTexture: ProTextureProc, gfxGray: ProGrayProc]; [] _ SymTab.Insert[x: proSubs, key: opaqueWhite, val: NEW [ColorRep _ [value: "0%", type: $ProPattern]]]; --sometimes (why?) ProIll uses a black or white msb instead of 1 or 0 SETGRAY; insert those exceptions to the rule that opaq grays are Setgrays [] _ SymTab.Insert[x: proSubs, key: opaqueBlack, val: NEW [ColorRep _ [value: "100%", type: $ProPattern]]]; proColorSubstitution _ NEW [SubsInfoRep _ [palette: profile, mapData: mapData, subpaletteList: prefixes, subs: proSubs]]; }; Value: TYPE ~ Scaled.Value; --MACHINE DEPENDENT RECORD [fraction: CARDINAL _ 0, integerPart: INTEGER] PackedReal: TYPE ~ Ieee.SingleReal; --MACHINE DEPENDENT RECORD [m2: CARDINAL, sign: BOOL, exp: [0..377B], m1: [0..177B]] ProIllustratorSetGrayFromReal: PROC [r: REAL, fudge: INT_0] RETURNS [rational: ROPE] ~ { int: PBasics.LongNumber ~ LOOPHOLE[Scaled.IntRep[RealToScaled[r]]+fudge]; text: Rope.Text ~ Rope.NewText[size: 4]; text[0] _ LOOPHOLE[int.hh]; text[1] _ LOOPHOLE[int.hl]; text[2] _ LOOPHOLE[int.lh]; text[3] _ LOOPHOLE[int.ll]; RETURN [Rope.Cat["\304\b" --short seqRational, 8 bytes--, text --numerator--, "\000\001\000\000\241\250" --65536 as divisor, SETGRAY--]]; }; RealToScaled: PROC [r: REAL] RETURNS [fpn: Value] = { p: PackedReal _ LOOPHOLE[r]; leftShift: INTEGER = p.exp - 134; -- (exponent _ p.e - 127) - 7 neg: BOOLEAN = p.sign; int: INT32; IF neg THEN p.sign _ FALSE; p.exp _ 1; -- supply the hidden bit and otherwise wipe out e SELECT leftShift FROM <-23 => RETURN[Scaled.ValRep[0]]; >=8 => RETURN [Scaled.ValRep[INT.LAST]]; --Actually, should Overflow ENDCASE; int _ PBasics.Shift[[real[LOOPHOLE[p, REAL]]], leftShift].int; RETURN [Scaled.ValRep[IF neg THEN -int ELSE int]]; }; proTexture: ARRAY ProTexture OF Pattern _ [ [000170B, 000170B, 000170B, 000170B, 000170B, 000170B, 000170B, 000170B, 000170B, 000170B, 000170B, 000170B, 000170B, 000170B, 000170B, 000170B], -- A: lineVert [000000B, 000000B, 000000B, 000000B, 000000B, 177777B, 177777B, 177777B, 177777B, 000000B, 000000B, 000000B, 000000B, 000000B, 000000B, 000000B], -- B: lineHoriz [174000B, 076000B, 037000B, 017400B, 007600B, 003700B, 001740B, 000760B, 000370B, 000174B, 000076B, 000037B, 100017B, 140007B, 160003B, 170001B], -- C: lineNW [160003B, 140007B, 100017B, 000037B, 000076B, 000174B, 000370B, 000760B, 001740B, 003700B, 007600B, 017400B, 037000B, 076000B, 174000B, 170001B], -- D: lineNE [037740B, 037740B, 037740B, 000000B, 000000B, 000000B, 000000B, 000000B, 000000B, 000000B, 000000B, 037740B, 037740B, 037740B, 037740B, 037740B], -- E: squareDot [000776B, 000776B, 000776B, 000776B, 000000B, 000000B, 000000B, 000000B, 177741B, 177741B, 177741B, 177741B, 000000B, 000000B, 000000B, 000000B], -- F: brick [140740B, 140777B, 140777B, 140777B, 037770B, 037770B, 037770B, 037770B, 036030B, 176037B, 176037B, 176037B, 176000B, 177740B, 177740B, 140740B], -- G: stipple [000374B, 000770B, 001760B, 001740B, 000700B, 140201B, 160003B, 170003B, 174001B, 176000B, 077000B, 037000B, 016010B, 004034B, 000076B, 000176B], -- H: crossweave [000000B, 000000B, 000000B, 000010B, 000034B, 000076B, 000037B, 100017B, 140007B, 160003B, 170001B, 174000B, 076000B, 037000B, 016000B, 004000B], -- I: dashNW [017400B, 037000B, 016000B, 004000B, 000000B, 000000B, 000000B, 000010B, 000034B, 000076B, 000174B, 000370B, 000760B, 001740B, 003700B, 007600B], -- J: dashNE [174777B, 174760B, 037700B, 017700B, 017600B, 007400B, 003000B, 000000B, 000000B, 000000B, 000000B, 000000B, 000000B, 100037B, 160177B, 170377B], -- K: wave [101777B, 001777B, 003776B, 003774B, 007760B, 017600B, 037600B, 077600B, 177600B, 177603B, 177777B, 160377B, 160377B, 140377B, 140777B, 100777B] -- L: whiteArc ]; proGray: ARRAY ProGray OF Pattern _ [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 2020H, 0, 0, 0, 202H, 0, 0, 0, 2020H, 0, 0, 0, 202H, 0, 0], [0, 6060H, 0, 0, 0, 606H, 0, 0, 0, 6060H, 0, 0, 0, 606H, 0, 0], [0, 6060H, 2020H, 0, 0, 606H, 202H, 0, 0, 6060H, 2020H, 0, 0, 606H, 202H, 0], [0, 6060H, 6060H, 0, 0, 606H, 606H, 0, 0, 6060H, 6060H, 0, 0, 606H, 606H, 0], [0, 7070H, 6060H, 0, 0, 707H, 606H, 0, 0, 7070H, 6060H, 0, 0, 707H, 606H, 0], [0, 7070H, 7070H, 0, 0, 707H, 707H, 0, 0, 7070H, 7070H, 0, 0, 707H, 707H, 0], [2020H, 7070H, 7070H, 0, 202H, 707H, 707H, 0, 2020H, 7070H, 7070H, 0, 202H, 707H, 707H, 0], [6060H, 7070H, 7070H, 0, 606H, 707H, 707H, 0, 6060H, 7070H, 7070H, 0, 606H, 707H, 707H, 0], [7070H, 7070H, 7070H, 0, 707H, 707H, 707H, 0, 7070H, 7070H, 7070H, 0, 707H, 707H, 707H, 0], [7070H, 0F0F0H, 7070H, 0, 707H, 0F0FH, 707H, 0, 7070H, 0F0F0H, 7070H, 0, 707H, 0F0FH, 707H, 0], [7070H, 0F0F0H, 7070H, 2020H, 707H, 0F0FH, 707H, 202H, 7070H, 0F0F0H, 7070H, 2020H, 707H, 0F0FH, 707H, 202H], [7070H, 0F0F0H, 7070H, 6060H, 707H, 0F0FH, 707H, 606H, 7070H, 0F0F0H, 7070H, 6060H, 707H, 0F0FH, 707H, 606H], [7070H, 0F0F0H, 0F0F0H, 6060H, 707H, 0F0FH, 0F0FH, 606H, 7070H, 0F0F0H, 0F0F0H, 6060H, 707H, 0F0FH, 0F0FH, 606H], [7070H, 0F0F0H, 0F0F0H, 7070H, 707H, 0F0FH, 0F0FH, 707H, 7070H, 0F0F0H, 0F0F0H, 7070H, 707H, 0F0FH, 0F0FH, 707H], [7070H, 0F0F0H, 0F0F0H, 0F0F0H, 707H, 0F0FH, 0F0FH, 0F0FH, 7070H, 0F0F0H, 0F0F0H, 0F0F0H, 707H, 0F0FH, 0F0FH, 0F0FH], [0F0F0H, 0F0F0H, 0F0F0H, 0F0F0H, 0F0FH, 0F0FH, 0F0FH, 0F0FH, 0F0F0H, 0F0F0H, 0F0F0H, 0F0F0H, 0F0FH, 0F0FH, 0F0FH, 0F0FH], [0F8F8H, 0F0F0H, 0F0F0H, 0F0F0H, 8F8FH, 0F0FH, 0F0FH, 0F0FH, 0F8F8H, 0F0F0H, 0F0F0H, 0F0F0H, 8F8FH, 0F0FH, 0F0FH, 0F0FH], [0F8F8H, 0F0F0H, 0F0F0H, 0F8F8H, 8F8FH, 0F0FH, 0F0FH, 8F8FH, 0F8F8H, 0F0F0H, 0F0F0H, 0F8F8H, 8F8FH, 0F0FH, 0F0FH, 8F8FH], [0F8F8H, 0F0F0H, 0F0F0H, 0F9F9H, 8F8FH, 0F0FH, 0F0FH, 9F9FH, 0F8F8H, 0F0F0H, 0F0F0H, 0F9F9H, 8F8FH, 0F0FH, 0F0FH, 9F9FH], [0F8F8H, 0F0F0H, 0F8F8H, 0F9F9H, 8F8FH, 0F0FH, 8F8FH, 9F9FH, 0F8F8H, 0F0F0H, 0F8F8H, 0F9F9H, 8F8FH, 0F0FH, 8F8FH, 9F9FH], [0F8F8H, 0F0F0H, 0F8F8H, 0FDFDH, 8F8FH, 0F0FH, 8F8FH, 0DFDFH, 0F8F8H, 0F0F0H, 0F8F8H, 0FDFDH, 8F8FH, 0F0FH, 8F8FH, 0DFDFH], [0F8F8H, 0F0F0H, 0F8F8H, 0FFFFH, 8F8FH, 0F0FH, 8F8FH, 0FFFFH, 0F8F8H, 0F0F0H, 0F8F8H, 0FFFFH, 8F8FH, 0F0FH, 8F8FH, 0FFFFH], [0F8F8H, 0F8F8H, 0F8F8H, 0FFFFH, 8F8FH, 8F8FH, 8F8FH, 0FFFFH, 0F8F8H, 0F8F8H, 0F8F8H, 0FFFFH, 8F8FH, 8F8FH, 8F8FH, 0FFFFH], [0F9F9H, 0F8F8H, 0F8F8H, 0FFFFH, 9F9FH, 8F8FH, 8F8FH, 0FFFFH, 0F9F9H, 0F8F8H, 0F8F8H, 0FFFFH, 9F9FH, 8F8FH, 8F8FH, 0FFFFH], [0FDFDH, 0F8F8H, 0F8F8H, 0FFFFH, 0DFDFH, 8F8FH, 8F8FH, 0FFFFH, 0FDFDH, 0F8F8H, 0F8F8H, 0FFFFH, 0DFDFH, 8F8FH, 8F8FH, 0FFFFH], [0FFFFH, 0F8F8H, 0F8F8H, 0FFFFH, 0FFFFH, 8F8FH, 8F8FH, 0FFFFH, 0FFFFH, 0F8F8H, 0F8F8H, 0FFFFH, 0FFFFH, 8F8FH, 8F8FH, 0FFFFH], [0FFFFH, 0F8F8H, 0F9F9H, 0FFFFH, 0FFFFH, 8F8FH, 9F9FH, 0FFFFH, 0FFFFH, 0F8F8H, 0F9F9H, 0FFFFH, 0FFFFH, 8F8FH, 9F9FH, 0FFFFH], [0FFFFH, 0F9F9H, 0F9F9H, 0FFFFH, 0FFFFH, 9F9FH, 9F9FH, 0FFFFH, 0FFFFH, 0F9F9H, 0F9F9H, 0FFFFH, 0FFFFH, 9F9FH, 9F9FH, 0FFFFH], [0FFFFH, 0F9F9H, 0FDFDH, 0FFFFH, 0FFFFH, 9F9FH, 0DFDFH, 0FFFFH, 0FFFFH, 0F9F9H, 0FDFDH, 0FFFFH, 0FFFFH, 9F9FH, 0DFDFH, 0FFFFH], [0FFFFH, 0F9F9H, 0FFFFH, 0FFFFH, 0FFFFH, 9F9FH, 0FFFFH, 0FFFFH, 0FFFFH, 0F9F9H, 0FFFFH, 0FFFFH, 0FFFFH, 9F9FH, 0FFFFH, 0FFFFH], [0FFFFH, 0FDFDH, 0FFFFH, 0FFFFH, 0FFFFH, 0DFDFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FDFDH, 0FFFFH, 0FFFFH, 0FFFFH, 0DFDFH, 0FFFFH, 0FFFFH], [0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH, 0FFFFH] ]; <> ColorizeViewPointBackdoor.InstallNewColorization[colorization: ColorizeColorVP, setting: ["ColorizeColorVP", "Do (re-)colorization for Color VP Basic Graphics", TRUE]]; ColorizeViewPointBackdoor.InstallNewColorization[colorization: NIL, setting: ["AmbushAllYESColors", "Turn all Color VP YES colors into RGB (some printers need this)", FALSE]]; ColorizeViewPointBackdoor.InstallNewColorization[colorization: ColorizeProIllustrator, setting: ["ColorizeProIllustrator", "Do colorization for VP Pro Illustrator", TRUE]]; ColorizeViewPointBackdoor.InstallNewColorization[colorization: ColorizeBasicGraphics, setting: ["ColorizeBasicGraphics", "Do colorization for VP Basic Graphics", TRUE]]; END.