-- TextBltImpl.mesa (last edited by: John Wick, August 29, 1980 4:18 PM)
-- edited by: Forrest, March 16, 1981 7:08 PM

DIRECTORY
BitBlt,
Fonts,
SoftwareTextBlt USING [],
TextBlt;

TextBltImpl: PROGRAM IMPORTS BitBlt EXPORTS TextBlt, SoftwareTextBlt =
BEGIN OPEN TextBltDefs: TextBlt;

Font: PUBLIC TYPE = Fonts.FontRecord;
FontHandle: TYPE = LONG POINTER TO Fonts.FontRecord;

TextBlt: PUBLIC PROC [
index: CARDINAL, bitPos: CARDINAL, micaPos: CARDINAL,
count: INTEGER, ptr: POINTER TO TextBltDefs.TextBltArg]
RETURNS [CARDINAL, CARDINAL, CARDINAL, INTEGER, TextBltDefs.Result] =
BEGIN
bbtablespace: BitBlt.BBTableSpace;
bb: BitBlt.BBptr = BitBlt.AlignedBBTable[@bbtablespace];
result: TextBltDefs.Result;
font: FontHandle = ptr.font;

UNTIL index > ptr.last DO
FetchChar: PROC RETURNS [CHARACTER] = INLINE
{RETURN[ptr.text[index]]};
BitWidth: PROC RETURNS [CARDINAL] = INLINE
{RETURN[font.font.widths[char]]};
Height: PROC RETURNS [CARDINAL] = INLINE
{RETURN[font.height]};
MicaWidth: PROC RETURNS [CARDINAL] = INLINE
{RETURN[font.font.char[char].mica]};
Pad: PROC RETURNS [BOOLEAN] = INLINE
{RETURN[font.rgflags[char].pad]};
Stop: PROC RETURNS [BOOLEAN] = INLINE
{RETURN[font.rgflags[char].stop]};

char: CHARACTER = FetchChar[];
IF ptr.function = resolve THEN ptr.coord[index] ← bitPos;
IF Stop[] THEN GOTO Quit;
IF micaPos + MicaWidth[] > ptr.margin THEN GOTO Margin;
IF ptr.function = display THEN DisplayChar[ptr, bitPos, char, bb];
bitPos ← bitPos + BitWidth[];
micaPos ← micaPos + MicaWidth[];
IF Pad[] THEN
BEGIN
count ← count + 1;
IF ptr.function # format THEN
BEGIN
bitPos ← bitPos + ptr.space;
IF count <= 0 THEN bitPos ← bitPos + 1;
END;
END;
index ← index + 1;
REPEAT
Quit => result ← stop;
Margin => result ← margin;
FINISHED => result ← normal;
ENDLOOP;
RETURN[index, bitPos, micaPos, count, result];
END; -- TextBlt

DisplayChar: PROC [
ptr: POINTER TO TextBltDefs.TextBltArg, bitPos: CARDINAL,
char: CHARACTER, bb: BitBlt.BBptr] = --INLINE
BEGIN
font: FontHandle = ptr.font;
ce: LONG POINTER TO Fonts.CharEntry = @font.font.char[char];
KernLeftWidth: PROC RETURNS [CARDINAL] = INLINE
{RETURN[LOOPHOLE[ce.leftKern]]};
KernRightWidth: PROC RETURNS [CARDINAL] = INLINE
{RETURN[LOOPHOLE[ce.rightKern]]};

bitPos ← bitPos - KernLeftWidth[];
bb.dst ← [word: ptr.dst + bitPos/16, reserved: 0, bit: bitPos MOD 16];
bb.dstBpl ← INTEGER[ptr.dstBpl];
bb.src ← [word: @font.font.bits[ce.offset], reserved: 0, bit: 0];
bb.srcDesc.srcBpl ← bb.width ←
font.font.widths[char] + KernLeftWidth[] + KernRightWidth[];
bb.height ← font.height;
bb.flags ← [
direction: forward, disjoint: TRUE, disjointItems: TRUE,
gray: FALSE, srcFunc: null, dstFunc: or, reserved: 0];
bb.reserved ← 0;
BitBlt.BITBLT[bb];
END;

END. -- of TextBltImpl

LOG
March 24, 1980 10:57 AM - Guyton - Created.
May 8, 1980 5:13 PM - Guyton - Fixed space count to be integer.
July 30, 1980 10:17 AM - Jim Frandeen - Integrate into Pilot.
August 6, 1980 6:40 PM - Guyton - Added kerning. Allow wider than 16 bit chars.
August 29, 1980 4:10 PM - Wick - Reversed parameters, juggled Fonts, added exported type.
March 16, 1981 7:15 PM - Forrest - Make current (characters are now compressed, Display checks for right margin).