-- TSBcplFontFile.mesa
-- Last modified by Michael Plass, May 27, 1982 8:39 am
-- Last modified by Maureen Stone 30-Dec-81 17:14:31
-- Last modified by Geschke on November 5, 1979  4:42 PM

DIRECTORY
	Rope,
	Mopcodes;


TSBcplFontFile: DEFINITIONS =
BEGIN

Byte: TYPE = [0..377B];

-- the IndexHeader corresponds to Structure IX pp5 Font Formats Manual.

IndexHeader: TYPE = RECORD[type: IndexType, length: [0..4096)];	--length in words, counting this one

IndexType: TYPE = {end,name,splines,chars,widths,
                   unassigned1,unassigned2,unassigned3,unassigned4,
                   unassigned5,unassigned6,unassigned7,unassigned8,
                   unassigned9,unassigned10,unassigned11};

bcplMaxLength: CARDINAL = 255;
BcplSTRING: TYPE = MACHINE DEPENDENT RECORD[
	body: PACKED ARRAY[0..bcplMaxLength] OF CHARACTER	--body[0] is the length of the string
	];

-- The RawIndex corresponds to the five kinds of index entries.
-- EndSegment, NameSegment, SplineSegment, CharacterSegment, and WidthSegment.

RawIndex: TYPE = MACHINE DEPENDENT RECORD
  [hdr: IndexHeader,
   variantPart: SELECT COMPUTED IndexType FROM
      end => NULL,
      name =>
        [
        fill: Byte,
        code: FontCode, -- local, unique name for font
        fontname: BcplSTRING
        ],
      splines, widths =>
        [
        family: FontCode,
        face: FaceType,
        bc, ec: CHARACTER,						-- first and last character
        size: CARDINAL,							-- Font size (10 micron units)
        rotation: CARDINAL,						-- Rotation (anti clockwise)
        startaddress: bcplLONGPOINTER,		-- Starting address of data part
        length: bcplLONGCARDINAL				-- Length of data part
        ],
      chars =>
        [
        family: FontCode,
        face: FaceType,
        bc, ec: CHARACTER,						-- first and last character
        size: CARDINAL,							-- Font size (10 micron units)
        rotation: CARDINAL,						-- Rotation (anti clockwise)
        startaddress: bcplLONGPOINTER,		-- Starting address of data part
        length: bcplLONGCARDINAL,				-- Length of data part
        resolutionx: CARDINAL,					-- 10*(number of bits/inch)
        resolutiony: CARDINAL					-- ditto
        ],
      ENDCASE
  ];

FontCode: TYPE = Byte;
FaceType: TYPE = Byte;
FaceWeight: TYPE = {L,M,B};
FaceSlant: TYPE = {I,R};
FaceWidth: TYPE = {C,R,E};

CharBboxDesc: TYPE = LONG DESCRIPTOR FOR ARRAY OF BoundingBox;
CharDirDesc: TYPE = LONG DESCRIPTOR FOR ARRAY OF bcplLONGPOINTER;

BoundingBox: TYPE = MACHINE DEPENDENT RECORD[
    xwidth, ywidth: bcplFraction,
    BBox, BBoy: INTEGER, BBdx, BBdy: CARDINAL];


--  BCPL data structures for spline definitions

SplineDataDesc: TYPE = LONG DESCRIPTOR FOR ARRAY OF BcplSplineData;
SplineDirDesc: TYPE = CharDirDesc;

BcplSplineData: TYPE = RECORD[
	xwidth, ywidth, bbox, bboy, rightx, topy: BcplREAL];

BcplSplineCommand: TYPE = MACHINE DEPENDENT RECORD
  [type: BcplCommandCode,
   variantPart: SELECT OVERLAID SplineCommandCode FROM
      MoveTo, DrawTo => [x,y: BcplREAL],
      DrawCurve => [x0,y0,x1,y1,x2,y2: BcplREAL],
      NewObject, EndDefinition => NULL,
      ENDCASE
  ];

BcplREAL: TYPE = MACHINE DEPENDENT RECORD[
    sign: [0..1], exp: [0..377B], sigbit: [0..1], topmantissa: [0..77B],
    restofmantissa: [0..177777B]];

BcplCommandCode: TYPE = INTEGER;

--  Mesa data structures for spline definitions

mesaSplineDataDesc: TYPE = LONG DESCRIPTOR FOR ARRAY OF SplineData;
mesaSplineDirDesc: TYPE = LONG DESCRIPTOR FOR ARRAY OF LONG POINTER;

SplineData: TYPE = RECORD[xwidth, ywidth, bbox, bboy, rightx, topy: REAL];

SplineCommand: TYPE = RECORD
  [next: SplineCommandPtr,
   variantPart: SELECT type: SplineCommandCode FROM
      MoveTo, DrawTo => [x,y: REAL],
      DrawCurve => [x0,y0,x1,y1,x2,y2: REAL],
      NewObject, EndDefinition => NULL,
      ENDCASE
  ];

SplineCommandPtr: TYPE = LONG POINTER TO SplineCommand;
SplineDataPtr: TYPE = LONG POINTER TO SplineData;

SplineCommandCode: TYPE = {MoveTo, DrawTo, DrawCurve, NewObject, EndDefinition};

AllocProc: TYPE = PROCEDURE [CARDINAL] RETURNS [LONG POINTER];

GetSplineCommands: PROCEDURE [char: CHARACTER, userAlloc: AllocProc]
                RETURNS [sd: SplineDataPtr, scp: SplineCommandPtr];
-- reads a list of spline commands into space obtained by invoking the allocation procedure (userAlloc) and returns the pointer to you (scp) along with a pointer to the spline bounding box data (sd).  It is the user's responsibility to free the command list.  The procedure returns [NIL,NIL] if the splines for char are not defined in the file.

OpenSDFontFile: PROCEDURE [file: Rope.ROPE];
-- opens a SD format file (named file) for reading (it does not assume the .SD extension; you must give the full file name).  This code supports only one SD file open at a time.

CloseSDFontFile: PROCEDURE;
-- closes the file.

--  converting from the doubleword world of Mesa to BCPL and conversely

MesaToBcplLongPointer: PROCEDURE [p: LONG POINTER] RETURNS [bp: bcplLONGPOINTER] =
    MACHINE CODE BEGIN Mopcodes.zEXCH; END;

BcplToMesaLongPointer: PROCEDURE [bp: bcplLONGPOINTER] RETURNS [p: LONG POINTER] =
    MACHINE CODE BEGIN Mopcodes.zEXCH; END;

MesaToBcplLongCardinal: PROCEDURE [c: LONG CARDINAL] RETURNS [bc: bcplLONGCARDINAL] =
    MACHINE CODE BEGIN Mopcodes.zEXCH; END;

BcplToMesaLongCardinal: PROCEDURE [bc: bcplLONGCARDINAL] RETURNS [c: LONG CARDINAL] =
    MACHINE CODE BEGIN Mopcodes.zEXCH; END;

MesaToBcplFraction: PROCEDURE [f: Fraction] RETURNS [bf: bcplFraction] =
    MACHINE CODE BEGIN Mopcodes.zEXCH; END;

BcplToMesaFraction: PROCEDURE [bf: bcplFraction] RETURNS [f: Fraction] =
    MACHINE CODE BEGIN Mopcodes.zEXCH; END;


bcplLONGPOINTER: TYPE = MACHINE DEPENDENT RECORD[
    highhalf, lowhalf: WORD];

bcplLONGCARDINAL: TYPE = MACHINE DEPENDENT RECORD[
    highhalf, lowhalf: WORD];

bcplFraction: TYPE = MACHINE DEPENDENT RECORD[
    integerpart, fractionpart: WORD];

Fraction: TYPE = LONG INTEGER;

-- ***** Raster font routines not implemented ***** 

ConvertACtoGS: PUBLIC PROCEDURE [from, to: STRING];
-- converts an AC format font file (from) to a GS format font file (to).  In the process of conversion the font is rotated 90 degrees.


ConvertGStoAC: PUBLIC PROCEDURE [from, to: STRING];
-- converts an GS format font file (from) to a AC format font file (to).  In the process of conversion the font is rotated 90 degrees (therby undoing the rotation in ConvertACtoGS).

RasterPointer: TYPE = LONG POINTER TO CharRaster;
RasterDimension: TYPE = MACHINE DEPENDENT RECORD[height: [0..77B], width: [0..1777B]];
InternalRasterPointer: TYPE = POINTER TO InternalCharRaster;
LongRasterPointer: TYPE = LONG POINTER TO CharRaster;
InternalCharRaster: TYPE = RECORD [height, width: CARDINAL, raster: Raster];
CharRaster: TYPE = MACHINE DEPENDENT RECORD[
    height: [0..77B], width: [0..1777B],
    raster: Raster];
Raster:TYPE = ARRAY [0..0) OF WORD;
END.