FontTuningParametersImpl.mesa
Copyright (C) 1984, Xerox Corporation. All rights reserved.
Michael Plass, October 17, 1985 2:27:25 pm PDT
DIRECTORY Basics, Real, GridModulation, ImagerPixelMap, Rope, FontTuningParameters, Convert, FS, IO;
FontTuningParametersImpl: CEDAR PROGRAM
IMPORTS Basics, Real, ImagerPixelMap, Rope, Convert, FS, IO
EXPORTS FontTuningParameters
~ BEGIN OPEN FontTuningParameters;
BadToken: PUBLIC SIGNAL [fileName: ROPE, token: ROPE, location: INT] ~ CODE;
parameterFimeNameExtension: ROPE ← ".fontTune";
Load: PUBLIC PROC [fileName: ROPE] RETURNS [Ref] ~ {
new: Ref ~ NEW[Rep];
meanIntensity: REF ARRAY [0..512) OF REAL ~ NEW[ARRAY [0..512) OF REAL];
stdDev: REF ARRAY [0..512) OF REAL ~ NEW[ARRAY [0..512) OF REAL];
occurrences: REF ARRAY [0..512) OF REAL ~ NEW[ARRAY [0..512) OF REAL];
minMeanIntensity: REAL ← 9999999999.9;
maxMeanIntensity: REAL ← 0;
printerModelRadius: [0..1] ← 0;
ReadModel: PROC [fileName: ROPE] ~ {
stream: IO.STREAMFS.StreamOpen[fileName: fileName];
token: REF TEXTNEW[TEXT[20]];
Match: PROC [key: ROPE] RETURNS [BOOL] ~ TRUSTED {
RETURN [key.Equal[LOOPHOLE[token]]]
};
tokenKind: IO.TokenKind ← tokenERROR;
tokenStartIndex: INT ← 0;
stackTop: [0..30] ← 0;
stack: ARRAY [0..30) OF REAL;
Push: PROC [real: REAL] ~ {stack[stackTop] ← real; stackTop ← stackTop + 1};
Pop: PROC RETURNS [real: REAL] ~ {stackTop ← stackTop - 1; real ← stack[stackTop]};
PopInt: PROC RETURNS [int: INT] ~ {stackTop ← stackTop - 1; int ← Real.RoundLI[stack[stackTop]]};
tokenArg: ROPENIL;
tokenArgStart: INT ← 0;
GetToken: PROC ~ {
charsSkipped: INT ← 0;
tokenStartIndex ← IO.GetIndex[stream];
[tokenKind: tokenKind, token: token, charsSkipped: charsSkipped] ← stream.GetCedarToken[buffer: token, flushComments: TRUE];
tokenStartIndex ← tokenStartIndex + charsSkipped;
};
GetKernel: PROC ~ {
radius: NAT ← PopInt[];
neighbors: DeviceRectangle ~ [-radius, -radius, 2*radius+1, 2*radius+1];
new.comparisonKernel ← ImagerPixelMap.Create[4, neighbors];
FOR s: INT DECREASING IN [-radius..radius] DO
FOR f: INT DECREASING IN [-radius..radius] DO
intensity: [0..255] ← PopInt[];
new.comparisonKernel.Fill[[s,f,1,1], intensity];
ENDLOOP;
ENDLOOP;
};
c: [0..512) ← 0;
GetToken[];
UNTIL tokenKind = tokenEOF DO
myArg: ROPE ← tokenArg;
SELECT tokenKind FROM
tokenID => {
SELECT TRUE FROM
Match["gridEvenness"] => new.gridParam.evenness ← Pop[];
Match["gridPenaltyWeight"] => new.gridParam.penaltyWeight ← Pop[];
Match["gridEdgePinning"] => new.gridParam.edgePinning ← Pop[];
Match["gridMaxOutputDeviation"] => new.gridParam.maxOutputDeviation ← Pop[];
Match["gridReductionFactor"] => new.gridReductionFactor ← PopInt[];
Match["comparisonKernel"] => GetKernel[];
Match["minIntensity"] => [] ← Pop[];
Match["maxIntensity"] => [] ← Pop[];
Match["printerModelRadius"] => printerModelRadius ← PopInt[];
Match["noiseWeight"] => new.noiseWeight ← Pop[];
Match["encoding"] => c ← PopInt[];
Match["aveIntensity"] => meanIntensity[c] ← Pop[];
Match["stdDev"] => stdDev[c] ← Pop[];
Match["occurrences"] => occurrences[c] ← PopInt[];
Match["swathWidth"] => new.swathWidth ← PopInt[];
Match["tuningPasses"] => new.tuningPasses ← PopInt[];
Match["Load"] => {ReadModel[Rope.Concat[myArg, parameterFimeNameExtension]]; myArg ← NIL};
ENDCASE => {
IF myArg # NIL THEN SIGNAL BadToken[fileName, Rope.FromRefText[token], tokenStartIndex];
myArg ← NIL;
tokenArg ← Rope.FromRefText[token];
tokenArgStart ← tokenStartIndex;
};
};
tokenDECIMAL, tokenOCTAL, tokenHEX => TRUSTED {Push[Convert.CardFromWholeNumberLiteral[LOOPHOLE[token]]]};
tokenREAL => TRUSTED {Push[Convert.RealFromRope[LOOPHOLE[token]]]};
ENDCASE => SIGNAL BadToken[fileName, Rope.FromRefText[token], tokenStartIndex];
IF myArg # NIL THEN SIGNAL BadToken[fileName, Rope.FromRefText[token], tokenStartIndex];
GetToken[];
ENDLOOP;
IO.Close[stream];
};
SaveSequences: PROC ~ {
d: NAT ~ 2*printerModelRadius+1;
n: NAT ~ Basics.BITSHIFT[1, d*d];
new.printerModelNeighborhood ← [-printerModelRadius, -printerModelRadius, d, d];
new.intensity ← NEW[RealSequenceRep[n]];
FOR i: NAT IN [0..n) DO new.intensity[i] ← meanIntensity[i] ENDLOOP;
new.noisePenalty ← NEW[RealSequenceRep[n]];
FOR i: NAT IN [0..n) DO new.noisePenalty[i] ← stdDev[i] ENDLOOP;
new.occurrences ← NEW[RealSequenceRep[n]];
FOR i: NAT IN [0..n) DO new.occurrences[i] ← occurrences[i] ENDLOOP;
};
printerModel: DynamicBits.PrinterModel ~ {
intensity: REAL ← meanIntensity[encoding];
scaledIntensity: REAL
(intensity-minMeanIntensity) / (maxMeanIntensity-minMeanIntensity);
RETURN [Real.RoundLI[scaledIntensity*DynamicBits.Intensity.LAST], Real.RoundLI[noiseWeight*stdDev[encoding]]]
};
ReadModel[fileName];
SaveSequences[];
FOR c: [0..512) IN [0..512) DO
minMeanIntensity ← MIN[minMeanIntensity, meanIntensity[c]];
maxMeanIntensity ← MAX[maxMeanIntensity, meanIntensity[c]];
ENDLOOP;
new.model ← DynamicBits.CreatePrinterModel[[-printerModelRadius, -printerModelRadius, printerModelRadius*2+1, printerModelRadius*2+1], printerModel, kernel];
RETURN [new]
};
Store: PUBLIC PROC [ref: Ref, fileName: ROPE] ~ {
io: IO.STREAMFS.StreamOpen[fileName, $create];
kradius: [0..1] ← SELECT ref.comparisonKernel.Window FROM
[0,0,1,1] => 0,
[-1,-1,3,3] => 1,
ENDCASE => ERROR;
pmRadius: [0..1] ← SELECT ref.printerModelNeighborhood FROM
[0,0,1,1] => 0,
[-1,-1,3,3] => 1,
ENDCASE => ERROR;
io.PutF["%g gridEvenness\n%g gridPenaltyWeight\n%g gridEdgePinning\n%g gridMaxOutputDeviation\n",
IO.real[ref.gridParam.evenness],
IO.real[ref.gridParam.penaltyWeight],
IO.real[ref.gridParam.edgePinning],
IO.real[ref.gridParam.maxOutputDeviation]
];
io.PutF["%g gridReductionFactor\n", IO.int[ref.gridReductionFactor]];
FOR s: INT IN [-kradius..kradius] DO
FOR f: INT IN [-kradius..kradius] DO
io.Put[IO.int[ref.comparisonKernel.GetPixel[s,f]]];
io.PutChar[IF f = kradius THEN '\n ELSE ' ];
ENDLOOP;
ENDLOOP;
io.PutF["%g comparisonKernel\n", IO.int[kradius]];
io.PutF["%g printerModelRadius\n", IO.int[pmRadius]];
io.PutF["%g swathWidth\n", IO.int[ref.swathWidth]];
io.PutF["%g tuningPasses\n", IO.int[ref.tuningPasses]];
io.PutF["%g noiseWeight\n", IO.real[ref.noiseWeight]];
FOR c: INT IN [0..ref.intensity.length) DO
io.PutF["%03BB encoding %g aveIntensity %g stdDev %g occurrences\n",
IO.int[c],
IO.real[ref.intensity[c]],
IO.real[ref.noisePenalty[c]],
IO.int[Real.RoundLI[ref.occurrences[c]]]
];
ENDLOOP;
io.Close;
};
END.