]> git.donarmstrong.com Git - lilypond.git/commitdiff
* scm/framework-pdf.scm (scm): new file
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 19 Feb 2005 02:16:22 +0000 (02:16 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 19 Feb 2005 02:16:22 +0000 (02:16 +0000)
* lily/include/pdf.hh (class Pdf_file): new file.

* lily/pdf.cc (write_trailer): new file.

ChangeLog
lily/grob.cc
lily/include/pdf.hh [new file with mode: 0644]
lily/pdf.cc [new file with mode: 0644]
lily/system.cc
scm/framework-pdf.scm [new file with mode: 0644]

index bf4097206ca252d099638d7df735821e95c80f27..a380d52e2baf711cb1d1d1fbe0634dfe5624db6c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2005-02-19  Han-Wen Nienhuys  <hanwen@xs4all.nl>
+
+       * scm/framework-pdf.scm (scm): new file
+
+       * lily/include/pdf.hh (class Pdf_file): new file.
+
+       * lily/pdf.cc (write_trailer): new file.
+
 2005-02-18  Erlend Aasland  <erlenda@gmail.com>
 
        * input/regression/color.ly: new file
index e6299cf8926cfc7a24f8d6e3dbd7ea17991ed2a7..35aa13328bce881eeb92d8068650efb37edbbea0 100644 (file)
@@ -217,7 +217,6 @@ Grob::get_stencil ()  const
     return unsmob_stencil (stil);
 
   stil = get_uncached_stencil ();
-
   if (is_live ())
     {
       Grob *me = (Grob*) this;
@@ -232,7 +231,7 @@ Grob::get_uncached_stencil () const
 {
   SCM proc = get_property ("print-function");
 
-  SCM  stil = SCM_EOL;
+  SCM stil = SCM_EOL;
   if (ly_c_procedure_p (proc))
     stil = scm_apply_0 (proc, scm_list_n (this->self_scm (), SCM_UNDEFINED));
 
@@ -246,6 +245,18 @@ Grob::get_uncached_stencil () const
                                 m->expr ());
          stil = Stencil (m->extent_box (), expr). smobbed_copy ();
        }
+
+      /* color support... see interpret_stencil_expression() for more... */
+      SCM color = get_property ("color");
+      if (color != SCM_EOL)
+       {
+         m = unsmob_stencil (stil);
+         SCM expr = scm_list_3 (ly_symbol2scm ("color"),
+                                color,
+                                m->expr ());
+
+         stil = Stencil (m->extent_box (), expr).smobbed_copy();
+       }
      }
 
   return stil;
@@ -771,6 +782,7 @@ ADD_INTERFACE (Grob, "grob-interface",
               "Y-extent-callback print-function extra-offset spacing-procedure "
               "context staff-symbol interfaces dependencies X-extent Y-extent extra-X-extent "
               "meta layer before-line-breaking-callback "
+              "color "
               "axis-group-parent-X "
               "axis-group-parent-Y "
               "after-line-breaking-callback extra-Y-extent minimum-X-extent "
diff --git a/lily/include/pdf.hh b/lily/include/pdf.hh
new file mode 100644 (file)
index 0000000..dea015d
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+  pdf.hh -- declare Pdf output data structures.
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#ifndef PDF_HH
+#define PDF_HH
+
+#include <stdio.h>
+
+#include "parray.hh"
+#include "smobs.hh"
+
+class Pdf_object
+{
+  DECLARE_SMOBS(Pdf_object,);
+  bool written_;
+  int object_number_;
+  SCM value_;
+  long byte_count_;
+
+
+  static void write_dict (FILE*, SCM);
+  static void write_stream (FILE*, SCM);
+  static void write_vector (FILE*, SCM);
+  static void typecheck (SCM);
+  static String escape_string (String);
+
+  String to_string () const;
+  void write_to_file (FILE*, bool) const;
+public:
+
+  bool is_indirect () const;
+  bool is_stream () const;
+  bool is_dict () const;
+  
+  Pdf_object();
+  void set_value (SCM value);
+
+  friend class Pdf_file;
+};
+
+class Pdf_file
+{
+  Link_array<Pdf_object> indirect_objects_;
+  Pdf_object *root_object_;
+  FILE *file_;
+  
+  DECLARE_SMOBS(Pdf_file,);
+
+protected:
+  void write_header ();
+  void write_trailer ();
+
+  String get_string ();
+  
+public:
+  void set_root_document (Pdf_object *obj);
+  Pdf_file (String filename);
+  void make_indirect (Pdf_object *obj);
+  void write_object (Pdf_object *obj);
+  void terminate();
+};
+
+DECLARE_UNSMOB(Pdf_object, pdf_object);
+DECLARE_UNSMOB(Pdf_file, pdf_file);
+
+#endif
diff --git a/lily/pdf.cc b/lily/pdf.cc
new file mode 100644 (file)
index 0000000..b319e16
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+  pdf.cc --  implement Pdf output routines.
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#include "warn.hh"
+#include "pdf.hh"
+#include "ly-smobs.icc"
+
+IMPLEMENT_SMOBS(Pdf_object);
+IMPLEMENT_DEFAULT_EQUAL_P(Pdf_object);
+IMPLEMENT_TYPE_P(Pdf_object, "pdf-object?");
+
+
+Pdf_object::Pdf_object ()
+{
+  object_number_ = 0;
+  value_ = SCM_BOOL_F;
+  written_ = false;
+  byte_count_ = 0;
+  
+  smobify_self ();
+}
+
+
+bool
+Pdf_object::is_dict () const
+{
+  return scm_is_pair (value_) && scm_car (value_) == ly_symbol2scm ("dictionary");
+}
+
+bool
+Pdf_object::is_indirect () const
+{
+  return object_number_ > 0;
+}
+
+Pdf_object::~Pdf_object()
+{
+  
+}
+
+void
+Pdf_object::typecheck (SCM val)
+{
+  if (scm_is_pair (val))
+    {
+      SCM tag = scm_car (val);
+      if (tag == ly_symbol2scm ("null"))
+       val = SCM_UNDEFINED;
+      else if (tag == ly_symbol2scm ("dictionary"))
+       {
+         SCM alist = scm_cdr (val);
+         for (SCM s = alist; scm_is_pair (alist); s = scm_cdr (s))
+           {
+             Pdf_object *key = unsmob_pdf_object (scm_caar (s));
+             Pdf_object *val = unsmob_pdf_object (scm_cdar (s));
+
+             if (!key || !val)
+               {
+                 ly_display_scm (scm_car (s));
+                 error ("key and value must be PDF objects.");
+               }
+           }
+       }
+      else if (tag == ly_symbol2scm ("stream"))
+       {
+         if (!scm_is_string (scm_cdr (val)))
+           error ("stream argument should be string");       
+       }
+      else
+       {
+         ly_display_scm (tag);
+         error ("unknown tag");
+       }
+    }
+  else if (scm_is_vector (val))
+    {
+      SCM vec = val;
+      int len = scm_c_vector_length (vec);
+      for (int i = 0; i < len; i++)
+       {
+         Pdf_object *val = unsmob_pdf_object (scm_c_vector_ref (vec, i));
+         if (!val)
+           {
+             ly_display_scm (scm_c_vector_ref (vec, i));
+             error ("array content should be PDF object");
+           }
+       }
+    }
+}
+
+void
+Pdf_object::set_value (SCM val)
+{
+  if (written_)
+    error ("Can't set value for written PDF object");
+
+  typecheck (val);
+
+  value_ = val; 
+}
+
+SCM
+Pdf_object::mark_smob (SCM smob)
+{
+  Pdf_object *p = (Pdf_object*) SCM_CELL_WORD_1 (smob);
+  return p->value_; 
+}
+
+int
+Pdf_object::print_smob (SCM smob, SCM port, scm_print_state *)
+{
+  Pdf_object *obj = (Pdf_object*) SCM_CELL_WORD_1 (smob);
+  scm_puts ("#<Pdf_object ", port);
+  scm_display (obj->value_, port);
+  scm_puts (">", port);
+  return 1;
+}
+
+
+void
+Pdf_object::write_dict (FILE *file, SCM alist)
+{
+  String str = "";
+
+  fputs ("<< " , file);
+  for (SCM s = alist; scm_is_pair (s); s = scm_cdr (s))
+    {
+      Pdf_object *key = unsmob_pdf_object (scm_caar (s));
+      Pdf_object *val = unsmob_pdf_object (scm_cdar (s));
+
+      assert (val && key);
+         
+      key->write_to_file (file, false);
+      val->write_to_file (file, false);
+    }
+  fputs (">>\n" , file);
+}
+
+void
+Pdf_object::write_vector (FILE *file, SCM vec)
+{
+  String str = "";
+
+  fputs ("[ " , file);
+  int len = scm_c_vector_length (vec);
+  for (int i = 0; i < len; i++)
+    {
+      Pdf_object *val = unsmob_pdf_object (scm_c_vector_ref (vec, i));
+      assert (val);
+      val->write_to_file (file, false);
+    }
+  fputs ("]\n" , file);
+}
+
+
+void 
+Pdf_object::write_stream (FILE *file, SCM scmstr)
+{
+  String str = ly_scm2string (scmstr);
+  fprintf (file, "<< /Length %d >>\nstream\n" , str.length());
+  fwrite (str.get_bytes(), str.length(), sizeof(Byte), file);
+  fputs ("endstream" , file);
+}
+
+String
+Pdf_object::escape_string (String str)
+{
+  str.substitute_char ('\\', "\\\\");
+  str.substitute_char ('(', "\\(");
+  str.substitute_char (')', "\\)");
+  return str;
+}
+
+String
+Pdf_object::to_string () const
+{
+  if (value_ == SCM_BOOL_F)
+    return "false";
+  else if (value_ == SCM_UNDEFINED)
+    return "null";
+  else if (value_ == SCM_BOOL_T)
+    return "true";
+  else if (scm_is_integer (value_))
+    return ::to_string (scm_to_int (value_));
+  else if (scm_is_number (value_))
+    return ::to_string (scm_to_double (value_));
+  else if (scm_is_symbol (value_))
+    return "/" + ly_symbol2string (value_) ;
+  else if (scm_is_string (value_))
+    return "(" + escape_string (ly_scm2string (value_)) + ")";
+
+  assert (false);
+}
+
+void
+Pdf_object::write_to_file (FILE* file, bool dump_definition) const
+{
+  if (is_indirect () && !dump_definition)
+    {
+      fprintf (file, "%d 0 R", object_number_);
+      return;
+    }
+  
+  if (scm_is_vector (value_))
+    write_vector (file, value_);
+  else if (scm_is_pair (value_))
+    {
+      SCM tag = scm_car (value_);
+      if (tag == ly_symbol2scm ("dictionary"))
+       {
+         write_dict (file, scm_cdr (value_));
+       }
+      else if (tag == ly_symbol2scm ("stream"))
+       {
+         write_stream (file, scm_cdr (value_));
+       }
+      else
+       {
+         assert (false);
+       }
+    }
+  else
+    {
+      String str = to_string ();
+      fwrite (str.get_bytes(), str.length(), sizeof(Byte), file);
+      
+      fputc (dump_definition ? '\n' : ' ', file);
+      return ;
+    }
+}
+
+bool
+Pdf_object::is_stream () const
+{
+  return scm_is_pair (value_) && scm_car (value_) == ly_symbol2scm ("stream");
+}
+
+/****************************************************************/
+  
+
+IMPLEMENT_SMOBS(Pdf_file);
+IMPLEMENT_DEFAULT_EQUAL_P(Pdf_file);
+IMPLEMENT_TYPE_P(Pdf_file, "pdf-file?");
+
+
+Pdf_file::Pdf_file (String name)
+{
+  char const *cp = name.to_str0 ();
+  root_object_ = NULL;
+  file_ = fopen  (cp, "w");
+  if (!file_)
+    {
+      error (_f ("Can't open file %s", cp));
+    }
+  write_header ();
+  smobify_self ();
+}
+
+void
+Pdf_file::write_header ()
+{
+  fputs ("%PDF-1.3\n", file_);
+}
+
+void
+Pdf_file::make_indirect (Pdf_object *obj)
+{
+  assert (!obj->is_indirect());
+
+  /*
+    Skip 0 , the null object.
+   */
+  obj->object_number_ = indirect_objects_.size() + 1;
+  indirect_objects_.push (obj);
+}
+
+void
+Pdf_file::write_object (Pdf_object *obj)
+{
+  assert (!obj->written_);
+  if (obj->is_stream() && !obj->is_indirect ())
+    {
+      make_indirect (obj);
+    }
+  
+  if (obj->is_indirect())
+    {
+      obj->byte_count_ = ftell (file_);
+      fprintf (file_, "%d obj\n", obj->object_number_);
+    }
+  
+  obj->write_to_file (file_, true);
+  obj->written_ = true;
+
+  if (obj->is_indirect ())
+    {
+      fprintf (file_, " \nendobj\n");
+    }
+}
+
+void
+Pdf_file::terminate ()
+{
+  for (int i = 0; i < indirect_objects_.size (); i++)
+    {
+      if (!indirect_objects_[i]->written_)
+       write_object (indirect_objects_[i]);
+    }
+  
+  write_trailer ();
+  fclose (file_);
+  file_ = NULL;
+}
+
+Pdf_file::~Pdf_file()
+{
+}
+
+
+void
+Pdf_file::set_root_document (Pdf_object*obj)
+{
+  if (root_object_)
+    {
+      error ("Can have only one root object");
+    }
+  
+  root_object_ = obj;
+  if (!obj->is_indirect ())
+    {
+      make_indirect (obj);
+    }  
+}
+
+void
+Pdf_file::write_trailer ()
+{
+  long xref_offset = ftell (file_);
+  fprintf (file_, "xref\n%d %d\n", 0, indirect_objects_.size() + 1);
+
+  char const *xref_entry = "%010d %05d %c \n";
+  fprintf (file_, xref_entry, 0, 65535, 'f');
+  for (int i = 0; i < indirect_objects_.size(); i++)
+    {
+      fprintf (file_, xref_entry, indirect_objects_[i]->byte_count_, 0, 'n');
+    }
+
+  fprintf (file_, "trailer\n<< /Size %d /Root %d 0 R >>",
+          indirect_objects_.size () + 1, (root_object_) ? root_object_->object_number_ : 0);
+  fprintf (file_, "\nstartxref\n%d\n", xref_offset);
+  fputs ("%%EOF", file_);
+}
+
+
+SCM
+Pdf_file::mark_smob (SCM f)
+{
+  Pdf_file *pfile = (Pdf_file*) SCM_CELL_WORD_1(f);
+  for (int i = 0; i < pfile->indirect_objects_.size(); i++)
+    scm_gc_mark (pfile->indirect_objects_[i]->self_scm());
+  return SCM_BOOL_F;
+}
+
+int
+Pdf_file::print_smob (SCM pdf, SCM port, scm_print_state*)
+{
+  scm_puts ("#<PDF file>", port);
+  return 1;
+}
index 7b8ff683496109eaf13d77642d07d5349f3050ab..d667bdd2a0a22d32a5f58879e04c61b5075ad131 100644 (file)
@@ -395,15 +395,7 @@ System::get_line ()
        Stencil st = *stil;
        st.translate (o + extra);
 
-       /* color support... see interpret_stencil_expression() for more... */
-       SCM color = g->get_property ("color");
-       if (color != SCM_EOL)
-         { 
-               SCM tmp = scm_list_3 (ly_symbol2scm ("color"), color, st.expr ());
-               *tail = scm_cons (tmp, SCM_EOL);
-         }
-       else
-               *tail = scm_cons (st.expr (), SCM_EOL);
+       *tail = scm_cons (st.expr (), SCM_EOL);
        tail = SCM_CDRLOC(*tail);
       }
 
diff --git a/scm/framework-pdf.scm b/scm/framework-pdf.scm
new file mode 100644 (file)
index 0000000..02b12d9
--- /dev/null
@@ -0,0 +1,68 @@
+;; WIP
+
+(define-module (scm framework-pdf))
+
+(use-modules (ice-9 regex)
+            (ice-9 string-fun)
+            (ice-9 format)
+            (guile)
+            (srfi srfi-1)
+            (srfi srfi-13)
+            (lily))
+
+(define framework-pdf-module (current-module))
+
+(define (stderr string . rest)
+  (apply format (cons (current-error-port) (cons string rest)))
+  (force-output (current-error-port)))
+
+;;(define pdebug stderr)
+(define (pdebug . rest) #f)
+
+(define (pdf-ify lst)
+  (cond
+   ((pair? lst)
+    (cons (pdf-ify (car lst)) (pdf-ify (cdr lst))))
+   ((vector? lst)
+    (vector-for-each pdf-ify lst))
+   ((ly:pdf-object? lst) lst)
+   ((or
+    (string? lst)
+    (number? lst)
+    (symbol? lst))
+    (pdf-ify lst))
+   
+   (else
+    (ly:make-pdf-object '(null)))
+       
+  ))
+
+(define (make-page-object parent contents)
+  (ly:make-pdf-object
+   (cons 'dictionary
+        (pdf-ify
+         `((Type . Page)
+           (Parent . ,parent)
+           (Contents . ,contents)
+           )))))
+
+(define (make-page-node root)  )
+
+
+(define-public (output-framework basename book scopes fields)
+  (let* ((filename (format "~a.pdf" basename))
+        (pdf (ly:open-pdf-file filename))
+        (outputter
+         (ly:make-paper-outputter (format "~a.bla.pdf" basename) "pdf"))
+
+
+         
+        (paper (ly:paper-book-paper book))
+        (pages (ly:paper-book-pages book))
+        (landscape? (eq? (ly:output-def-lookup paper 'landscape) #t))
+        (page-number (1- (ly:output-def-lookup paper 'firstpagenumber)))
+        (page-count (length pages))
+        (port (ly:outputter-port outputter))))
+
+    
+))