Logo Search packages:      
Sourcecode: pango-graphite version File versions  Download package

silgraphite-fc.c

/* Pango
 * silgraphite-fc.c: SILGraphite based shaper for FreeType-based backends
 *
 * Copyright (C) 2004-2005 SIL International
 * Author: Daniel Glassey <wdg@debian.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 <gmodule.h>
#include <pango/pango-engine.h>
#include <pango/pango-utils.h>
#include <pango/pangofc-font.h>
#include <pango/pangoxft.h>
#include "pangographite.h"

static gboolean have_graphite = FALSE;
static gboolean graphite_initialised = FALSE;

//void graphite_PangoGlyphString(const char *text, int length, PangoFont *font, PangoGlyphString *glyphs);
typedef void (*pgraphite_real_shape) (const char *text, int length, 
    PangoFont *font, PangoGlyphString *glyphs);

static pgraphite_real_shape graphite_real_shape = NULL;
static GModule *graphitelibrary = NULL;

/* No extra fields needed */
typedef PangoEngineShape      GraphiteEngineFc;
typedef PangoEngineShapeClass GraphiteEngineFcClass;

#define SCRIPT_ENGINE_NAME "GraphiteScriptEngineFc"
#define RENDER_TYPE PANGO_RENDER_TYPE_FC

static PangoEngineScriptInfo graphite_scripts[] = {
  {    PANGO_SCRIPT_COMMON,   "*" },             /* Zyyy */
  {    PANGO_SCRIPT_INHERITED,      "*" },          /* Qaai */
  {    PANGO_SCRIPT_ARABIC,   "*" },             /* Arab */
  {    PANGO_SCRIPT_ARMENIAN, "*" },           /* Armn */
  {    PANGO_SCRIPT_BENGALI,  "*" },            /* Beng */
  {    PANGO_SCRIPT_BOPOMOFO, "*" },           /* Bopo */
  {    PANGO_SCRIPT_CHEROKEE, "*" },           /* Cher */
  {    PANGO_SCRIPT_COPTIC,   "*" },             /* Qaac */
  {    PANGO_SCRIPT_CYRILLIC, "*" },           /* Cyrl (Cyrs) */
  {    PANGO_SCRIPT_DESERET,  "*" },            /* Dsrt */
  {    PANGO_SCRIPT_DEVANAGARI,     "*" },         /* Deva */
  {    PANGO_SCRIPT_ETHIOPIC, "*" },           /* Ethi */
  {    PANGO_SCRIPT_GEORGIAN, "*" },           /* Geor (Geon, Geoa) */
  {    PANGO_SCRIPT_GOTHIC,   "*" },             /* Goth */
  {    PANGO_SCRIPT_GREEK,    "*" },              /* Grek */
  {    PANGO_SCRIPT_GUJARATI, "*" },           /* Gujr */
  {    PANGO_SCRIPT_GURMUKHI, "*" },           /* Guru */
  {    PANGO_SCRIPT_HAN,      "*" },                /* Hani */
  {    PANGO_SCRIPT_HANGUL,   "*" },             /* Hang */
  {    PANGO_SCRIPT_HEBREW,   "*" },             /* Hebr */
  {    PANGO_SCRIPT_HIRAGANA, "*" },           /* Hira */
  {    PANGO_SCRIPT_KANNADA,  "*" },            /* Knda */
  {    PANGO_SCRIPT_KATAKANA, "*" },           /* Kana */
  {    PANGO_SCRIPT_KHMER,    "*" },              /* Khmr */
  {    PANGO_SCRIPT_LAO,      "*" },                /* Laoo */
  {    PANGO_SCRIPT_LATIN,    "*" },              /* Latn (Latf, Latg) */
  {    PANGO_SCRIPT_MALAYALAM,      "*" },          /* Mlym */
  {    PANGO_SCRIPT_MONGOLIAN,      "*" },          /* Mong */
  {    PANGO_SCRIPT_MYANMAR,  "*" },            /* Mymr */
  {    PANGO_SCRIPT_OGHAM,    "*" },              /* Ogam */
  {    PANGO_SCRIPT_OLD_ITALIC,     "*" },         /* Ital */
  {    PANGO_SCRIPT_ORIYA,    "*" },              /* Orya */
  {    PANGO_SCRIPT_RUNIC,    "*" },              /* Runr */
  {    PANGO_SCRIPT_SINHALA,  "*" },            /* Sinh */
  {    PANGO_SCRIPT_SYRIAC,   "*" },             /* Syrc (Syrj, Syrn, Syre) */
  {    PANGO_SCRIPT_TAMIL,    "*" },              /* Taml */
  {    PANGO_SCRIPT_TELUGU,   "*" },             /* Telu */
  {    PANGO_SCRIPT_THAANA,   "*" },             /* Thaa */
  {    PANGO_SCRIPT_THAI,     "*" },               /* Thai */
  {    PANGO_SCRIPT_TIBETAN,  "*" },            /* Tibt */
  {    PANGO_SCRIPT_CANADIAN_ABORIGINAL,  "*" }, /* Cans */
  {    PANGO_SCRIPT_YI,       "*" },                 /* Yiii */
  {    PANGO_SCRIPT_TAGALOG,  "*" },            /* Tglg */
  {    PANGO_SCRIPT_HANUNOO,  "*" },            /* Hano */
  {    PANGO_SCRIPT_BUHID,    "*" },              /* Buhd */
  {    PANGO_SCRIPT_TAGBANWA, "*" },           /* Tagb */
  
      /* Unicode-4.0 additions */
  {    PANGO_SCRIPT_BRAILLE,  "*" },            /* Brai */
  {    PANGO_SCRIPT_CYPRIOT,  "*" },            /* Cprt */
  {    PANGO_SCRIPT_LIMBU,    "*" },              /* Limb */
  {    PANGO_SCRIPT_OSMANYA,  "*" },            /* Osma */
  {    PANGO_SCRIPT_SHAVIAN,  "*" },            /* Shaw */
  {    PANGO_SCRIPT_LINEAR_B, "*" },           /* Linb */
  {    PANGO_SCRIPT_TAI_LE,   "*" },             /* Tale */
  {    PANGO_SCRIPT_UGARITIC, "*" }            /* Ugar */
#if (PANGO_MAJOR_VERSION > 1) || (PANGO_MINOR_VERSION > 9)
      /* Unicode-4.1 additions  (requires pango >= 1.9.1) */
  ,{    PANGO_SCRIPT_NEW_TAI_LUE,   "*" },            /* Talu */
  {    PANGO_SCRIPT_BUGINESE, "*" },            /* Bugi */
  {    PANGO_SCRIPT_GLAGOLITIC,     "*" },            /* Glag */
  {    PANGO_SCRIPT_TIFINAGH, "*" },            /* Tfng */
  {    PANGO_SCRIPT_SYLOTI_NAGRI,   "*" },            /* Sylo */
  {    PANGO_SCRIPT_OLD_PERSIAN,    "*" },            /* Xpeo */
  {    PANGO_SCRIPT_KHAROSHTHI,     "*" }            /* Khar */
#endif

#if (PANGO_MAJOR_VERSION > 1) || (PANGO_MINOR_VERSION > 12)
      /* Unicode-5.0 additions */
  ,{    PANGO_SCRIPT_UNKNOWN,   "*" },            /* Zzzz */
  {    PANGO_SCRIPT_BALINESE,   "*" },           /* Bali */
  {    PANGO_SCRIPT_CUNEIFORM,  "*" },          /* Xsux */
  {    PANGO_SCRIPT_PHOENICIAN, "*" },         /* Phnx */
  {    PANGO_SCRIPT_PHAGS_PA,   "*" },           /* Phag */
  {    PANGO_SCRIPT_NKO,        "*" }                 /* Nkoo */
#endif
};

static PangoEngineInfo script_engines[] = {
  {
    SCRIPT_ENGINE_NAME,
    PANGO_ENGINE_TYPE_SHAPE,
    RENDER_TYPE,
    graphite_scripts, G_N_ELEMENTS(graphite_scripts)
  }
};

static void 
graphite_engine_shape (PangoEngineShape *engine,
                PangoFont        *font,
                const char       *text,
                gint              length,
                PangoAnalysis    *analysis,
                PangoGlyphString *glyphs)
{
    //g_return_if_fail (PANGO_XFT_IS_FONT (font) || PANGO_FT2_IS_FONT (font));
    g_return_if_fail (PANGO_IS_FC_FONT (font));
    g_return_if_fail (have_graphite);
      //g_message("graphite_engine_shape");
  static GStaticMutex mutex = G_STATIC_MUTEX_INIT;

    g_static_mutex_lock (&mutex);
    // Do Graphite Shaping
    (*graphite_real_shape)(text, length, font, glyphs);

    g_static_mutex_unlock (&mutex);
}

static PangoCoverageLevel
graphite_engine_covers (PangoEngineShape *engine,
                 PangoFont        *font,
                 PangoLanguage    *lang,
                 gunichar          wc)
{
  PangoFcFont *fcfont;
  FcChar8 * fontcap;
  
  if (!have_graphite)
        return PANGO_COVERAGE_NONE;

  // First check that the font covers the lang
  PangoCoverage *coverage = pango_font_get_coverage (font, lang);
  PangoCoverageLevel result = pango_coverage_get (coverage, wc);
  pango_coverage_unref (coverage);

  if (result != PANGO_COVERAGE_EXACT)
  {
        return PANGO_COVERAGE_NONE;
  }

  if (!PANGO_IS_FONT (font))
  {
        g_message("not a PangoFont");
      return PANGO_COVERAGE_NONE;
  }
  if (!PANGO_IS_FC_FONT (font))
  {
        g_message("not a PangoFcFont");
      return PANGO_COVERAGE_NONE;
  }
  #if 0
  if (!PANGO_XFT_IS_FONT (font) && !PANGO_FT2_IS_FONT (font))
  {
        g_message("not a PangoXftFont");
      return PANGO_COVERAGE_NONE;
  }
  #endif


  fcfont = (PangoFcFont *)font;
  if (FcPatternGetString (fcfont->font_pattern, FC_CAPABILITY, 0, &fontcap) != FcResultMatch)
  {
        return PANGO_COVERAGE_NONE;
  }
  if (strstr((char *)fontcap, "ttable:Silf"))
  {
        return PANGO_COVERAGE_EXACT;
  }
  else
        return PANGO_COVERAGE_NONE;
  // fontconfig >= 2.3.0 has fontcap for font capabilities inc silgraphite tttables 
  
  #if 0
  //FcResult FcPatternGet (FcPattern *p, const char *object, int id, FcValue *v)

  /* Returns in `v' the `id'th value associated with the property `object'. 
     The value returned is not a copy, but rather refers to the data stored 
       within the pattern directly. Applications must not free this value.
  */
  #endif
}

#if CURSORHACK
void 
graphite_engine_glyph_string_x_to_index (PangoGlyphString *glyphs,
                         const char       *text,
                         int               length,
                         PangoAnalysis    *analysis,
                         int               x_pos,
                         int              *index, 
                         gboolean         *trailing)
{
      //g_message("graphite_glyph_string_x_to_index");
      pango_glyph_string_x_to_index (glyphs,
                         text,
                         length,
                         analysis,
                         x_pos,
                         index, 
                         trailing);
}

void 
graphite_engine_glyph_string_index_to_x (PangoGlyphString *glyphs,
                         const char       *text,
                         int               length,
                         PangoAnalysis    *analysis,
                         int               index, 
                         gboolean          trailing,
                         int               *x_pos)
{
      //g_message("graphite_glyph_string_index_to_x");
      graphite_glyph_string_index_to_x (glyphs,
                         text,
                         length,
                         analysis,
                         index, 
                         trailing,
                         x_pos);
}

#endif

static void
init_graphite (void)
{
      if (!graphite_initialised)
      {
            graphite_initialised = TRUE;
            //g_message("opening libsilgraphitepango");
            graphitelibrary = g_module_open("libgraphitepango.so.0", G_MODULE_BIND_LAZY);
            if (graphitelibrary)
            {
                  //g_message("looking for graphite_PangoGlyphString");
            gpointer gp_shape;
                  have_graphite = g_module_symbol(graphitelibrary,
                        "graphite_PangoGlyphString",
                        &gp_shape);
            graphite_real_shape = gp_shape;
                  //if (!have_graphite) g_message("Failed to find graphite_PangoGlyphString");
                  //else g_message("Found graphite_PangoGlyphString");
            }
      }
} 


static void
graphite_engine_fc_class_init (PangoEngineShapeClass *class)
{
  class->covers = graphite_engine_covers;
  class->script_shape = graphite_engine_shape;
  #if CURSORHACK
  class->glyph_string_index_to_x = graphite_engine_glyph_string_index_to_x;
  class->glyph_string_x_to_index = graphite_engine_glyph_string_x_to_index;
  #endif
}

PANGO_ENGINE_SHAPE_DEFINE_TYPE (GraphiteEngineFc, graphite_engine_fc,
                        graphite_engine_fc_class_init, NULL);

void 
PANGO_MODULE_ENTRY(init) (GTypeModule *module)
{
  init_graphite();
  graphite_engine_fc_register_type (module);
  //g_message("init pangographite");
}

void 
PANGO_MODULE_ENTRY(exit) (void)
{
      //g_message("exit pangographite");
}

void 
PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
                    int              *n_engines)
{
  init_graphite();
  *engines = script_engines;
  *n_engines = G_N_ELEMENTS (script_engines);
}

PangoEngine *
PANGO_MODULE_ENTRY(create) (const char *id)
{
  if (!strcmp (id, SCRIPT_ENGINE_NAME))
    return g_object_new (graphite_engine_fc_type, NULL);
  else
    return NULL;
}



Generated by  Doxygen 1.6.0   Back to index