]> git.donarmstrong.com Git - lilypond.git/blob - lily/open-type-font.cc
* 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 SCM
43 load_scheme_table (char const *tag_str, FT_Face face)
44 {
45   FT_ULong length = 0;
46   FT_Byte* buffer =load_table ("LILC", face, &length);
47
48   SCM tab = SCM_EOL;
49   if (buffer)
50     {
51       String contents ((Byte const*)buffer, length);
52       contents = "(quote (" +  contents + "))";
53
54       SCM alist = scm_c_eval_string (contents.to_str0());
55       tab = alist_to_hashq (alist);
56       free (buffer);
57     }
58   return tab;
59 }
60             
61 SCM
62 Open_type_font::make_otf (String str)
63 {
64   Open_type_font * otf = new Open_type_font;
65   int error_code = FT_New_Face(freetype2_library, str.to_str0(),
66                                0, &(otf->face_));
67   
68   if (error_code == FT_Err_Unknown_File_Format)
69     {
70       error("Unsupported font format");
71     }
72   else if (error_code)
73     {
74       error ("Unknown error reading font file.");
75     }
76
77
78
79   otf->lily_character_table_ =  load_scheme_table ("LILC", otf->face_);
80   otf->lily_global_table_ =  load_scheme_table ("LILY", otf->face_);
81   
82   return otf->self_scm ();
83 }
84
85 Open_type_font::Open_type_font()
86 {
87   lily_character_table_ = SCM_EOL;
88   lily_global_table_ = SCM_EOL;
89 }
90
91 void
92 Open_type_font::derived_mark () const
93 {
94   scm_gc_mark (lily_character_table_);
95   scm_gc_mark (lily_global_table_);
96 }
97
98 Offset
99 Open_type_font::attachment_point (String glyph_name) const
100 {
101   SCM sym = ly_symbol2scm (glyph_name.to_str0 ());
102   SCM entry =  scm_hashq_ref (lily_character_table_, sym, SCM_BOOL_F);
103
104   Offset o;
105   if  (entry == SCM_BOOL_F)
106     return o;
107
108   SCM char_alist = entry;
109
110   SCM att_scm =scm_cdr (scm_assq (char_alist, ly_symbol2scm ("attachment")));
111   
112   return ly_scm2offset (att_scm);
113 }
114
115
116 Open_type_font::~Open_type_font()
117 {
118   FT_Done_Face (face_);
119 }
120
121
122 Box
123 Open_type_font::get_indexed_char (int signed_idx) const
124 {
125   FT_UInt idx = signed_idx;
126   FT_Load_Glyph (face_,
127                  idx,
128                  FT_LOAD_NO_SCALE);
129
130   FT_Glyph_Metrics m = face_->glyph->metrics;
131   int hb = m.horiBearingX;
132   int vb = m.horiBearingY;
133   Box b (Interval (-hb, m.width - hb),
134          Interval (-vb, m.height - vb));
135
136   Real point_constant = 1 PT;
137   
138
139   b.scale (design_size() * Real (point_constant) / face_->units_per_EM);
140   return b;
141 }
142
143 int
144 Open_type_font::name_to_index (String nm) const
145 {
146   char * nm_str = (char * )nm.to_str0 ();
147   int idx = FT_Get_Name_Index (face_, nm_str);
148
149   if (idx == 0)
150     return -1;
151   else
152     return idx;
153 }
154
155
156 Real
157 Open_type_font::design_size () const
158 {
159   return 20.0;
160 }