Re: Adding any new Pango engines...
- From: Chookij Vanatham <chookij mpkmail Eng Sun COM>
- To: gtk-i18n-list gnome org, otaylor redhat com
- Cc: Chookij Vanatham Eng Sun COM, pablo mandrakesoft com
- Subject: Re: Adding any new Pango engines...
- Date: Mon, 16 Apr 2001 16:17:23 -0700 (PDT)
Hi Owen, Pablo,
Finally, I found where the problem was.
It's in macro "is_composible" which was refered to "char_class" variable which
wasn't declared.
Attached is the fix one.
I think I'll take a couple days to test it and, at least, the hebrew case
is still working like before, I'm going to put it back to CVS.
Thanks,
Chookij V.
] Date: Fri, 13 Apr 2001 15:34:46 -0400
] From: Owen Taylor <otaylor redhat com>
] Subject: Re: Adding any new Pango engines...
] To: gtk-i18n-list gnome org
] Cc: Chookij Vanatham <Chookij Vanatham Eng Sun COM>
] MIME-version: 1.0
] User-Agent: Gnus/5.0807 (Gnus v5.8.7) Emacs/20.7
]
]
] Chookij Vanatham <chookij mpkmail Eng Sun COM> writes:
]
] > Hi,
] >
] > I'm trying to add another new Pango engine but I've got the following error
] > by running "pango/pango/pango-querymodules".
] >
] > % ./pango-querymodules
] > ...
] > ...
] > Cannot load module
/home/chookij/GNOME2.0/lib/pango/modules/pango-hebrew-x.so:
] > couldn't open libtool archive
] > /home/chookij/GNOME2.0/lib/pango/modules/pango-hebrew-x.so does not export
Pango
] > module API
] >
] > If anybody has the clue, please let me know.
]
] I don't see anything obviously wrong with your code or makefiles. What
] symbols are exported from the .so file? (You probably can check that
] with 'nm')
]
] Regards,
] Owen
]
/* Pango
* hebrew-x.c:
*
* Copyright (C) 1999 Red Hat Software
* Author: Owen Taylor <otaylor redhat com>
*
* Copyright (c) 1996-2000 by Sun Microsystems, Inc.
* Author: Chookij Vanatham <Chookij Vanatham Eng Sun COM>
*
* 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 <string.h>
#include <glib.h>
#include <string.h>
#include "pangox.h"
#include "pango-engine.h"
#define ucs2iso8859_8(wc) (unsigned int)((unsigned int)(wc) - 0x0590 + 0x20)
#define iso8859_8_2uni(c) ((gunichar)(c) - 0x20 + 0x0590)
#define MAX_CLUSTER_CHRS 256
#define MAX_GLYPHS 256
/* Define Hebrew character classes */
#define _ND 0
#define _LT 1
#define _LD (1<<1) /* Bet, Kaf, Shin */
#define _YD (1<<2)
#define _VA (1<<3)
#define _DA (1<<4)
#define _PT (1<<5)
#define _HO (1<<6)
#define _12 (1<<7)
#define NormalLetter _LT
#define BetKafShinLetter _LD
#define YODLetter _YD
#define VAVLetter _VA
#define DAGESHPoint _DA
#define OtherPoint _PT
#define HolamPoint _HO
#define OneTwoPoint _12
#define is_char_type(wc, mask) (char_type_table[ucs2iso8859_8 ((wc))] & (mask))
#define is_composible(cur_wc, nxt_wc) (compose_table[char_type_table[ucs2iso8859_8 (cur_wc)]]\
[char_type_table[ucs2iso8859_8 (nxt_wc)]])
#define SCRIPT_ENGINE_NAME "HebrewScriptEngineX"
/* We handle the range U+0591 to U+05f4 exactly
*/
static PangoEngineRange hebrew_ranges[] = {
{ 0x0591, 0x05f4, "*" }, /* Hebrew */
};
static PangoEngineInfo script_engines[] = {
{
SCRIPT_ENGINE_NAME,
PANGO_ENGINE_TYPE_SHAPE,
PANGO_RENDER_TYPE_X,
hebrew_ranges, G_N_ELEMENTS(hebrew_ranges)
}
};
/*
* X window system script engine portion
*/
typedef struct _HebrewFontInfo HebrewFontInfo;
/* The type of encoding that we will use
*/
typedef enum {
HEBREW_FONT_NONE,
HEBREW_FONT_ISO8859_8,
HEBREW_FONT_ISO10646
} HebrewFontType;
struct _HebrewFontInfo
{
PangoFont *font;
HebrewFontType type;
PangoXSubfont subfont;
};
static const gint char_type_table[128] = {
/* 0, 1, 2, 3, 4, 5, 6, 7 */
/*00*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*10*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*20*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*30*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*40*/ _PT, _PT, _PT, _PT, _12, _12, _PT, _PT,
_PT, _HO, _ND, _PT, _DA, _ND, _ND, _ND,
/*50*/ _ND, _PT, _PT, _ND, _PT, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*60*/ _LT, _LT, _LT, _LT, _LT, _VA, _LT, _LT,
_LT, _YD, _LT, _LT, _LT, _LT, _LT, _LT,
/*70*/ _LT, _LT, _LT, _LT, _LT, _LT, _LT, _LT,
_LT, _LT, _LT, _ND, _ND, _ND, _ND, _ND,
};
static const gboolean compose_table[9][9] = {
/* Cn */ /* 0, 1, 2, 3, 4, 5, 6, 7, 8 */
/* Cn-1 00 */ { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
/* 10 */ { FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE },
/* 20 */ { FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE },
/* 30 */ { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
/* 40 */ { FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE },
/* 50 */ { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
/* 60 */ { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
/* 70 */ { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
/* 80 */ { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE }
};
/* Sun Hebrew Font Layout
*/
static const gint Sun_shape_table[128] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
/* Unicode Hebrew Font Layout
*/
static const gint Unicode_shape_table[128] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05C4, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};
/* Returns a structure with information we will use to rendering given the
* #PangoFont. This is computed once per font and cached for later retrieval.
*/
static HebrewFontInfo *
get_font_info (PangoFont *font)
{
static const char *charsets[] = {
"iso8859-8",
"iso10646-1",
};
static const int charset_types[] = {
HEBREW_FONT_ISO8859_8,
HEBREW_FONT_ISO10646,
};
HebrewFontInfo *font_info;
GQuark info_id = g_quark_from_string ("hebrew-font-info");
font_info = g_object_get_qdata (G_OBJECT (font), info_id);
if (!font_info)
{
/* No cached information not found, so we need to compute it
* from scratch
*/
PangoXSubfont *subfont_ids;
gint *subfont_charsets;
gint n_subfonts, i;
font_info = g_new (HebrewFontInfo, 1);
font_info->font = font;
font_info->type = HEBREW_FONT_NONE;
g_object_set_qdata_full (G_OBJECT (font), info_id, font_info, (GDestroyNotify)g_free);
n_subfonts = pango_x_list_subfonts (font, (char **)charsets, G_N_ELEMENTS (charsets),
&subfont_ids, &subfont_charsets);
for (i=0; i < n_subfonts; i++)
{
HebrewFontType font_type = charset_types[subfont_charsets[i]];
if (font_type == HEBREW_FONT_ISO10646 &&
pango_x_has_glyph (font, PANGO_X_MAKE_GLYPH (subfont_ids[i], 0x05D0)))
{
font_info->type = font_type;
font_info->subfont = subfont_ids[i];
break;
}
else if (font_type == HEBREW_FONT_ISO8859_8 &&
pango_x_has_glyph (font, PANGO_X_MAKE_GLYPH (subfont_ids[i], 0xE0)))
{
font_info->type = font_type;
font_info->subfont = subfont_ids[i];
break;
}
}
g_free (subfont_ids);
g_free (subfont_charsets);
}
return font_info;
}
static void
add_glyph (HebrewFontInfo *font_info,
PangoGlyphString *glyphs,
gint cluster_start,
PangoGlyph glyph,
gboolean combining)
{
PangoRectangle ink_rect, logical_rect;
gint index = glyphs->num_glyphs;
pango_glyph_string_set_size (glyphs, index + 1);
glyphs->glyphs[index].glyph = glyph;
glyphs->glyphs[index].attr.is_cluster_start = combining ? 0 : 1;
glyphs->log_clusters[index] = cluster_start;
pango_font_get_glyph_extents (font_info->font,
glyphs->glyphs[index].glyph, &ink_rect, &logical_rect);
if (combining)
{
if ((font_info->type == HEBREW_FONT_ISO8859_8) ||
(font_info->type == HEBREW_FONT_ISO10646))
{
glyphs->glyphs[index].geometry.width =
logical_rect.width + glyphs->glyphs[index - 1].geometry.width;
if (logical_rect.width > 0)
glyphs->glyphs[index].geometry.x_offset = glyphs->glyphs[index - 1].geometry.width;
else
glyphs->glyphs[index].geometry.x_offset = glyphs->glyphs[index].geometry.width;
glyphs->glyphs[index - 1].geometry.width = 0;
}
else
{
glyphs->glyphs[index].geometry.width =
MAX (logical_rect.width, glyphs->glyphs[index - 1].geometry.width);
glyphs->glyphs[index - 1].geometry.width = 0;
glyphs->glyphs[index].geometry.x_offset = 0;
}
}
else
{
glyphs->glyphs[index].geometry.x_offset = 0;
glyphs->glyphs[index].geometry.width = logical_rect.width;
}
glyphs->glyphs[index].geometry.y_offset = 0;
}
static gint
get_adjusted_glyphs_list (HebrewFontInfo *font_info,
gunichar *cluster,
gint num_chrs,
PangoGlyph *glyph_lists,
const gint *shaping_table)
{
gint i = 0;
if ((num_chrs == 1) &&
is_char_type (cluster[0], DAGESHPoint|OtherPoint|HolamPoint|OneTwoPoint))
{
glyph_lists[0] = PANGO_X_MAKE_GLYPH (font_info->subfont, 0x20);
glyph_lists[1] = PANGO_X_MAKE_GLYPH (font_info->subfont,
shaping_table[ucs2iso8859_8 (cluster[0])]);
return 2;
}
else
{
while (i < num_chrs) {
glyph_lists[i] = PANGO_X_MAKE_GLYPH (font_info->subfont,
shaping_table[ucs2iso8859_8 (cluster[i])]);
i++;
}
return num_chrs;
}
}
static gint
get_glyphs_list (HebrewFontInfo *font_info,
gunichar *cluster,
gint num_chrs,
PangoGlyph *glyph_lists)
{
gint i;
switch (font_info->type)
{
case HEBREW_FONT_NONE:
for (i=0; i < num_chrs; i++)
glyph_lists[i] = pango_x_get_unknown_glyph (font_info->font);
return num_chrs;
case HEBREW_FONT_ISO8859_8:
return get_adjusted_glyphs_list (font_info, cluster,
num_chrs, glyph_lists, Sun_shape_table);
case HEBREW_FONT_ISO10646:
return get_adjusted_glyphs_list (font_info, cluster,
num_chrs, glyph_lists, Unicode_shape_table);
}
return 0;
}
static void
add_cluster (HebrewFontInfo *font_info,
PangoGlyphString *glyphs,
gint cluster_start,
gunichar *cluster,
gint num_chrs)
{
PangoGlyph glyphs_list[MAX_GLYPHS];
gint num_glyphs;
gint i;
num_glyphs = get_glyphs_list(font_info, cluster, num_chrs, glyphs_list);
for (i=0; i<num_glyphs; i++)
add_glyph (font_info, glyphs, cluster_start, glyphs_list[i],
i == 0 ? FALSE : TRUE);
}
static const char *
get_next_cluster(const char *text,
gint length,
gunichar *cluster,
gint *num_chrs)
{
const char *p;
gint n_chars = 0;
p = text;
while (p < text + length && n_chars < 3)
{
gunichar current = g_utf8_get_char (p);
if (n_chars == 0 ||
is_composible ((gunichar)(cluster[n_chars - 1]), current))
{
cluster[n_chars++] = current;
p = g_utf8_next_char (p);
}
else
break;
}
*num_chrs = n_chars;
return p;
}
static void
hebrew_engine_shape (PangoFont *font,
const char *text,
gint length,
PangoAnalysis *analysis,
PangoGlyphString *glyphs)
{
HebrewFontInfo *font_info;
const char *p;
const char *log_cluster;
gunichar cluster[MAX_CLUSTER_CHRS];
gint num_chrs;
pango_glyph_string_set_size (glyphs, 0);
font_info = get_font_info (font);
p = text;
while (p < text + length)
{
log_cluster = p;
p = get_next_cluster (p, text + length - p, cluster, &num_chrs);
add_cluster (font_info, glyphs, log_cluster - text, cluster, num_chrs);
}
}
static PangoCoverage *
hebrew_engine_get_coverage (PangoFont *font,
const char *lang)
{
PangoCoverage *result = pango_coverage_new ();
HebrewFontInfo *font_info = get_font_info (font);
if (font_info->type != HEBREW_FONT_NONE)
{
gunichar wc;
for (wc = 0x590; wc <= 0x5f4; wc++)
pango_coverage_set (result, wc, PANGO_COVERAGE_EXACT);
}
return result;
}
static PangoEngine *
hebrew_engine_x_new ()
{
PangoEngineShape *result;
result = g_new (PangoEngineShape, 1);
result->engine.id = SCRIPT_ENGINE_NAME;
result->engine.type = PANGO_ENGINE_TYPE_SHAPE;
result->engine.length = sizeof (result);
result->script_shape = hebrew_engine_shape;
result->get_coverage = hebrew_engine_get_coverage;
return (PangoEngine *)result;
}
/* The following three functions provide the public module API for
* Pango. If we are compiling it is a module, then we name the
* entry points script_engine_list, etc. But if we are compiling
* it for inclusion directly in Pango, then we need them to
* to have distinct names for this module, so we prepend
* _pango_hebrew_x_
*/
#ifdef X_MODULE_PREFIX
#define MODULE_ENTRY(func) _pango_hebrew_x_##func
#else
#define MODULE_ENTRY(func) func
#endif
/* List the engines contained within this module
*/
void
MODULE_ENTRY(script_engine_list) (PangoEngineInfo **engines, gint *n_engines)
{
*engines = script_engines;
*n_engines = G_N_ELEMENTS (script_engines);
}
/* Load a particular engine given the ID for the engine
*/
PangoEngine *
MODULE_ENTRY(script_engine_load) (const char *id)
{
if (!strcmp (id, SCRIPT_ENGINE_NAME))
return hebrew_engine_x_new ();
else
return NULL;
}
void
MODULE_ENTRY(script_engine_unload) (PangoEngine *engine)
{
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]