Search code examples
compiler-constructionpostscript

postscript merge two paths


I am making a high-level language on top of postscript for my course on compilers, and I want to create two functions: concatenate and union, which should take two paths and joints them. Concatenate works by connecting the end point of the first path to the start point of the second. Union works does not connect the end points.

After playing for a while, I managed to perform those operations automatically. I got the intended result in some cases, but not in others. I will give concrete examples of my solution, and where they fail.

WORKING: If I want to take two paths, one made by an arc, and other by connecting three dots, I can take the following basic paths:

 newpath 100 200 70 0 45 arc  %create an arc path
 newpath 100 100 moveto  200 200 lineto 200 300 lineto %create a polygon

and concatenate them (creating a line from the endpoint of the arc to the start point of the lines) by letting my compiler write the code:

newpath 100 100 moveto  200 200 lineto 200 300 lineto reversepath currentpoint newpath %stores the startpoint of the polygon to be used later

newpath 100 200 70 0 45 arc % creates the arc
lineto  %takes the saved information about start of the polygon and creates a line to it
100 100 moveto  200 200 lineto 200 300 lineto  %finishes by adding the polygon to the path

STILL MISSING:

I am operating on the raw strings that I used to create those paths, but how to proceed in the case the user had create bindings for paths, and now I want to join them. For example, supposed the user create the binds:

/p1 {  newpath 100 200 70 0 45 arc } bind def
/p2 {  newpath 100 100 moveto  200 200 lineto 200 300 lineto } bind def

How could I proceed to join these two paths as needed WITHOUT modifying the bindings?

I tried something like

p1 uappend p2

, but it didnt work. I can find no help even after looking for many days.

Thanks


Solution

  • You could load the definition of the functions and then look at the contents of the executable array.

    /p1 load {==} forall
    

    will show you what that looks like. Or you could define versions of each of the path operators which store their operands and just execute the procedures.

    /moveto {....} def
    /lineto {....} def
    ...
    ...
    p1 p2
    

    As usual with a programming problem there are multiple possible solutions.