<> <> <> <<>> 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: BOOLEAN _ FALSE; 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: ROPE _ NIL] = { 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.STREAM _ IO.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.