]> git.donarmstrong.com Git - lilypond.git/blob - lily/pangofc-afm-decoder.cc
*** empty log message ***
[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.hh"
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 #ifndef PANGO_FC_AFM_DECODER_TEST
48 #define PUA_OFFSET 0xe00
49 #else
50 #define PUA_OFFSET 0
51 #endif
52
53 struct _PangoFcAfmDecoderPrivate
54 {
55   GString encoding[256];
56   char const *file_name;
57   PangoFcFont *fc_font;
58 };
59
60 static void pango_fc_afm_decoder_init (PangoFcAfmDecoder *fontmap);
61 static void pango_fc_afm_decoder_class_init (PangoFcAfmDecoderClass *clss);
62 static void pango_fc_afm_decoder_finalize (GObject *object);
63
64 static FcCharSet *pango_fc_afm_get_charset (PangoFcDecoder *decoder,
65                                             PangoFcFont *fcfont);
66 static PangoGlyph pango_fc_afm_get_glyph (PangoFcDecoder *decoder,
67                                           PangoFcFont *fcfont, guint32 wc);
68 static void pango_fc_afm_decoder_set_file_name (PangoFcAfmDecoder *self,
69                                                 char const *file_name);
70
71 static PangoFcDecoderClass *parent_class;
72
73 G_DEFINE_TYPE (PangoFcAfmDecoder, pango_fc_afm_decoder, PANGO_TYPE_FC_DECODER);
74
75 static void 
76 pango_fc_afm_decoder_init (PangoFcAfmDecoder *fcafmdecoder)
77 {
78   PangoFcAfmDecoderPrivate *priv = fcafmdecoder->priv;
79   priv = fcafmdecoder->priv
80     = G_TYPE_INSTANCE_GET_PRIVATE (fcafmdecoder,
81                                    PANGO_TYPE_FC_AFM_DECODER,
82                                    PangoFcAfmDecoderPrivate);
83 }
84
85 static void
86 pango_fc_afm_decoder_class_init (PangoFcAfmDecoderClass *clss)
87 {
88   GObjectClass *object_class = G_OBJECT_CLASS (clss);
89   object_class->finalize = pango_fc_afm_decoder_finalize;
90   g_type_class_add_private (object_class, sizeof (PangoFcAfmDecoderPrivate));
91
92   PangoFcDecoderClass *parent_class = PANGO_FC_DECODER_CLASS (clss);
93   parent_class->get_charset = pango_fc_afm_get_charset;
94   parent_class->get_glyph = pango_fc_afm_get_glyph;
95 }
96
97 static void
98 pango_fc_afm_decoder_finalize (GObject *object)
99 {
100   G_OBJECT_CLASS (parent_class)->finalize (object);
101 }
102
103 static FcCharSet *
104 pango_fc_afm_get_charset (PangoFcDecoder *decoder, PangoFcFont *fcfont)
105 {
106   (void) decoder;
107   dprintf ("get charset: \n");
108 #if 0  
109   FcCharSet *charset = 0;
110   FcPatternGetCharSet (fcfont->font_pattern, FC_CHARSET, 0, &charset);
111 #else
112   /* Return plain, undecoded charset.
113      FIXME:
114        - actually read AFM
115        - caching  */
116   (void) fcfont;
117   int i;
118   FcChar32 chr = 0;
119   FcCharSet *charset = FcCharSetCreate ();
120   for (i = 0; i < 256; i++)
121     if (!FcCharSetAddChar (charset, chr++))
122       return 0;
123 #endif  
124   return charset;
125 }
126
127 static PangoGlyph
128 pango_fc_afm_get_glyph (PangoFcDecoder *decoder, PangoFcFont *fcfont,
129                         guint32 wc)
130 {
131   (void) decoder;
132 #if 0
133   XftFont *xft_font;
134   xft_font = XftFontOpenPattern (GDK_DISPLAY (),
135                                  FcPatternDuplicate (fcfont->font_pattern));
136   PangoGlyph g = XftCharIndex (0, xft_font, wc);
137   dprintf ("get glyph! 0x%x --> 0x%x\n", wc, (unsigned)g);
138 #else
139   (void) fcfont;
140   /* FIXME
141      Use direct privat usage area (PUA) mapping as shortcut for
142      actual AFM reading.  The Feta charsets are encoded without any
143      gaps, and mappend onto PUA.  */
144   return wc - PUA_OFFSET;
145 #endif  
146 }
147
148 static void
149 pango_fc_afm_decoder_set_file_name (PangoFcAfmDecoder *self,
150                                     char const *file_name)
151 {
152   self->priv->file_name = file_name;
153 }
154
155 PangoFcAfmDecoder *
156 pango_fc_afm_decoder_new (void)
157 {
158   return PANGO_FC_AFM_DECODER (g_object_new (PANGO_TYPE_FC_AFM_DECODER, 0));
159 }
160
161 PangoFcDecoder *
162 pango_fc_afm_find_decoder (FcPattern *pattern, gpointer user_data)
163 {
164   FcChar8 *family_name;
165   
166   if (FcPatternGetString (pattern, FC_FAMILY, 0, &family_name)
167       == FcResultMatch)
168     {
169       dprintf ("Family name: %s\n", family_name);
170       dprintf ("user_data: %s\n", (char const*) user_data);
171
172       if (!strcasecmp ((char const*) family_name, (char const*) user_data))
173         {
174           PangoFcAfmDecoder *afm = pango_fc_afm_decoder_new ();
175           char const *file_name = "feta20.afm";
176           pango_fc_afm_decoder_set_file_name (afm, file_name);
177           dprintf ("Adding decoder: %s\n", file_name);
178           return PANGO_FC_DECODER (afm);
179         }
180     }
181   return 0;
182 }
183
184 void
185 pango_fc_afm_add_decoder (char const *family_name)
186 {
187   PangoFcFontMap *fc_map
188     = PANGO_FC_FONT_MAP (pango_xft_get_font_map (GDK_DISPLAY (), 0));
189
190   pango_fc_font_map_add_decoder_find_func (fc_map, pango_fc_afm_find_decoder,
191                                            (gpointer)family_name, 0);
192 }
193
194 #ifdef PANGO_FC_AFM_DECODER_TEST
195
196 #include <gtk/gtk.h>
197 #include <libgnomecanvas/libgnomecanvas.h>
198 #include <pango/pangoft2.h>
199 #include <pango/pangox.h>
200 #include <pango/pangoxft.h>
201
202 #include "pangofc-afm-decoder.hh"
203
204 #define CANVAS_WIDTH 600
205 #define CANVAS_HEIGHT 300
206
207 static void
208 exit_clicked (GtkWidget *widget, gpointer data)
209 {
210   gtk_widget_destroy (GTK_WIDGET (data));
211   gtk_main_quit ();
212 }
213
214 static gint
215 delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
216 {
217   gtk_widget_destroy (widget);
218   gtk_main_quit ();
219   return TRUE;
220 }
221
222 GnomeCanvas *
223 make_canvas (int width, int height)
224 {
225   GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
226   GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
227   GtkWidget *canvas = gnome_canvas_new ();
228   GtkWidget *hbox = gtk_hbox_new (TRUE, 0);
229   GtkWidget *button = gtk_button_new_with_label ("Exit");
230
231   gtk_container_add (GTK_CONTAINER (window), vbox);
232   gtk_widget_set_size_request (canvas, width, height);
233   gtk_box_pack_start (GTK_BOX (vbox), canvas, TRUE, TRUE, 0);
234   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
235   gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
236
237   gtk_signal_connect (GTK_OBJECT (button), "clicked",
238                       (GtkSignalFunc) exit_clicked, window);
239   
240   gtk_signal_connect (GTK_OBJECT (window), "delete_event",
241                       (GtkSignalFunc) delete_event, 0);
242
243   gtk_widget_show_all (window);
244   return GNOME_CANVAS (canvas);
245 }
246
247 #define gnome_canvas_text(x, y, font, text) \
248   gnome_canvas_item_new (root, text_item, "x", x, "y", y, "font", font, \
249                          "text", text, "anchor", GTK_ANCHOR_SOUTH_WEST, \
250                          "fill_color", "black", 0)
251
252 int
253 main (int argc, char **argv)
254 {
255   gtk_init (&argc, &argv);
256   GnomeCanvas *canvas = make_canvas (CANVAS_WIDTH, CANVAS_HEIGHT);
257
258   /* Register GNU LilyPond FETA AFM decoders.  */
259   pango_fc_afm_add_decoder ("lilypond-feta");
260   pango_fc_afm_add_decoder ("lilypond-feta-braces-f");
261   pango_fc_afm_add_decoder ("lilypond-din");
262   pango_fc_afm_add_decoder ("lilypond-parmesan");
263
264   int text_item = gnome_canvas_text_get_type ();
265   GnomeCanvasGroup *root = gnome_canvas_root (canvas);
266   char const *g_clef_utf8 = "p";
267
268   gnome_canvas_text (45.0, 122.5, "LilyPond-feta-nummer 16", "3");
269   gnome_canvas_text (45.0, 142.5, "LilyPond-feta-nummer, r 16", "4");
270   gnome_canvas_text (10.0, 142.0, "LilyPond-feta, 32", g_clef_utf8);
271   gnome_canvas_text (10.0, 162.0, "LilyPond-feta-din, 32", "fmsrpz");
272   gnome_canvas_text (5.0, 142.0, "LilyPond-feta-braces-f, 32", "AZ");
273
274   gtk_main ();
275   return 0;
276 }
277 #endif /* PANGO_FC_AFM_DECODER_TEST */
278
279 #endif /* HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC */