/*
- 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"
= (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");
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");
}
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)
{
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...
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;
}
chunks.push_back (CHUNKSIZE);
rest -= CHUNKSIZE;
}
- chunks.push_back (rest);
+ chunks.push_back (FT_UShort (rest));
}
else
chunks.push_back (CHUNKSIZE);
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
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;
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;
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];
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 */
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;
}
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
}
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);
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)
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 ());