help using pangofc afm decoder on the canvas?



I've taken a first attempt to make and afm decoder for pango, and hook
it into the pango_fc_font_map.  See attached.  It's still mostly
empty; I'm having trouble to get a proof of concept going.

Here's the snippet where I hook the decoder

    PangoFontMap *map = pango_ft2_font_map_for_display ();
    PangoFcFontMap *fc_map = PANGO_FC_FONT_MAP (map);

    pango_fc_font_map_add_decoder_find_func (fc_map,
                                             pango_fc_afm_find_decoder,
                                             0, 0);

and the decoder gets of course simply added to the findfuncs list.
But when lateron, I blondly say

    gnome_canvas_item_new (root, text_item, "x", 10.0, "y", 142.0,
	 		  "font", "LilyPond-feta, 32", "text", g_clef_utf8,
			  "anchor", GTK_ANCHOR_WEST, "fill_color", "black", 0);

the decoder callback is not invoked, although the right font file is
being found and displayed

    $ ./gfs
    Selected: LilyPond-feta 32.

    $ l ~/.fonts
    totaal 32
    -rw-rw-r--    1 janneke  janneke     30628 2004-06-15 20:39 GNU-LilyPond-feta-20.otf

That's the only LilyPond font that the font selector finds.  [I've also
tried with a plain .pfa font.]

What do I have to do for the decoder pango_fc_afm_find_decoder () to
get called?

Does Pango use the `wrong' map, ie, one without the decoder?  Should I
tell the canvas to use Pango's FT2 backend?  How?

Please bear with me, this is my first attempt at a gtk+ class.

Greetings,
Jan.

/*
  GNU LilyPond -- the music typesetter.

  canvas-afm.c -- testing the GNOME canvas output backend
  
  Copyright (C) 2004  Jan Nieuwenhuizen <janneke gnu org>

  Use the Pango font-decoder mechanism (pango CVS) to draw characters
  with index >= 0x80 from a custom font, using the AFM encoding
  vector, if possible using AFM glyph names.

  See also: http://le-hacker.org/papers/gobject/ch04.html
*/

#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gnome.h>
#include <pango/pangoft2.h>
#include <pango/pangox.h>

#include "pangofc-afm-decoder.h"

/* This defines the size of the canvas, in pixels */
#define CANVAS_WIDTH 600
#define CANVAS_HEIGHT 300

/* Callback for the clicked signal of the Exit button */
static void
exit_clicked (GtkWidget *widget, gpointer data)
{
 /* the user data points to the main window */
  gtk_widget_destroy (GTK_WIDGET (data));
  gtk_main_quit ();
}

/* Callback for the delete_event signal of the main application window */
static gint
delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
{
  gtk_widget_destroy (widget); /* destroy the main window */
  gtk_main_quit ();
  return TRUE;
}

GtkWidget *toplevel_window;

GnomeCanvas *
make_canvas (int width, int height)
{
  // put in class
  GtkWidget *window;
  GtkWidget *vbox;
  GtkWidget *frame;
  GtkWidget *canvas;
  GtkWidget *hbox = 0;
  GtkWidget *button;

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  // urg
  toplevel_window = window;

  vbox = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (window), vbox);
  gtk_widget_show (vbox);

  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
  gtk_widget_show (frame);

  canvas = gnome_canvas_new ();
  gtk_widget_set_usize (canvas, width, height);
  gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas), 0.0, 0.0,
				  width, height);

  gtk_container_add (GTK_CONTAINER (frame), canvas);
  gtk_widget_show (canvas);

  if (!hbox)
    {
      hbox = gtk_hbox_new (TRUE, 0);
      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
      gtk_widget_show (hbox);
    }

  button = gtk_button_new_with_label ("Exit");
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
		      (GtkSignalFunc) exit_clicked, window);
  
  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
  gtk_widget_show (button);

  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
		      (GtkSignalFunc) delete_event, NULL);

  gtk_widget_show (window);
  return GNOME_CANVAS (canvas);
}


void
setup_pango_afm (GtkWidget *widget)
{
#if 0

  /* This may .  */
  GdkDisplay *gdk_display = gdk_drawable_get_display (widget->window);
  Display *display = gdk_x11_display_get_xdisplay (gdk_display);
  PangoFontMap *map = pango_x_font_map_for_display (display);

  /* FIXME: the decoder_find_func wants a PangoFcFontMap --- but how
     to get it?*/
  //  PangoFcFontMap *fc_map = PANGO_FC_FONT_MAP (map2);

#else
  
#if 0
  /* How do I tell pango to use this new font map?  */
  PangoFontMap *map = pango_ft2_font_map_new ();
#else
  /* Deprecated, but it works.  */
  PangoFontMap *map = pango_ft2_font_map_for_display ();
#endif

  PangoFcFontMap *fc_map = PANGO_FC_FONT_MAP (map);
#endif

  pango_fc_font_map_add_decoder_find_func (fc_map, pango_fc_afm_find_decoder,
					   /*user_data*/0, (GDestroyNotify)0);
}


int
main (int argc, char **argv)
{
  gnome_init ("canvas-example", "1.0", argc, argv);
  GnomeCanvas *canvas = make_canvas (CANVAS_WIDTH, CANVAS_HEIGHT);

  /* Do the magic LilyPond FETA AFM thingy.  */
  setup_pango_afm (toplevel_window);

  int text_item = gnome_canvas_text_get_type ();
  GnomeCanvasGroup *root = gnome_canvas_root (canvas);

  /* FIXME:
     
     The pango_fc_afm_find_decoder function is never invoked.
     Does Pango use the wrong map?
     Should I tell the canvas to use Pango's FT2 backend?  */

  gnome_canvas_item_new (root, text_item, "x", 45.0, "y", 122.5,
			 "font", "lilypond-feta-nummer 16", "text", "3",
			 "anchor", GTK_ANCHOR_WEST, "fill_color", "black", 0);
  gnome_canvas_item_new (root, text_item, "x", 45.0, "y", 142.5,
			 "font", "lilypond-feta-nummer, r 16", "text", "4",
			 "anchor", GTK_ANCHOR_WEST, "fill_color", "black", 0);

  unsigned char g_clef_index = '\220';
  /* 144 -> 194 144 -> \302 \220 */
  char const *g_clef_utf8 = "ab\302\220";
  
  gnome_canvas_item_new (root, text_item, "x", 10.0, "y", 142.0,
			 //"font", "lilypond-feta, r 32", "text", g_clef_utf8,
			 "font", "LilyPond-feta, 32", "text", g_clef_utf8,
			 "anchor", GTK_ANCHOR_WEST, "fill_color", "black", 0);

  gtk_main ();
  return 0;
}
/* GNU LilyPond
 * pangofc-afm-decoder.h -- 
 *
 * Copyright (C) 2004  Jan Nieuwenhuizen <janneke gnu org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef __PANGOFC_AFM_DECODER_H__
#define __PANGOFC_AFM_DECODER_H__

#include <pango/pangofc-fontmap.h>

G_BEGIN_DECLS

#define PANGO_TYPE_FC_AFM_DECODER              (pango_fc_afm_decoder_get_type ())
#define PANGO_FC_AFM_DECODER(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FC_AFM_DECODER, PangoFcAfmDecoder))
#define PANGO_IS_FC_AFM_DECODER(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FC_AFM_DECODER))

#define PANGO_FC_AFM_DECODER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FC_AFM_DECODER, PangoFcAfmDecoderClass))
#define PANGO_IS_FC_AFM_DECODER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FC_AFM_DECODER))
#define PANGO_FC_AFM_DECODER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FC_AFM_DECODER, PangoFcAfmDecoderClass))

typedef struct _PangoFcAfmDecoder        PangoFcAfmDecoder;
typedef struct _PangoFcAfmDecoderClass   PangoFcAfmDecoderClass;
typedef struct _PangoFcAfmDecoderPrivate PangoFcAfmDecoderPrivate;


/**
 * PangoFcAfmDecoder:
 * 
 * #PangoFcAfmDecoder implements an PangoFcDecoder for fonts
 * with an afm mapping.
 **/
struct _PangoFcAfmDecoder
{
  PangoFcDecoder parent_instance;

  PangoFcAfmDecoderPrivate *priv;
};

PangoFcDecoder * pango_fc_afm_find_decoder (FcPattern *pattern, gpointer user_data);

/**
 * PangoFcAfmDecoderClass:
 * @read_afm: Read afm mapping for #fcfont.
 *
 * Class structure for #PangoFcAfmDecoder.
 **/
struct _PangoFcAfmDecoderClass
{
  /*< private >*/
  PangoFcDecoderClass parent_class;

  /*< public >*/
  void         (*read_afm) (PangoFcAfmDecoder   *self,
			    PangoFcFont    *fcfont);

  /*< private >*/

  /* Padding for future expansion */
  void (*_pango_reserved1) (void);
  void (*_pango_reserved2) (void);
  void (*_pango_reserved3) (void);
  void (*_pango_reserved4) (void);
};

G_END_DECLS

#endif /* __PANGOFC_AFM_DECODER_H__ */
/* GNU LilyPond
 * pango-afm-decoder.c -- AFM fontencoding for Pango fontconfig
 *
 * Copyright (C) 2004  Jan Nieuwenhuizen <janneke gnu org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "pangofc-afm-decoder.h"

struct _PangoFcAfmDecoderPrivate
{
  GString encoding[256];
  //GString file_name;
  char const *file_name;
  PangoFcFont *fc_font;
};

static void pango_fc_afm_decoder_init (PangoFcAfmDecoder *fontmap);
static void pango_fc_afm_decoder_class_init (PangoFcDecoderClass *class);
static void pango_fc_afm_decoder_finalize (GObject *object);

static FcCharSet *pango_fc_afm_get_charset (PangoFcFont *fcfont);
static PangoGlyph pango_fc_afm_get_glyph (PangoFcFont *fcfont, guint32 wc);
static void pango_fc_afm_decoder_set_file_name (PangoFcAfmDecoder *self, char const* file_name);


static PangoFcDecoderClass *parent_class;

GType
pango_fc_afm_decoder_get_type (void)
{
  static GType object_type = 0;

  if (!object_type)
    {
      static const GTypeInfo object_info =
      {
        sizeof (PangoFcAfmDecoderClass),
        (GBaseInitFunc) NULL,
        (GBaseFinalizeFunc) NULL,
        (GClassInitFunc) pango_fc_afm_decoder_class_init,
        NULL,           /* class_finalize */
        NULL,           /* class_data */
        sizeof (PangoFcAfmDecoder),
        0,              /* n_preallocs */
        (GInstanceInitFunc) pango_fc_afm_decoder_init,
      };
      
      object_type = g_type_register_static (PANGO_TYPE_FONT_MAP,
                                            "PangoFcAfmDecoder",
                                            &object_info, 0);
    }
  
  return object_type;
}

static void 
pango_fc_afm_decoder_init (PangoFcAfmDecoder *fcafmdecoder)
{
  static gboolean registered_modules = FALSE;
  PangoFcAfmDecoderPrivate *priv = fcafmdecoder->priv;

  priv = fcafmdecoder->priv = G_TYPE_INSTANCE_GET_PRIVATE (fcafmdecoder,
							   PANGO_TYPE_FC_AFM_DECODER,
							   PangoFcAfmDecoderPrivate);

  //self->private = g_new0 (MamanBarPrivate, 1);

  /*
    init members
   */
}

static void
pango_fc_afm_decoder_class_init (PangoFcDecoderClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);
  
  parent_class = g_type_class_peek_parent (class);
  
  object_class->finalize = pango_fc_afm_decoder_finalize;

  class->get_charset = pango_fc_afm_get_charset;
  class->get_glyph = pango_fc_afm_get_glyph;

  g_type_class_add_private (object_class, sizeof (PangoFcAfmDecoderPrivate));
}

static void
pango_fc_afm_decoder_finalize (GObject *object)
{
  PangoFcAfmDecoder *fcafmdecoder = PANGO_FC_AFM_DECODER (object);
  PangoFcAfmDecoderPrivate *priv = fcafmdecoder->priv;

  /*
    destroy members
   */

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static FcCharSet *
pango_fc_afm_get_charset (PangoFcFont *fcfont)
{
  // read afm
  // convert afm mapping into FcCharset
  return 0;
}

static PangoGlyph
pango_fc_afm_get_glyph (PangoFcFont *fcfont, guint32 wc)
{
  // map wc -> character name
  // `get' character by name from font
  // turn character into PangoGlyph
  return 0;
}

static void
pango_fc_afm_decoder_set_file_name (PangoFcAfmDecoder *self, char const* file_name)
{
  self->priv->file_name = file_name;
}

#include <stdio.h>

PangoFcDecoder *
pango_fc_afm_find_decoder (FcPattern *pattern, gpointer user_data)
{
  /* TODO:
     - figure out what pattern, use_data are ant what they contain,
     - if we're a customly encoded afm file, create an afm decoder,
     - initialize decoder with name of font, or afm file name.
   */
  //PangoFcAfmDecoder *afm = g_object_new (PANGO_FC_AFM_DECODER, null);
  PangoFcAfmDecoder *afm = g_object_new (PANGO_TYPE_FC_AFM_DECODER, 0);
  pango_fc_afm_decoder_set_file_name (afm, "feta20.afm");

  fprintf (stderr, "Hello world\n");

  // Hmmm, is this the right way to return an instance of a derived class?
  return afm;
}
-- 
Jan Nieuwenhuizen <janneke gnu org> | GNU LilyPond - The music typesetter
http://www.xs4all.nl/~jantien       | http://www.lilypond.org


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]