summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2001-01-05 21:23:31 +0000
committerOwen Taylor <otaylor@src.gnome.org>2001-01-05 21:23:31 +0000
commit61b674ffd7dc481289d1b73b79048a7ee6f2da8b (patch)
treeb12d9383e95208cf07971347d65b669494abe837 /modules
parentcfeef42ca84e57542052ac489766b02a2a5fce8f (diff)
downloadpango-61b674ffd7dc481289d1b73b79048a7ee6f2da8b.tar.gz
Adopt to new prototype for g_utf8_to_ucs4 (etc.).
Fri Jan 5 16:12:37 2001 Owen Taylor <otaylor@redhat.com> * modules/arabic/{arabic-xft,arabic}.c pango/{pango-context.c,pangoft.c,pangox.c}: Adopt to new prototype for g_utf8_to_ucs4 (etc.).
Diffstat (limited to 'modules')
-rw-r--r--modules/arabic/arabic-fc.c2
-rw-r--r--modules/arabic/arabic-xft.c2
-rw-r--r--modules/arabic/arabic.c361
3 files changed, 363 insertions, 2 deletions
diff --git a/modules/arabic/arabic-fc.c b/modules/arabic/arabic-fc.c
index 9413433d..4ee981a2 100644
--- a/modules/arabic/arabic-fc.c
+++ b/modules/arabic/arabic-fc.c
@@ -167,7 +167,7 @@ arabic_engine_shape (PangoFont *font,
ruleset = get_ruleset (font);
if (ruleset)
{
- wcs = g_utf8_to_ucs4 (text, length);
+ wcs = g_utf8_to_ucs4_fast (text, length, NULL);
properties = g_new0 (gulong, n_chars);
Assign_Arabic_Properties (wcs, properties, n_chars);
diff --git a/modules/arabic/arabic-xft.c b/modules/arabic/arabic-xft.c
index 9413433d..4ee981a2 100644
--- a/modules/arabic/arabic-xft.c
+++ b/modules/arabic/arabic-xft.c
@@ -167,7 +167,7 @@ arabic_engine_shape (PangoFont *font,
ruleset = get_ruleset (font);
if (ruleset)
{
- wcs = g_utf8_to_ucs4 (text, length);
+ wcs = g_utf8_to_ucs4_fast (text, length, NULL);
properties = g_new0 (gulong, n_chars);
Assign_Arabic_Properties (wcs, properties, n_chars);
diff --git a/modules/arabic/arabic.c b/modules/arabic/arabic.c
new file mode 100644
index 00000000..74131bff
--- /dev/null
+++ b/modules/arabic/arabic.c
@@ -0,0 +1,361 @@
+/* Pango - Arabic module
+ * arabic module
+ *
+ * (C) 2000 Karl Koehler<koehler@or.uni-bonn.de>
+ * Owen Taylor <otaylor@redhat.com>
+ *
+ */
+
+#include <stdio.h>
+#include <glib.h>
+#include <string.h>
+#include "pango-engine.h"
+#include "pangox.h"
+
+#include "arconv.h"
+#include "mulefont.h"
+#include "langboxfont.h"
+#include "naqshfont.h"
+
+/* #define DEBUG */
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+
+static PangoEngineRange arabic_range[] = {
+ { 0x060B, 0x06D3, "*" } /* 0x060B, 0x06D3 */
+};
+
+static PangoEngineInfo script_engines[] = {
+ {
+ "ArabicScriptEngineX",
+ PANGO_ENGINE_TYPE_SHAPE,
+ PANGO_RENDER_TYPE_X,
+ arabic_range, G_N_ELEMENTS(arabic_range)
+ }
+};
+
+static gint n_script_engines = G_N_ELEMENTS (script_engines);
+
+/*
+ * X window system script engine portion
+ */
+
+static ArabicFontInfo*
+arabic_unicodeinit(PangoFont *font, PangoXSubfont subfont)
+{
+ ArabicFontInfo *fs = NULL;
+
+ if (subfont != 0)
+ {
+ if ( pango_x_has_glyph /* Alif-Madda */
+ (font,PANGO_X_MAKE_GLYPH(subfont,0xFE81)))
+ {
+ fs = g_new (ArabicFontInfo,1);
+ fs->level = ar_standard | ar_unifont;
+ fs->subfonts[0] = subfont;
+
+ if ( pango_x_has_glyph /* Shadda+Kasra */
+ (font,PANGO_X_MAKE_GLYPH(subfont,0xFC62)))
+ {
+ fs->level |= ar_composedtashkeel;
+ /* extra vowels in font, hopefully */
+ }
+ if ( pango_x_has_glyph /* Lam-Min alone */
+ (font,PANGO_X_MAKE_GLYPH(subfont,0xFC42)))
+ {
+ fs->level |= ar_lig;
+ /* extra ligatures in font, hopefully */
+ }
+ }
+ }
+ return fs;
+}
+
+static ArabicFontInfo*
+find_unic_font (PangoFont *font)
+{
+ static char *charsets[] = {
+ "iso10646-1",
+ "iso8859-6.8x",
+ "mulearabic-2",
+ "urdunaqsh-0",
+/* "symbol-0" */
+ };
+
+ ArabicFontInfo *fs = NULL;
+ PangoXSubfont *subfonts;
+ int *subfont_charsets;
+ int n_subfonts;
+ int i;
+
+ GQuark info_id = g_quark_from_string ("arabic-font-info");
+ fs = g_object_get_qdata (G_OBJECT (font), info_id);
+ if (fs) return fs;
+
+ n_subfonts = pango_x_list_subfonts (font, charsets, 4,
+ &subfonts, &subfont_charsets);
+
+ for (i=0; i < n_subfonts; i++)
+ {
+ if ( !strcmp (charsets[subfont_charsets[i]], "mulearabic-2"))
+ {
+#ifdef DEBUG
+ if (getenv("PANGO_AR_NOMULEFONT") == NULL )
+#endif
+ fs = arabic_muleinit(font);
+ }
+ else if ( !strcmp (charsets[subfont_charsets[i]], "iso8859-6.8x"))
+ {
+#ifdef DEBUG
+ if (getenv("PANGO_AR_NOLBOXFONT") == NULL )
+#endif
+ fs = arabic_lboxinit(font);
+ }
+ else if ( !strcmp (charsets[subfont_charsets[i]], "urdunaqsh-0"))
+ {
+#ifdef DEBUG
+ if (getenv("PANGO_AR_NONQFONT") == NULL )
+#endif
+ fs = urdu_naqshinit(font);
+ }
+ else
+ {
+#ifdef DEBUG
+ if (getenv("PANGO_AR_NOUNIFONT") == NULL )
+#endif
+ fs = arabic_unicodeinit(font,subfonts[i]);
+ }
+ if (fs){
+ g_object_set_qdata_full (G_OBJECT (font), info_id,
+ fs, (GDestroyNotify)g_free);
+ break;
+ }
+ }
+
+ g_free (subfonts);
+ g_free (subfont_charsets);
+
+ return fs;
+}
+
+
+
+static void
+set_glyph (PangoGlyphString *glyphs,
+ PangoFont *font, PangoXSubfont subfont,
+ int i, int cluster_start, int glyph, int is_vowel)
+{
+ PangoRectangle logical_rect;
+
+ glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, glyph);
+
+ glyphs->glyphs[i].geometry.x_offset = 0;
+ glyphs->glyphs[i].geometry.y_offset = 0;
+
+ pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect);
+ glyphs->log_clusters[i] = cluster_start;
+ if (is_vowel)
+ {
+ glyphs->glyphs[i].geometry.width = 0;
+ }
+ else
+ {
+ glyphs->glyphs[i].geometry.width = logical_rect.width;
+ }
+}
+
+
+/* The following thing is actually critical ... */
+
+static void
+arabic_engine_shape (PangoFont *font,
+ const char *text,
+ int length,
+ PangoAnalysis *analysis,
+ PangoGlyphString *glyphs)
+{
+ PangoXSubfont subfont;
+ int n_chars;
+ int i;
+ ArabicFontInfo *fs;
+ const char *p;
+ const char *pold;
+ gunichar *wc;
+
+ g_return_if_fail (font != NULL);
+ g_return_if_fail (text != NULL);
+ g_return_if_fail (length >= 0);
+ g_return_if_fail (analysis != NULL);
+
+ /* We hope there is a suitible font installed ..
+ */
+
+ if (! (fs = find_unic_font (font)) )
+ {
+
+ PangoGlyph unknown_glyph = pango_x_get_unknown_glyph (font);
+
+ n_chars = g_utf8_strlen(text,length);
+ pango_glyph_string_set_size (glyphs, n_chars);
+
+ p = text;
+ for (i=0; i<n_chars; i++)
+ {
+ set_glyph (glyphs, font,
+ PANGO_X_GLYPH_SUBFONT (unknown_glyph), i,
+ p - text, PANGO_X_GLYPH_INDEX (unknown_glyph),0);
+ p = g_utf8_next_char (p);
+ }
+ return;
+ }
+
+
+ p = text;
+ if (analysis->level % 2 == 0)
+ {
+ wc = g_utf8_to_ucs4_fast(text,length,&n_chars);
+ /* We were called on a LTR directional run (e.g. some numbers);
+ fallback as simple as possible */
+ pango_glyph_string_set_size (glyphs, n_chars);
+
+ }
+ else
+ {
+ wc = (gunichar *)g_malloc(sizeof(gunichar)* (length) ); /* length is succicient: all arabic chars use at
+ least 2 bytes in utf-8 encoding */
+ n_chars = length;
+ arabic_reshape(&n_chars,text,wc,fs->level);
+ pango_glyph_string_set_size (glyphs, n_chars);
+ };
+
+
+ p = text;
+ pold = p;
+ i = 0;
+ subfont = fs->subfonts[0];
+
+ while(i < n_chars)
+ {
+ if (wc[i] == 0)
+ {
+ p = g_utf8_next_char (p);
+#ifdef DEBUG
+ fprintf(stderr,"NULL-character detected in generated string.!");
+#endif
+ i++;
+ }
+ else
+ {
+ int cluster_start ;
+ int is_vowel = arabic_isvowel(wc[i]);
+ cluster_start = is_vowel ? pold - text : p - text;
+
+ if ( fs->level & ar_mulefont )
+ {
+ arabic_mule_recode(&subfont,&(wc[i]),
+ fs->subfonts);
+ }
+ else if ( fs->level & ar_lboxfont )
+ {
+ if (( i < n_chars-1 )&&(wc[i+1] == 0))
+ {
+ arabic_lbox_recode(&subfont,&(wc[i]),
+ &(wc[i+1]),
+ fs->subfonts);
+ }
+ else
+ arabic_lbox_recode(&subfont,&(wc[i]),NULL,
+ fs->subfonts);
+ }
+ else if ( fs->level & ar_naqshfont )
+ {
+ if (( i < n_chars-1 )&&(wc[i+1] == 0))
+ {
+ urdu_naqsh_recode(&subfont,&(wc[i]),
+ &(wc[i+1]),
+ fs->subfonts);
+ }
+ else
+ urdu_naqsh_recode(&subfont,&(wc[i]),NULL,
+ fs->subfonts);
+ }
+
+ set_glyph(glyphs, font, subfont, n_chars - i - 1,
+ cluster_start, wc[i], is_vowel);
+
+ pold = p;
+ p = g_utf8_next_char (p);
+ i++;
+ }
+ }
+
+ g_free(wc);
+}
+
+
+static PangoCoverage *
+arabic_engine_get_coverage (PangoFont *font,
+ const char *lang)
+{
+ gunichar i;
+ PangoCoverage *result = pango_coverage_new ();
+
+ for (i = 0x60B; i <= 0x66D; i++)
+ pango_coverage_set (result, i, PANGO_COVERAGE_EXACT);
+ for (i = 0x670; i <= 0x6D3; i++)
+ pango_coverage_set (result, i, PANGO_COVERAGE_EXACT);
+
+ return result;
+}
+
+static PangoEngine *
+arabic_engine_x_new ()
+{
+ PangoEngineShape *result;
+
+ result = g_new (PangoEngineShape, 1);
+
+ result->engine.id = "ArabicScriptEngine";
+ result->engine.type = PANGO_ENGINE_TYPE_SHAPE;
+ result->engine.length = sizeof (result);
+ result->script_shape = arabic_engine_shape;
+ result->get_coverage = arabic_engine_get_coverage;
+
+ return (PangoEngine *)result;
+}
+
+
+
+
+
+/* The following three functions provide the public module API for
+ * Pango
+ */
+#ifdef MODULE_PREFIX
+#define MODULE_ENTRY(func) _pango_arabic_##func
+#else
+#define MODULE_ENTRY(func) func
+#endif
+
+void
+MODULE_ENTRY(script_engine_list) (PangoEngineInfo **engines, int *n_engines)
+{
+ *engines = script_engines;
+ *n_engines = n_script_engines;
+}
+
+PangoEngine *
+MODULE_ENTRY(script_engine_load) (const char *id)
+{
+ if (!strcmp (id, "ArabicScriptEngineX"))
+ return arabic_engine_x_new ();
+ else
+ return NULL;
+}
+
+void
+MODULE_ENTRY(script_engine_unload) (PangoEngine *engine)
+{
+}