X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fttf.cc;h=fc75e719fb56b61af4da4e078902c31c06c1eca1;hb=fcc66561444b7c55317674b29ebf4ce629c8126a;hp=cbd43f76f986ed8bb55f62ba0079232d6d7461d5;hpb=34090093e3f87416d4f2b247d314c6944b884755;p=lilypond.git diff --git a/lily/ttf.cc b/lily/ttf.cc index cbd43f76f9..fc75e719fb 100644 --- a/lily/ttf.cc +++ b/lily/ttf.cc @@ -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--2010 Han-Wen Nienhuys - (c) 2005--2007 Han-Wen Nienhuys + 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 . */ +#include #include "freetype.hh" #include +#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"); } @@ -116,7 +131,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 chunks; /* FIXME: use dynamic array */ + vector chunks; if (is_glyf) { @@ -155,9 +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... @@ -168,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; } @@ -191,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); @@ -240,7 +253,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 lengths, tags; /* we must build our own TTF header -- the original font @@ -250,13 +263,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; @@ -264,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; @@ -279,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]; @@ -326,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 */ @@ -379,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; } @@ -455,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); @@ -466,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; + + /* 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); + } - FT_Face face = open_ft_face (file_name); + 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 +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 ());