MakeRasterFontImpl.mesa
Copyright (C) 1984, Xerox Corporation. All rights reserved.
Michael Plass, October 15, 1984 10:05:48 am PDT
DIRECTORY BitmapViewer, Commander, Imager, ImagerPixelMaps, ImagerTransform, IO, Font, FontEdit, Real, Rope, RasterFontWriter, MakeRasterFont, UFPressFontReader, ViewerClasses;
MakeRasterFontImpl: CEDAR PROGRAM
IMPORTS BitmapViewer, Commander, Imager, ImagerPixelMaps, ImagerTransform, IO, Font, FontEdit, Real, Rope, UFPressFontReader, RasterFontWriter
EXPORTS MakeRasterFont ~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
FONT: TYPE ~ Font.FONT;
InternalFont: TYPE ~ RasterFontWriter.InternalFont;
visible: BOOLEANFALSE;
FromUnifiedFont: PUBLIC PROC [font: FONT] RETURNS [internalFont: InternalFont] ~ {
bb: Font.Box ← Font.FontBoundingBox[font];
dbb: ImagerPixelMaps.DeviceRectangle ← [Real.RoundLI[-bb.ymax], Real.RoundLI[+bb.xmin], Real.RoundLI[bb.ymax]-Real.RoundLI[bb.ymin], Real.RoundLI[bb.xmax]-Real.RoundLI[bb.xmin]];
pixelMap: ImagerPixelMaps.PixelMap ← ImagerPixelMaps.Create[0, [0, 0, dbb.sSize+4, dbb.fSize+4]];
context: Imager.Context ← Imager.Create[$LFDisplay, NEW[ImagerPixelMaps.PixelMap ← pixelMap]];
viewer: ViewerClasses.Viewer ← IF visible THEN BitmapViewer.Create[[name: font.Name]] ELSE NIL;
pixelMap ← pixelMap.ShiftMap[dbb.sMin-2, dbb.fMin-2];
internalFont ← RasterFontWriter.Create[dbb, dbb.fSize];
IF font.GetProp[$PressFont] = $PressFont THEN {
internalFont.family ← UFPressFontReader.Family[[font.graphicsKey, 0]];
internalFont.face ← UFPressFontReader.Face[[font.graphicsKey, 0]];
internalFont.bitsPerEmQuad ← font.actualTransformation.SingularValues.x;
};
context.state.T ← Imager.Translate[2-bb.xmin, 2+dbb.sMin+dbb.sSize];
context.SetFont[font];
FOR c: CHAR IN [font.bc..font.ec] DO
widthVector: Font.Pair ← Font.WidthVector[font, c];
pixelMap.Clear;
context.SetXY[[0,0]];
context.ShowChar[c];
{pixels: ImagerPixelMaps.PixelMap ← pixelMap.Trim[0].Copy;
IF viewer # NIL THEN BitmapViewer.SetBitmap[viewer, pixels];
internalFont.charRep[c] ← [
fWidth: widthVector.x,
sWidth: -widthVector.y,
pixels: pixelMap.Trim[0].Copy
];
};
ENDLOOP;
};
ConvertFile: PUBLIC PROC [outputFileName: ROPE, fontName: ROPE, size: REAL, rotation: REAL, bitsPerInch: REAL] ~ {
font: FONT ← Font.Create[fontName, Imager.Concat[Imager.Scale[size], Imager.Rotate[rotation]]];
internalFont: InternalFont ← FromUnifiedFont[font];
FontEdit.WriteFormatDerivedFromName[internalFont, outputFileName, bitsPerInch];
};
Break: PROC [char: CHAR] RETURNS [IO.CharClass] = {
IF char = '← OR char = '; THEN RETURN [break];
IF char = ' OR char = '  OR char = ', OR char = '\n THEN RETURN [sepr];
RETURN [other];
};
GetToken: PROC [stream: IO.STREAM] RETURNS [rope: ROPENIL] = {
rope ← stream.GetTokenRope[Break ! IO.EndOfStream => CONTINUE].token;
};
GetReal: PROC [stream: IO.STREAM] RETURNS [real: REAL ← 0.0] = {
real ← stream.GetReal[! IO.Error, IO.EndOfStream => CONTINUE];
};
MakeRasterFontCommand: Commander.CommandProc ~ {
stream: IO.STREAMIO.RIS[cmd.commandLine];
outputName: ROPE ← GetToken[stream];
gets: ROPE ← GetToken[stream];
inputName: ROPE ← GetToken[stream];
size: REAL ← GetReal[stream];
rotation: REAL ← GetReal[stream];
bitsPerInch: REAL ← GetReal[stream];
IF bitsPerInch = 0.0 THEN bitsPerInch ← 384.0;
IF NOT gets.Equal["←"] OR size <= 0.0 THEN {
cmd.out.PutRope["Specify output ← fontname size rotation, please\n"];
RETURN;
};
ConvertFile[outputName, inputName, size, rotation, bitsPerInch];
};
Commander.Register["MakeRasterFont", MakeRasterFontCommand, "Convert a UnifiedFont to raster format (output ← fontname size rotation)"];
END.