]> git.donarmstrong.com Git - lilypond.git/blob - lily/pango-font.cc
d9944caaab6eb663b310b58dc6bf8d275dcdb570
[lilypond.git] / lily / pango-font.cc
1 /*
2   pango-font.cc --  implement Pango_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 <pango/pangoft2.h>
11
12 #include "pango-font.hh"
13 #include "stencil.hh" 
14
15 PangoStyle
16 symbol_to_pango_style (SCM style)
17 {
18   PangoStyle pstyle = PANGO_STYLE_NORMAL;
19   if (style == ly_symbol2scm ("italic"))
20     {
21       pstyle = PANGO_STYLE_NORMAL;
22     }
23   else if (style == ly_symbol2scm ("oblique")
24            || style == ly_symbol2scm ("slanted")
25            )
26     {
27       pstyle = PANGO_STYLE_OBLIQUE;
28     }
29
30   return pstyle;
31 }
32
33 PangoVariant
34 symbol_to_pango_variant (SCM variant)
35 {
36   PangoVariant pvariant;
37   if (variant == ly_symbol2scm ("caps"))
38     {
39       pvariant = PANGO_VARIANT_SMALL_CAPS;
40     }
41   return pvariant;
42 }
43
44
45 PangoWeight
46 symbol_to_pango_weight (SCM weight)
47 {
48   PangoWeight pw = PANGO_WEIGHT_NORMAL;
49   if (weight == ly_symbol2scm ("bold"))
50     {
51       pw = PANGO_WEIGHT_BOLD;
52     }
53   if (weight == ly_symbol2scm ("heavy"))
54     {
55       pw = PANGO_WEIGHT_HEAVY;
56     }
57   if (weight == ly_symbol2scm ("ultrabold"))
58     {
59       pw = PANGO_WEIGHT_ULTRABOLD;
60     }
61   if (weight == ly_symbol2scm ("light"))
62     {
63       pw = PANGO_WEIGHT_LIGHT;
64     }
65   if (weight == ly_symbol2scm ("ultralight"))
66     {
67       pw = PANGO_WEIGHT_ULTRALIGHT;
68     }
69
70   return pw;
71 }
72
73 PangoStretch
74 symbol_to_pango_stretch (SCM stretch)
75 {
76   PangoStretch ps = PANGO_STRETCH_NORMAL;
77
78   /*
79     // TODO
80     
81   PANGO_STRETCH_ULTRA_CONDENSED,
82   PANGO_STRETCH_EXTRA_CONDENSED,
83   PANGO_STRETCH_CONDENSED,
84   PANGO_STRETCH_SEMI_CONDENSED,
85   
86   PANGO_STRETCH_SEMI_EXPANDED,
87   PANGO_STRETCH_EXPANDED,
88   PANGO_STRETCH_EXTRA_EXPANDED,
89   PANGO_STRETCH_ULTRA_EXPANDED
90   */ 
91   return ps;
92 }
93
94
95
96 PangoFontDescription* 
97 symbols_to_pango_font_description(SCM family,
98                                   SCM style,
99                                   SCM variant,
100                                   SCM weight,
101                                   SCM stretch,
102                                   SCM size)
103 {
104   PangoFontDescription * description = pango_font_description_new ();
105
106   pango_font_description_set_family (description,
107                                      ly_symbol2string (family).to_str0 ());
108   pango_font_description_set_style (description,
109                                     symbol_to_pango_style (style));
110   pango_font_description_set_variant (description,
111                                       symbol_to_pango_variant (variant));
112   pango_font_description_set_weight (description,
113                                      symbol_to_pango_weight (weight));
114   pango_font_description_set_stretch (description,
115                                       symbol_to_pango_stretch (stretch));
116   pango_font_description_set_size (description,
117                                    gint (scm_to_double (size) * PANGO_SCALE));
118
119   return description;
120 }
121
122 Pango_font::Pango_font (PangoFT2FontMap *fontmap,
123                         int resolution,
124                         Direction dir,
125                         PangoFontDescription * description)
126 {
127   PangoDirection pango_dir = (dir==RIGHT)
128     ? PANGO_DIRECTION_LTR
129     : PANGO_DIRECTION_RTL;
130   context_ = pango_ft2_font_map_create_context (fontmap);  
131   attribute_list_= pango_attr_list_new();
132   scale_ = PANGO_SCALE * resolution * 72.27;
133   
134   pango_context_set_language (context_, pango_language_from_string ("en_US"));
135   pango_context_set_base_dir (context_, pango_dir);
136   pango_context_set_font_description (context_, description);
137 }
138
139 Pango_font::~Pango_font ()
140 {
141   g_object_unref (context_);
142   pango_attr_list_unref (attribute_list_);
143 }
144
145
146 Stencil
147 Pango_font::text_stencil (String str) const
148 {
149   GList * items = pango_itemize (context_,
150                                  str.to_str0 (),
151                                  0, str.length (), attribute_list_,
152                                  NULL);
153
154   const int GLYPH_NAME_LEN = 256;
155   char glyph_name[GLYPH_NAME_LEN];
156   
157   Box dest_extent;
158   dest_extent.set_empty ();
159   GList * ptr = items;
160   SCM glyph_exprs = SCM_EOL;
161   while (ptr)
162     {
163       PangoItem *item = (PangoItem*) ptr->data;
164       PangoAnalysis *pa = &(item->analysis);
165       PangoGlyphString *pgs = pango_glyph_string_new();
166       pango_shape (str.to_str0 (), str.length (), pa, pgs);
167
168       PangoRectangle logical_rect;
169       pango_glyph_string_extents (pgs, pa->font, NULL, &logical_rect);
170       
171       PangoFcFont * fcfont = G_TYPE_CHECK_INSTANCE_CAST(pa->font,
172                                                         PANGO_TYPE_FC_FONT,
173                                                         PangoFcFont);
174       FT_Face ftface = pango_fc_font_lock_face (fcfont);
175       Box b (Interval (0, logical_rect.width),
176              Interval (0, logical_rect.height));
177
178       b.translate (Offset (- logical_rect.x, -logical_rect.y));
179       
180       b.scale (scale_);
181       dest_extent.unite (b);
182       
183       for (int i = 0; i < pgs->num_glyphs; i++)
184         {
185           PangoGlyphInfo *pgi = pgs->glyphs + i;
186           
187           PangoGlyph pg = pgi->glyph;
188           PangoGlyphGeometry ggeo = pgi->geometry;
189           
190           FT_Get_Glyph_Name (ftface, pg, glyph_name, GLYPH_NAME_LEN);
191           glyph_exprs = scm_cons (scm_list_5 (ly_symbol2scm ("named-ps-glyph"),
192                                               scm_from_int (ggeo.x_offset),
193                                               scm_from_int (ggeo.y_offset),
194                                               scm_makfrom0str (glyph_name),
195                                               scm_makfrom0str (FT_Get_Postscript_Name (ftface))),
196                                   glyph_exprs);
197         }
198
199       ptr = ptr->next;      
200     }
201
202   Stencil dest (dest_extent,
203                 scm_cons (ly_symbol2scm ("combine-stencil"),
204                           glyph_exprs));
205   return dest;
206 }