home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!van-bc!cs.ubc.ca!unixg.ubc.ca!reg.triumf.ca!advax
- From: advax@reg.triumf.ca (A.Daviel)
- Newsgroups: alt.sources
- Subject: Canadian Postcode matrix generator for Laserjet
- Date: 24 Dec 1992 14:39 PST
- Organization: TRIUMF: Tri-University Meson Facility
- Lines: 349
- Distribution: canada
- Message-ID: <24DEC199214390279@reg.triumf.ca>
- NNTP-Posting-Host: reg.triumf.ca
- News-Software: VAX/VMS VNEWS 1.41
-
- This program prints commercial size envelopes on an HP Laserjet II, using
- the manual feed feature. It gets the mailing address and senders address from
- a textfile containing a letter to be sent. It assumes that the first lines of
- the letter are the mailing address, and the last lines are the senders
- address. It tries to find a Canadian Postcode and validate it. If a valid
- postcode is found, it generates the precode matrix as found on 1991
- greetmore envelopes and billing return envelopes. This will be recognised by
- the sorting machines and result in a quicker passage through the sorting
- process.
-
- Canada Post currently uses fairly smart OCR machines. They can cope with a
- variety of fonts, preferably fixed-pitch, black, upper-case and with a uniform
- font used throughout the address. If posted within Canada, the
- postcode should be on the last line. If posted outside Canada, the postcode
- should be on the penultimate line separated from the province code by 2
- spaces, eg. VANCOUVER BC V6T 2A3.
-
- If the address cannot be read by the OCR machine, the letter is routed to a
- clerk who tries to read your writing and applies a fluorescent barcode to the
- bottom of the letter for subsequent sorting.
-
- Canada Post is moving to a barcode system, which will encode the entire
- address including apartment and street numbers. I don't have any information
- on this system.
-
- This program compiles in FORTRAN-77 under VAX-VMS. I make no apologies and
- offer no guarantees. Anyone is free to distribute, modify, improve, etc. this
- program.
-
- --
- Andrew Daviel, Vancouver, Canada
-
- --- cut here ---
- program pcode
- c program to write postcode graphics on HP Laserjet
- implicit none
-
- integer j,k,x0,y0,x1,y1,x2,y2,naddress,nraddress,nc,ll,fl,i
- real dx,dy,scale
- integer ama
-
- data x2,y2 /1000,3000/ ! positon for postcode
- integer kv(7)
- logical invalid, do_raddress/.true./
- integer maxa
- parameter (maxa=10)
- character*7 postcode ,rpostcode
- character*60 address(maxa),filename, raddress(maxa), lines(maxa)
-
- character*1 esc,block,cr,lf,ch
- c block is a solid character in IBM-US font
- parameter (esc=char(27),block=char(221),cr=char(13),lf=char(10))
- character*2 pfix,sfix
-
-
- data pfix(1:1),pfix(2:2) /esc,'P'/ ! prefix & suffix to protect escape
- data sfix(1:1),sfix(2:2) /esc,'\'/ ! sequences from VMS
-
- scale=1000./1.37 ! convert inches to decipoints
-
- dx=scale*2.0/34. ! x increment in postcode pattern
- dy=scale*0.23 ! x increment
-
-
- c code blocks are 42mm from bottom of envelope, 27mm from right
-
- x0=scale * 7.56
- y0=scale * 4.16 ! position of code blocks wrt. top left (inches)
-
- x1=scale * 7.8
- y1=scale * 2.34 ! position of bars wrt. top left
-
- ama=ichar('A')-ichar('a')
-
- 9 type *,'Enter filename of letter to get address'
- accept 1,filename
-
- c obtain address from file, assuming it is top-left justified and
- c terminated by a blank line, and that postcode is last line of
- c address
-
- open(unit=1,status='old',file=filename,err=9)
- k=1
- 10 read(1,11) nc,address(k)
- 11 format(q,a)
- if ((nc.eq.0..or.address(k)(1:7).eq.' ').and.k.eq.1) goto 10
- c convert address to upper case
- do j=1,nc
- if (address(k)(j:j).le.'z'.and.address(k)(j:j).ge.'a')
- 1 address(k)(j:j)=char(ichar(address(k)(j:j))+ama)
- enddo
- k=k+1
- if (nc.gt.0.or.address(k-1)(1:7).ne.' ') goto 10
- naddress=k-2
-
-
- if (do_raddress) then
- c look for a return address, left justified at bottom
- c of letter, preceded by a blank line
-
- c read remainder of letter into ring buffer,
- k=1
- 20 read(1,11,end=25) nc,lines(k)
- k=k+1
- if (k.gt.maxa) k=1
- goto 20
-
- 25 ll=k-1 ! last line of return address
- if (ll.eq.0) ll=maxa
- 31 if (lines(ll)(1:7).ne.' ') goto 32
- ll=ll-1
- if (ll.eq.0) ll=maxa
- if (ll.eq.k) goto 32
- goto 31
-
- 32 k=ll
- 26 if (lines(k)(1:7).eq.' ') goto 30
- k=k-1
- if (k.eq.0) k=maxa
- if (k.eq.ll) goto 30
- goto 26
-
- 30 fl=k+1 ! first line of return address
- if (fl.gt.maxa) fl=1
- i=1
- k=fl
- 27 continue
- c convert return address to upper case
- do j=1,60
- if (lines(k)(j:j).le.'z'.and.lines(k)(j:j).ge.'a') then
- raddress(i)(j:j)=char(ichar(lines(k)(j:j))+ama)
- else
- raddress(i)(j:j)=lines(k)(j:j)
- endif
- enddo
- if (k.eq.ll) goto 28
- k=k+1
- if (k.gt.maxa) k=1
- i=i+1
- goto 27
- 28 nraddress=i
-
-
- c verify postcode in return address just for the hell of it.
- c initally, try for a postcode on last line
- rpostcode=raddress(nraddress)(1:7)
- call validate(rpostcode,kv,invalid)
-
- if (invalid) then
- c try for a postcode on penultimate line (preceded by 2 spaces)
- k=index(raddress(nraddress-1),' ')
- if (raddress(nraddress-1)(k+2:k+2).ne.' ') then
- rpostcode=raddress(nraddress-1)(k+2:k+9)
- call validate(rpostcode,kv,invalid)
- endif
- if (invalid) then
- c try for a postcode on last line (preceded by 2 spaces)
- k=index(raddress(nraddress),' ')
- if (raddress(nraddress)(k+2:k+2).ne.' ') then
- rpostcode=raddress(nraddress)(k+2:k+9)
- call validate(rpostcode,kv,invalid)
- endif
- endif ! invalid
- endif ! invalid
-
- type *,'Return address from letter:'
- do k=1,nraddress
- type *,raddress(k)
- enddo
- type *,' '
- if (invalid) then
- type *,'Invalid Canadian Postcode in return address"',rpostcode,'"'
- else
- type *,'Return address Postcode: ',rpostcode
- endif
- type *,' '
- type *,'Print this return address (y|n) ?'
- accept 13,ch
- 13 format(a)
- do_raddress=(ch.eq.'y'.or.ch.eq.'Y')
-
- endif ! do_raddress
-
- c initally, try for a postcode on last line
- postcode=address(naddress)(1:7)
-
- call validate(postcode,kv,invalid)
-
- if (invalid) then
- c try for a postcode on penultimate line (preceded by 2 spaces)
- k=index(address(naddress-1),' ')
- if (address(naddress-1)(k+2:k+2).ne.' ') then
- postcode=address(naddress-1)(k+2:k+9)
- call validate(postcode,kv,invalid)
- endif
- if (invalid) then
- c try for a postcode on last line (preceded by 2 spaces)
- k=index(address(naddress),' ')
- if (address(naddress)(k+2:k+2).ne.' ') then
- rpostcode=address(naddress)(k+2:k+9)
- call validate(postcode,kv,invalid)
- endif
- endif ! invalid
- endif
-
- type *,'Mailing address from letter:'
- do k=1,naddress
- type *,address(k)
- enddo
- type *,' '
- if (invalid) then
- type *,'Invalid Canadian Postcode "',postcode,'"'
- else
- type *,'Address Postcode: ',postcode
- endif
-
-
- open(unit=2,carriagecontrol='list',status='new',file='envelope.')
-
- c reset, manual envelope, landscape
- write (2,1) pfix//esc//'E'//esc//'&l3H'//esc//'&l1O'//sfix
- 1 format(a)
- write(2,1) pfix//esc//'(10U'//sfix ! IBM-US set
-
- if (.not.invalid) then
- c print vertical bars
- do j=0,3
- do k=0,3
- call ink(x1+nint(j*0.12*scale),y1+nint(k*0.14*scale))
- enddo
- enddo
- c print 6 bounding blocks
- do j=0,2
- call ink2(x0,y0+nint(j*dy))
- call ink2(x0+nint(34.*dx),y0+nint(j*dy))
- enddo
- c print postcode blocks
- call ink2(x0+nint((1+kv(1))*dx),y0)
- call ink2(x0+nint((1+kv(2))*dx),y0)
- call ink2(x0+nint((1+kv(3))*dx),y0+nint(dy))
- call ink2(x0+nint((1+kv(5))*dx),y0+nint(dy))
- call ink2(x0+nint((1+kv(6))*dx),y0+nint(2.0*dy))
- call ink2(x0+nint((1+kv(7))*dx),y0+nint(2.0*dy))
- c call plot(x2,y2,postcode)
- endif
-
- c address must be 40mm from top, 25mm from left, 19mm from bottom
- c postcode must be within (26+19mm) from bottom
-
- c set top margin, left margin for address (lines/characters)
- write(2,1) pfix//esc//'&l24E'//esc//'&a40L'//sfix ! was 24, 26
- c move to top left
- write(2,1) pfix//esc//'&a0H'//esc//'&a0V'//sfix//CR
- do k=1,naddress
- write(2,1) address(k)//cr//lf
- enddo
-
- if (do_raddress) then
- c set top, left margin for return address
- write(2,1) pfix//esc//'&l15E'//esc//'&a20L'//sfix
- write(2,1) pfix//esc//'&a0H'//esc//'&a0V'//sfix//CR
- c ISO 6 font, 16 pitch 12 point, italic, bold stroke, Courier
- write(2,1) pfix//esc//'(0U'//esc//'(s0p16h12v1s3b3T'//esc//
- 1 '&l8D'//sfix//CR
- write(2,1) 'From:'//cr//lf
-
- c ISO 6 font, 16 pitch 12 point, upright, medium stroke, Courier
- write(2,1) pfix//esc//'(0U'//esc//'(s0p16h12v0s0b3T'//esc//
- 1 '&l8D'//sfix//CR
-
- do k=1,nraddress
- write(2,1) raddress(k)//cr//lf
- enddo
- endif
-
- write (2,1) pfix//esc//'E'//sfix ! reset
- type *,'Use HPRINT ENVELOPE. P to print' ! passall print command
- end
- c---
- subroutine ink(x,y)
- implicit none
- integer x,y,y2,k
-
- character*1 esc,block,ch,block2
- parameter (esc=char(27),block=char(221),block2=char(254))
- character*2 pfix,sfix
-
- data pfix(1:1),pfix(2:2) /esc,'P'/ ! prefix & suffix to protect escape
- data sfix(1:1),sfix(2:2) /esc,'\'/ ! sequences from VMS
-
- character*4 cx,cy
- character*7 code
-
- ch=block
-
- write(cx,1) x
- 1 format(i4.4)
- write(cy,1) y
- write(2,2) pfix//esc//'&a'//cx//'H'//esc//'&a'//cy//'V'//sfix//ch
- 2 format(a)
- return
-
- entry plot(x,y,code)
- write(cx,1) x
- write(cy,1) y
- write(2,2) pfix//esc//'&a'//cx//'H'//esc//'&a'//cy//'V'//sfix//code
- return
-
- entry ink2(x,y)
- write(cx,1) x
- ch=block2
-
- do k=0,4
- y2=y+k*17 ! 0.6mm /25.4 * 1000/1.37
- write(cy,1) y2
- write(2,2) pfix//esc//'&a'//cx//'H'//esc//'&a'//cy//'V'//sfix//ch
- enddo
-
- return
- end
- c--
- subroutine validate(postcode,kv,invalid)
- implicit none
-
- character*7 postcode
- logical invalid
- character*31 validcode
- data validcode /'ABCEGHJKLMNPRSTVWXYZ_0123456789'/
- integer k
- integer kv(7)
-
- c==
- invalid=.false.
- do k=1,7
- kv(k)=index(validcode,postcode(k:k))
- if (k.eq.4) then
- if (postcode(4:4).ne.' ') then
- invalid=.true.
- c type *,'Invalid character ',postcode(k:k),' at position',k
- endif
- elseif (kv(k).eq.0) then
- c type *,'Invalid character ',postcode(k:k),' at position',k
- invalid=.true.
- endif
- enddo
-
- return
- end
-
-