TextLooks.mesa
Copyright Ó 1985, 1986, 1988 by Xerox Corporation. All rights reserved.
written by Bill Paxton, February 1981
last edit by Bill Paxton, December 13, 1982 1:17 pm
Last Edited by: Maxwell, January 5, 1983 12:35 pm
Michael Plass, March 14, 1985 10:00:03 am PST
Doug Wyatt, February 17, 1988 5:16:21 pm PST
This package provides Looks for text in Tioga
it allows a client to associate looks with characters in a rope
looks are represented as a vector of 32 bits
The implementation expects that long sequences will have the same looks
and thus uses a run encoding to save space.
The runs of looks are immutable just like the text in a rope.
i.e., you don't change runs;
instead you build new ones out of parts of old ones
Also like ropes, we use piece tables in the implementation
thus making the cost of setting looks independent of the size of the rope.
DIRECTORY
Basics USING [DoubleAnd, DoubleNot, DoubleOr],
Rope USING [ROPE],
Rosary USING [ROSARY];
TextLooks: CEDAR DEFINITIONS IMPORTS Basics
= BEGIN
Runs: TYPE = Rosary.ROSARY--OF REF Looks--;
Looks: TYPE = PACKED ARRAY Look OF Bit;
Look: TYPE = CHAR ['a..'a+31]; -- 32 bits; indexed from "a"
Bit: TYPE = BOOLFALSE;
noLooks: Looks = ALL[FALSE];
allLooks: Looks = ALL[TRUE];
MaxOffset: INT = LAST[INT];
General operations on runs
CreateRun: PROC [len: INT, looks: Looks ← noLooks] RETURNS [Runs];
Size: PROC [runs: Runs] RETURNS [size: INT];
FetchLooks: PROC [runs: Runs, index: INT] RETURNS [Looks];
returns the looks for the character at the given location
CountRuns: PROC [runs: Runs, start: INT ← 0, len: INT ← MaxOffset] RETURNS [INT];
counts the number of runs
RunAction: TYPE ~ PROC [looks: Looks, len: INT] RETURNS [quit: BOOLFALSE];
MapRuns: PROC [runs: Runs, action: RunAction,
start: INT ← 0, len: INT ← MaxOffset] RETURNS [quit: BOOL];
calls action for each run
Operations to change looks
LooksAnd: PROC [looks1, looks2: Looks] RETURNS [Looks] ~ INLINE {
RETURN[LOOPHOLE[Basics.DoubleAnd[LOOPHOLE[looks1], LOOPHOLE[looks2]]]];
};
LooksOr: PROC [looks1, looks2: Looks] RETURNS [Looks] ~ INLINE {
RETURN[LOOPHOLE[Basics.DoubleOr[LOOPHOLE[looks1], LOOPHOLE[looks2]]]];
};
LooksNot: PROC [looks: Looks] RETURNS [Looks] ~ INLINE {
RETURN[LOOPHOLE[Basics.DoubleNot[LOOPHOLE[looks]]]];
};
ModifyLooks: PROC [old, remove, add: Looks] RETURNS [Looks];
ChangeLooks: PROC [runs: Runs, size: INT, remove, add: Looks,
start: INT ← 0, len: INT ← MaxOffset] RETURNS [Runs];
first remove then add in the given range
Editing Operations
Substr: PROC [base: Runs, start: INT, len: INT] RETURNS [Runs];
returns a substring of the runs
Concat: PROC [base, rest: Runs, baseLen, restLen: INT] RETURNS [Runs];
returns the concatenation of two Runs
Replace: PROC [base: Runs, start, len: INT, replace: Runs, baseSize, repSize: INT
] RETURNS [Runs];
returns new Runs with the given range replaced
ReplaceByRun: PROC [dest: Runs, start, len, runLen, destSize: INT,
inherit: BOOL, looks: Looks] RETURNS [Runs];
equivalent to, but faster than,
Replace[dest,start,len,CreateRun[runLen,xlooks],destSize,runLen]
where xlooks determined in the following manner:
if inherit is false, looks specifed in arg list
if inherit is true, looks found in following manner:
if destSize is 0, then take looks from argument list, else
if start > 0, then looks of previous char,
else looks following replacement
Miscellaneous
OutOfBounds: ERROR;
LooksToRope: PROC [looks: Looks] RETURNS [rope: Rope.ROPE];
RopeToLooks: PROC [rope: Rope.ROPE] RETURNS [looks: Looks];
Internal declarations
LooksBytes: TYPE = MACHINE DEPENDENT RECORD [
byte0(0:0..7), byte1(0:8..15),
byte2(1:0..7), byte3(1:8..15): [0..255] ← 0
];
END.