summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2003-07-25 16:11:30 +0000
committerOwen Taylor <otaylor@src.gnome.org>2003-07-25 16:11:30 +0000
commit8dd3441bacfa9e9badd1a3fedf17c62f7e8df224 (patch)
tree616914fbccfe0c75f5b56a87ede9d57326868d00
parent1705254b8e07f9ca96fff7132bda44d70df908d9 (diff)
downloadpango-8dd3441bacfa9e9badd1a3fedf17c62f7e8df224.tar.gz
Port pre-base-mantra fixup code from ICU, as needed for Tamil and
Fri Jul 25 12:07:21 2003 Owen Taylor <otaylor@redhat.com> * modules/indic/mprefixups.[ch] modules/indic/indic-ot.[ch] modules/indic/indic-{xft,ft2}.c: Port pre-base-mantra fixup code from ICU, as needed for Tamil and Malayalam. (Based on patch from Sivaraj Doddannan, #111166)
-rw-r--r--ChangeLog7
-rw-r--r--ChangeLog.pre-1-107
-rw-r--r--ChangeLog.pre-1-47
-rw-r--r--ChangeLog.pre-1-67
-rw-r--r--ChangeLog.pre-1-87
-rw-r--r--modules/indic/Makefile.am4
-rw-r--r--modules/indic/indic-ft2.c19
-rw-r--r--modules/indic/indic-ot.c37
-rw-r--r--modules/indic/indic-ot.h3
-rw-r--r--modules/indic/indic-xft.c19
-rw-r--r--modules/indic/mprefixups.c125
-rw-r--r--modules/indic/mprefixups.h50
12 files changed, 274 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index a2bf4ff9..55906fcb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Fri Jul 25 12:07:21 2003 Owen Taylor <otaylor@redhat.com>
+
+ * modules/indic/mprefixups.[ch] modules/indic/indic-ot.[ch]
+ modules/indic/indic-{xft,ft2}.c: Port pre-base-mantra
+ fixup code from ICU, as needed for Tamil and Malayalam.
+ (Based on patch from Sivaraj Doddannan, #111166)
+
Fri Jul 25 11:06:14 2003 Owen Taylor <otaylor@redhat.com>
* modules/indic/indic-ot.[ch]: Port of some fixes from
diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10
index a2bf4ff9..55906fcb 100644
--- a/ChangeLog.pre-1-10
+++ b/ChangeLog.pre-1-10
@@ -1,3 +1,10 @@
+Fri Jul 25 12:07:21 2003 Owen Taylor <otaylor@redhat.com>
+
+ * modules/indic/mprefixups.[ch] modules/indic/indic-ot.[ch]
+ modules/indic/indic-{xft,ft2}.c: Port pre-base-mantra
+ fixup code from ICU, as needed for Tamil and Malayalam.
+ (Based on patch from Sivaraj Doddannan, #111166)
+
Fri Jul 25 11:06:14 2003 Owen Taylor <otaylor@redhat.com>
* modules/indic/indic-ot.[ch]: Port of some fixes from
diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4
index a2bf4ff9..55906fcb 100644
--- a/ChangeLog.pre-1-4
+++ b/ChangeLog.pre-1-4
@@ -1,3 +1,10 @@
+Fri Jul 25 12:07:21 2003 Owen Taylor <otaylor@redhat.com>
+
+ * modules/indic/mprefixups.[ch] modules/indic/indic-ot.[ch]
+ modules/indic/indic-{xft,ft2}.c: Port pre-base-mantra
+ fixup code from ICU, as needed for Tamil and Malayalam.
+ (Based on patch from Sivaraj Doddannan, #111166)
+
Fri Jul 25 11:06:14 2003 Owen Taylor <otaylor@redhat.com>
* modules/indic/indic-ot.[ch]: Port of some fixes from
diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6
index a2bf4ff9..55906fcb 100644
--- a/ChangeLog.pre-1-6
+++ b/ChangeLog.pre-1-6
@@ -1,3 +1,10 @@
+Fri Jul 25 12:07:21 2003 Owen Taylor <otaylor@redhat.com>
+
+ * modules/indic/mprefixups.[ch] modules/indic/indic-ot.[ch]
+ modules/indic/indic-{xft,ft2}.c: Port pre-base-mantra
+ fixup code from ICU, as needed for Tamil and Malayalam.
+ (Based on patch from Sivaraj Doddannan, #111166)
+
Fri Jul 25 11:06:14 2003 Owen Taylor <otaylor@redhat.com>
* modules/indic/indic-ot.[ch]: Port of some fixes from
diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8
index a2bf4ff9..55906fcb 100644
--- a/ChangeLog.pre-1-8
+++ b/ChangeLog.pre-1-8
@@ -1,3 +1,10 @@
+Fri Jul 25 12:07:21 2003 Owen Taylor <otaylor@redhat.com>
+
+ * modules/indic/mprefixups.[ch] modules/indic/indic-ot.[ch]
+ modules/indic/indic-{xft,ft2}.c: Port pre-base-mantra
+ fixup code from ICU, as needed for Tamil and Malayalam.
+ (Based on patch from Sivaraj Doddannan, #111166)
+
Fri Jul 25 11:06:14 2003 Owen Taylor <otaylor@redhat.com>
* modules/indic/indic-ot.[ch]: Port of some fixes from
diff --git a/modules/indic/Makefile.am b/modules/indic/Makefile.am
index c1a41742..a9ebc18d 100644
--- a/modules/indic/Makefile.am
+++ b/modules/indic/Makefile.am
@@ -171,7 +171,9 @@ ft2_sources = \
indic-ft2.c \
indic-ot-class-tables.c \
indic-ot.c \
- indic-ot.h
+ indic-ot.h \
+ mprefixups.c \
+ mprefixups.h
pango_indic_ft2_la_LDFLAGS = -export-dynamic -avoid-version -module $(no_undefined)
pango_indic_ft2_la_LIBADD = $(indic_ft2_libadd)
diff --git a/modules/indic/indic-ft2.c b/modules/indic/indic-ft2.c
index d40881d1..5d0b6c75 100644
--- a/modules/indic/indic-ft2.c
+++ b/modules/indic/indic-ft2.c
@@ -303,7 +303,8 @@ indic_engine_shape (PangoFont *font,
PangoOTRuleset *gsub_ruleset = NULL, *gpos_ruleset = NULL;
PangoEngineShapeIndic *indic_shape_engine = NULL;
PangoIndicInfo *indic_info = NULL;
-
+ MPreFixups *mprefixups;
+
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
g_return_if_fail (length >= 0);
@@ -321,14 +322,15 @@ indic_engine_shape (PangoFont *font,
indic_info = indic_shape_engine->indicInfo;
wc_in = expand_text (text, length, &utf8_offsets, &n_chars);
- n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, NULL, NULL, NULL);
-
+
+ n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, NULL, NULL, NULL, NULL);
+
wc_out = g_new (gunichar, n_glyphs);
indices = g_new (glong, n_glyphs);
tags = g_new (gulong, n_glyphs);
- n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, wc_out, indices, tags);
-
+ n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, wc_out, indices, tags, &mprefixups);
+
pango_glyph_string_set_size (glyphs, n_glyphs);
set_glyphs(font, face, wc_out, n_glyphs, glyphs);
@@ -339,6 +341,13 @@ indic_engine_shape (PangoFont *font,
pango_ot_ruleset_shape (gsub_ruleset, glyphs, tags);
}
+ /* Fix pre-modifiers for some scripts before base consonant */
+ if (mprefixups)
+ {
+ indic_mprefixups_apply (mprefixups, glyphs);
+ indic_mprefixups_free (mprefixups);
+ }
+
/* apply default positioning */
for (i = 0; i < glyphs->num_glyphs; i += 1)
{
diff --git a/modules/indic/indic-ot.c b/modules/indic/indic-ot.c
index 99fdff4d..ca05ae30 100644
--- a/modules/indic/indic-ot.c
+++ b/modules/indic/indic-ot.c
@@ -7,7 +7,7 @@
*/
#include "indic-ot.h"
-
+#include "mprefixups.h"
/*
* FIXME: should the IndicOutput stuff be moved
* to a spereate .h and .c file just to keep the
@@ -29,13 +29,16 @@ struct _Output
gunichar fMabove;
gunichar fMpost;
gunichar fLengthMark;
- glong fMatraIndex;
+ glong fMatraIndex;
gulong fMatraTags;
+ glong fMPreOutIndex;
+
+ MPreFixups *fMPreFixups;
};
typedef struct _Output Output;
-static void initOutput(Output *output, const glong *originalOffsets, gunichar *outChars, glong *charIndices, gulong *charTags)
+static void initOutput(Output *output, const glong *originalOffsets, gunichar *outChars, glong *charIndices, gulong *charTags, MPreFixups *mpreFixups)
{
output->fOriginalOffsets = originalOffsets;
@@ -47,6 +50,9 @@ static void initOutput(Output *output, const glong *originalOffsets, gunichar *o
output->fMatraTags = 0;
output->fMpre = output->fMbelow = output->fMabove = output->fMpost = output->fLengthMark = 0;
+
+ output->fMPreOutIndex = -1;
+ output->fMPreFixups = mpreFixups;
}
static void saveMatra(Output *output, gunichar matra, IndicOTCharClass matraClass)
@@ -70,6 +76,7 @@ static void noteMatra(Output *output, const IndicOTClassTable *classTable, gunic
IndicOTCharClass matraClass = indic_ot_get_char_class(classTable, matra);
output->fMpre = output->fMbelow = output->fMabove = output->fMpost = output->fLengthMark = 0;
+ output->fMPreOutIndex = -1;
output->fMatraIndex = matraIndex;
output->fMatraTags = matraTags;
@@ -90,6 +97,12 @@ static void noteMatra(Output *output, const IndicOTClassTable *classTable, gunic
}
}
+static void noteBaseConsonant(Output *output)
+{
+ if (output->fMPreFixups && output->fMPreOutIndex >= 0) {
+ indic_mprefixups_add(output->fMPreFixups, output->fOutIndex, output->fMPreOutIndex);
+ }
+}
static void writeChar(Output *output, gunichar ch, guint32 charIndex, gulong charTags)
{
if (output->fOutChars != NULL) {
@@ -104,6 +117,7 @@ static void writeChar(Output *output, gunichar ch, guint32 charIndex, gulong cha
static void writeMpre(Output *output)
{
if (output->fMpre != 0) {
+ output->fMPreOutIndex = output->fOutIndex;
writeChar(output, output->fMpre, output->fMatraIndex, output->fMatraTags);
}
}
@@ -144,12 +158,17 @@ static glong getOutputIndex(Output *output)
#define false 0
#define true 1
-glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags)
+glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags, MPreFixups **outMPreFixups)
{
+ MPreFixups *mpreFixups = NULL;
Output output;
glong i, prev = 0;
- initOutput(&output, utf8_offsets, out_chars, char_indices, char_tags);
+ if (outMPreFixups && (class_table->scriptFlags & SF_MPRE_FIXUP)) {
+ mpreFixups = indic_mprefixups_new (char_count);
+ }
+
+ initOutput(&output, utf8_offsets, out_chars, char_indices, char_tags, mpreFixups);
while (prev < char_count) {
glong syllable = indic_ot_find_syllable(class_table, chars, prev, char_count);
@@ -306,6 +325,9 @@ glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong c
}
}
+ /* note the base consonant for post-GSUB fixups */
+ noteBaseConsonant(&output);
+
/* write base consonant */
for (i = baseConsonant; i < bcSpan; i += 1) {
writeChar(&output, chars[i], /*i*/ prev, nukt_p);
@@ -401,6 +423,9 @@ glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong c
prev = syllable;
}
+ if (mpreFixups) {
+ *outMPreFixups = mpreFixups;
+ }
+
return getOutputIndex(&output);
}
-
diff --git a/modules/indic/indic-ot.h b/modules/indic/indic-ot.h
index 2e831f9a..caf229d4 100644
--- a/modules/indic/indic-ot.h
+++ b/modules/indic/indic-ot.h
@@ -12,6 +12,7 @@
#include <freetype/freetype.h>
#include <pango/pango-glyph.h>
#include <pango/pango-types.h>
+#include "mprefixups.h"
G_BEGIN_DECLS
@@ -241,7 +242,7 @@ gboolean indic_ot_has_below_base_form(const IndicOTClassTable *class_table, guni
glong indic_ot_find_syllable(const IndicOTClassTable *class_table, const gunichar *chars, glong prev, glong char_count);
-glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags);
+glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags, MPreFixups **outMPreFixups);
#endif /* PANGO_ENABLE_ENGINE */
diff --git a/modules/indic/indic-xft.c b/modules/indic/indic-xft.c
index 5d5afa2d..5cafdd29 100644
--- a/modules/indic/indic-xft.c
+++ b/modules/indic/indic-xft.c
@@ -302,7 +302,8 @@ indic_engine_shape (PangoFont *font,
PangoOTRuleset *gsub_ruleset = NULL, *gpos_ruleset = NULL;
PangoEngineShapeIndic *indic_shape_engine = NULL;
PangoIndicInfo *indic_info = NULL;
-
+ MPreFixups *mprefixups;
+
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
g_return_if_fail (length >= 0);
@@ -320,14 +321,15 @@ indic_engine_shape (PangoFont *font,
indic_info = indic_shape_engine->indicInfo;
wc_in = expand_text (text, length, &utf8_offsets, &n_chars);
- n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, NULL, NULL, NULL);
-
+
+ n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, NULL, NULL, NULL, NULL);
+
wc_out = g_new (gunichar, n_glyphs);
indices = g_new (glong, n_glyphs);
tags = g_new (gulong, n_glyphs);
- n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, wc_out, indices, tags);
-
+ n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, wc_out, indices, tags, &mprefixups);
+
pango_glyph_string_set_size (glyphs, n_glyphs);
set_glyphs(font, face, wc_out, n_glyphs, glyphs);
@@ -338,6 +340,13 @@ indic_engine_shape (PangoFont *font,
pango_ot_ruleset_shape (gsub_ruleset, glyphs, tags);
}
+ /* Fix pre-modifiers for some scripts before base consonant */
+ if (mprefixups)
+ {
+ indic_mprefixups_apply (mprefixups, glyphs);
+ indic_mprefixups_free (mprefixups);
+ }
+
/* apply default positioning */
for (i = 0; i < glyphs->num_glyphs; i += 1)
{
diff --git a/modules/indic/mprefixups.c b/modules/indic/mprefixups.c
new file mode 100644
index 00000000..29b126d0
--- /dev/null
+++ b/modules/indic/mprefixups.c
@@ -0,0 +1,125 @@
+/*
+ * mprefixups.h: Handle left matra placement
+ *
+ * Author: Sivaraj Doddannan
+ * Ported from IBM's ICU engine. Original copyright:
+ * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
+ *
+ * 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 <pango/pango-types.h>
+#include "mprefixups.h"
+#include <stdio.h>
+
+struct _FixupData
+{
+ glong fBaseIndex;
+ glong fMPreIndex;
+};
+
+MPreFixups *indic_mprefixups_new(glong char_count)
+{
+ MPreFixups *mprefixups = g_new (MPreFixups, 1);
+ mprefixups->fFixupCount = 0;
+ mprefixups->fFixupData = g_new (FixupData, char_count);
+
+ return mprefixups;
+}
+
+void indic_mprefixups_free (MPreFixups *mprefixups)
+{
+ g_free (mprefixups->fFixupData);
+ g_free (mprefixups);
+}
+
+void indic_mprefixups_add (MPreFixups *mprefixups, glong baseIndex, glong mpreIndex)
+{
+ /* NOTE: don't add the fixup data if the mpre is right
+ * before the base consonant glyph.
+ */
+ if (baseIndex - mpreIndex > 1) {
+ mprefixups->fFixupData[mprefixups->fFixupCount].fBaseIndex = baseIndex;
+ mprefixups->fFixupData[mprefixups->fFixupCount].fMPreIndex = mpreIndex;
+
+ mprefixups->fFixupCount += 1;
+ }
+}
+
+void indic_mprefixups_apply(MPreFixups *mprefixups, PangoGlyphString *glyphs)
+{
+ glong fixup;
+
+ for (fixup = 0; fixup < mprefixups->fFixupCount; fixup += 1) {
+ glong baseIndex = mprefixups->fFixupData[fixup].fBaseIndex;
+ glong mpreIndex = mprefixups->fFixupData[fixup].fMPreIndex;
+ glong mpreLimit, mpreCount, moveCount, mpreDest;
+ glong i;
+ PangoGlyph *mpreSave;
+ int *clusterSave;
+
+ /* determine post GSUB location of baseIndex and mpreIndex */
+ gboolean no_base = TRUE;
+ for (i = 0; i<glyphs->num_glyphs; i++) {
+ if (glyphs->log_clusters[i] == baseIndex) {
+ baseIndex = i + 1;
+ no_base = FALSE;
+ }
+ if (glyphs->log_clusters[i] == mpreIndex)
+ mpreIndex = i;
+ }
+ if (no_base)
+ break;
+
+ mpreLimit = mpreIndex + 1;
+
+ while (glyphs->glyphs[baseIndex].glyph == 0xFFFF || glyphs->glyphs[baseIndex].glyph == 0xFFFE) {
+ baseIndex -= 1;
+ }
+
+ while (glyphs->glyphs[mpreIndex].glyph == 0xFFFF || glyphs->glyphs[mpreIndex].glyph == 0xFFFE) {
+ mpreLimit += 1;
+ }
+
+ if (mpreLimit == baseIndex) {
+ continue;
+ }
+
+ mpreCount = mpreLimit - mpreIndex;
+ moveCount = baseIndex - mpreLimit;
+ mpreDest = baseIndex - mpreCount - 1;
+
+ mpreSave = g_new (PangoGlyph, mpreCount);
+ clusterSave = g_new (int, mpreCount);
+
+ for (i = 0; i < mpreCount; i += 1) {
+ mpreSave[i] = glyphs->glyphs[mpreIndex + i].glyph;
+ clusterSave[i] = glyphs->log_clusters[mpreIndex + i];
+ }
+
+ for (i = 0; i < moveCount; i += 1) {
+ glyphs->glyphs[mpreIndex + i].glyph = glyphs->glyphs[mpreLimit + i].glyph;
+ glyphs->log_clusters[mpreIndex + i] = glyphs->log_clusters[mpreLimit + i];
+ }
+
+ for (i = 0; i < mpreCount; i += 1) {
+ glyphs->glyphs[mpreDest + i].glyph = mpreSave[i];
+ glyphs->log_clusters[mpreDest + i] = clusterSave[i];
+ }
+
+ g_free(mpreSave);
+ }
+}
diff --git a/modules/indic/mprefixups.h b/modules/indic/mprefixups.h
new file mode 100644
index 00000000..4bab8cac
--- /dev/null
+++ b/modules/indic/mprefixups.h
@@ -0,0 +1,50 @@
+/*
+ * mprefixups.c: Handle left matra placement
+ *
+ * Author: Sivaraj Doddannan
+ * Ported from IBM's ICU engine. Original copyright:
+ * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
+ *
+ * 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 __MPREFIXUPS_H
+#define __MPREFIXUPS_H
+
+#include <pango/pango-types.h>
+#include <pango/pango-glyph.h>
+
+G_BEGIN_DECLS
+
+typedef struct _FixupData FixupData;
+
+struct _MPreFixups {
+ glong fFixupCount;
+ FixupData *fFixupData;
+};
+
+typedef struct _MPreFixups MPreFixups;
+
+MPreFixups *indic_mprefixups_new(glong char_count);
+void indic_mprefixups_free(MPreFixups *mprefixups);
+void indic_mprefixups_add(MPreFixups *mprefixups, glong baseIndex, glong mpreIndex);
+void indic_mprefixups_apply(MPreFixups *mprefixups, PangoGlyphString *glyphs);
+
+
+G_END_DECLS
+
+#endif
+