]> git.donarmstrong.com Git - lilypond.git/blob - lily/open-type-font.cc
(attachment_point): new function.
[lilypond.git] / lily / open-type-font.cc
1 /*
2   open-type-font.cc --  implement Open_type_font
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
7
8 */
9
10 #include <stdio.h>
11
12 #include <freetype/tttables.h>
13  
14 #include "warn.hh"
15 #include "open-type-font.hh"
16 #include "dimensions.hh"
17
18 FT_Byte *
19 load_table (char const *tag_str, FT_Face face, FT_ULong *length)
20 {
21   FT_ULong tag = FT_MAKE_TAG(tag_str[0], tag_str[1], tag_str[2], tag_str[3]);
22   
23   int error_code = FT_Load_Sfnt_Table (face, tag, 0, NULL, length);
24   if (!error_code)
25     {
26       FT_Byte*buffer = (FT_Byte*) malloc (*length);
27       if (buffer == NULL)
28         error ("Not enough memory");
29
30       error_code = FT_Load_Sfnt_Table (face, tag, 0, buffer, length );
31       if (error_code)
32         {
33           error (_f ("Could not load %s font table", tag_str));
34         }
35
36       return buffer;
37     }
38   
39   return 0 ;
40 }
41
42             
43 SCM
44 Open_type_font::make_otf (String str)
45 {
46   Open_type_font * otf = new Open_type_font;
47   int error_code = FT_New_Face(freetype2_library, str.to_str0(),
48                                0, &(otf->face_));
49   
50   if (error_code == FT_Err_Unknown_File_Format)
51     {
52       error("Unsupported font format");
53     }
54   else if (error_code)
55     {
56       error ("Unknown error reading font file.");
57     }
58
59
60   FT_ULong length = 0;
61   FT_Byte* buffer =load_table ("LILC", otf->face_, &length);
62   if (buffer)
63     {
64       String contents ((Byte const*)buffer, length);
65       contents = "(quote (" +  contents + "))";
66
67       SCM alist = scm_c_eval_string (contents.to_str0());
68       otf->lily_character_table_ = alist_to_hashq (alist);
69       free (buffer);
70     }
71
72   return otf->self_scm ();
73 }
74
75 Open_type_font::Open_type_font()
76 {
77   lily_character_table_ = SCM_EOL;
78 }
79
80 void
81 Open_type_font::derived_mark () const
82 {
83   scm_gc_mark (lily_character_table_);
84 }
85
86 Offset
87 Open_type_font::attachment_point (String glyph_name) const
88 {
89   SCM sym = ly_symbol2scm (glyph_name.to_str0 ());
90   SCM entry =  scm_hashq_ref (lily_character_table_, sym, SCM_BOOL_F);
91
92   Offset o;
93   if  (entry == SCM_BOOL_F)
94     return o;
95
96   SCM char_alist = entry;
97
98   SCM att_scm =scm_cdr (scm_assq (char_alist, ly_symbol2scm ("attachment")));
99   
100   return ly_scm2offset (att_scm);
101 }
102
103
104 Open_type_font::~Open_type_font()
105 {
106   FT_Done_Face (face_);
107 }
108
109
110 Box
111 Open_type_font::get_indexed_char (int signed_idx) const
112 {
113   FT_UInt idx = signed_idx;
114   FT_Load_Glyph (face_,
115                  idx,
116                  FT_LOAD_NO_SCALE);
117
118   FT_Glyph_Metrics m = face_->glyph->metrics;
119   int hb = m.horiBearingX;
120   int vb = m.horiBearingY;
121   Box b (Interval (-hb, m.width - hb),
122          Interval (-vb, m.height - vb));
123
124   Real point_constant = 1 PT;
125   
126
127   b.scale (design_size() * Real (point_constant) / face_->units_per_EM);
128   return b;
129 }
130
131 int
132 Open_type_font::name_to_index (String nm) const
133 {
134   char * nm_str = (char * )nm.to_str0 ();
135   int idx = FT_Get_Name_Index (face_, nm_str);
136
137   if (idx == 0)
138     return -1;
139   else
140     return idx;
141 }
142
143
144 Real
145 Open_type_font::design_size () const
146 {
147   return 20.0;
148 }