DIRECTORY Rope; TextLooks: CEDAR DEFINITIONS = BEGIN Runs: TYPE = REF RunsBody; Looks: TYPE = PACKED ARRAY Look OF Bit; Look: TYPE = CHARACTER ['a..'a+31]; -- 32 bits; indexed from "a" Bit: TYPE = BOOLEAN _ FALSE; noLooks: Looks = ALL[FALSE]; allLooks: Looks = ALL[TRUE]; Offset: TYPE = LONG INTEGER; MaxOffset: Offset = LAST[Offset]; OutOfBounds: ERROR; LooksToRope: PROC [looks: Looks] RETURNS [rope: Rope.ROPE]; RopeToLooks: PROC [rope: Rope.ROPE] RETURNS [looks: Looks]; CreateRun: PROC [len: Offset, looks: Looks _ noLooks] RETURNS [Runs]; FetchLooks: PROC [runs: Runs, index: Offset] RETURNS [Looks]; CountRuns: PROC [runs: Runs, start, len: Offset, limit: Offset _ MaxOffset, merge: BOOLEAN _ FALSE, firstLooks: Looks _ noLooks] RETURNS [count: Offset, nonempty: BOOLEAN, lastLooks: Looks]; Size: PROC [base: Runs] RETURNS [size: Offset] = TRUSTED INLINE { RETURN [IF base = NIL THEN 0 ELSE WITH x:base SELECT FROM base => IF x.length=0 THEN 0 ELSE x[x.length-1].after, node => LOOPHOLE[base, REF Tconcat].size, ENDCASE => ERROR] }; ChangeLooks: PROC [ runs: Runs, size: Offset, remove, add: Looks, start: Offset _ 0, len: Offset _ MaxOffset] RETURNS [Runs]; AddLooks: PROC [ runs: Runs, size: Offset, add: Looks, start: Offset _ 0, len: Offset _ MaxOffset] RETURNS [Runs] = INLINE { RETURN [ ChangeLooks[runs, size, noLooks, add, start, len] ] }; RemoveLooks: PROC [ runs: Runs, size: Offset, remove: Looks _ allLooks, start: Offset _ 0, len: Offset _ MaxOffset] RETURNS [Runs] = INLINE { RETURN [ ChangeLooks[runs, size, remove, noLooks, start, len] ] }; SetLooks: PROC [ runs: Runs, size: Offset, new: Looks, start: Offset _ 0, len: Offset _ MaxOffset] RETURNS [Runs] = INLINE { RETURN [ ChangeLooks[runs, size, allLooks, new, start, len] ] }; ClearLooks: PROC [ runs: Runs, size: Offset, start: Offset _ 0, len: Offset _ MaxOffset] RETURNS [Runs] = INLINE { RETURN [ ChangeLooks[runs, size, allLooks, noLooks, start, len] ] }; Substr: PROC [base: Runs, start: Offset, len: Offset] RETURNS [Runs]; Flatten: PROC [base: Runs] RETURNS [new: Runs]; Concat: PROC [base, rest: Runs, baseLen, restLen: Offset] RETURNS [Runs]; Replace: PROC [ base: Runs, start, len: Offset, replace: Runs, baseSize, repSize: Offset, tryFlat: BOOLEAN _ TRUE] RETURNS [Runs]; Delete: PROC [base: Runs, start, len, baseSize: Offset] RETURNS [Runs] = INLINE { RETURN [ Replace[base,start,len,NIL,baseSize,0] ] }; Insert: PROC [base, insert: Runs, loc, baseSize, insertSize: Offset] RETURNS [Runs] = INLINE { RETURN [ Replace[base,loc,0,insert,baseSize,insertSize] ] }; Copy: PROC [dest: Runs, destLoc: Offset, source: Runs, start, len, destSize: Offset] RETURNS [Runs]; ReplaceByRun: PROC [ dest: Runs, start, len, runLen, destSize: Offset, inherit: BOOLEAN, looks: Looks] RETURNS [Runs]; LooksStats: PROC [base: Runs, start: Offset _ 0, len: Offset _ MaxOffset] RETURNS [size, pieces, depth: Offset]; Start: PROC; -- for initialization only LooksBytes: TYPE = MACHINE DEPENDENT RECORD [ byte0(0:0..7), byte1(0:8..15), byte2(1:0..7), byte3(1:8..15): [0..255] _ 0]; qZone: ZONE; -- quantized zone for allocating looks records pZone: ZONE; -- prefixed zone for allocating looks records RunsBody: TYPE = RECORD [SELECT tag: * FROM base => [runs: SEQUENCE length: NAT OF Run], node => [SELECT case: * FROM substr => [size: Offset, base: Runs, start: Offset], concat => [size: Offset, base,rest: Runs, pos: Offset], replace => [size: Offset, base,replace: Runs, start,oldPos,newPos: Offset], change => [size: Offset, base: Runs, remove,add:Looks, start,len: Offset], ENDCASE], ENDCASE]; Run: TYPE = RECORD [after: Offset _ 0, looks: Looks _ noLooks]; BaseRuns: TYPE = REF Tbase; Tbase: TYPE = base RunsBody; Tsubstr: TYPE = substr node RunsBody; Tconcat: TYPE = concat node RunsBody; Treplace: TYPE = replace node RunsBody; Tchange: TYPE = change node RunsBody; FlatMax: Offset = 10; -- flatten if length of run <= FlatMax END. |-- TextLooks.mesa -- written by Bill Paxton, February 1981 -- last edit by Bill Paxton, December 13, 1982 1:17 pm -- 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. Last Edited by: Maxwell, January 5, 1983 12:35 pm -- **** General operations on runs **** -- returns the looks for the character at the given location -- counts the number of runs in the given range -- stops counting if reaches limit -- if merge is true, then doesn't count first run if its looks=firstLooks -- **** Operations to change looks **** -- first remove then add in the given range -- **** Editing Operations **** -- returns a substring of the runs -- returns a flattened version of base runs -- returns a flattened version of base runs -- new has at most 5 pieces; reuses biggest pieces of base -- returns the concatenation of two Runs -- returns new Runs with the given range replaced -- 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 -- ***** Initialization -- ***** Offseternal declarations -- RunsBody is modeled after RopeRep from ROPE.Mesa Κ˜JšΟc™Jš(™(Jš6™6J˜š0™0JšB™BJš/™/J˜—šJ™JJš.™.J˜—š@™@š™Jš7™7J˜——š>™>JšN™NJ™1—šΟk ˜ J˜J˜—Jšœ žœ˜Jšž˜J˜Jšœžœžœ ˜Jš œžœžœžœžœ˜'Jšœžœž œ˜AJšœžœžœžœ˜Jšœžœžœ˜Jšœžœžœ˜J˜Jšœžœžœžœ˜Jšœžœ ˜!J˜Jšœ žœ˜Iproc˜KšΟn œžœžœ žœ˜;J˜KšŸ œžœ žœžœ˜;K˜J˜Jš'™'J˜JšŸ œžœ'žœ˜EJ˜šŸ œžœžœ ˜=Jš<™˜DJ˜J˜—Jš™J˜šŸœžœ)˜5Jšžœ˜Jš"™"J˜—šŸœžœžœ ˜/Jš+™+J˜Jš+™+Jš:™:J˜—šŸœžœ.žœ˜IJš(™(J˜—šŸœžœ˜J˜.Jšœ$žœžœ˜3Jšžœ˜Jš1™1J˜—šŸœžœ,žœ ž˜OJšœžœžœ˜6J˜—šŸœžœ8˜Dšžœ žœžœ˜"J˜3J˜——šŸœžœJ˜TJšžœ˜J˜—šŸ œžœ˜J˜1Jšœ žœ˜Jšžœ˜Jš"™"JšC™Cš3™3Jš4™4š7™7Jš=™=Jš-™-Jš#™#J˜———šŸ œžœ9˜IJšžœ˜&J˜—Jš™J˜JšŸœžœ˜'J˜J˜Jš!™!J˜š œ žœžœž œžœ˜-J˜J˜-J˜—Jšœžœ.˜;Jšœžœ-˜:J˜šœ žœžœžœž˜+Jš3™3Jšœžœ žœžœ˜,šœ žœ ž˜J˜4J˜7J˜KJ˜JJšžœ˜ —Jšžœ˜ —Jšœžœžœ-˜?Jšœ žœžœ˜Jšœžœ˜Jšœ žœ˜%Jšœ žœ˜%Jšœ žœ˜'Jšœ žœ˜%J˜Jšœ&˜