-- BcplFontFileDefs.Mesa: Last modified by Geschke on November 5, 1979 4:42 PM

DIRECTORY
Mopcodes: FROM "mopcodes",
StringDefs: FROM "stringdefs";


BcplFontFileDefs: DEFINITIONS =
BEGIN

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

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

IndexHeader
: TYPE = RECORD[type: IndexType, length: [0..4096)];

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

-- 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: StringDefs.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};

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).

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

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

RasterPointer: TYPE = 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;

-- BCPL data structures for spline definitions

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

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

BcplSplineCommand
: TYPE = PRIVATE 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 = PRIVATE INTEGER;

-- Mesa data structures for spline definitions

mesaSplineDataDesc: TYPE = DESCRIPTOR FOR ARRAY OF SplineData;
mesaSplineDirDesc: TYPE = 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 = POINTER TO SplineCommand;
SplineDataPtr: TYPE = POINTER TO SplineData;

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

AllocProc: TYPE = PROCEDURE [CARDINAL] RETURNS [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: STRING];
-- 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;

END.