-- Copyright (C) 1981 by Xerox Corporation. All rights reserved.
-- File: WindowFonts.mesa edit by
-- Karlton, 2-Jul-81 13:08:51
DIRECTORY
WindowFont USING [ErrorCode, Handle];
WindowFonts: PROGRAM EXPORTS WindowFont =
BEGIN
Handle: TYPE = WindowFont.Handle;
Strike: TYPE = LONG POINTER TO StrikeObject;
StrikeObject: TYPE = RECORD [header: StrikeHeader, body: StrikeBody];
StrikeHeader: TYPE = RECORD [
bits: StrikeBits, min: CARDINAL, max: CARDINAL, maxwidth: CARDINAL];
StrikeBits: TYPE = RECORD [
newStyle: BOOLEAN,
indexed: BOOLEAN,
fixed: BOOLEAN,
kerned: BOOLEAN,
pad: [0..7777B]];
BoundingBox: TYPE = RECORD [FontBBox, FontBBoy, FontBBdx, FontBBDy: INTEGER];
StrikeBody: TYPE = RECORD [
length: CARDINAL,
ascent: CARDINAL,
descent: CARDINAL,
xoffset: CARDINAL,
raster: CARDINAL,
bitmap: ARRAY [0..0) OF WORD];
defaultFont: PUBLIC Handle ← NIL;
Error: PUBLIC ERROR [code: WindowFont.ErrorCode] = CODE;
SetDefault: PUBLIC PROCEDURE [font: Handle] = {defaultFont ← font};
CharIsDefined: PUBLIC PROCEDURE [char: CHARACTER, font: Handle ← defaultFont]
RETURNS [BOOLEAN] = {
IF font = NIL THEN font ← defaultFont; RETURN[font.width[char] # 0]};
CharWidth: PUBLIC PROCEDURE [char: CHARACTER, font: Handle ← defaultFont]
RETURNS [width: NATURAL] = {
IF font = NIL THEN font ← defaultFont;
width ← font.width[char];
IF width = 0 THEN width ← font.width[font.max + 1]};
FontHeight: PUBLIC PROCEDURE [font: Handle ← defaultFont] RETURNS [NATURAL] = {
RETURN[IF font = NIL THEN defaultFont.height ELSE font.height]};
SetFontAddresses: PROCEDURE [font: WindowFont.Handle] = {
strike: Strike = font.address;
font.bitmap ←
@strike.body.bitmap + (IF font.kerned THEN SIZE[BoundingBox] ELSE 0);
font.xInSegment ←
LOOPHOLE[font.bitmap, LONG POINTER] + font.raster*font.height -
LOOPHOLE[font.min, INTEGER]};
Initialize: PUBLIC PROCEDURE [font: Handle] = {
strike: Strike = font.address;
c: CHARACTER;
bits: StrikeBits = strike.header.bits;
IF ~bits.newStyle THEN ERROR Error[illegalFormat];
IF bits.indexed THEN ERROR Error[illegalFormat];
font.kerned ← bits.kerned;
IF strike.header.min ~IN [0..377B] THEN ERROR Error[illegalFormat];
font.min ← LOOPHOLE[strike.header.min];
IF strike.header.max ~IN [strike.header.min..377B) THEN
ERROR Error[illegalFormat];
font.max ← LOOPHOLE[strike.header.max];
font.height ← strike.body.ascent + strike.body.descent;
font.raster ← strike.body.raster;
font.maxWidth ← strike.header.maxwidth;
SetFontAddresses[font];
FOR c IN [0C..font.min) DO font.width[c] ← 0 ENDLOOP;
FOR c IN [font.min..font.max + 1] DO
font.width[c] ← font.xInSegment[c + 1] - font.xInSegment[c] ENDLOOP;
FOR c IN (font.max + 1..377C] DO font.width[c] ← 0 ENDLOOP};
END.