[comp.lang.postscript] path to calligraphy penstroke

dylan@cs.washington.edu (Dylan McNamee) (05/30/90)

I would like to take a single path (usually will be arcs and curves)
and a Calligraphy pen description (nib width, angle) and return the
two paths that define the borders of the penstroke.

Can anyone point to or provide any examples of ways of doing this?

The only thing I can think of at the moment would be to sample the path
at some interval, and use the pen width/angle to get a pair of points
that correspond to the penstroke at that point.  The problems with this
are that I can't think of how to "sample" a curve, and the output is a
bunch of points...hardly kosher PostScript.

thanks in advance,
dylan
dylan@cs.washington.edu

mar@athena.mit.edu (Mark A. Rosenstein) (05/30/90)

I actually wrote a routine at one point to do calligraphy.  There are
three operators I defined: penwidth which takes 1 argument and sets
the width of the nib, penangle which takes 1 argument and sets the
angle of the nib, and penstroke, which strokes the current path with a
pen that has the last specified angle and width.  Like stroke, it does
a newpath after it has produced its line.  Here are the routines and a
sample usage.
					-Mark Rosenstein

		 Constants aren't and Variables wont

----------------

%!  penstroke routine

% data is kept in a private dictionary
/pendict 20 dict def
pendict begin
	/mtx matrix def
	/angle 30 def
	/width 1 def
	/dx 0 def
	/dy 0 def
	/trans { dy add exch dx add exch } def
	/calculate {
		/mtx [ angle cos angle sin dup neg 2 index 0 0 ] def
		/dx width 0 mtx transform /dy exch def def
	} def
end

% set the current angle of the pen nib
/penangle {
	pendict begin
		/angle exch def
		calculate
	end
} bind def

% set the width of the pen nib
/penwidth {
	pendict begin
		/width exch def
		calculate
	end
} bind def

% stroke the current path with the current nib
/penstroke { pendict begin
    {	/yo exch def
	/xo exch def
	/xx xo def
	/yy yo def
    } { gsave
	/y exch def
	/x exch def
	newpath xx yy moveto x y lineto 
	x y trans lineto
	xx yy trans lineto
	closepath fill
	/xx x def
	/yy y def
	grestore
    } {	gsave
	/y exch def
	/x exch def
	/y2 exch def
	/x2 exch def
	/y1 exch def
	/x1 exch def
	newpath xx yy moveto x1 y1 x2 y2 x y curveto
	x y trans lineto
	x2 y2 trans x1 y1 trans xx yy trans curveto
	closepath fill
	/xx x def
	/yy y def
	grestore
    } { gsave
	newpath xx yy moveto xo yo lineto
	xo yo trans lineto
	xx yy trans lineto
	closepath fill
	/xx xo def
	/yy yo def
	grestore
    } pathforall
    newpath
end } bind def


% Here is some sample usage:
/inch { 72 mul } def

10 penwidth 30 penangle

1 inch 2 inch translate

0 0 moveto 0 1 inch lineto
.5 inch 0 lineto
.5 inch 1 inch lineto penstroke

1.5 inch 0 moveto
1.5 inch .5 inch .5 inch -90 270 arc 
closepath penstroke

2 inch 0 moveto
2.6 inch 1 inch lineto
3.2 inch 0 lineto
closepath penstroke

1 inch 4 inch moveto
/Helvetica findfont 1 inch scalefont setfont
(TESTING) false charpath penstroke

showpage

alfred@dutepp1.tudelft.nl (Alfred Kayser) (06/01/90)

mar@athena.mit.edu (Mark A. Rosenstein) writes:
>I actually wrote a routine at one point to do calligraphy.  There are
>three operators I defined: penwidth which takes 1 argument and sets
>the width of the nib, penangle which takes 1 argument and sets the
>angle of the nib, and penstroke, which strokes the current path with a
>pen that has the last specified angle and width.  Like stroke, it does
>a newpath after it has produced its line.  Here are the routines and a
>sample usage.

 ...penstroke routine deleted...

BUT here comes the problem:

>1 inch 4 inch moveto
>/Helvetica findfont 1 inch scalefont setfont
>(TESTING) false charpath penstroke

According to my laserprinter (TI2115) and the PS red book: (page 192)
If <charpath> was used to construct any portion of the current path,
<pathforall> is not allowed; its execution will produce an 'invalidaccess'
error.

Who can invent a routine <penstroke> alike, but working with fonts?
May be something can be done with defining a new font on basis of 
an existing font.
					Alfred.

(This is not a flame, just an error report)
--
-- Ir. Alfred Kayser. PACS, OS/2, TCP/IP. --- Email: AKayser@et.tudelft.nl --
-- CARDIT, Delft University of Technology ------------ Tel: (31)-15-786179 --
-- P.O.Box 5031, 2600 GA Delft, The Netherlands ------ Fax: (31)-15-784898 --

toms@ncifcrf.gov (Tom Schneider) (06/02/90)

I tried Mark Rosenstein's calligraphy program posted a day ago and it didn't
work.  Mark hasn't responded to my messages so far.  I was able to trace the
problem to the call to transform, but don't know enough about transforms yet to
correct the problem.  Did anyone else get the program to run, or do you have a
clue how to fix it?  I use NeWS and an Apple LaserWriter.  Thanks for your
help.

  Tom Schneider
  National Cancer Institute
  Laboratory of Mathematical Biology
  Frederick, Maryland  21701-1013
  toms@ncifcrf.gov

rajkumar@plains.UUCP (A. Joseph Rajkumar) (06/02/90)

In article <1715@fcs280s.ncifcrf.gov> toms@fcs260c2.UUCP (Tom Schneider) writes:
>I tried Mark Rosenstein's calligraphy program posted a day ago and it didn't
>work.  Mark hasn't responded to my messages so far. 

   I tried it on the NeXT cube and it did not work. Since I have busy with
other things, I could not get the time to locate the bug or fix it.
   May be someday, I will check it again. It just printed a capital-N, a
capital-letter-o and the greek letter-capital delta.

Joseph Rajkumar

 

andwi@majestix.ida.liu.se (Andreas Wickberg) (06/02/90)

Whould this do the job?

%!  penstroke routine

/mx matrix def

/D {bind def} bind def

/penwidth {
	/pw exch def
} D

/penangle {
	/pa exch def
} D

/penstroke {
	mx currentmatrix pa rotate pw 0.01 scale stroke setmatrix
} D

% Here is some sample usage:
/inch { 72 mul } def

10 penwidth 30 penangle

1 inch 2 inch translate

0 0 moveto 0 1 inch lineto
.5 inch 0 lineto
.5 inch 1 inch lineto penstroke

1.5 inch 0 moveto
1.5 inch .5 inch .5 inch -90 270 arc
closepath penstroke

2 inch 0 moveto
2.6 inch 1 inch lineto
3.2 inch 0 lineto
closepath penstroke

1 inch 4 inch moveto
/Helvetica findfont 1 inch scalefont setfont
(TESTING) false charpath penstroke

showpage

toms@ncifcrf.gov (Tom Schneider) (06/04/90)

In article <1896@majestix.ida.liu.se> andwi@majestix.ida.liu.se
(Andreas Wickberg) writes:
>
>Whould this do the job?
>
>%!  penstroke routine
(deleted)

Yes, that works!  On NeWS it shows a NO followed by a delta in simple outline,
but when sent to my Apple LaserWriter it shows the NO-Delta as a path drawn by
a pen at an angle, and the word TESTING does appear.  Unfortunately it is ugly
since the OUTLINE of the character is being drawn rather than the way one would
with a calligraphy pen.  This is due to the use of the charpath function.
(NeWS 1.1 can't handle charpath so shows nothing.) It looks like a REAL
calligraphy font is in order, or some really sharp programming.  Howcome with
all the power of PostScript and TeX or the older troff that all the nifty fonts
that have been invented haven't become very widely available yet?

  Tom Schneider
  National Cancer Institute
  Laboratory of Mathematical Biology
  Frederick, Maryland  21701-1013
  toms@ncifcrf.gov

(ps: Whould -> Would)

woody@chinacat.Unicom.COM (Woody Baker @ Eagle Signal) (06/04/90)

In article <.644234162@dutepp1>, alfred@dutepp1.tudelft.nl (Alfred Kayser) writes:
> mar@athena.mit.edu (Mark A. Rosenstein) writes:
> >(TESTING) false charpath penstroke
> 
> According to my laserprinter (TI2115) and the PS red book: (page 192)
> If <charpath> was used to construct any portion of the current path,
> <pathforall> is not allowed; its execution will produce an 'invalidaccess'
> error.
> 
> Who can invent a routine <penstroke> alike, but working with fonts?

This invalidaccess thing on fontpaths has now been defeated.  I have seen
a nifty little routine that is called apathforall that happily allows you
to do apathforall on a path that has charcters in it, and proceeds to merrily
give you all of the coordinates and strokes.  It works on all type 1 fonts,
including the ROM ed ones.  I have NO idea who wrote it and don't know
how the guy got it, but it does work.  When I find out more, I'll put
out an update on the routine.

Cheers
Woody

amanda@mermaid.intercon.com (Amanda Walker) (06/06/90)

In article <1297@chinacat.Unicom.COM>, woody@chinacat.Unicom.COM (Woody Baker @
Eagle Signal) writes:
> [about "apathforall"] I have NO idea who wrote it and don't know
> how the guy got it, but it does work.  When I find out more, I'll put
> out an update on the routine.

I believe that this is part of the "Metamorphosis" program sold by Altsys.
I don't know if they have a copyright on it, or if it was licensed from
Adobe, but you might want to check with them before posting.

--
Amanda Walker
InterCon Systems Corporation

woody@chinacat.Unicom.COM (Woody Baker @ Eagle Signal) (06/06/90)

In article <266BEB96.4364@intercon.com>, amanda@mermaid.intercon.com (Amanda Walker) writes:
> In article <1297@chinacat.Unicom.COM>, woody@chinacat.Unicom.COM (Woody Baker @
> 
> I believe that this is part of the "Metamorphosis" program sold by Altsys.
> Adobe, but you might want to check with them before posting.
> 
Good advice.  I don't intend to post it until after it appears in print
somewhere else.

Cheers
Woody.

dylan@cs.washington.edu (Dylan McNamee) (06/08/90)

> andwi@majestix.ida.liu.se (Andreas Wickberg) writes
> Would this do the job?
...
Yes, it worked great!  Outline fonts come out poorly, as has been noted.
Courier, a stroked font, comes out looking great!  Does anyone know
of any other stroked fonts we could "calligraphize"?

dylan