Re: pdf generator

2009-05-07 Thread Tomas Hlavaty
Hi Alex,

> I think it is wiser and much easier to write a separate C library
> for specialized I/O.

you convinced me:-)

Thanks,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: pdf generator

2009-05-07 Thread Alexander Burger
Hi Tomas,

> >> Alex, I need to call 'lseek' function.  How could I get hold of the

Hmm, I deliberately omitted 'lseek' from the standard system, as I think
it is useful only for very special cases.

For the PicoLisp I/O system it does not make much sense, as reading and
writing is buffered, so that an 'lseek' on the Lisp level will give
rather unpredictable results.

Also, mixing Lisp I/O functions like 'read', 'write', 'line', 'char'
etc. with the low-level functions 'rd', 'wr' and 'pr' might give
unexpected results, as the Lisp functions use, for example, a
single-char read-ahead buffer.

In fact, in cases where I needed low-level binary file I/O, I used calls
to the external 'dd' program. But this is rather clumsy.

I think it is wiser and much easier to write a separate C library for
specialized I/O.

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: pdf generator

2009-05-06 Thread Tomas Hlavaty
Hi Alex,

>> Alex, I need to call 'lseek' function.  How could I get hold of the
>> current input and output file descriptors?  I want to feed it to the
>
> Yep, implementing 'ifd' and 'ofd' (analog to 'ipid' and 'opid') would be
> the right way.

do you think it would be possible to include the following code in the
standard release?

#include 
#include 

// (fpos 'fd) -> cnt
// (fpos 'fd 'off) -> cnt
// (fpos 'fd 'off 'flg) -> cnt
any fpos(any ex) {
   int fd = evCnt(ex, cdr(ex));
   off_t off = 0;
   int whence = SEEK_CUR;
   if(!isNil(cddr(ex))) {
  off = evCnt(ex, cddr(ex));
  if(!isNil(cdddr(ex))) {
 any w = evExpr(ex, cdddr(ex));
 whence = isNil(w) ? SEEK_SET : SEEK_END;
  }
   }
   off_t z = lseek(fd, off, whence);
   return boxCnt(z);
}

// (idf) -> cnt
any ifd(any ex __attribute__((unused))) {
   return boxCnt(InFile->fd);
}

// (odf) -> cnt
any ofd(any ex __attribute__((unused))) {
   return boxCnt(OutFile->fd);
}

// (fpos 'fd) -> cnt... Gets current file position
// (fpos 'fd 'off) -> cnt   ... Moves position relative to the current one
// (fpos 'fd 'off 'flg) -> cnt  ... Goes to the beginning (flg=NIL)
otherwise to start
Thank you,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: pdf generator

2009-05-04 Thread Alexander Burger
Hi Tomas,

> I have attached a prototype pdf generator pdf.l.  It can be used to
> generate pdf files directly without going through @lib/ps.l.  It is

Great! This is another thing I would have liked to do, but never found
the time. The procedure with going through PostScript is a mess (but, on
the other hand, sometimes necessary e.g. when directly printing to a
PostScript printer as we do for some customers).

Let me look at it in more detail later. To your question:

> Alex, I need to call 'lseek' function.  How could I get hold of the
> current input and output file descriptors?  I want to feed it to the
> ...

>(fpos (ifd) 123) # set current position to 123rd byte from start of the 
> file
>(fpos (ifd) 0 1) # get current position

Yep, implementing 'ifd' and 'ofd' (analog to 'ipid' and 'opid') would be
the right way.

For a quick solution, you can directly access the file descriptors from
within your function, via the globals 'InFile' and 'OutFile':

> ...
>off_t z = lseek(InFile->fd, offset, whence);
> ...

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


pdf generator

2009-05-04 Thread Tomas Hlavaty
Hi all,

I have attached a prototype pdf generator pdf.l.  It can be used to
generate pdf files directly without going through @lib/ps.l.  It is
still experimental version.  It can be used as follows:

(afmDir "fonts") # load & parse font metric files

(pdf "/tmp/A.pdf" # generate sample pdf file
   (pdfWr (pdfO 1 0 (pdfM '/Type '/Page
  '/Parent '(5 0 R)
  '/Resources '(3 0 R)
  '/Contents '(2 0 R) ) ) )
   (pdfWr (pdfO 2 0 (pdfS NIL "BT
  /F1 24 Tf
  1 0 0 1 260 254 Tm
  (Hello World)Tj
  ET
  0 0 1 rg
 4 0 0 4 315 204 cm
0 5.5 m
  -4 -5.5 l
6 1 l
  -6 1  l
4 -5.5 l
  f" ) ) )
   (pdfWr (pdfO 3 0 (pdfM '/ProcSet (pdfV '/PDF '/Text)
  '/Font (pdfM '/F1 '(4 0 R)) ) ) )
   (pdfWr (pdfO 4 0 (pdfM '/Type '/Font
  '/Subtype '/Type1
  '/Name '/F1
  '/BaseFont '/Helvetica ) ) )
   (pdfWr (pdfO 5 0 (pdfM '/Type '/Pages
  '/Kids (pdfV '(1 0 R))
  '/Count 1
  '/MediaBox (pdfV 0 0 612 446) ) ) )
   (pdfWr (pdfO 6 0 (pdfM '/Type '/Catalog
  '/Pages '(5 0 R) ) ) )
   (setq *PdfX (pdfM '/Root '(6 0 R) '/Size 6)) )

(pdfUpdate "/tmp/A.pdf" "/tmp/A3.pdf" # incremental update
   (pdfWr (pdfO 7 0 (pdfS NIL
  (pdfDraw
 (q (BT (Tf "/F1" 24)
(Tm 1 0 0 1 160 154)
(Tj "H£ll0 W€rld Ťitěrňoučká řeřiščička")
(let S "hello Minime"
   (pdfDraw
  (Tm 1 0 0 1 160 174)
  (Tj S 'left)
  (Tm 1 0 0 1 160 194)
  (Tj S 'center)
  (Tm 1 0 0 1 160 214)
  (Tj S 'right) ) ) ) ) ) )))
   (pdfWr (pdfO 1 0 (pdfM '/Type '/Page
  '/Parent '(5 0 R)
  '/Resources '(3 0 R)
  '/Contents (pdfV '(7 0 R 2 0 R)) ) ) )
   (setq *PdfX (pdfM '/Prev *Fpos)) ) #'/Root '(6 0 R)

Unicode does not work and incremental updates do not generate correct
updated xref section.  Also, it expects a "fonts/" directory with afm
files and glyphs:

   Courier.afm
   Courier-Bold.afm
   Courier-BoldOblique.afm
   Courier-Oblique.afm
   Helvetica.afm
   Helvetica-Bold.afm
   Helvetica-BoldOblique.afm
   Helvetica-Oblique.afm
   Symbol.afm
   Times-Bold.afm
   Times-BoldItalic.afm
   Times-Italic.afm
   Times-Roman.afm
   ZapfDingbats.afm
   glyphlist.txt


Alex, I need to call 'lseek' function.  How could I get hold of the
current input and output file descriptors?  I want to feed it to the
following function 'fpos':

(gcc "pdf" NIL 'fpos)

#include 
#include 

any fpos(any ex) {
   int fd = evCnt(ex, cdr(ex));
   off_t offset = evCnt(ex, cddr(ex));
   int whence = evCnt(ex, cdddr(ex));
   whence = whence == 1 ? SEEK_CUR : (whence == 2 ? SEEK_END : SEEK_SET);
   off_t z = lseek(fd, offset, whence);
   return boxCnt(z);
}
/**/

and use it something like:

(in "/tmp/file"
   (fpos (ifd) 123) # set current position to 123rd byte from start of the file
   (fpos (ifd) 0 1) # get current position
..

and similar for 'out'.

Thank you,

Tomas

# requires iconv for utf-16be conversion

# *Glyph *Codepoint
# *Afm
# *Fpos *PdfO *PdfOa *PdfOut *PdfX *PdfDraw *Fnm *Fsz

### glyphs

(in "fonts/glyphlist.txt" #(appDir "fonts/glyphlist.txt")
   (use (L N)
  (while (setq L (line))
 (unless (= '"#" (car L))
(setq L (split L '";") N (pack (car L)))
(for C (mapcar '((X) (char (hex (pack X (split (cadr L) " "))
   (if (idx '*Glyph C)
  (push (car @) N)
  (set C (list N))
  (idx '*Glyph C T) )
   (if (idx '*Codepoint N)
  (push (car @) C)
  (set N (list C))
  (idx '*Codepoint N T) ) ) ) ) ) )

(de glyph (C)
   (val (car (idx '*Glyph C))) )

(de codepoint (C)
   (val (car (idx '*Codepoint C))) )

()

### afm

(class +Afm)
# nm c kpx

(dm charWidth> (C)
   (setq C (pack (if (num? C) C (char C
   (format (cadr (assoc "WX" (find '((X) (= C (cadr (assoc "C" X (: c) )

(dm charGlyph> (C)
   (setq C (pack (if (num? C) C (char C
   (cadr (assoc "N" (find '((X) (= C (cadr (assoc "C" X (: c )

(dm glyphChar> (G)
   (format