]> git.donarmstrong.com Git - lilypond.git/blob - lily/pangofc-afm-decoder.cc
c6a587c5ca2145acebf525c68dcb9c299237858c
[lilypond.git] / lily / pangofc-afm-decoder.cc
1 /*
2   pango-afm-decoder.c -- AFM fontencoding for Pango fontconfig
3
4   source file of the GNU LilyPond music typesetter
5
6   Copyright (C) 2004  Jan Nieuwenhuizen <janneke@gnu.org>
7
8   Note: in C and with explicit LPGL header for easier use with PANGO
9   outside of LilyPond.
10
11   This library is free software; you can redistribute it and/or
12   modify it under the terms of the GNU Lesser General Public
13   License as published by the Free Software Foundation; either
14   version 2.1 of the License, or (at your option) any later version.
15  
16   This library is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19   Lesser General Public License for more details.
20  
21   You should have received a copy of the GNU Lesser General Public
22   License along with this library; if not, write to the Free Software
23   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26 #include "config.h"
27 #if HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC
28
29 /* Need to access to PangoFcFont.full_pattern.  */
30 #define PANGO_ENABLE_BACKEND
31
32 #include <pango/pango-font.h>
33 #include <pango/pangoxft.h>
34 #include <pango/pangofc-font.h>
35 #include <gdk/gdkx.h>
36 #include <X11/Xft/Xft.h>
37
38 #include "pangofc-afm-decoder.hh"
39
40 #ifdef DEBUG_PANGO_AFM
41 #include <stdio.h>
42 #define dprintf(args...) fprintf (stderr, args)
43 #else
44 #define dprintf(args...)
45 #endif
46
47 struct _PangoFcAfmDecoderPrivate
48 {
49   GString encoding[256];
50   //GString file_name;
51   char const *file_name;
52   PangoFcFont *fc_font;
53 };
54
55 static void pango_fc_afm_decoder_init (PangoFcAfmDecoder *fontmap);
56 static void pango_fc_afm_decoder_class_init (PangoFcAfmDecoderClass *clss);
57 static void pango_fc_afm_decoder_finalize (GObject *object);
58
59 static FcCharSet *pango_fc_afm_get_charset (PangoFcDecoder *decoder,
60                                             PangoFcFont *fcfont);
61 static PangoGlyph pango_fc_afm_get_glyph (PangoFcDecoder *decoder,
62                                           PangoFcFont *fcfont, guint32 wc);
63 static void pango_fc_afm_decoder_set_file_name (PangoFcAfmDecoder *self,
64                                                 char const *file_name);
65
66 static PangoFcDecoderClass *parent_class;
67
68 #if 0
69 /* ugly warning */
70 G_DEFINE_TYPE (PangoFcAfmDecoder, pango_fc_afm_decoder, PANGO_TYPE_FC_DECODER);
71 #else
72 GType
73 pango_fc_afm_decoder_get_type (void)
74 {
75   static GType object_type = 0;
76
77   if (!object_type)
78     {
79       static const GTypeInfo object_info =
80       {
81         sizeof (PangoFcAfmDecoderClass),
82         (GBaseInitFunc) 0,
83         (GBaseFinalizeFunc) 0,
84         (GClassInitFunc) pango_fc_afm_decoder_class_init,
85         0,           /* class_finalize */
86         0,           /* class_data */
87         sizeof (PangoFcAfmDecoder),
88         0,              /* n_preallocs */
89         (GInstanceInitFunc) pango_fc_afm_decoder_init,
90         0, /* value table */
91       };
92       
93       object_type = g_type_register_static (PANGO_TYPE_FC_DECODER,
94                                             "PangoFcAfmDecoder",
95                                             &object_info, (GTypeFlags)0);
96     }
97   
98   return object_type;
99 }
100 #endif
101
102 static void 
103 pango_fc_afm_decoder_init (PangoFcAfmDecoder *fcafmdecoder)
104 {
105   PangoFcAfmDecoderPrivate *priv = fcafmdecoder->priv;
106   priv = fcafmdecoder->priv
107     = G_TYPE_INSTANCE_GET_PRIVATE (fcafmdecoder,
108                                    PANGO_TYPE_FC_AFM_DECODER,
109                                    PangoFcAfmDecoderPrivate);
110   /*
111     init members
112    */
113 }
114
115 static void
116 pango_fc_afm_decoder_class_init (PangoFcAfmDecoderClass *clss)
117 {
118   GObjectClass *object_class = G_OBJECT_CLASS (clss);
119   object_class->finalize = pango_fc_afm_decoder_finalize;
120   g_type_class_add_private (object_class, sizeof (PangoFcAfmDecoderPrivate));
121
122   PangoFcDecoderClass *parent_class = PANGO_FC_DECODER_CLASS (clss);
123   parent_class->get_charset = pango_fc_afm_get_charset;
124   parent_class->get_glyph = pango_fc_afm_get_glyph;
125 }
126
127 static void
128 pango_fc_afm_decoder_finalize (GObject *object)
129 {
130 #if 0  
131   PangoFcAfmDecoder *fcafmdecoder = PANGO_FC_AFM_DECODER (object);
132   PangoFcAfmDecoderPrivate *priv = fcafmdecoder->priv;
133 #endif
134
135   /*
136     destroy members
137    */
138   G_OBJECT_CLASS (parent_class)->finalize (object);
139 }
140
141 static FcCharSet *
142 pango_fc_afm_get_charset (PangoFcDecoder *decoder, PangoFcFont *fcfont)
143 {
144   (void) decoder;
145   //dprintf ("get charset: %s\n", fcfont->font_pattern);
146   dprintf ("get charset: \n");
147 #if 0  
148   FcCharSet *charset = 0;
149   FcPatternGetCharSet (fcfont->font_pattern, FC_CHARSET, 0, &charset);
150 #else
151   /* Return plain, undecoded charset.
152      TODO:
153        - actually read AFM?
154        - caching?
155        - PUA mapping ? */
156   (void) fcfont;
157   int i;
158   FcChar32 chr = 0;
159   FcCharSet *charset = FcCharSetCreate ();
160   for (i = 0; i < 256; i++)
161     if (!FcCharSetAddChar (charset, chr++))
162       return 0;
163 #endif  
164   return charset;
165 }
166
167 static PangoGlyph
168 pango_fc_afm_get_glyph (PangoFcDecoder *decoder, PangoFcFont *fcfont,
169                         guint32 wc)
170 {
171   (void) decoder;
172 #if 0
173   XftFont *xft_font;
174   xft_font = XftFontOpenPattern (GDK_DISPLAY (),
175                                  FcPatternDuplicate (fcfont->font_pattern));
176   PangoGlyph g = XftCharIndex (0, xft_font, wc);
177   dprintf ("get glyph! 0x%x --> 0x%x\n", wc, (unsigned)g);
178 #else
179   /* TODO:
180        - PUA mapping?
181        
182      Shortcut PUA mapping/AFM reading: The Feta charsets are encoded
183      without any gaps, starting at 0x21.  *grin*  */
184   (void) fcfont;
185   return wc - 0x21;
186 #endif  
187 }
188
189 static void
190 pango_fc_afm_decoder_set_file_name (PangoFcAfmDecoder *self,
191                                     char const *file_name)
192 {
193   self->priv->file_name = file_name;
194 }
195
196 PangoFcAfmDecoder *
197 pango_fc_afm_decoder_new (void)
198 {
199   return PANGO_FC_AFM_DECODER (g_object_new (PANGO_TYPE_FC_AFM_DECODER, 0));
200 }
201
202 PangoFcDecoder *
203 pango_fc_afm_find_decoder (FcPattern *pattern, gpointer user_data)
204 {
205   FcChar8 *family_name;
206   
207   if (FcPatternGetString (pattern, FC_FAMILY, 0, &family_name)
208       == FcResultMatch)
209     {
210       dprintf ("Family name: %s\n", family_name);
211       dprintf ("user_data: %s\n", (char const*) user_data);
212
213       if (!strcasecmp ((char const*) family_name, (char const*) user_data))
214         {
215           PangoFcAfmDecoder *afm = pango_fc_afm_decoder_new ();
216           char const *file_name = "feta20.afm";
217           pango_fc_afm_decoder_set_file_name (afm, file_name);
218           dprintf ("Adding decoder: %s\n", file_name);
219           return PANGO_FC_DECODER (afm);
220         }
221     }
222   return 0;
223 }
224
225 void
226 pango_fc_afm_add_decoder (char const *family_name)
227 {
228   PangoFcFontMap *fc_map
229     = PANGO_FC_FONT_MAP (pango_xft_get_font_map (GDK_DISPLAY (), 0));
230
231   pango_fc_font_map_add_decoder_find_func (fc_map, pango_fc_afm_find_decoder,
232                                            (gpointer)family_name, 0);
233 }
234
235 #ifdef PANGO_FC_AFM_DECODER_TEST
236
237 #include <gtk/gtk.h>
238 #include <libgnomecanvas/libgnomecanvas.h>
239 #include <pango/pangoft2.h>
240 #include <pango/pangox.h>
241 #include <pango/pangoxft.h>
242
243 #include "pangofc-afm-decoder.hh"
244
245 #define CANVAS_WIDTH 600
246 #define CANVAS_HEIGHT 300
247
248 static void
249 exit_clicked (GtkWidget *widget, gpointer data)
250 {
251   gtk_widget_destroy (GTK_WIDGET (data));
252   gtk_main_quit ();
253 }
254
255 static gint
256 delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
257 {
258   gtk_widget_destroy (widget);
259   gtk_main_quit ();
260   return TRUE;
261 }
262
263 GnomeCanvas *
264 make_canvas (int width, int height)
265 {
266   GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
267   GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
268   GtkWidget *canvas = gnome_canvas_new ();
269   GtkWidget *hbox = gtk_hbox_new (TRUE, 0);
270   GtkWidget *button = gtk_button_new_with_label ("Exit");
271
272   gtk_container_add (GTK_CONTAINER (window), vbox);
273   gtk_widget_set_size_request (canvas, width, height);
274   gtk_box_pack_start (GTK_BOX (vbox), canvas, TRUE, TRUE, 0);
275   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
276   gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
277
278   gtk_signal_connect (GTK_OBJECT (button), "clicked",
279                       (GtkSignalFunc) exit_clicked, window);
280   
281   gtk_signal_connect (GTK_OBJECT (window), "delete_event",
282                       (GtkSignalFunc) delete_event, 0);
283
284   gtk_widget_show_all (window);
285   return GNOME_CANVAS (canvas);
286 }
287
288 #define gnome_canvas_text(x, y, font, text) \
289   gnome_canvas_item_new (root, text_item, "x", x, "y", y, "font", font, \
290                          "text", text, "anchor", GTK_ANCHOR_SOUTH_WEST, \
291                          "fill_color", "black", 0)
292
293 int
294 main (int argc, char **argv)
295 {
296   gtk_init (&argc, &argv);
297   GnomeCanvas *canvas = make_canvas (CANVAS_WIDTH, CANVAS_HEIGHT);
298
299   /* Register GNU LilyPond FETA AFM decoders.  */
300   pango_fc_afm_add_decoder ("lilypond-feta");
301   pango_fc_afm_add_decoder ("lilypond-braces");
302   pango_fc_afm_add_decoder ("lilypond-dyn");
303   pango_fc_afm_add_decoder ("lilypond-parmesan");
304
305   int text_item = gnome_canvas_text_get_type ();
306   GnomeCanvasGroup *root = gnome_canvas_root (canvas);
307   char const *g_clef_utf8 = "\302\220";
308
309   gnome_canvas_text (45.0, 122.5, "LilyPond-feta-nummer 16", "3");
310   gnome_canvas_text (45.0, 142.5, "LilyPond-feta-nummer, r 16", "4");
311   gnome_canvas_text (10.0, 142.0, "LilyPond-feta, 32", g_clef_utf8);
312
313   gtk_main ();
314   return 0;
315 }
316 #endif /* PANGO_FC_AFM_DECODER_TEST */
317
318 #endif /* HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC */