-- PressFontReader.mesa
-- Written by Michael Plass on August 5, 1982 11:01 am
-- Last edit by Michael Plass on August 11, 1982 10:30 am

DIRECTORY
 Graphics,
 PressFontFormat,
 Rope;

PressFontReader: DEFINITIONS =
BEGIN

ROPE: TYPE = Rope.ROPE;

Handle: TYPE = REF PressFontFileRec;
PressFontFileRec: TYPE;

Font: TYPE = REF READONLY FontRec;

FontRec: TYPE = RECORD [
 info: FontInfoRec,
 pressFontFile: Handle,
 private: REF FontPrivateRec
 ];

FontInfoRec: TYPE = RECORD [
 family: ROPE,
 face: [0..256),
 bc, ec: CHAR,
 size: REAL, -- in meters, or 0 for a scalable font
 rotation: REAL, -- in degrees
 representation: CharShapeRepresentation,
 xRes, yRes: REAL -- in bits per inch; only useful for raster fonts
 ];

CharShapeRepresentation: TYPE = {raster, outline, widthsOnly};

FontPrivateRec: TYPE = PressFontFormat.FontPrivateRec; -- Dig into this at your own risk.

Error: SIGNAL[errorCode: ErrorCode, fontFileWordOffset: INT];

ErrorCode: TYPE = {fileNotFound, fontIndexTooLong, cantHappen, dataSegmentTooLong, invalidPointerInFile, consistencyCheck, fileHasBeenClosed, wrongFontFormatForThisOperation, invalidCodeInFile};

FromFile: PROCEDURE [fileName: ROPE] RETURNS [handle: Handle];

Close: PUBLIC PROCEDURE [handle: Handle];

FirstFont: PROCEDURE [handle: Handle] RETURNS [font: Font];
-- Use this for .ac and .sd files, where there is typically only one font in the file.

ListFonts: PROCEDURE [handle: Handle] RETURNS [fonts: LIST OF Font];
-- Use this when you are interested in many fonts in the file.

EnumerateDirectory: PROCEDURE [handle: Handle, visitFontProc: VisitFontProc]
RETURNS [font: Font];
-- EnumerateDirectory will enumerate all the fonts that appear in the directory. Use this for finding a particular font, since it does no allocations.

VisitFontProc: TYPE = PROCEDURE [fontRec: FontInfoRec]
RETURNS [quit: BOOLEANFALSE];
-- Quitting the enumeration will cause EnumerateDirectory to return that font.

-- ========== Getting information about characters ==========

GetCharInfo: PROCEDURE [font: Font, char: CHAR] RETURNS [info: CharInfo];

CharInfo: TYPE = RECORD [
 widthX, widthY: REAL, -- the width vector
 minX, minY: REAL,  -- the lower left corner of the bounding box
 maxX, maxY: REAL  -- the upper right corner of the bounding box
 ];
-- All of the above dimensions are relative to the point size of the character, and are measured from the reference point of the character, with y increasing upwards and x increasing to the right.

DrawChar: PROCEDURE [context: Graphics.Context, font: Font, char: CHAR];
-- The character, which may be in any supported format, is drawn at the scale of one em per unit. Thus to draw a 10 point font, scale by a factor of 10 before drawing. The current position is updated by the width after the character is drawn.

DrawCharRaster: PROCEDURE [context: Graphics.Context, font: Font, char: CHAR];
-- The character is drawn at the scale of one pixel per unit. The current position is updated by the width after the character is drawn.

MoveToProc: TYPE = PROCEDURE [x, y: REAL];
LineToProc: TYPE = PROCEDURE [x, y: REAL];
CurveToProc: TYPE = PROCEDURE [x1, y1, x2, y2, x3, y3: REAL];
DrawAreaProc: TYPE = PROCEDURE;

GetCharOutline: PROCEDURE [
 font: Font,
 char: CHAR,
 moveToProc: MoveToProc,
 lineToProc: LineToProc,
 curveToProc: CurveToProc,
 drawAreaProc: DrawAreaProc
 ];

GetCharPath
: PROCEDURE [
 font: Font,
 char: CHAR
 ] RETURNS [path: Graphics.Path];

END.