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