INTERFACE PZSegment; (* A PZSegment.T is a descriptor of part of a fragment contour *) (* Last edited on 1999-11-16 19:55:47 by hcgl *) IMPORT Wr, Rd; FROM PZTypes IMPORT INT, NAT, NATS, BOOL, BOOLS; TYPE T = RECORD cvx: NAT; (* Contour index. *) tot: NAT; (* Number of samples in curve. *) ini: NAT; (* Initial sample index. *) ns: NAT; (* Number of samples in segment. *) rev: BOOL; (* TRUE to use the segment in reverse. *) END; (* A "PZSegment.T" record "s" describes a set of "s.ns" consecutive samples, starting at sample index "s.ini", along a fragment contour with a total of "s.tot" samples. The indices are always taken modulo "s.tot", so the segment may wrap around the end of the sample array. If "rev" is TRUE the samples are to be used in reverse order, and possibly complemented depending on their nature. Note that if "s.rev = TRUE" the client should start with sample "(s.ini + s.ns - 1) MOD s.tot" and finish with "s.ini". Normally a segment has at least two samples, and at most "s.tot" samples. Singleton segments ("s.ns = 1"), empty segments (with "ns = 0") and ``full circle'' segments ("s.ns = s.tot+1") are sometimes useful but may cause some operations to fail. *) Pair = ARRAY [0..1] OF T; CONST Empty = T{cvx := 0, tot := 1, ini := 0, ns := 0, rev := FALSE}; (* An empty segment (NOT the only one!). *) PROCEDURE IsEmpty(READONLY s: T): BOOL; (* TRUE if the segment is empty (has zero samples). *) PROCEDURE AbsIndex(iRel: INT; READONLY s: T): INT; (* Given a sample index "iRel" relative to the segment "s", returns the corresponding sample index in the original chain, taking the direction of "s" into account. Note that the result must be reduced "MOD s.tot" before indexing the chain. *) PROCEDURE RelIndex(iAbs: INT; READONLY s: T): INT; (* Given a sample index "iAbs" in a whole chain, returns the corresponding sample index relative to the segment "s", taking the direction of "s" into account. Note that the result must be reduced "MOD s.tot" and checked against "s.ns" before indexing the extracted segment samples. *) PROCEDURE AbsIndexClip(i: NAT; READONLY s: T): NAT; (* Given a sample index "i" relative to the segment "s", returns the corresponding sample index in the whole curve. *) PROCEDURE RelIndexClip(i: NAT; READONLY s: T): NAT; (* Given a sample index "i" in some curve, returns the corresponding sample index relative to segment "s" of that curve. Returns "LAST(NAT)" if that sample lies outside "s". *) PROCEDURE Complement(READONLY s: T): T; (* The complement of segment "s" with respect to its parent curve, which is assumed to be closed. The result has same initial and final samples as "s", in the opposite order, and same sense "rev". Fails if "s.ns = 0" or "s.ns > s.tot + 1". *) PROCEDURE Overlap(READONLY a, b: T): NAT; (* Maximum number of consecutive samples in common beween "a" and "b". Returns 0 if "a" and "b" are on different curves or have different orientations. If they intersect in two disjoint segments, considers only the longest one. *) PROCEDURE Join(READONLY a, b: T): T; (* Joins two segments of the same curve (with same direction) into a single segment. If the segments don't overlap, they are joined by the shortest uncovered arc. If the segments overlap at both ends, the result is a segment that covers the whole contour once, starting and ending at sample 0. *) PROCEDURE Meet(READONLY a, b: T): T; (* Returns the intersection of two segments, which must belong to the same curve and have the same reading direction. The result is an empty segment ("ns = 0") if they are disjoint, or if their intersection is not a single segment. *) PROCEDURE Expand( READONLY s: T; (* Segment to expand *) iniExtra, finExtra: INT; (* Number of steps to add/delete. *) ): T; (* Expands the given segment by "iniExtra" steps at the low end, and "finExtra" steps at the high end. If either quantity is negative, removes that many steps from the respective end. In any case, the result will have at least one sample and at most "s.tot + 1" samples. *) TYPE List = ARRAY OF T; ReadData = RECORD cmt: TEXT; s: REF List END; PROCEDURE Write( wr :Wr.T; cmt: TEXT; READONLY s: List; ); (* Writes the list of segments "s" to the writer "wr". *) PROCEDURE Read(rd :Rd.T): ReadData; (* Reads from "rd" a list of segments that was written by "Write". *) PROCEDURE ReadOld(rd :Rd.T; READONLY m: NATS): ReadData; (* Reads from "rd" a list of segments that was written BY the old version of "Write", without the "rev" bits. Takes the "tot" fields of the result from from the argument "m", assuming that "m[k]" the number of samples of contour "k". *) PROCEDURE GetCurves(READONLY s: List): REF BOOLS; (* Returns a vector "seen" such that "seen[k]" is TRUE iff curve "k" occurs in some segment "s[i]". *) PROCEDURE Print (wr: Wr.T; READONLY s: T); (* Prints the segment descriptor "s" to "wr", in a readable format, without trailing newline. *) END PZSegment. (* Copyright © 2001 Universidade Estadual de Campinas (UNICAMP). Authors: Helena C. G. Leitão and Jorge Stolfi. This file can be freely distributed, used, and modified, provided that this copyright and authorship notice is preserved, and that any modified versions are clearly marked as such. This software has NO WARRANTY of correctness or applicability for any purpose. Neither the authors nor their employers chall be held responsible for any losses or damages that may result from its use. *)