-- CGOutlinesImpl.mesa --Written by Doug Wyatt, Nov-81 -- Last changed by J Warnock June 28, 1982 12:24 pm --Maureen Stone January 31, 1984 4:27:02 pm PST DIRECTORY ParametricMap, CGCubic USING [Bezier], GraphicsBasic USING [Vec], CGVector USING [Add,Mul,Sub,Dot], CGOutlines USING [Data, DataRep, ErrorType, NodeRep, Rep], CGStorage USING [pZone, qZone], RealFns USING [SqRt]; CGOutlinesImpl: CEDAR PROGRAM IMPORTS CGStorage,CGVector,ParametricMap,RealFns EXPORTS CGOutlines = { OPEN CGOutlines, GraphicsBasic, CGVector, CGCubic; Ref: TYPE = REF Rep; Error: PUBLIC ERROR[type: ErrorType] = CODE; dataZone: ZONE = CGStorage.pZone; nodeZone: ZONE = CGStorage.qZone; boxZone: ZONE = CGStorage.qZone; repZone: ZONE = CGStorage.qZone; New: PUBLIC PROC[size: NAT] RETURNS[Ref] = { self: Ref _ repZone.NEW[Rep _ [size: 0, data: NIL, fpi: 0, fp: [0,0], lp: [0,0], sum:0]]; [] _ GetData[self,size]; RETURN[self]; }; GetData: PROC[self: Ref, size: NAT, bump: NAT _ 0] RETURNS[Data] = INLINE { data: Data _ self.data; space: NAT _ IF data=NIL THEN 0 ELSE data.space; IF space self.sum THEN v.x_self.sum; UNTIL v.x IN [self.data[i].l1..self.data[i].l2] DO i_i+1; ENDLOOP; bz_self.data[i].bz; x_v.x-self.data[i].l1; IF self.data[i].line THEN {t_x/(self.data[i].l2-self.data[i].l1)} ELSE {[,t]_ParametricMap.GetTforArc[@bz,x];}; [pos,dc]_ParametricMap.GetDirCos[t,@bz]; a1_self.data[i].a1; a2_self.data[i].a2; w_Add[pos,Mul[Add[Vec[-dc.y,dc.x],Mul[dc,a1+(a2-a1)*t]],v.y]]; }; GetLinkCount:PUBLIC PROC[self:Ref] RETURNS [c:NAT]= {RETURN[self.size];}; GetLinkLength:PUBLIC PROC[self:Ref,i:NAT] RETURNS [l:REAL]= {RETURN[self.data[i].l2-self.data[i].l1];}; Copy: PUBLIC PROC[self: Ref] RETURNS[Ref] = { size: NAT _ self.size; old: Data _ self.data; copy: Ref _ New[size]; new: Data _ copy.data; FOR i: NAT IN[0..size) DO new[i]^ _ old[i]^ ENDLOOP; copy.size _ size; copy.fpi _ self.fpi; copy.fp _ self.fp; copy.lp _ self.lp; RETURN[copy]; }; Assign: PUBLIC PROC[self: Ref, copy: Ref] = { size: NAT _ copy.size; new: Data _ copy.data; old: Data _ GetData[self,size]; FOR i: NAT IN[0..size) DO old[i]^ _ new[i]^ ENDLOOP; self.size _ size; self.fpi _ copy.fpi; self.fp _ copy.fp; self.lp _ copy.lp; }; Mag:PROC[v:Vec] RETURNS [REAL]=INLINE {RETURN[RealFns.SqRt[v.x*v.x+v.y*v.y]];}; Norm:PROC[v:Vec] RETURNS [Vec]=INLINE {m:REAL_Mag[v]; IF m = 0 THEN RETURN [v] ELSE RETURN [Mul[v,1.0/m]];}; GetLength:PROC[v1,v2,v3,v4:Vec] RETURNS [REAL]= TRUSTED {bz:CGCubic.Bezier; bz_CGCubic.Bezier[v1,v2,v3,v4]; RETURN[ParametricMap.ArcLength[@bz]];}; }.