]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/ttf.cc
apply Julian's patch to fix install-info warnings
[lilypond.git] / lily / ttf.cc
index d4bb86968bc048d606272475b80262c5ee1d0b9e..4bd6378f27687c7d36ef82a1fb31b9f6624067bb 100644 (file)
@@ -1,15 +1,28 @@
 /*
-  ttf.cc --  implement ttf -> pfa routine.
+  This file is part of LilyPond, the GNU music typesetter.
 
-  source file of the GNU LilyPond music typesetter
+  Copyright (C) 2005--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
-  (c) 2005--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <cstdio>
 #include "freetype.hh"
 
 #include <freetype/tttables.h>
 
+#include "international.hh"
 #include "memory-stream.hh"
 #include "warn.hh"
 #include "lily-guile.hh"
@@ -65,10 +78,10 @@ print_header (void *out, FT_Face face)
     = (TT_Header *)FT_Get_Sfnt_Table (face, ft_sfnt_head);
 
   lily_cookie_fprintf (out, "/FontBBox [%lf %lf %lf %lf] def\n",
-                      float (ht->xMin) / ht->Units_Per_EM,
-                      float (ht->yMin) / ht->Units_Per_EM,
-                      float (ht->xMax) / ht->Units_Per_EM,
-                      float (ht->yMax) / ht->Units_Per_EM);
+                      float (ht->xMin) / float (ht->Units_Per_EM),
+                      float (ht->yMin) / float (ht->Units_Per_EM),
+                      float (ht->xMax) / float (ht->Units_Per_EM),
+                      float (ht->yMax) / float (ht->Units_Per_EM));
 
   lily_cookie_fprintf (out, "/FontType 42 def\n");
   lily_cookie_fprintf (out, "/FontInfo 8 dict dup begin\n");
@@ -99,9 +112,11 @@ print_header (void *out, FT_Face face)
   lily_cookie_fprintf (out, "/isFixedPitch %s def\n",
                       pt->isFixedPitch ? "true" : "false");
   lily_cookie_fprintf (out, "/UnderlinePosition %lf def\n",
-                      float (pt->underlinePosition) / ht->Units_Per_EM);
+                      float (pt->underlinePosition)
+                      / float (ht->Units_Per_EM));
   lily_cookie_fprintf (out, "/UnderlineThickness %lf def\n",
-                      float (pt->underlineThickness) / ht->Units_Per_EM);
+                      float (pt->underlineThickness)
+                      / float (ht->Units_Per_EM));
   lily_cookie_fprintf (out, "end readonly def\n");
 }
 
@@ -155,7 +170,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 (FT_UShort (last_offset - last_chunk));
            /*
              a single glyph with more than 64k data
              is a pathological case but...
@@ -166,18 +181,18 @@ void t42_write_table (void *out, FT_Face face, unsigned char const *buffer,
                chunks.push_back (CHUNKSIZE);
                rest -= CHUNKSIZE;
              }
-           chunks.push_back (rest);
+           chunks.push_back (FT_UShort (rest));
            last_chunk = offset;
          }
        else if (offset > last_chunk + CHUNKSIZE)
          {
-           chunks.push_back (last_offset - last_chunk);
+           chunks.push_back (FT_UShort (last_offset - last_chunk));
            last_chunk = last_offset;
          }
 
        last_offset = offset;
       }
-      chunks.push_back (s - last_chunk);
+      chunks.push_back (FT_UShort (s - last_chunk));
 
       delete[] loca_buf;
     }
@@ -189,7 +204,7 @@ void t42_write_table (void *out, FT_Face face, unsigned char const *buffer,
          chunks.push_back (CHUNKSIZE);
          rest -= CHUNKSIZE;
        }
-      chunks.push_back (rest);
+      chunks.push_back (FT_UShort (rest));
     }
   else
     chunks.push_back (CHUNKSIZE);
@@ -262,11 +277,11 @@ print_body (void *out, FT_Face face)
   unsigned char *hbuf = new unsigned char[hlength];
   unsigned char *p;
 
-  hbuf[0] = 0x00;                      /* version */
+  hbuf[0] = 0x00;                                      /* version */
   hbuf[1] = 0x01;
   hbuf[2] = 0x00;
   hbuf[3] = 0x00;
-  hbuf[4] = (idx & 0xFF00) >> 8;       /* numTables */
+  hbuf[4] = (unsigned char) ((idx & 0xFF00) >> 8);     /* numTables */
   hbuf[5] = idx & 0x00FF;
 
   FT_UInt searchRange, entrySelector, rangeShift;
@@ -277,11 +292,11 @@ print_body (void *out, FT_Face face)
   searchRange = 0x10 << entrySelector;
   rangeShift = (idx << 4) - searchRange;
 
-  hbuf[6] = (searchRange & 0xFF00) >> 8;
+  hbuf[6] = (unsigned char) ((searchRange & 0xFF00) >> 8);
   hbuf[7] = searchRange & 0x00FF;
-  hbuf[8] = (entrySelector & 0xFF00) >> 8;
+  hbuf[8] = (unsigned char) ((entrySelector & 0xFF00) >> 8);
   hbuf[9] = entrySelector & 0x00FF;
-  hbuf[10] = (rangeShift & 0xFF00) >> 8;
+  hbuf[10] = (unsigned char) ((rangeShift & 0xFF00) >> 8);
   hbuf[11] = rangeShift & 0x00FF;
 
   p = &hbuf[12];
@@ -324,24 +339,24 @@ print_body (void *out, FT_Face face)
 
     delete[] buf;
 
-    *(p++) = (tags[i] & 0xFF000000UL) >> 24;
-    *(p++) = (tags[i] & 0x00FF0000UL) >> 16;
-    *(p++) = (tags[i] & 0x0000FF00UL) >> 8;
+    *(p++) = (unsigned char) ((tags[i] & 0xFF000000UL) >> 24);
+    *(p++) = (unsigned char) ((tags[i] & 0x00FF0000UL) >> 16);
+    *(p++) = (unsigned char) ((tags[i] & 0x0000FF00UL) >> 8);
     *(p++) = tags[i] & 0x000000FFUL;
 
-    *(p++) = (checksum & 0xFF000000UL) >> 24;
-    *(p++) = (checksum & 0x00FF0000UL) >> 16;
-    *(p++) = (checksum & 0x0000FF00UL) >> 8;
+    *(p++) = (unsigned char) ((checksum & 0xFF000000UL) >> 24);
+    *(p++) = (unsigned char) ((checksum & 0x00FF0000UL) >> 16);
+    *(p++) = (unsigned char) ((checksum & 0x0000FF00UL) >> 8);
     *(p++) = checksum & 0x000000FFUL;
 
-    *(p++) = (offset & 0xFF000000UL) >> 24;
-    *(p++) = (offset & 0x00FF0000UL) >> 16;
-    *(p++) = (offset & 0x0000FF00UL) >> 8;
+    *(p++) = (unsigned char) ((offset & 0xFF000000UL) >> 24);
+    *(p++) = (unsigned char) ((offset & 0x00FF0000UL) >> 16);
+    *(p++) = (unsigned char) ((offset & 0x0000FF00UL) >> 8);
     *(p++) = offset & 0x000000FFUL;
 
-    *(p++) = (lengths[i] & 0xFF000000UL) >> 24;
-    *(p++) = (lengths[i] & 0x00FF0000UL) >> 16;
-    *(p++) = (lengths[i] & 0x0000FF00UL) >> 8;
+    *(p++) = (unsigned char) ((lengths[i] & 0xFF000000UL) >> 24);
+    *(p++) = (unsigned char) ((lengths[i] & 0x00FF0000UL) >> 16);
+    *(p++) = (unsigned char) ((lengths[i] & 0x0000FF00UL) >> 8);
     *(p++) = lengths[i] & 0x000000FFUL;
 
     /* offset must be a multiple of 4 */
@@ -377,9 +392,9 @@ print_body (void *out, FT_Face face)
       if (tag == head_tag)
        {
          /* in the second pass simply store the computed font checksum */
-         buf[8] = (font_checksum & 0xFF000000UL) >> 24;
-         buf[9] = (font_checksum & 0x00FF0000UL) >> 16;
-         buf[10] = (font_checksum & 0x0000FF00UL) >> 8;
+         buf[8] = (unsigned char) ((font_checksum & 0xFF000000UL) >> 24);
+         buf[9] = (unsigned char) ((font_checksum & 0x00FF0000UL) >> 16);
+         buf[10] = (unsigned char) ((font_checksum & 0x0000FF00UL) >> 8);
          buf[11] = font_checksum & 0x000000FFUL;
        }
 
@@ -438,7 +453,7 @@ print_trailer (void *out,
 
       if (glyph_name[0])
        {
-         lily_cookie_fprintf (out, "/%s %d def ", glyph_name, i);
+         lily_cookie_fprintf (out, "(%s) cvn %d def ", glyph_name, i);
          output_count ++;
        }
       else
@@ -453,9 +468,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);
@@ -464,20 +494,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)
@@ -486,22 +545,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 ());