]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/ttf.cc
* Ignore test failures on non-i386/amd64 architectures (Closes:
[lilypond.git] / lily / ttf.cc
index cbd43f76f986ed8bb55f62ba0079232d6d7461d5..d8e2b56f4549340bf9ef44f192a2d0759b9a6d4c 100644 (file)
@@ -3,13 +3,15 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2005--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  (c) 2005--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
 */
 
+#include <cstdio>
 #include "freetype.hh"
 
 #include <freetype/tttables.h>
 
+#include "international.hh"
 #include "memory-stream.hh"
 #include "warn.hh"
 #include "lily-guile.hh"
@@ -116,7 +118,7 @@ void t42_write_table (void *out, FT_Face face, unsigned char const *buffer,
                      size_t s, bool is_glyf,
                      FT_ULong head_length, FT_ULong loca_length)
 {
-  vector<FT_UShort> chunks;            /* FIXME: use dynamic array */
+  vector<FT_UShort> chunks;
 
   if (is_glyf)
     {
@@ -155,9 +157,7 @@ void t42_write_table (void *out, FT_Face face, unsigned char const *buffer,
        if (offset > last_offset + CHUNKSIZE)
          {
            if (last_chunk != last_offset)
-             {
-               chunks.push_back (last_offset - last_chunk);
-             }
+             chunks.push_back (last_offset - last_chunk);
            /*
              a single glyph with more than 64k data
              is a pathological case but...
@@ -240,7 +240,7 @@ print_body (void *out, FT_Face face)
   FT_UInt idx = 0;
   FT_ULong head_length = 0, loca_length = 0;
   FT_ULong tag, length;
-  FT_ULong lengths[100], tags[100];    /* FIXME: use dynamic arrays */
+  vector<FT_ULong> lengths, tags;
 
   /*
     we must build our own TTF header -- the original font
@@ -250,13 +250,13 @@ print_body (void *out, FT_Face face)
   while (FT_Sfnt_Table_Info (face, idx, &tag, &length)
         != FT_Err_Table_Missing)
   {
-    assert (idx < 100);                        /* FIXME: only for static arrays */
-    lengths[idx] = length;
-    tags[idx ++] = tag;
+    lengths.push_back (length);
+    tags.push_back (tag);
     if (tag == head_tag)
       head_length = length;
     else if (tag == loca_tag)
       loca_length = length;
+    idx ++;
   }
 
   FT_ULong hlength = 12 + 16 * idx;
@@ -455,9 +455,24 @@ print_trailer (void *out,
 }
 
 static void
-create_type42_font (void *out, string name)
+create_type42_font (void *out, string name, int idx)
 {
-  FT_Face face = open_ft_face (name);
+  FT_Face face;
+
+  /* check whether font index is valid */
+  if (idx > 0)
+    {
+      face = open_ft_face (name, -1);
+      if (idx >= face->num_faces)
+       {
+         warning (_f ("font index %d too large for font `%s', using index 0",
+                      idx, name.c_str()));
+         idx = 0;
+       }
+      FT_Done_Face (face);
+    }
+
+  face = open_ft_face (name, idx);
 
   print_header (out, face);
   print_body (out, face);
@@ -466,20 +481,49 @@ create_type42_font (void *out, string name)
   FT_Done_Face (face);
 }
 
-
 LY_DEFINE (ly_ttf_ps_name, "ly:ttf-ps-name",
-          1, 0, 0, (SCM ttf_file_name),
-          "Extract the PostScript name from a TrueType font.")
+          1, 1, 0, (SCM ttf_file_name, SCM idx),
+          "Extract the PostScript name from a TrueType font.  The optional"
+          " @var{idx} argument is useful for TrueType collections (TTC)"
+          " only; it specifies the font index within the TTC.  The default"
+          " value of @var{idx} is@tie{}0.")
 {
   LY_ASSERT_TYPE (scm_is_string, ttf_file_name, 1);
+
+  int i = 0;
+  if (idx != SCM_UNDEFINED)
+    {
+      LY_ASSERT_TYPE (scm_is_integer, idx, 2);
+      i = scm_to_int (idx);
+      if (i < 0)
+       {
+         warning (_ ("font index must be non-negative, using index 0"));
+         i = 0;
+       }
+    }
+
   string file_name = ly_scm2string (ttf_file_name);
   if (be_verbose_global)
-    progress_indication ("[" + file_name);
+    progress_indication ("\n[" + file_name);
 
-  FT_Face face = open_ft_face (file_name);
+  FT_Face face;
+
+  /* check whether font index is valid */
+  if (i > 0)
+    {
+      face = open_ft_face (file_name, -1);
+      if (i >= face->num_faces)
+       {
+         warning (_f ("font index %d too large for font `%s', using index 0",
+                      i, file_name.c_str()));
+         i = 0;
+       }
+      FT_Done_Face (face);
+    }
+
+  face = open_ft_face (file_name, i);
   char const *ps_name_str0 = FT_Get_Postscript_Name (face);
   SCM ps_name = scm_from_locale_string (ps_name_str0 ? ps_name_str0 : "");
-
   FT_Done_Face (face);
 
   if (be_verbose_global)
@@ -488,22 +532,35 @@ LY_DEFINE (ly_ttf_ps_name, "ly:ttf-ps-name",
   return ps_name;
 }
 
-
-
 LY_DEFINE (ly_ttf_2_pfa, "ly:ttf->pfa",
-          1, 0, 0, (SCM ttf_file_name),
-          "Convert the contents of a TTF file to Type42 PFA, returning it as"
-          " a string.")
+          1, 1, 0, (SCM ttf_file_name, SCM idx),
+          "Convert the contents of a TrueType font file to PostScript"
+          " Type@tie{}42 font, returning it as a string.  The optional"
+          " @var{idx} argument is useful for TrueType collections (TTC)"
+          " only; it specifies the font index within the TTC.  The default"
+          " value of @var{idx} is@tie{}0.")
 {
   LY_ASSERT_TYPE (scm_is_string, ttf_file_name, 1);
 
+  int i = 0;
+  if (idx != SCM_UNDEFINED)
+    {
+      LY_ASSERT_TYPE (scm_is_integer, idx, 2);
+      i = scm_to_int (idx);
+      if (i < 0)
+       {
+         warning (_ ("font index must be non-negative, using index 0"));
+         i = 0;
+       }
+    }
+
   string file_name = ly_scm2string (ttf_file_name);
   if (be_verbose_global)
-    progress_indication ("[" + file_name);
+    progress_indication ("\n[" + file_name);
 
   Memory_out_stream stream;
 
-  create_type42_font (&stream, file_name);
+  create_type42_font (&stream, file_name, i);
   SCM asscm = scm_from_locale_stringn (stream.get_string (),
                                       stream.get_length ());