if (figdepth = 0) then begin (* ---- do the primitive by itself *) (* re-transform it to the 4th Quadrant *) dvilinepts (x1, y1, x2, y2, h, v); (* global h and v posit *) IPUSH; TylLine (x1, y1, x2, y2, thk, vk, patt); IPOP; end else if (figdepth > 0) then begin (* ---- Pack it and stack it *) lineitem := NewItem (Aline); with lineitem^ do begin BBlx := minx; BBby := miny; BBrx := maxx; BBty := maxy; lx1 := x1; ly1 := y1; lx2 := x2; ly2 := y2; itemthick := thk; itemvec := vk; itempatt := patt; end; pushItem (figdepth, lineitem); end else if (figdepth < 0) then begin (* ---- just do it right away without any PUSH/POP pair *) (* this is the case when we are unpacking a figure for * immediate output *) TylLine (x1, y1, x2, y2, thk, vk, patt); end; end; (* linehandle *) (* --- Simple Splines -----*) {-----------------------------------------------------} procedure splinehandle (figdepth : integer; scalefact : real; thetype : SplineKind; isclosed : boolean; markdiam : integer; var contpts : ControlPoints; nknots : integer; dvih, dviv : ScaledPts; (* possible dvi-offsets *) thk : VThickness; vec : VectKind; patt : LineStyle; minx, maxx, miny, maxy : ScaledPts; tx, ty : ScaledPts; sx, sy, r : real); var midx, midy : ScaledPts; splineitem : pItem; i : integer; begin midx := (minx + maxx) div 2; midy := (miny + maxy) div 2; xfmcontpts (contpts, nknots, dvih, dviv, midx, midy, scalefact, r, tx, ty, sx, sy); if (figdepth = 0) then begin (* ---- do the primitive *) (* transform to 4th quad *) dvicontpts (contpts, nknots, h, v); IPUSH; TylSpline (thetype, isclosed, contpts, nknots, thk, vec, patt, markdiam); IPOP; end else if (figdepth > 0) then begin splineitem := NewItem (Aspline); with splineitem^ do begin BBlx := minx; BBby := miny; BBrx := maxx; BBty := maxy; itemthick := thk; itemvec := vec; itempatt := patt; nsplknots := nknots; spltype := thetype; sclosed := isclosed; dosmarks := markdiam; for i := 1 to nknots do begin spts[i,1] := contpts[i,1]; spts[i,2] := contpts[i,2]; end; end; pushItem (figdepth, splineitem); end else if (figdepth < 0) then begin TylSpline (thetype, isclosed, contpts, nknots, thk, vec, patt, markdiam); end; end; (* splinehandle *) (* --- Variable thickness splines ----- *) {-----------------------------------------------------} procedure ttsplhandle (figdepth : integer; scalefact : real; thetype : SplineKind; isclosed : boolean; markdiam : integer; contpts : ControlPoints; ttks : ThickAryType; nknots : integer; dvih, dviv : ScaledPts; (* possible dvi-offsets *) vec : VectKind; patt : LineStyle; minx, maxx, miny, maxy : ScaledPts; tx, ty : ScaledPts; sx, sy, r : real); var midx, midy : ScaledPts; ttsplitem : pItem; i : integer; begin midx := (minx + maxx) div 2; midy := (miny + maxy) div 2; xfmcontpts (contpts, nknots, dvih, dviv, midx, midy, scalefact, r, tx, ty, sx, sy); if (figdepth = 0) then begin (* transform to 4th quad *) dvicontpts (contpts, nknots, h, v); IPUSH; TylThickThinSpline (thetype, isclosed, contpts, ttks, nknots, vec, patt, markdiam); IPOP; end else if (figdepth > 0) then begin ttsplitem := NewItem (Attspline); with ttsplitem^ do begin BBlx := minx; BBby := miny; BBrx := maxx; BBty := maxy; itemvec := vec; itempatt := patt; nttknots := nknots; tspltype := thetype; dottmarks := markdiam; tclosed := isclosed; for i := 1 to nknots do begin ttpts[i,1] := contpts[i,1]; ttpts[i,2] := contpts[i,2]; ttarry[i] := ttks[i]; end; end; (* ttsplitem *) pushItem (figdepth, ttsplitem); end else if (figdepth < 0) then begin TylThickThinSpline (thetype, isclosed, contpts, ttks, nknots, vec, patt, markdiam); end; end; (* ttsplhandle *) (* ---- Musical Beams ---- *) {-----------------------------------------------------} procedure beamhandle (depth, siz : integer; bk : BeamKind; x1, y1, x2, y2 : ScaledPts); var bmitem : pItem; begin if (depth = 0) then begin dvilinepts (x1, y1, x2, y2, h, v); IPUSH; TylBeam (x1, y1, x2, y2, siz, bk); IPOP; end else if (depth > 0) then begin bmitem := NewItem (Abeam); with bmitem^ do begin BBlx := min(x1, x2); BBby := min(y1, y2); BBrx := max(x1, x2); BBty := max(y1, y2); bx1 := x1; by1 := y1; bx2 := x2; by2 := y2; staf := siz; bkind := bk; end; (* with *) pushItem (depth, bmitem); end else if (depth < 0) then begin TylBeam (x1, y1, x2, y2, siz, bk); end; (* else *) end; (* beamhandle *) (* ---- Musical Ties and Slurs ----- *) {-----------------------------------------------------} procedure tieslurhandle (depth: integer; pts : ControlPoints; numk : integer; minthick, maxthick : VThickness); var tsitem : pItem; i : integer; begin if (depth = 0) then begin dvicontpts (pts, numk, h, v); IPUSH; TylTieSlur (pts, numk, minthick, maxthick); IPOP; end else if (depth > 0) then begin tsitem := NewItem (Atieslur); with tsitem^ do begin ntknots := numk; for i := 1 to numk do begin tspts[i,1] := pts[i,1]; tspts[i,2] := pts[i,2]; end; minth := minthick; maxth := maxthick; end; (* with *) pushItem (depth, tsitem); end else if (depth < 0) then begin TylTieSlur (pts, numk, minthick, maxthick); end; (* else *) end; (* tieslurhandle *) {---------------------------------------------------------} procedure arccirclehandle (figdepth : integer; scalefact : real; cx, cy : ScaledPts; radius : ScaledPts; ang1, ang2 : integer; var contpts : ControlPoints; (* IN *) nknots : integer; dvih, dviv : ScaledPts; (* possible dvi-offsets *) thk : VThickness; vec : VectKind; patt : LineStyle; minx, maxx, miny, maxy : ScaledPts; tx, ty : ScaledPts; sx, sy, r : real); var midx, midy : ScaledPts; middlex, middley : ScaledPts; arcitem : pItem; i : integer; isclosedarc : boolean; begin midx := cx; middlex := (minx + maxx) div 2; midy := cy; middley := (miny + maxy) div 2; isclosedarc := (ang1 = ang2); { if (isclosedarc) then maxspanlen := round ((360.0 / 16.0) * DEGTORAD * radius) else maxspanlen := round ((abs(ang2 - ang1) / 16.0) * DEGTORAD * radius); { } xfmcontpts (contpts, nknots+1, dvih, dviv, midx, midy, scalefact, r, tx, ty, sx, sy); if (figdepth = 0) then begin (* ---- just do the primitive *) (* transform to 4th quad *) dvicontpts (contpts, nknots+1, h, v); IPUSH; doTylArc (isclosedarc, contpts, nknots, thk, vec, patt); IPOP; end else if (figdepth > 0) then begin arcitem := NewItem (Aarc); with arcitem^ do begin BBlx := minx; BBby := miny; BBrx := maxx; BBty := maxy; itemthick := thk; itemvec := vec; itempatt := patt; narcknots := nknots; acentx := cx; acenty := cy; aradius := radius; firstang := ang1; lastang := ang2; for i := 0 to nknots+1 do begin arcpts[i,1] := contpts[i,1]; arcpts[i,2] := contpts[i,2]; end; end; pushItem (figdepth, arcitem); end else if (figdepth < 0) then begin doTylArc (isclosedarc, contpts, nknots, thk, vec, patt); end; end; (* arccirclehandle *) {---------------------------------------------------------} procedure labelhandle (depth : integer; scalefact: real; lax, lay : ScaledPts; dvih, dviv : ScaledPts; (* possible dvi-offsets *) style : integer; phrase : strng; tx, ty : ScaledPts); var labitem : pItem; null1, null2 : ScaledPts; begin (* xfm the label point if necessary *) lax := lax + round(tx * scalefact); lay := lay + round(ty * scalefact); if (depth = 0) then begin null1 := 0; null2 := 0; dvilinepts (lax, lay, null1, null2, h, v); IPUSH; TylLabel (lax, lay, style, phrase.str, phrase.len); IPOP; end else if (depth > 0) then begin labitem := NewItem (Alabel); with labitem^ do begin labx := lax; laby := lay; fontstyle := style; strcopy (phrase.str, labeltext.str, phrase.len); labeltext.len := phrase.len; end; pushItem (depth, labitem); end else if (depth < 0) then begin TylLabel (lax, lay, style, phrase.str, phrase.len); end; end; (* #### Insert new handlers here for new "primitives" i.e., names callable from the \special[tyl ...] level *) {----------------------------------------------------------------} (* transform the current bbox coordinates, and output the new one *) procedure newbbox (var minx, maxx, miny, maxy : ScaledPts; midx, midy : ScaledPts; sx, sy, rot : real; tx, ty : ScaledPts); var (* coords of full bbox for transformation [n/s][e/w][x/y] *) nex, ney, sex, sey, swx, swy, nwx, nwy: ScaledPts; temp1, temp2 : integer; begin (* describe and transform the bbox *) nwx := round (minx * sx); nex := round (maxx * sx); sex := round (maxx * sx); swx := round (minx * sx); ney := round (maxy * sy); nwy := round (maxy * sy); swy := round (miny * sy); sey := round (miny * sy); ptrotate (nex, ney, midx, midy, rot); ptrotate (sex, sey, midx, midy, rot); ptrotate (swx, swy, midx, midy, rot); ptrotate (nwx, nwy, midx, midy, rot); nex := nex + tx; sex := sex + tx; swx := swx + tx; nwx := nwx + tx; ney := ney + ty; sey := sey + ty; swy := swy + ty; nwy := nwy + ty; (* now find the actual extents of the bbox *) temp1 := min (nex, nwx); temp2 := min (swx, sex); minx := min (temp1, temp2); temp1 := min (ney, nwy); temp2 := min (swy, sey); miny := min (temp1, temp2); temp1 := max (nex, nwx); temp2 := max (swx, sex); maxx := max (temp1, temp2); temp1 := max (ney, nwy); temp2 := max (swy, sey); maxy := max (temp1, temp2); end; {-----------------------------------------------} (* find the bounding box of the list of primitives and/or sub-figures in this Item *) procedure findBBox (blot : pItem; var mnx, mxx, mny, mxy : ScaledPts); var pi : pItem; bmnx, bmxx, bmny, bmxy, midx, midy : ScaledPts; (* bbox [min/max][x/y] *) tmnx, tmxx, tmny, tmxy : ScaledPts; (* temporary, in case of recursion *) null1, null2 : ScaledPts; prescale, postscale : real; old1, old2 : ScaledPts; begin bmnx := TWO24; bmny := TWO24; bmxx := -TWO24; bmxy :=-TWO24; if (blot^.kind = Afigure) then begin (* afigure *) pi := blot^.body^.things; while (pi <> nil) do begin (* find the current bbox of the list of items here *) if (pi^.kind = Afigure) then begin (* recur *) findBBox (pi, tmnx, tmxx, tmny, tmxy); bmnx := min (bmnx, tmnx); bmny := min (bmny, tmny); bmxx := max (bmxx, tmxx); bmxy := max (bmxy, tmxy); end else begin bmnx := min (bmnx, pi^.BBlx); bmny := min (bmny, pi^.BBby); bmxx := max (bmxx, pi^.BBrx); bmxy := max (bmxy, pi^.BBty); end; pi := pi^.nextitem; end; (* while *) (* now transform the items inside, AND the bbox *) pi := blot^.body^.things; midx := (bmnx + bmxx) div 2; midy := (bmny + bmxy) div 2; (* now take care of any pre and post size requirements *) (* see also the "figurehandle" proc. *) with blot^ do begin (* ### Keep this scaling biz here, too, for now. May blast it later *) if ((preWid <> 0) and (preHt <> 0)) then begin prescale := scalefitfactor ((bmxx - bmnx), (bmxy - bmny), preWid, preHt); fsx := fsx * prescale; fsy := fsy * prescale; end; if ((postWid <> 0) and (postHt <> 0)) then begin postscale := scalefitfactor ((bmxx - bmnx), (bmxy - bmny), postWid, postHt); fsx := fsx * postscale; fsy := fsy * postscale; end; (* the actual scale-up is taken care of later in this proc. *) end; (* with *) while (pi <> nil) do begin with pi^ do begin case (kind) of Aline : begin xfmlinepts (lx1, ly1, lx2, ly2, 0, 0, midx, midy, 1.0, blot^.figtheta, blot^.fdx, blot^.fdy, blot^.fsx, blot^.fsy); end; Aspline : begin xfmcontpts (spts, nsplknots, 0, 0, midx, midy, 1.0, blot^.figtheta, blot^.fdx, blot^.fdy, blot^.fsx, blot^.fsy); end; Attspline : begin xfmcontpts (ttpts, nttknots, 0, 0, midx, midy, 1.0, blot^.figtheta, blot^.fdx, blot^.fdy, blot^.fsx, blot^.fsy); end; Aarc : begin null1 := 0; null2 := 0; old1 := acentx; old2 := acenty; xfmlinepts (acentx, acenty, null1, null2, 0,0, midx, midy, 1.0, blot^.figtheta, blot^.fdx, blot^.fdy, blot^.fsx, blot^.fsy); xfmcontpts (arcpts, narcknots + 1, 0, 0, old1, old2, 1.0, blot^.figtheta, blot^.fdx + (acentx - old1), blot^.fdy + (acenty - old2), blot^.fsx, blot^.fsy); end; Alabel : begin null1 := 0; null2 := 0; xfmlinepts (labx, laby, null1, null2, 0,0, midx, midy, 1.0, blot^.figtheta, blot^.fdx, blot^.fdy, blot^.fsx, blot^.fsy); end; Abeam : ; (* not transformable *) Atieslur: ; (* not transformable *) Afigure : ; (* do not need to re-transform *) end; (* case *) end; (* with *) pi := pi^.nextitem; end; (* while *) (* transform the bbox, and re-find the new bbox *) newbbox (bmnx, bmxx, bmny, bmxy, midx, midy, blot^.fsx, blot^.fsy, blot^.figtheta, blot^.fdx, blot^.fdy); mnx := bmnx; mny := bmny; mxx := bmxx; mxy := bmxy; end (* if *) else (* some other primitive *) begin mnx := blot^.BBlx; mny := blot^.BBby; mxx := blot^.BBrx; mxy := blot^.BBty; end; (* else *) end; (* findBBox *) {---------------------------------------------------------} (* traverse the list, determining the current bounding box for * the items. We need this to find the mid-point * for doing any remaining rotations *) procedure traverse (thefig, theitem : pItem); var minx, maxx, miny, maxy : ScaledPts; curminx, curmaxx, curminy, curmaxy : ScaledPts; begin minx := TWO24; maxx := -TWO24; miny := TWO24; maxy := -TWO24; while (theitem <> nil) do begin if (theitem^.kind = Afigure) then begin (* recur *) findBBox (theitem, curminx, curmaxx, curminy, curmaxy); with theitem^ do begin BBlx := curminx; BBby := curminy; BBrx := curmaxx; BBty := curmaxy; (* reset the symbol's parameters since all the primitives in it have now been transformed according to the previous specifications *) figtheta := 0.0; fsx := 1.0; fsy := 1.0; fdx := 0; fdy := 0; preWid := 0; preHt := 0; postWid := 0; postHt := 0; end; (* with *) minx := min (minx, curminx); miny := min (miny, curminy); maxx := max (maxx, curmaxx); maxy := max (maxy, curmaxy); end (* if a figure/symbol*) else begin (* a primitive *) with theitem^ do begin minx := min (minx, BBlx); miny := min (miny, BBby); maxx := max (maxx, BBrx); maxy := max (maxy, BBty); end; (* with *) end; (* else *) theitem := theitem^.nextitem; end; (* while *) with thefig^ do begin (* set the bounding box for this upper-level symbol defn *) BBlx := minx; BBby := miny; BBrx := maxx; BBty := maxy; end; (* with *) end; (* traverse *) (* ----- Figure symbols ----- *) {---------------------------------------------------} procedure figurehandle (globalsymlist, symbollist : pItem; dopush : integer); const DoItNow = -1; NoScale = 1; var pi, curfig : pItem; midx, midy : ScaledPts; null1, null2 : ScaledPts; prescale, postscale : real; tmnx, tmny, tmxx, tmxy : ScaledPts; begin (* figurehandle *) (* PUSH. traverse the lists (recursively if necessary) and * compute the transformed points. * Convert to 4th quadrant and offset by H & V. * We can do this destructively here * since we're going to output them right away anyhow. * Then call each respective primitive handler with a level * of -1 to indicate to do its job immediately. * POP. *) curfig := symbollist; pi := curfig^.body^.things; (* find and set the bounding box for the figure's sub-symbols and primitives *) if (dopush > 0) then traverse (curfig, pi); (* We eventually transform the items to 4th Quadrant DVI space and output them! *) pi := curfig^.body^.things; midy := (globalsymlist^.BBby + globalsymlist^.BBty) div 2; midx := (globalsymlist^.BBlx + globalsymlist^.BBrx) div 2; if (dopush > 0) then begin (* the top-level figure for outputting *) (* convert the bounding box because we are about to enter into DVI space, and all calls to handlers hereafter are in terms of DVI coordinates *) with globalsymlist^ do begin (* Since there were external specifications about this figure, fit the current figure's actual size to the "pre" size (specified by W marker) and/or to the "post" size (specified by the F marker). We do this by simple scaling, *without* changing the midpoint of the bounding box, just its extents *) if ((preWid <> 0) and (preHt <> 0)) then begin prescale := scalefitfactor ((BBrx - BBlx), (BBty - BBby), preWid, preHt); fsx := fsx * prescale; fsy := fsy * prescale; end; if ((postWid <> 0) and (postHt <> 0)) then begin postscale := scalefitfactor ((BBrx - BBlx), (BBty - BBby), postWid, postHt); fsx := fsx * postscale; fsy := fsy * postscale; end; tmnx := BBlx; tmny := BBby; tmxx := BBrx; tmxy := BBty; xfmlinepts (tmnx, tmny, tmxx, tmxy, 0,0, midx, midy, 1.0, 0.0, 0, 0, fsx, fsy); toplevelxfm (globalsymlist, globalsymlist, 0); dviBBlx := tmnx; dviBBrx := tmxx; dviBBby := tmny; dviBBty := tmxy; xfmlinepts (dviBBlx, dviBBby, dviBBrx, dviBBty, 0,0, midx, midy, 1.0, 0.0, - (tmnx - BBlx), - (tmny - BBby), 1.0, 1.0); fdx := fdx - (tmnx - BBlx); fdy := fdy - (tmny - BBby); end; dvilinepts (dviBBlx, dviBBby, dviBBrx, dviBBty, h, v); pgfigurenum := pgfigurenum + 1; (* We are ready to output the figure to the page *) writeln(logfile); write(logfile,'Figure #',pgfigurenum:0,' on page ',currpagenum:0,' is approx. '); { write(logfile,((globalsymlist^.BBty - globalsymlist^.BBby) div SPPERPT):0,' pts high and '); writeln(logfile,((globalsymlist^.BBrx - globalsymlist^.BBlx) div SPPERPT):0,' pts wide (actual size)'); } write(logfile,((tmxy - tmny) div SPPERPT):0,' pts high and '); writeln(logfile,((tmxx - tmnx) div SPPERPT):0,' pts wide (actual size)'); IPUSH; end; while (pi <> nil) do begin with pi^ do begin case (kind) of Aline : begin dvilinepts (lx1, ly1, lx2, ly2, h, v); (* DVI h and v posit *) with globalsymlist^ do linehandle (DoItNow, NoScale, pi^.lx1, pi^.ly1, pi^.lx2, pi^.ly2, 0, 0, pi^.itemthick, pi^.itemvec, pi^.itempatt, dviBBlx, dviBBrx, dviBBby, dviBBty, fdx, -fdy, fsx, fsy, -figtheta); end; (* Aline *) Aspline : begin dvicontpts (spts, nsplknots, h, v); with globalsymlist^ do splinehandle (DoItNow, NoScale, pi^.spltype, pi^.sclosed, pi^.dosmarks, pi^.spts, pi^.nsplknots, 0, 0, pi^.itemthick, pi^.itemvec, pi^.itempatt, dviBBlx, dviBBrx, dviBBby, dviBBty, fdx, -fdy, fsx, fsy, -figtheta); end; (* Aspline *) Attspline : begin dvicontpts (ttpts, nttknots, h, v); with globalsymlist^ do ttsplhandle (DoItNow, NoScale, pi^.tspltype, pi^.tclosed, pi^.dottmarks, pi^.ttpts, pi^.ttarry, pi^.nttknots, 0, 0, pi^.itemvec, pi^.itempatt, dviBBlx, dviBBrx, dviBBby, dviBBty, fdx, -fdy, fsx, fsy, -figtheta); end; (* Attspline *) Abeam : begin dvilinepts (bx1, by1, bx2, by2, h, v); beamhandle (DoItNow, staf, bkind, bx1, by1, bx2, by2); end; (* Abeam *) Atieslur : begin dvicontpts (tspts, ntknots, h, v); tieslurhandle (DoItNow, tspts, ntknots, minth, maxth); end; (* a tie or slur *) Aarc : begin dvicontpts (arcpts, narcknots + 1, h, v); with globalsymlist^ do arccirclehandle (DoItNow, NoScale, pi^.acentx, pi^.acenty, pi^.aradius, pi^.firstang, pi^.lastang, pi^.arcpts, pi^.narcknots, 0, 0, pi^.itemthick, pi^.itemvec, pi^.itempatt, dviBBlx, dviBBrx, dviBBby, dviBBty, fdx, -fdy, fsx, fsy, -figtheta); end; (* arc *) Alabel : begin null1 := 0; null2 := 0; dvilinepts (labx, laby, null1, null2, h, v); with globalsymlist^ do labelhandle (DoItNow, NoScale, pi^.labx, pi^.laby, 0, 0, pi^.fontstyle, pi^.labeltext, fdx, -fdy); end; (* label *) Afigure : begin (* recur *) figurehandle (globalsymlist, pi, 0); end; (* another symbol *) end; (* case *) end; (* with *) pi := pi^.nextitem; end; (* while *) if (dopush > 0) then begin IPOP; end; end; (* figurehandle *) (* %%% *) {-----------------------------------------------------} procedure mainhandlespecials (specnum, numpbytes : integer); (* specnum is the DVI-number of the special * numpbytes is the number of parameter bytes *) label 888; const PARSLEN = 50; (* Length of the byte-string-cache *) EMPTY = 0; type charset = set of char; var siz, numknots : integer; (* Lots of temp vars that we use *) x1, y1, x2, y2 : integer; sx100, sy100 : real; transx, transy : ScaledPts; rot : real; SPscale : real; cpts : ControlPoints; thk : VThickness; patt : LineStyle; TTary : ThickAryType; vk : VectKind; bk : BeamKind; markdiam : integer; radius, ang1, ang2 : integer; phrase : strng; style : integer; nam : strng; sysnam : strng; (* the first parameter of the \special *) let : char; i, gotten : integer; b : OctByt; pi : pItem; minx, miny, maxx, maxy : ScaledPts; maxthk, minthk : integer; tylnam, beginfigurenam, (* names used for string to string comparisons *) endfigurenam, linenam, splinenam, ttsplnam, beamnam, tieslurnam, arcnam, labelnam, paramnam {internal} : charstring; splinetype : SplineKind; isclosedspline : boolean; parsearray : array [1..PARSLEN] of OctByt; (* cache of bytes to run through *) parsposit, parsmax : integer; (* current and max position in cache *) usingstream : boolean; (* whether we read/parse using cache or from file *) (*-------------------------------------------------------------- These procedures depend on the correct ordering of GETs with respect to the number of bytes read in so far. precond: byte "b" has been read and gotten < numpbytes postcond: byte "b" has been read iff gotten < numpbytes. If your impl. definition of READ is non-standard, you will have to dink with the ordering and be really careful of keeping track of 'gotten' and 'numpbytes' variables --------------------------------------------------------------*) function nextpbyte : integer; begin if (usingstream) then begin if (gotten < numpbytes) then begin nextpbyte := Dget1byte; gotten := gotten + 1; end else nextpbyte := EMPTY; end else begin (* not using stream *) if (parsposit <= parsmax) then begin nextpbyte := parsearray[parsposit]; parsposit := parsposit + 1; end else begin (* at end of parse array, so read from stream now *) usingstream := true; if (gotten < numpbytes) then begin nextpbyte := Dget1byte; gotten := gotten + 1; end else nextpbyte := EMPTY; end; end; (* else *) end; (* !!!!! Make sure all these predicates jive correctly with the key-letter definitions *) {__________________________________________________________________} function isanumber (b : integer) : boolean; begin isanumber := ((b >= xord['0']) and (b <= xord['9'])); end; function isaletter (b : integer) : boolean; begin isaletter := (((b >= xord['A']) and (b <= xord['Z'])) or ((b >= xord['a']) and (b <= xord['z'])) or (b = xord['@']) or (b = xord['"']) ); end; function isaspace (b : integer) : boolean; begin isaspace := ((b = xord[' ']) or (b = CR) or (b = LF) or (b = HT) or (b = FF)); end; function isdelimiter (b : integer) : boolean; begin (* not a key-letter *) isdelimiter := (((b < xord['A']) or (b > xord['Z'])) and ((b < xord['a']) or (b > xord['z'])) and (b <> xord['@']) and (b <> xord['"']) ); end; function isnotnull (b : integer) : boolean; begin isnotnull := (b <> EMPTY); end; {__________________________________________________________________} function getnumber : integer; var n : integer; isneg : boolean; begin n := 0; isneg := false; while ( (isnotnull (b)) and (not (isanumber (b)))) do begin (* not a numeral *) if (b = xord['-']) then isneg := true; b := nextpbyte; end; while (isaspace (b)) do (* Skip spaces *) b := nextpbyte; while ( (isnotnull (b)) and isanumber (b)) do begin (* a numeral *) n := n * 10 + (b - xord['0']); b := nextpbyte; end; if ((gotten = numpbytes) and isanumber (b)) then begin (* end condition *) n := n * 10 + (b - xord['0']); end; if (isneg) then getnumber := -(n) else getnumber := n; end; {__________________________________________________________________} function getletter : char; var k : char; begin k := ' '; while ( (isnotnull (b)) and (isdelimiter (b) and not (isaspace (b)))) do begin (* non letter *) b := nextpbyte; end; if ( (isnotnull (b)) and ( isaletter (b) or isaspace (b) and not (isanumber (b)))) then begin k := xchr[b]; b := nextpbyte; end; getletter := k; end; {__________________________________________________________________} function getanything : char; var k : char; begin k := ' '; while (not (isnotnull (b))) do begin (* not usable *) b := nextpbyte; end; if (isnotnull (b)) then begin k := xchr[b]; b := nextpbyte; end; getanything := k; end; {**************************************************** The following routines look for key - letter tokens that indicate certain attributes for a primitive. Currently, the letters used are: S for scaled-points measurement P for printers points M millimeters measurement C use a Circular vector for drawing H Horizontal-pen vector V Vertical vector B B-spline I Interpolating B-spline K Catmull-Rom spline D Cardinal spline U Open spline O closed spline X put marks on spline control pts T Transformation marker R Regular beam characters G Grace Beam characters @ Specify center-point for arc/circle L Line-style F for beginfigure: Fit figure to wid/ht W for beginfigure: figure was created at this wid & ht **************************************************} {__________________________________________________________________}